diff --git a/api/devices_list.go b/api/devices_list.go index d3bb44c..2f6097e 100644 --- a/api/devices_list.go +++ b/api/devices_list.go @@ -23,9 +23,14 @@ type DevicesListParams struct { } func (dlp *DevicesListParams) FillFromQuery(query Queryable) { - dlp.Status, _ = strconv.Atoi(query.Get("status")) - if dlp.Status > 2 { - dlp.Status = 2 + statusStr := query.Get("status") + switch statusStr { + case "0": + dlp.Status = 0 + case "1": + dlp.Status = 1 + default: + dlp.Status = -1 } dlp.Q = query.Get("q") @@ -68,8 +73,8 @@ func (dlp DevicesListParams) Query() (expr []bob.Mod[*dialect.SelectQuery]) { } func (dlp DevicesListParams) CountQuery() (expr []bob.Mod[*dialect.SelectQuery]) { - if dlp.Status > 0 { - expr = append(expr, models.SelectWhere.Devices.Enable.EQ(int32(dlp.Status-1))) + if dlp.Status >= 0 { + expr = append(expr, models.SelectWhere.Devices.Enable.EQ(int32(dlp.Status))) } if dlp.Q != "" { diff --git a/config/default.go b/config/default.go index 7f0a7d8..0c44537 100644 --- a/config/default.go +++ b/config/default.go @@ -56,8 +56,9 @@ var DefaultConfig = map[string]any{ "telemetry.trace.ratio": 1, - "web.dependencies.htmx.version": "1.9.12", - "web.dependencies.dayjs.version": "1.11.10", + "web.dependencies.htmx.version": "1.9.12", + "web.dependencies.dayjs.version": "1.11.10", + "web.dependencies.alpinejs.version": "3.13.10", "runtime.version": "0.0.1", "runtime.environment": "development", diff --git a/go.mod b/go.mod index 057c44c..b56ae3a 100644 --- a/go.mod +++ b/go.mod @@ -40,6 +40,8 @@ require ( github.com/boreq/errors v0.1.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/gosimple/slug v1.14.0 // indirect + github.com/gosimple/unidecode v1.0.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect github.com/lithammer/shortuuid/v3 v3.0.7 // indirect github.com/oklog/ulid v1.3.1 // indirect diff --git a/go.sum b/go.sum index b38c892..e662de4 100644 --- a/go.sum +++ b/go.sum @@ -184,6 +184,10 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gosimple/slug v1.14.0 h1:RtTL/71mJNDfpUbCOmnf/XFkzKRtD6wL6Uy+3akm4Es= +github.com/gosimple/slug v1.14.0/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= +github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o= +github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc= github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is= github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= diff --git a/server/routes/device_validate_name.go b/server/routes/device_validate_name.go new file mode 100644 index 0000000..6934360 --- /dev/null +++ b/server/routes/device_validate_name.go @@ -0,0 +1,59 @@ +package routes + +import ( + "net/http" + + "github.com/gosimple/slug" + "github.com/tigorlazuardi/redmage/pkg/errs" + "github.com/tigorlazuardi/redmage/pkg/log" + "github.com/tigorlazuardi/redmage/views/devicesview/adddevice" +) + +func (routes *Routes) DevicesValidateNameHTMX(rw http.ResponseWriter, req *http.Request) { + ctx, span := tracer.Start(req.Context(), "*Routes.ValidateName") + defer span.End() + + var nameData adddevice.NameInputData + nameData.Value = req.FormValue("name") + nameComponent := adddevice.NameInput(nameData) + s := req.FormValue("slug") + if s != "" || nameData.Value == "" { + if err := nameComponent.Render(ctx, rw); err != nil { + log.New(ctx).Err(err).Error("failed to render name input") + } + return + } + s = slug.Make(nameData.Value) + + slugData := adddevice.SlugInputData{ + Value: s, + HXSwapOOB: true, + } + exist, err := routes.API.DevicesValidateSlug(ctx, s) + if err != nil { + log.New(ctx).Err(err).Error("failed to validate slug") + _, message := errs.HTTPMessage(err) + slugData.Error = message + _ = nameComponent.Render(ctx, rw) + if err := adddevice.SlugInput(slugData).Render(ctx, rw); err != nil { + log.New(ctx).Err(err).Error("failed to render name input") + } + } + + if exist { + slugData.Error = "Device with this identifier already exist. Please change the value manually." + // rw.WriteHeader(http.StatusConflict) + _ = nameComponent.Render(ctx, rw) + if err := adddevice.SlugInput(slugData).Render(ctx, rw); err != nil { + log.New(ctx).Err(err).Error("failed to render name input") + } + return + } + + slugData.Valid = "Identifier is available" + + _ = nameComponent.Render(ctx, rw) + if err := adddevice.SlugInput(slugData).Render(ctx, rw); err != nil { + log.New(ctx).Err(err).Error("failed to render name input") + } +} diff --git a/server/routes/device_validate_slug.go b/server/routes/device_validate_slug.go index 4f70354..8099b9a 100644 --- a/server/routes/device_validate_slug.go +++ b/server/routes/device_validate_slug.go @@ -3,6 +3,7 @@ package routes import ( "net/http" + "github.com/gosimple/slug" "github.com/tigorlazuardi/redmage/pkg/errs" "github.com/tigorlazuardi/redmage/pkg/log" "github.com/tigorlazuardi/redmage/views/devicesview/adddevice" @@ -13,7 +14,7 @@ func (routes *Routes) DevicesValidateSlugHTMX(rw http.ResponseWriter, req *http. defer span.End() var data adddevice.SlugInputData - data.Value = req.FormValue("slug") + data.Value = slug.Make(req.FormValue("slug")) if data.Value == "" { if err := adddevice.SlugInput(data).Render(ctx, rw); err != nil { log.New(ctx).Err(err).Error("failed to render slug input") diff --git a/server/routes/routes.go b/server/routes/routes.go index a864a8e..2681a54 100644 --- a/server/routes/routes.go +++ b/server/routes/routes.go @@ -64,6 +64,7 @@ func (routes *Routes) registerHTMXRoutes(router chi.Router) { router.Get("/subreddits/validate/schedule", routes.SubredditValidateScheduleHTMX) router.Post("/devices/add/validate/slug", routes.DevicesValidateSlugHTMX) + router.Post("/devices/add/validate/name", routes.DevicesValidateNameHTMX) } func (routes *Routes) registerWWWRoutes(router chi.Router) { diff --git a/views/devicesview/adddevice/aspect_ratio_tolerance_input.templ b/views/devicesview/adddevice/aspect_ratio_tolerance_input.templ new file mode 100644 index 0000000..1c04f6d --- /dev/null +++ b/views/devicesview/adddevice/aspect_ratio_tolerance_input.templ @@ -0,0 +1,39 @@ +package adddevice + +import "fmt" + +type AspectRatioToleranceData struct { + Value float64 +} + +templ AspectRatioToleranceInput(data AspectRatioToleranceData) { + +} diff --git a/views/devicesview/adddevice/max_image_resolution_input.templ b/views/devicesview/adddevice/max_image_resolution_input.templ new file mode 100644 index 0000000..cd7bd87 --- /dev/null +++ b/views/devicesview/adddevice/max_image_resolution_input.templ @@ -0,0 +1,99 @@ +package adddevice + +import "fmt" +import "github.com/tigorlazuardi/redmage/views/utils" +import "strconv" + +templ MaxImageResolutionXInput(data ResolutionData) { + +} + +templ MaxImageResolutionYInput(data ResolutionData) { + +} diff --git a/views/devicesview/adddevice/min_image_resolution_input.templ b/views/devicesview/adddevice/min_image_resolution_input.templ new file mode 100644 index 0000000..e0ccc2f --- /dev/null +++ b/views/devicesview/adddevice/min_image_resolution_input.templ @@ -0,0 +1,101 @@ +package adddevice + +import "fmt" +import "github.com/tigorlazuardi/redmage/views/utils" +import "strconv" + +templ MinImageResolutionXInput(data ResolutionData) { + +} + +templ MinImageResolutionYInput(data ResolutionData) { + +} diff --git a/views/devicesview/adddevice/resolution_input.templ b/views/devicesview/adddevice/resolution_input.templ new file mode 100644 index 0000000..0c5a5ef --- /dev/null +++ b/views/devicesview/adddevice/resolution_input.templ @@ -0,0 +1,109 @@ +package adddevice + +import "github.com/tigorlazuardi/redmage/views/utils" +import "fmt" +import "strconv" + +type ResolutionData struct { + Error string + Value int + HXSwapOOB bool +} + +templ ResolutionXInput(data ResolutionData) { + +} + +templ ResolutionYInput(data ResolutionData) { + +} diff --git a/views/devicesview/adddevice/slug_input.templ b/views/devicesview/adddevice/slug_input.templ index c85daf6..cbd3aac 100644 --- a/views/devicesview/adddevice/slug_input.templ +++ b/views/devicesview/adddevice/slug_input.templ @@ -11,7 +11,13 @@ type SlugInputData struct { } templ SlugInput(data SlugInputData) { -