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 @@
+
+