diff --git a/backend/app/api/handlers/v1/v1_ctrl_maint_entry.go b/backend/app/api/handlers/v1/v1_ctrl_maint_entry.go index 267dbb87..63c8fb6d 100644 --- a/backend/app/api/handlers/v1/v1_ctrl_maint_entry.go +++ b/backend/app/api/handlers/v1/v1_ctrl_maint_entry.go @@ -13,7 +13,7 @@ import ( // HandleMaintenanceLogGet godoc // // @Summary Get Maintenance Log -// @Tags Maintenance +// @Tags Item Maintenance // @Produce json // @Success 200 {object} repo.MaintenanceLog // @Router /v1/items/{id}/maintenance [GET] @@ -30,7 +30,7 @@ func (ctrl *V1Controller) HandleMaintenanceLogGet() errchain.HandlerFunc { // HandleMaintenanceEntryCreate godoc // // @Summary Create Maintenance Entry -// @Tags Maintenance +// @Tags Item Maintenance // @Produce json // @Param payload body repo.MaintenanceEntryCreate true "Entry Data" // @Success 201 {object} repo.MaintenanceEntry @@ -44,39 +44,3 @@ func (ctrl *V1Controller) HandleMaintenanceEntryCreate() errchain.HandlerFunc { return adapters.ActionID("id", fn, http.StatusCreated) } - -// HandleMaintenanceEntryDelete godoc -// -// @Summary Delete Maintenance Entry -// @Tags Maintenance -// @Produce json -// @Success 204 -// @Router /v1/items/{id}/maintenance/{entry_id} [DELETE] -// @Security Bearer -func (ctrl *V1Controller) HandleMaintenanceEntryDelete() errchain.HandlerFunc { - fn := func(r *http.Request, entryID uuid.UUID) (any, error) { - auth := services.NewContext(r.Context()) - err := ctrl.repo.MaintEntry.Delete(auth, entryID) - return nil, err - } - - return adapters.CommandID("entry_id", fn, http.StatusNoContent) -} - -// HandleMaintenanceEntryUpdate godoc -// -// @Summary Update Maintenance Entry -// @Tags Maintenance -// @Produce json -// @Param payload body repo.MaintenanceEntryUpdate true "Entry Data" -// @Success 200 {object} repo.MaintenanceEntry -// @Router /v1/items/{id}/maintenance/{entry_id} [PUT] -// @Security Bearer -func (ctrl *V1Controller) HandleMaintenanceEntryUpdate() errchain.HandlerFunc { - fn := func(r *http.Request, entryID uuid.UUID, body repo.MaintenanceEntryUpdate) (repo.MaintenanceEntry, error) { - auth := services.NewContext(r.Context()) - return ctrl.repo.MaintEntry.Update(auth, entryID, body) - } - - return adapters.ActionID("entry_id", fn, http.StatusOK) -} diff --git a/backend/app/api/handlers/v1/v1_ctrl_maintenance.go b/backend/app/api/handlers/v1/v1_ctrl_maintenance.go new file mode 100644 index 00000000..647bfa70 --- /dev/null +++ b/backend/app/api/handlers/v1/v1_ctrl_maintenance.go @@ -0,0 +1,65 @@ +package v1 + +import ( + "net/http" + + "github.com/google/uuid" + "github.com/hay-kot/httpkit/errchain" + "github.com/sysadminsmedia/homebox/backend/internal/core/services" + "github.com/sysadminsmedia/homebox/backend/internal/data/repo" + "github.com/sysadminsmedia/homebox/backend/internal/web/adapters" +) + +// HandleMaintenanceGetAll godoc +// +// @Summary Query All Maintenance +// @Tags Maintenance +// @Produce json +// @Param filters query repo.MaintenanceFilters false "which maintenance to retrieve" +// @Success 200 {array} repo.MaintenanceEntryWithDetails[] +// @Router /v1/maintenance [GET] +// @Security Bearer +func (ctrl *V1Controller) HandleMaintenanceGetAll() errchain.HandlerFunc { + fn := func(r *http.Request, filters repo.MaintenanceFilters) ([]repo.MaintenanceEntryWithDetails, error) { + auth := services.NewContext(r.Context()) + return ctrl.repo.MaintEntry.GetAllMaintenance(auth, auth.GID, filters) + } + + return adapters.Query(fn, http.StatusOK) +} + +// HandleMaintenanceEntryUpdate godoc +// +// @Summary Update Maintenance Entry +// @Tags Maintenance +// @Produce json +// @Param payload body repo.MaintenanceEntryUpdate true "Entry Data" +// @Success 200 {object} repo.MaintenanceEntry +// @Router /v1/maintenance/{id} [PUT] +// @Security Bearer +func (ctrl *V1Controller) HandleMaintenanceEntryUpdate() errchain.HandlerFunc { + fn := func(r *http.Request, entryID uuid.UUID, body repo.MaintenanceEntryUpdate) (repo.MaintenanceEntry, error) { + auth := services.NewContext(r.Context()) + return ctrl.repo.MaintEntry.Update(auth, entryID, body) + } + + return adapters.ActionID("id", fn, http.StatusOK) +} + +// HandleMaintenanceEntryDelete godoc +// +// @Summary Delete Maintenance Entry +// @Tags Maintenance +// @Produce json +// @Success 204 +// @Router /v1/maintenance/{id} [DELETE] +// @Security Bearer +func (ctrl *V1Controller) HandleMaintenanceEntryDelete() errchain.HandlerFunc { + fn := func(r *http.Request, entryID uuid.UUID) (any, error) { + auth := services.NewContext(r.Context()) + err := ctrl.repo.MaintEntry.Delete(auth, entryID) + return nil, err + } + + return adapters.CommandID("id", fn, http.StatusNoContent) +} diff --git a/backend/app/api/routes.go b/backend/app/api/routes.go index 03288df5..386675e0 100644 --- a/backend/app/api/routes.go +++ b/backend/app/api/routes.go @@ -4,6 +4,12 @@ import ( "embed" "errors" "fmt" + "io" + "mime" + "net/http" + "path" + "path/filepath" + "github.com/go-chi/chi/v5" "github.com/hay-kot/httpkit/errchain" httpSwagger "github.com/swaggo/http-swagger/v2" // http-swagger middleware @@ -13,11 +19,6 @@ import ( _ "github.com/sysadminsmedia/homebox/backend/app/api/static/docs" "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles" "github.com/sysadminsmedia/homebox/backend/internal/data/repo" - "io" - "mime" - "net/http" - "path" - "path/filepath" ) const prefix = "/api" @@ -133,11 +134,14 @@ func (a *app) mountRoutes(r *chi.Mux, chain *errchain.ErrChain, repos *repo.AllR r.Get("/items/{id}/maintenance", chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceLogGet(), userMW...)) r.Post("/items/{id}/maintenance", chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceEntryCreate(), userMW...)) - r.Put("/items/{id}/maintenance/{entry_id}", chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceEntryUpdate(), userMW...)) - r.Delete("/items/{id}/maintenance/{entry_id}", chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceEntryDelete(), userMW...)) r.Get("/assets/{id}", chain.ToHandlerFunc(v1Ctrl.HandleAssetGet(), userMW...)) + // Maintenance + r.Get("/maintenance", chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceGetAll(), userMW...)) + r.Put("/maintenance/{id}", chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceEntryUpdate(), userMW...)) + r.Delete("/maintenance/{id}", chain.ToHandlerFunc(v1Ctrl.HandleMaintenanceEntryDelete(), userMW...)) + // Notifiers r.Get("/notifiers", chain.ToHandlerFunc(v1Ctrl.HandleGetUserNotifiers(), userMW...)) r.Post("/notifiers", chain.ToHandlerFunc(v1Ctrl.HandleCreateNotifier(), userMW...)) diff --git a/backend/app/api/static/docs/docs.go b/backend/app/api/static/docs/docs.go index 7c9a7486..7fef44b3 100644 --- a/backend/app/api/static/docs/docs.go +++ b/backend/app/api/static/docs/docs.go @@ -917,7 +917,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Maintenance" + "Item Maintenance" ], "summary": "Get Maintenance Log", "responses": { @@ -939,7 +939,7 @@ const docTemplate = `{ "application/json" ], "tags": [ - "Maintenance" + "Item Maintenance" ], "summary": "Create Maintenance Entry", "parameters": [ @@ -963,60 +963,6 @@ const docTemplate = `{ } } }, - "/v1/items/{id}/maintenance/{entry_id}": { - "put": { - "security": [ - { - "Bearer": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Maintenance" - ], - "summary": "Update Maintenance Entry", - "parameters": [ - { - "description": "Entry Data", - "name": "payload", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/repo.MaintenanceEntryUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/repo.MaintenanceEntry" - } - } - } - }, - "delete": { - "security": [ - { - "Bearer": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Maintenance" - ], - "summary": "Delete Maintenance Entry", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/v1/items/{id}/path": { "get": { "security": [ @@ -1409,6 +1355,104 @@ const docTemplate = `{ } } }, + "/v1/maintenance": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Maintenance" + ], + "summary": "Query All Maintenance", + "parameters": [ + { + "enum": [ + "scheduled", + "completed", + "both" + ], + "type": "string", + "x-enum-varnames": [ + "MaintenanceFilterStatusScheduled", + "MaintenanceFilterStatusCompleted", + "MaintenanceFilterStatusBoth" + ], + "name": "status", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.MaintenanceEntryWithDetails" + } + } + } + } + } + }, + "/v1/maintenance/{id}": { + "put": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Maintenance" + ], + "summary": "Update Maintenance Entry", + "parameters": [ + { + "description": "Entry Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.MaintenanceEntryUpdate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.MaintenanceEntry" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Maintenance" + ], + "summary": "Delete Maintenance Entry", + "responses": { + "204": { + "description": "No Content" + } + } + } + }, "/v1/notifiers": { "get": { "security": [ @@ -2476,6 +2520,9 @@ const docTemplate = `{ "parent": { "$ref": "#/definitions/repo.LocationSummary" }, + "totalPrice": { + "type": "number" + }, "updatedAt": { "type": "string" } @@ -2611,6 +2658,49 @@ const docTemplate = `{ } } }, + "repo.MaintenanceEntryWithDetails": { + "type": "object", + "properties": { + "completedDate": { + "type": "string" + }, + "cost": { + "type": "string", + "example": "0" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "itemID": { + "type": "string" + }, + "itemName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "scheduledDate": { + "type": "string" + } + } + }, + "repo.MaintenanceFilterStatus": { + "type": "string", + "enum": [ + "scheduled", + "completed", + "both" + ], + "x-enum-varnames": [ + "MaintenanceFilterStatusScheduled", + "MaintenanceFilterStatusCompleted", + "MaintenanceFilterStatusBoth" + ] + }, "repo.MaintenanceLog": { "type": "object", "properties": { diff --git a/backend/app/api/static/docs/swagger.json b/backend/app/api/static/docs/swagger.json index 2b695bc5..6c642d8d 100644 --- a/backend/app/api/static/docs/swagger.json +++ b/backend/app/api/static/docs/swagger.json @@ -910,7 +910,7 @@ "application/json" ], "tags": [ - "Maintenance" + "Item Maintenance" ], "summary": "Get Maintenance Log", "responses": { @@ -932,7 +932,7 @@ "application/json" ], "tags": [ - "Maintenance" + "Item Maintenance" ], "summary": "Create Maintenance Entry", "parameters": [ @@ -956,60 +956,6 @@ } } }, - "/v1/items/{id}/maintenance/{entry_id}": { - "put": { - "security": [ - { - "Bearer": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Maintenance" - ], - "summary": "Update Maintenance Entry", - "parameters": [ - { - "description": "Entry Data", - "name": "payload", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/repo.MaintenanceEntryUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/repo.MaintenanceEntry" - } - } - } - }, - "delete": { - "security": [ - { - "Bearer": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Maintenance" - ], - "summary": "Delete Maintenance Entry", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/v1/items/{id}/path": { "get": { "security": [ @@ -1402,6 +1348,104 @@ } } }, + "/v1/maintenance": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Maintenance" + ], + "summary": "Query All Maintenance", + "parameters": [ + { + "enum": [ + "scheduled", + "completed", + "both" + ], + "type": "string", + "x-enum-varnames": [ + "MaintenanceFilterStatusScheduled", + "MaintenanceFilterStatusCompleted", + "MaintenanceFilterStatusBoth" + ], + "name": "status", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.MaintenanceEntryWithDetails" + } + } + } + } + } + }, + "/v1/maintenance/{id}": { + "put": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Maintenance" + ], + "summary": "Update Maintenance Entry", + "parameters": [ + { + "description": "Entry Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.MaintenanceEntryUpdate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.MaintenanceEntry" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Maintenance" + ], + "summary": "Delete Maintenance Entry", + "responses": { + "204": { + "description": "No Content" + } + } + } + }, "/v1/notifiers": { "get": { "security": [ @@ -2607,6 +2651,49 @@ } } }, + "repo.MaintenanceEntryWithDetails": { + "type": "object", + "properties": { + "completedDate": { + "type": "string" + }, + "cost": { + "type": "string", + "example": "0" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "itemID": { + "type": "string" + }, + "itemName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "scheduledDate": { + "type": "string" + } + } + }, + "repo.MaintenanceFilterStatus": { + "type": "string", + "enum": [ + "scheduled", + "completed", + "both" + ], + "x-enum-varnames": [ + "MaintenanceFilterStatusScheduled", + "MaintenanceFilterStatusCompleted", + "MaintenanceFilterStatusBoth" + ] + }, "repo.MaintenanceLog": { "type": "object", "properties": { @@ -2710,9 +2797,6 @@ }, "total": { "type": "integer" - }, - "totalPrice": { - "type": "number" } } }, @@ -2995,4 +3079,4 @@ "in": "header" } } -} +} \ No newline at end of file diff --git a/backend/app/api/static/docs/swagger.yaml b/backend/app/api/static/docs/swagger.yaml index dbb31e6c..d6275708 100644 --- a/backend/app/api/static/docs/swagger.yaml +++ b/backend/app/api/static/docs/swagger.yaml @@ -390,6 +390,8 @@ definitions: type: string parent: $ref: '#/definitions/repo.LocationSummary' + totalPrice: + type: number updatedAt: type: string type: object @@ -479,6 +481,36 @@ definitions: scheduledDate: type: string type: object + repo.MaintenanceEntryWithDetails: + properties: + completedDate: + type: string + cost: + example: "0" + type: string + description: + type: string + id: + type: string + itemID: + type: string + itemName: + type: string + name: + type: string + scheduledDate: + type: string + type: object + repo.MaintenanceFilterStatus: + enum: + - scheduled + - completed + - both + type: string + x-enum-varnames: + - MaintenanceFilterStatusScheduled + - MaintenanceFilterStatusCompleted + - MaintenanceFilterStatusBoth repo.MaintenanceLog: properties: costAverage: @@ -1228,7 +1260,7 @@ paths: - Bearer: [] summary: Get Maintenance Log tags: - - Maintenance + - Item Maintenance post: parameters: - description: Entry Data @@ -1248,39 +1280,7 @@ paths: - Bearer: [] summary: Create Maintenance Entry tags: - - Maintenance - /v1/items/{id}/maintenance/{entry_id}: - delete: - produces: - - application/json - responses: - "204": - description: No Content - security: - - Bearer: [] - summary: Delete Maintenance Entry - tags: - - Maintenance - put: - parameters: - - description: Entry Data - in: body - name: payload - required: true - schema: - $ref: '#/definitions/repo.MaintenanceEntryUpdate' - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/repo.MaintenanceEntry' - security: - - Bearer: [] - summary: Update Maintenance Entry - tags: - - Maintenance + - Item Maintenance /v1/items/{id}/path: get: parameters: @@ -1581,6 +1581,66 @@ paths: summary: Get Locations Tree tags: - Locations + /v1/maintenance: + get: + parameters: + - enum: + - scheduled + - completed + - both + in: query + name: status + type: string + x-enum-varnames: + - MaintenanceFilterStatusScheduled + - MaintenanceFilterStatusCompleted + - MaintenanceFilterStatusBoth + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/repo.MaintenanceEntryWithDetails' + type: array + security: + - Bearer: [] + summary: Query All Maintenance + tags: + - Maintenance + /v1/maintenance/{id}: + delete: + produces: + - application/json + responses: + "204": + description: No Content + security: + - Bearer: [] + summary: Delete Maintenance Entry + tags: + - Maintenance + put: + parameters: + - description: Entry Data + in: body + name: payload + required: true + schema: + $ref: '#/definitions/repo.MaintenanceEntryUpdate' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/repo.MaintenanceEntry' + security: + - Bearer: [] + summary: Update Maintenance Entry + tags: + - Maintenance /v1/notifiers: get: produces: diff --git a/backend/go.sum b/backend/go.sum index 6b273da0..15ebc039 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -110,6 +110,8 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.14.23 h1:gbShiuAP1W5j9UOksQ06aiiqPMxYecovVGwmTxWtuw0= github.com/mattn/go-sqlite3 v1.14.23/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= @@ -119,6 +121,8 @@ github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJm github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/olahol/melody v1.2.1 h1:xdwRkzHxf+B0w4TKbGpUSSkV516ZucQZJIWLztOWICQ= github.com/olahol/melody v1.2.1/go.mod h1:GgkTl6Y7yWj/HtfD48Q5vLKPVoZOH+Qqgfa7CvJgJM4= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= @@ -136,6 +140,10 @@ github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= diff --git a/backend/internal/data/repo/repo_locations.go b/backend/internal/data/repo/repo_locations.go index f5796d50..1797ca6f 100644 --- a/backend/internal/data/repo/repo_locations.go +++ b/backend/internal/data/repo/repo_locations.go @@ -48,8 +48,8 @@ type ( LocationOut struct { Parent *LocationSummary `json:"parent,omitempty"` LocationSummary - Children []LocationSummary `json:"children"` - TotalPrice float64 `json:"totalPrice"` + Children []LocationSummary `json:"children"` + TotalPrice float64 `json:"totalPrice"` } ) diff --git a/backend/internal/data/repo/repo_maintenance.go b/backend/internal/data/repo/repo_maintenance.go new file mode 100644 index 00000000..c488efd7 --- /dev/null +++ b/backend/internal/data/repo/repo_maintenance.go @@ -0,0 +1,72 @@ +package repo + +import ( + "context" + "time" + + "github.com/google/uuid" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/group" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/item" + "github.com/sysadminsmedia/homebox/backend/internal/data/ent/maintenanceentry" +) + +type ( + MaintenanceEntryWithDetails struct { + MaintenanceEntry + ItemName string `json:"itemName"` + ItemID uuid.UUID `json:"itemID"` + } +) + +var ( + mapEachMaintenanceEntryWithDetails = mapTEachFunc(mapMaintenanceEntryWithDetails) +) + +func mapMaintenanceEntryWithDetails(entry *ent.MaintenanceEntry) MaintenanceEntryWithDetails { + return MaintenanceEntryWithDetails{ + MaintenanceEntry: mapMaintenanceEntry(entry), + ItemName: entry.Edges.Item.Name, + ItemID: entry.ItemID, + } +} + +type MaintenanceFilterStatus string + +const ( + MaintenanceFilterStatusScheduled MaintenanceFilterStatus = "scheduled" + MaintenanceFilterStatusCompleted MaintenanceFilterStatus = "completed" + MaintenanceFilterStatusBoth MaintenanceFilterStatus = "both" +) + +type MaintenanceFilters struct { + Status MaintenanceFilterStatus `json:"status" schema:"status"` +} + +func (r *MaintenanceEntryRepository) GetAllMaintenance(ctx context.Context, groupID uuid.UUID, filters MaintenanceFilters) ([]MaintenanceEntryWithDetails, error) { + query := r.db.MaintenanceEntry.Query().Where( + maintenanceentry.HasItemWith( + item.HasGroupWith(group.IDEQ(groupID)), + ), + ) + + if filters.Status == MaintenanceFilterStatusScheduled { + query = query.Where(maintenanceentry.Or( + maintenanceentry.DateIsNil(), + maintenanceentry.DateEQ(time.Time{}), + )) + } else if filters.Status == MaintenanceFilterStatusCompleted { + query = query.Where( + maintenanceentry.Not(maintenanceentry.Or( + maintenanceentry.DateIsNil(), + maintenanceentry.DateEQ(time.Time{})), + )) + } + entries, err := query.WithItem().Order(maintenanceentry.ByScheduledDate()).All(ctx) + + if err != nil { + return nil, err + } + + return mapEachMaintenanceEntryWithDetails(entries), nil +} diff --git a/docs/docs/api/openapi-2.0.json b/docs/docs/api/openapi-2.0.json index 2b695bc5..6c642d8d 100644 --- a/docs/docs/api/openapi-2.0.json +++ b/docs/docs/api/openapi-2.0.json @@ -910,7 +910,7 @@ "application/json" ], "tags": [ - "Maintenance" + "Item Maintenance" ], "summary": "Get Maintenance Log", "responses": { @@ -932,7 +932,7 @@ "application/json" ], "tags": [ - "Maintenance" + "Item Maintenance" ], "summary": "Create Maintenance Entry", "parameters": [ @@ -956,60 +956,6 @@ } } }, - "/v1/items/{id}/maintenance/{entry_id}": { - "put": { - "security": [ - { - "Bearer": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Maintenance" - ], - "summary": "Update Maintenance Entry", - "parameters": [ - { - "description": "Entry Data", - "name": "payload", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/repo.MaintenanceEntryUpdate" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/repo.MaintenanceEntry" - } - } - } - }, - "delete": { - "security": [ - { - "Bearer": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Maintenance" - ], - "summary": "Delete Maintenance Entry", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/v1/items/{id}/path": { "get": { "security": [ @@ -1402,6 +1348,104 @@ } } }, + "/v1/maintenance": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Maintenance" + ], + "summary": "Query All Maintenance", + "parameters": [ + { + "enum": [ + "scheduled", + "completed", + "both" + ], + "type": "string", + "x-enum-varnames": [ + "MaintenanceFilterStatusScheduled", + "MaintenanceFilterStatusCompleted", + "MaintenanceFilterStatusBoth" + ], + "name": "status", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/repo.MaintenanceEntryWithDetails" + } + } + } + } + } + }, + "/v1/maintenance/{id}": { + "put": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Maintenance" + ], + "summary": "Update Maintenance Entry", + "parameters": [ + { + "description": "Entry Data", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/repo.MaintenanceEntryUpdate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/repo.MaintenanceEntry" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Maintenance" + ], + "summary": "Delete Maintenance Entry", + "responses": { + "204": { + "description": "No Content" + } + } + } + }, "/v1/notifiers": { "get": { "security": [ @@ -2607,6 +2651,49 @@ } } }, + "repo.MaintenanceEntryWithDetails": { + "type": "object", + "properties": { + "completedDate": { + "type": "string" + }, + "cost": { + "type": "string", + "example": "0" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "itemID": { + "type": "string" + }, + "itemName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "scheduledDate": { + "type": "string" + } + } + }, + "repo.MaintenanceFilterStatus": { + "type": "string", + "enum": [ + "scheduled", + "completed", + "both" + ], + "x-enum-varnames": [ + "MaintenanceFilterStatusScheduled", + "MaintenanceFilterStatusCompleted", + "MaintenanceFilterStatusBoth" + ] + }, "repo.MaintenanceLog": { "type": "object", "properties": { @@ -2710,9 +2797,6 @@ }, "total": { "type": "integer" - }, - "totalPrice": { - "type": "number" } } }, @@ -2995,4 +3079,4 @@ "in": "header" } } -} +} \ No newline at end of file diff --git a/frontend/components/Maintenance/EditModal.vue b/frontend/components/Maintenance/EditModal.vue new file mode 100644 index 00000000..ce917dc8 --- /dev/null +++ b/frontend/components/Maintenance/EditModal.vue @@ -0,0 +1,139 @@ + + + diff --git a/frontend/layouts/default.vue b/frontend/layouts/default.vue index b7b87389..4e7abe65 100644 --- a/frontend/layouts/default.vue +++ b/frontend/layouts/default.vue @@ -12,15 +12,15 @@
-
+