Skip to content

Commit 71da02d

Browse files
hay-kotOrell Bühler
authored andcommitted
feat: locations tree viewer (hay-kot#248)
* location tree API * test fixes * initial tree location elements * locations tree page * update meta-data * code-gen * store item display preferences * introduce basic table/card view elements * codegen * set parent location during location creation * add item support for tree query * refactor tree view * wip: location selector improvements * type gen * rename items -> search * remove various log statements * fix markdown rendering for description * update location selectors * fix tests * fix currency tests * formatting
1 parent a33fc5e commit 71da02d

File tree

22 files changed

+216
-389
lines changed

22 files changed

+216
-389
lines changed

backend/app/api/handlers/v1/v1_ctrl_locations.go

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,64 @@ import (
1111
"github.com/thechosenlan/homebox/backend/pkgs/server"
1212
)
1313

14-
// HandleLocationTreeQuery
15-
//
16-
// @Summary Get Locations Tree
17-
// @Tags Locations
18-
// @Produce json
19-
// @Param withItems query bool false "include items in response tree"
20-
// @Success 200 {object} []repo.TreeItem
21-
// @Router /v1/locations/tree [GET]
22-
// @Security Bearer
23-
func (ctrl *V1Controller) HandleLocationTreeQuery() errchain.HandlerFunc {
24-
fn := func(r *http.Request, query repo.TreeQuery) ([]repo.TreeItem, error) {
25-
auth := services.NewContext(r.Context())
26-
return ctrl.repo.Locations.Tree(auth, auth.GID, query)
14+
// HandleLocationTreeQuery godoc
15+
// @Summary Get All Locations
16+
// @Tags Locations
17+
// @Produce json
18+
// @Param withItems query bool false "include items in response tree"
19+
// @Success 200 {object} server.Results{items=[]repo.TreeItem}
20+
// @Router /v1/locations/tree [GET]
21+
// @Security Bearer
22+
func (ctrl *V1Controller) HandleLocationTreeQuery() server.HandlerFunc {
23+
return func(w http.ResponseWriter, r *http.Request) error {
24+
user := services.UseUserCtx(r.Context())
25+
26+
q := r.URL.Query()
27+
28+
withItems := queryBool(q.Get("withItems"))
29+
30+
locTree, err := ctrl.repo.Locations.Tree(
31+
r.Context(),
32+
user.GroupID,
33+
repo.TreeQuery{
34+
WithItems: withItems,
35+
},
36+
)
37+
38+
if err != nil {
39+
log.Err(err).Msg("failed to get locations tree")
40+
return validate.NewRequestError(err, http.StatusInternalServerError)
41+
}
42+
43+
return server.Respond(w, http.StatusOK, server.Results{Items: locTree})
44+
}
45+
}
46+
47+
// HandleLocationGetAll godoc
48+
// @Summary Get All Locations
49+
// @Tags Locations
50+
// @Produce json
51+
// @Param filterChildren query bool false "Filter locations with parents"
52+
// @Success 200 {object} server.Results{items=[]repo.LocationOutCount}
53+
// @Router /v1/locations [GET]
54+
// @Security Bearer
55+
func (ctrl *V1Controller) HandleLocationGetAll() server.HandlerFunc {
56+
return func(w http.ResponseWriter, r *http.Request) error {
57+
user := services.UseUserCtx(r.Context())
58+
59+
q := r.URL.Query()
60+
61+
filter := repo.LocationQuery{
62+
FilterChildren: queryBool(q.Get("filterChildren")),
63+
}
64+
65+
locations, err := ctrl.repo.Locations.GetAll(r.Context(), user.GroupID, filter)
66+
if err != nil {
67+
log.Err(err).Msg("failed to get locations")
68+
return validate.NewRequestError(err, http.StatusInternalServerError)
69+
}
70+
71+
return server.Respond(w, http.StatusOK, server.Results{Items: locations})
2772
}
2873

2974
return adapters.Query(fn, http.StatusOK)

backend/app/api/routes.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,12 @@ func (a *app) mountRoutes(r *chi.Mux, chain *errchain.ErrChain, repos *repo.AllR
9090
r.Post(v1Base("/actions/zero-item-time-fields"), chain.ToHandlerFunc(v1Ctrl.HandleItemDateZeroOut(), userMW...))
9191
r.Post(v1Base("/actions/ensure-import-refs"), chain.ToHandlerFunc(v1Ctrl.HandleEnsureImportRefs(), userMW...))
9292

93-
r.Get(v1Base("/locations"), chain.ToHandlerFunc(v1Ctrl.HandleLocationGetAll(), userMW...))
94-
r.Post(v1Base("/locations"), chain.ToHandlerFunc(v1Ctrl.HandleLocationCreate(), userMW...))
95-
r.Get(v1Base("/locations/tree"), chain.ToHandlerFunc(v1Ctrl.HandleLocationTreeQuery(), userMW...))
96-
r.Get(v1Base("/locations/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleLocationGet(), userMW...))
97-
r.Put(v1Base("/locations/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleLocationUpdate(), userMW...))
98-
r.Delete(v1Base("/locations/{id}"), chain.ToHandlerFunc(v1Ctrl.HandleLocationDelete(), userMW...))
93+
a.server.Get(v1Base("/locations"), v1Ctrl.HandleLocationGetAll(), userMW...)
94+
a.server.Post(v1Base("/locations"), v1Ctrl.HandleLocationCreate(), userMW...)
95+
a.server.Get(v1Base("/locations/tree"), v1Ctrl.HandleLocationTreeQuery(), userMW...)
96+
a.server.Get(v1Base("/locations/{id}"), v1Ctrl.HandleLocationGet(), userMW...)
97+
a.server.Put(v1Base("/locations/{id}"), v1Ctrl.HandleLocationUpdate(), userMW...)
98+
a.server.Delete(v1Base("/locations/{id}"), v1Ctrl.HandleLocationDelete(), userMW...)
9999

100100
r.Get(v1Base("/labels"), chain.ToHandlerFunc(v1Ctrl.HandleLabelsGetAll(), userMW...))
101101
r.Post(v1Base("/labels"), chain.ToHandlerFunc(v1Ctrl.HandleLabelsCreate(), userMW...))

backend/app/api/static/docs/docs.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,7 +1191,7 @@ const docTemplate = `{
11911191
"tags": [
11921192
"Locations"
11931193
],
1194-
"summary": "Get Locations Tree",
1194+
"summary": "Get All Locations",
11951195
"parameters": [
11961196
{
11971197
"type": "boolean",
@@ -1204,10 +1204,22 @@ const docTemplate = `{
12041204
"200": {
12051205
"description": "OK",
12061206
"schema": {
1207-
"type": "array",
1208-
"items": {
1209-
"$ref": "#/definitions/repo.TreeItem"
1210-
}
1207+
"allOf": [
1208+
{
1209+
"$ref": "#/definitions/server.Results"
1210+
},
1211+
{
1212+
"type": "object",
1213+
"properties": {
1214+
"items": {
1215+
"type": "array",
1216+
"items": {
1217+
"$ref": "#/definitions/repo.TreeItem"
1218+
}
1219+
}
1220+
}
1221+
}
1222+
]
12111223
}
12121224
}
12131225
}

backend/app/api/static/docs/swagger.json

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,7 +1183,7 @@
11831183
"tags": [
11841184
"Locations"
11851185
],
1186-
"summary": "Get Locations Tree",
1186+
"summary": "Get All Locations",
11871187
"parameters": [
11881188
{
11891189
"type": "boolean",
@@ -1196,10 +1196,22 @@
11961196
"200": {
11971197
"description": "OK",
11981198
"schema": {
1199-
"type": "array",
1200-
"items": {
1201-
"$ref": "#/definitions/repo.TreeItem"
1202-
}
1199+
"allOf": [
1200+
{
1201+
"$ref": "#/definitions/server.Results"
1202+
},
1203+
{
1204+
"type": "object",
1205+
"properties": {
1206+
"items": {
1207+
"type": "array",
1208+
"items": {
1209+
"$ref": "#/definitions/repo.TreeItem"
1210+
}
1211+
}
1212+
}
1213+
}
1214+
]
12031215
}
12041216
}
12051217
}

backend/app/api/static/docs/swagger.yaml

Lines changed: 9 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,112 +1440,19 @@ paths:
14401440
"200":
14411441
description: OK
14421442
schema:
1443-
items:
1444-
$ref: '#/definitions/repo.TreeItem'
1445-
type: array
1443+
allOf:
1444+
- $ref: '#/definitions/server.Results'
1445+
- properties:
1446+
items:
1447+
items:
1448+
$ref: '#/definitions/repo.TreeItem'
1449+
type: array
1450+
type: object
14461451
security:
14471452
- Bearer: []
1448-
summary: Get Locations Tree
1453+
summary: Get All Locations
14491454
tags:
14501455
- Locations
1451-
/v1/notifiers:
1452-
get:
1453-
produces:
1454-
- application/json
1455-
responses:
1456-
"200":
1457-
description: OK
1458-
schema:
1459-
items:
1460-
$ref: '#/definitions/repo.NotifierOut'
1461-
type: array
1462-
security:
1463-
- Bearer: []
1464-
summary: Get Notifiers
1465-
tags:
1466-
- Notifiers
1467-
post:
1468-
parameters:
1469-
- description: Notifier Data
1470-
in: body
1471-
name: payload
1472-
required: true
1473-
schema:
1474-
$ref: '#/definitions/repo.NotifierCreate'
1475-
produces:
1476-
- application/json
1477-
responses:
1478-
"200":
1479-
description: OK
1480-
schema:
1481-
$ref: '#/definitions/repo.NotifierOut'
1482-
security:
1483-
- Bearer: []
1484-
summary: Create Notifier
1485-
tags:
1486-
- Notifiers
1487-
/v1/notifiers/{id}:
1488-
delete:
1489-
parameters:
1490-
- description: Notifier ID
1491-
in: path
1492-
name: id
1493-
required: true
1494-
type: string
1495-
responses:
1496-
"204":
1497-
description: No Content
1498-
security:
1499-
- Bearer: []
1500-
summary: Delete a Notifier
1501-
tags:
1502-
- Notifiers
1503-
put:
1504-
parameters:
1505-
- description: Notifier ID
1506-
in: path
1507-
name: id
1508-
required: true
1509-
type: string
1510-
- description: Notifier Data
1511-
in: body
1512-
name: payload
1513-
required: true
1514-
schema:
1515-
$ref: '#/definitions/repo.NotifierUpdate'
1516-
responses:
1517-
"200":
1518-
description: OK
1519-
schema:
1520-
$ref: '#/definitions/repo.NotifierOut'
1521-
security:
1522-
- Bearer: []
1523-
summary: Update Notifier
1524-
tags:
1525-
- Notifiers
1526-
/v1/notifiers/test:
1527-
post:
1528-
parameters:
1529-
- description: Notifier ID
1530-
in: path
1531-
name: id
1532-
required: true
1533-
type: string
1534-
- description: URL
1535-
in: query
1536-
name: url
1537-
required: true
1538-
type: string
1539-
produces:
1540-
- application/json
1541-
responses:
1542-
"204":
1543-
description: No Content
1544-
security:
1545-
- Bearer: []
1546-
summary: Test Notifier
1547-
tags:
1548-
- Notifiers
15491456
/v1/qrcode:
15501457
get:
15511458
parameters:

backend/internal/data/ent/group/group.go

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/internal/data/ent/migrate/schema.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/internal/data/ent/schema/group.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func (Group) Fields() []ent.Field {
2727
NotEmpty(),
2828
field.Enum("currency").
2929
Default("chf").
30-
Values("chf", "usd", "eur", "gbp", "jpy", "zar", "aud", "nok", "sek", "dkk"),
30+
Values("chf", "usd", "eur", "gbp", "jpy", "zar", "aud", "nok", "sek", "dkk", "inr", "rmb", "bgn"),
3131
}
3232
}
3333

0 commit comments

Comments
 (0)