forked from mirrors/homebox
feat: support item nesting in tree view (#306)
This commit is contained in:
parent
9d9b05d8a6
commit
fb57120067
1 changed files with 46 additions and 17 deletions
|
@ -251,11 +251,11 @@ type TreeQuery struct {
|
||||||
|
|
||||||
func (lr *LocationRepository) Tree(ctx context.Context, GID uuid.UUID, tq TreeQuery) ([]TreeItem, error) {
|
func (lr *LocationRepository) Tree(ctx context.Context, GID uuid.UUID, tq TreeQuery) ([]TreeItem, error) {
|
||||||
query := `
|
query := `
|
||||||
WITH recursive location_tree(id, NAME, location_children, level, node_type) AS
|
WITH recursive location_tree(id, NAME, parent_id, level, node_type) AS
|
||||||
(
|
(
|
||||||
SELECT id,
|
SELECT id,
|
||||||
NAME,
|
NAME,
|
||||||
location_children,
|
location_children AS parent_id,
|
||||||
0 AS level,
|
0 AS level,
|
||||||
'location' AS node_type
|
'location' AS node_type
|
||||||
FROM locations
|
FROM locations
|
||||||
|
@ -265,41 +265,70 @@ func (lr *LocationRepository) Tree(ctx context.Context, GID uuid.UUID, tq TreeQu
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT c.id,
|
SELECT c.id,
|
||||||
c.NAME,
|
c.NAME,
|
||||||
c.location_children,
|
c.location_children AS parent_id,
|
||||||
level + 1,
|
level + 1,
|
||||||
'location' AS node_type
|
'location' AS node_type
|
||||||
FROM locations c
|
FROM locations c
|
||||||
JOIN location_tree p
|
JOIN location_tree p
|
||||||
ON c.location_children = p.id
|
ON c.location_children = p.id
|
||||||
WHERE level < 10 -- prevent infinite loop & excessive recursion
|
WHERE level < 10 -- prevent infinite loop & excessive recursion
|
||||||
|
){{ WITH_ITEMS }}
|
||||||
|
|
||||||
{{ WITH_ITEMS }}
|
|
||||||
)
|
|
||||||
SELECT id,
|
SELECT id,
|
||||||
NAME,
|
NAME,
|
||||||
level,
|
level,
|
||||||
location_children,
|
parent_id,
|
||||||
node_type
|
node_type
|
||||||
|
FROM (
|
||||||
|
SELECT *
|
||||||
FROM location_tree
|
FROM location_tree
|
||||||
ORDER BY level,
|
|
||||||
node_type DESC, -- sort locations before items
|
|
||||||
|
{{ WITH_ITEMS_FROM }}
|
||||||
|
|
||||||
|
|
||||||
|
) tree
|
||||||
|
ORDER BY node_type DESC, -- sort locations before items
|
||||||
|
level,
|
||||||
lower(NAME)`
|
lower(NAME)`
|
||||||
|
|
||||||
if tq.WithItems {
|
if tq.WithItems {
|
||||||
itemQuery := `
|
itemQuery := `, item_tree(id, NAME, parent_id, level, node_type) AS
|
||||||
|
(
|
||||||
|
SELECT id,
|
||||||
|
NAME,
|
||||||
|
location_items as parent_id,
|
||||||
|
0 AS level,
|
||||||
|
'item' AS node_type
|
||||||
|
FROM items
|
||||||
|
WHERE item_children IS NULL
|
||||||
|
AND location_items IN (SELECT id FROM location_tree)
|
||||||
|
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT i.id,
|
|
||||||
i.name,
|
SELECT c.id,
|
||||||
location_items as location_children,
|
c.NAME,
|
||||||
|
c.item_children AS parent_id,
|
||||||
level + 1,
|
level + 1,
|
||||||
'item' AS node_type
|
'item' AS node_type
|
||||||
FROM items i
|
FROM items c
|
||||||
JOIN location_tree p
|
JOIN item_tree p
|
||||||
ON i.location_items = p.id
|
ON c.item_children = p.id
|
||||||
WHERE level < 10 -- prevent infinite loop & excessive recursion`
|
WHERE c.item_children IS NOT NULL
|
||||||
|
AND level < 10 -- prevent infinite loop & excessive recursion
|
||||||
|
)`
|
||||||
|
|
||||||
|
// Conditional table joined to main query
|
||||||
|
itemsFrom := `
|
||||||
|
UNION ALL
|
||||||
|
SELECT *
|
||||||
|
FROM item_tree`
|
||||||
|
|
||||||
query = strings.ReplaceAll(query, "{{ WITH_ITEMS }}", itemQuery)
|
query = strings.ReplaceAll(query, "{{ WITH_ITEMS }}", itemQuery)
|
||||||
|
query = strings.ReplaceAll(query, "{{ WITH_ITEMS_FROM }}", itemsFrom)
|
||||||
} else {
|
} else {
|
||||||
query = strings.ReplaceAll(query, "{{ WITH_ITEMS }}", "")
|
query = strings.ReplaceAll(query, "{{ WITH_ITEMS }}", "")
|
||||||
|
query = strings.ReplaceAll(query, "{{ WITH_ITEMS_FROM }}", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
rows, err := lr.db.Sql().QueryContext(ctx, query, GID)
|
rows, err := lr.db.Sql().QueryContext(ctx, query, GID)
|
||||||
|
|
Loading…
Add table
Reference in a new issue