devices: filled the add device page
This commit is contained in:
parent
19ffbdf98c
commit
494a4bc956
|
@ -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 != "" {
|
||||
|
|
|
@ -58,6 +58,7 @@ var DefaultConfig = map[string]any{
|
|||
|
||||
"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",
|
||||
|
|
2
go.mod
2
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
|
||||
|
|
4
go.sum
4
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=
|
||||
|
|
59
server/routes/device_validate_name.go
Normal file
59
server/routes/device_validate_name.go
Normal file
|
@ -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")
|
||||
}
|
||||
}
|
|
@ -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")
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package adddevice
|
||||
|
||||
import "fmt"
|
||||
|
||||
type AspectRatioToleranceData struct {
|
||||
Value float64
|
||||
}
|
||||
|
||||
templ AspectRatioToleranceInput(data AspectRatioToleranceData) {
|
||||
<label
|
||||
id="aspect-ratio-tolerance-form"
|
||||
class="form-control sm:col-span-2"
|
||||
>
|
||||
<div class="label">
|
||||
<span class="label-text">Aspect Ratio Tolerance</span>
|
||||
<span class="label-text-alt hidden sm:inline">NOTE: This is NOT a filter for image sizes, but just the shape of it.</span>
|
||||
</div>
|
||||
<input
|
||||
id="aspect-ratio-tolerance-field"
|
||||
name="aspect_ratio_tolerance"
|
||||
type="number"
|
||||
min="0"
|
||||
@change="$el.setCustomValidity(''); this.error = false"
|
||||
class="input input-bordered"
|
||||
:class="{'text-error': error, 'input-error': error}"
|
||||
value={ fmt.Sprintf("%.2f", data.Value) }
|
||||
placeholder="0.20"
|
||||
step="0.01"
|
||||
required
|
||||
/>
|
||||
<div class="label">
|
||||
<span class="label-text">
|
||||
Aspect Ratio Tolerance is a filter on how close the shape of the download images to the device shape is.
|
||||
The bigger the value, the more images will be accepted and vice versa. '0.20' is the default value because
|
||||
it accept quite a bit of images to download while still looking good even when the image is stretched for the device's wallpaper.
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
}
|
99
views/devicesview/adddevice/max_image_resolution_input.templ
Normal file
99
views/devicesview/adddevice/max_image_resolution_input.templ
Normal file
|
@ -0,0 +1,99 @@
|
|||
package adddevice
|
||||
|
||||
import "fmt"
|
||||
import "github.com/tigorlazuardi/redmage/views/utils"
|
||||
import "strconv"
|
||||
|
||||
templ MaxImageResolutionXInput(data ResolutionData) {
|
||||
<label
|
||||
x-data={ fmt.Sprintf(`{error: %t}`, data.Error != "") }
|
||||
id="max-image-width-form"
|
||||
class="form-control"
|
||||
if data.HXSwapOOB {
|
||||
hx-swap-oob="true"
|
||||
}
|
||||
>
|
||||
<div class="label">
|
||||
<span
|
||||
class={ utils.CXX("label-text", true, "text-error", data.Error != "") }
|
||||
:class="{'text-error': error}"
|
||||
>Maximum Image Width</span>
|
||||
</div>
|
||||
<input
|
||||
id="max-image-width-field"
|
||||
x-data={ fmt.Sprintf(`{ init() { $el.setCustomValidity(%q) } }`, data.Error) }
|
||||
name="max_x"
|
||||
type="number"
|
||||
min="0"
|
||||
@change="$el.setCustomValidity(''); this.error = false"
|
||||
class={ utils.CXX(
|
||||
"input input-bordered", true,
|
||||
"text-error", data.Error != "",
|
||||
"input-error", data.Error != "",
|
||||
) }
|
||||
:class="{'text-error': error, 'input-error': error}"
|
||||
value={ strconv.Itoa(data.Value) }
|
||||
placeholder="0"
|
||||
required
|
||||
/>
|
||||
<div class="label">
|
||||
<span
|
||||
class={ utils.CXX("label-text", true, "text-error", data.Error != "") }
|
||||
:class="{'text-error': error}"
|
||||
>
|
||||
if data.Error != "" {
|
||||
{ data.Error }
|
||||
} else {
|
||||
Maximum image width resolution to download for this device. Set to '0' to disable this filter. Set this value to avoid image sizes that are too big.
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
}
|
||||
|
||||
templ MaxImageResolutionYInput(data ResolutionData) {
|
||||
<label
|
||||
x-data={ fmt.Sprintf(`{error: %t}`, data.Error != "") }
|
||||
id="max-image-height-form"
|
||||
class="form-control"
|
||||
if data.HXSwapOOB {
|
||||
hx-swap-oob="true"
|
||||
}
|
||||
>
|
||||
<div class="label">
|
||||
<span
|
||||
class={ utils.CXX("label-text", true, "text-error", data.Error != "") }
|
||||
:class="{'text-error': error}"
|
||||
>Maximum Image Height</span>
|
||||
</div>
|
||||
<input
|
||||
id="max-image-height-field"
|
||||
x-data={ fmt.Sprintf(`{ init() { $el.setCustomValidity(%q) } }`, data.Error) }
|
||||
name="min_y"
|
||||
type="number"
|
||||
min="0"
|
||||
@change="$el.setCustomValidity(''); this.error = false"
|
||||
class={ utils.CXX(
|
||||
"input input-bordered", true,
|
||||
"text-error", data.Error != "",
|
||||
"input-error", data.Error != "",
|
||||
) }
|
||||
:class="{'text-error': error, 'input-error': error}"
|
||||
value={ strconv.Itoa(data.Value) }
|
||||
placeholder="0"
|
||||
required
|
||||
/>
|
||||
<div class="label">
|
||||
<span
|
||||
class={ utils.CXX("label-text", true, "text-error", data.Error != "") }
|
||||
:class="{'text-error': error}"
|
||||
>
|
||||
if data.Error != "" {
|
||||
{ data.Error }
|
||||
} else {
|
||||
Maximum image height resolution to download for this device. Set to '0' to disable this filter. Set this value to avoid image sizes that are too big.
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
}
|
101
views/devicesview/adddevice/min_image_resolution_input.templ
Normal file
101
views/devicesview/adddevice/min_image_resolution_input.templ
Normal file
|
@ -0,0 +1,101 @@
|
|||
package adddevice
|
||||
|
||||
import "fmt"
|
||||
import "github.com/tigorlazuardi/redmage/views/utils"
|
||||
import "strconv"
|
||||
|
||||
templ MinImageResolutionXInput(data ResolutionData) {
|
||||
<label
|
||||
x-data={ fmt.Sprintf(`{error: %t}`, data.Error != "") }
|
||||
id="min-image-width-form"
|
||||
class="form-control"
|
||||
if data.HXSwapOOB {
|
||||
hx-swap-oob="true"
|
||||
}
|
||||
>
|
||||
<div class="label">
|
||||
<span
|
||||
class={ utils.CXX("label-text", true, "text-error", data.Error != "") }
|
||||
:class="{'text-error': error}"
|
||||
>Minimum Image Width</span>
|
||||
</div>
|
||||
<input
|
||||
id="min-image-width-field"
|
||||
x-data={ fmt.Sprintf(`{ init() { $el.setCustomValidity(%q) } }`, data.Error) }
|
||||
name="min_x"
|
||||
type="number"
|
||||
min="0"
|
||||
@change="$el.setCustomValidity(''); this.error = false"
|
||||
class={ utils.CXX(
|
||||
"input input-bordered", true,
|
||||
"text-error", data.Error != "",
|
||||
"input-error", data.Error != "",
|
||||
) }
|
||||
:class="{'text-error': error, 'input-error': error}"
|
||||
value={ strconv.Itoa(data.Value) }
|
||||
placeholder="0"
|
||||
required
|
||||
/>
|
||||
<div class="label">
|
||||
<span
|
||||
class={ utils.CXX("label-text", true, "text-error", data.Error != "") }
|
||||
:class="{'text-error': error}"
|
||||
>
|
||||
if data.Error != "" {
|
||||
{ data.Error }
|
||||
} else {
|
||||
Minimum image width resolution to download for this device. Set to '0' to disable this filter. Recommended to set this value same as your device's width resolution
|
||||
so you will get non-blurry images when used as wallpaper.
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
}
|
||||
|
||||
templ MinImageResolutionYInput(data ResolutionData) {
|
||||
<label
|
||||
x-data={ fmt.Sprintf(`{error: %t}`, data.Error != "") }
|
||||
id="min-image-height-form"
|
||||
class="form-control"
|
||||
if data.HXSwapOOB {
|
||||
hx-swap-oob="true"
|
||||
}
|
||||
>
|
||||
<div class="label">
|
||||
<span
|
||||
class={ utils.CXX("label-text", true, "text-error", data.Error != "") }
|
||||
:class="{'text-error': error}"
|
||||
>Minimum Image Height</span>
|
||||
</div>
|
||||
<input
|
||||
id="min-image-height-field"
|
||||
x-data={ fmt.Sprintf(`{ init() { $el.setCustomValidity(%q) } }`, data.Error) }
|
||||
name="min_y"
|
||||
type="number"
|
||||
min="0"
|
||||
@change="$el.setCustomValidity(''); this.error = false"
|
||||
class={ utils.CXX(
|
||||
"input input-bordered", true,
|
||||
"text-error", data.Error != "",
|
||||
"input-error", data.Error != "",
|
||||
) }
|
||||
:class="{'text-error': error, 'input-error': error}"
|
||||
value={ strconv.Itoa(data.Value) }
|
||||
placeholder="0"
|
||||
required
|
||||
/>
|
||||
<div class="label">
|
||||
<span
|
||||
class={ utils.CXX("label-text", true, "text-error", data.Error != "") }
|
||||
:class="{'text-error': error}"
|
||||
>
|
||||
if data.Error != "" {
|
||||
{ data.Error }
|
||||
} else {
|
||||
Minimum image height resolution to download for this device. Set to '0' to disable this filter. Recommended to set this value same as your device's height resolution
|
||||
so you will get non-blurry images when used as wallpaper.
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
}
|
109
views/devicesview/adddevice/resolution_input.templ
Normal file
109
views/devicesview/adddevice/resolution_input.templ
Normal file
|
@ -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) {
|
||||
<label
|
||||
x-data={ fmt.Sprintf(`{error: %t}`, data.Error != "") }
|
||||
id="resolution-x-form"
|
||||
class="form-control"
|
||||
if data.HXSwapOOB {
|
||||
hx-swap-oob="true"
|
||||
}
|
||||
>
|
||||
<div class="label">
|
||||
<span
|
||||
class={ utils.CXX("label-text", true, "text-error", data.Error != "") }
|
||||
:class="{'text-error': error}"
|
||||
>Width</span>
|
||||
</div>
|
||||
<input
|
||||
id="resolution-x-field"
|
||||
x-data={ fmt.Sprintf(`{ init() { $el.setCustomValidity(%q) } }`, data.Error) }
|
||||
name="resolution_x"
|
||||
type="number"
|
||||
min="1"
|
||||
@change="$el.setCustomValidity(''); this.error = false"
|
||||
class={ utils.CXX(
|
||||
"input input-bordered", true,
|
||||
"text-error", data.Error != "",
|
||||
"input-error", data.Error != "",
|
||||
) }
|
||||
:class="{'text-error': error, 'input-error': error}"
|
||||
if data.Value > 0 {
|
||||
value={ strconv.Itoa(data.Value) }
|
||||
}
|
||||
placeholder="1920"
|
||||
required
|
||||
/>
|
||||
<div class="label">
|
||||
<span
|
||||
class={ utils.CXX("label-text", true, "text-error", data.Error != "") }
|
||||
:class="{'text-error': error}"
|
||||
>
|
||||
if data.Error != "" {
|
||||
{ data.Error }
|
||||
} else {
|
||||
Your intended device width resolution.
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
}
|
||||
|
||||
templ ResolutionYInput(data ResolutionData) {
|
||||
<label
|
||||
x-data={ fmt.Sprintf(`{error: %t}`, data.Error != "") }
|
||||
id="resolution-y-form"
|
||||
class="form-control"
|
||||
if data.HXSwapOOB {
|
||||
hx-swap-oob="true"
|
||||
}
|
||||
>
|
||||
<div class="label">
|
||||
<span
|
||||
class={ utils.CXX("label-text", true, "text-error", data.Error != "") }
|
||||
:class="{'text-error': error}"
|
||||
>Height</span>
|
||||
</div>
|
||||
<input
|
||||
id="resolution-y-field"
|
||||
x-data={ fmt.Sprintf(`{ init() { $el.setCustomValidity(%q) } }`, data.Error) }
|
||||
name="resolution_y"
|
||||
type="number"
|
||||
min="1"
|
||||
@change="$el.setCustomValidity(''); this.error = false"
|
||||
class={ utils.CXX(
|
||||
"input input-bordered", true,
|
||||
"text-error", data.Error != "",
|
||||
"input-error", data.Error != "",
|
||||
) }
|
||||
:class="{'text-error': error, 'input-error': error}"
|
||||
if data.Value > 0 {
|
||||
value={ strconv.Itoa(data.Value) }
|
||||
}
|
||||
placeholder="1080"
|
||||
required
|
||||
/>
|
||||
<div class="label">
|
||||
<span
|
||||
class={ utils.CXX("label-text", true, "text-error", data.Error != "") }
|
||||
:class="{'text-error': error}"
|
||||
>
|
||||
if data.Error != "" {
|
||||
{ data.Error }
|
||||
} else {
|
||||
Your intended device height resolution.
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
}
|
|
@ -11,7 +11,13 @@ type SlugInputData struct {
|
|||
}
|
||||
|
||||
templ SlugInput(data SlugInputData) {
|
||||
<label id="slug-input-form" class="form-control">
|
||||
<label
|
||||
id="slug-input-form"
|
||||
class="form-control"
|
||||
if data.HXSwapOOB {
|
||||
hx-swap-oob="true"
|
||||
}
|
||||
>
|
||||
<div class="label">
|
||||
<span
|
||||
class={ utils.CXX(
|
||||
|
@ -35,12 +41,15 @@ templ SlugInput(data SlugInputData) {
|
|||
"input-success", data.Valid != "",
|
||||
) }
|
||||
hx-post="/htmx/devices/add/validate/slug"
|
||||
hx-trigger="change, input delay:200ms"
|
||||
hx-trigger="change, input delay:2s"
|
||||
hx-target="#slug-input-form"
|
||||
hx-target-409="#slug-input-form"
|
||||
hx-swap="outerHTML"
|
||||
value={ data.Value }
|
||||
placeholder="my-awesome-device"
|
||||
title="Url Friendly Characters Only"
|
||||
pattern="^[a-z0-9-_]+$"
|
||||
required
|
||||
/>
|
||||
<div class="label">
|
||||
<span class={ utils.CXX("label-text", true, "text-error", data.Error != "", "text-success", data.Valid != "") }>
|
||||
|
@ -50,7 +59,7 @@ templ SlugInput(data SlugInputData) {
|
|||
{ data.Error }
|
||||
} else {
|
||||
Unique identifier for the device.
|
||||
Value must be lowercase english alphabet and supported separator is only 'dash' (-).
|
||||
Value must be lowercase english alphabet and supported separator is only 'dash' (-) and 'underscores' (_).
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -17,9 +17,23 @@ templ Content(c *views.Context) {
|
|||
@components.Container() {
|
||||
<h1>Add Device</h1>
|
||||
<div class="divider"></div>
|
||||
<form class="grid sm:grid-cols-2 gap-4">
|
||||
<form
|
||||
method="post"
|
||||
hx-post="/htmx/devices/add"
|
||||
action="/htmx/devices/add"
|
||||
class="grid sm:grid-cols-2 gap-4"
|
||||
>
|
||||
@NameInput(NameInputData{})
|
||||
@SlugInput(SlugInputData{})
|
||||
@ResolutionXInput(ResolutionData{})
|
||||
@ResolutionYInput(ResolutionData{})
|
||||
<div class="divider my-auto sm:col-span-2"><h3 class="m-0 p-0">Filter</h3></div>
|
||||
@AspectRatioToleranceInput(AspectRatioToleranceData{Value: 0.2})
|
||||
@MinImageResolutionXInput(ResolutionData{})
|
||||
@MinImageResolutionYInput(ResolutionData{})
|
||||
@MaxImageResolutionXInput(ResolutionData{})
|
||||
@MaxImageResolutionYInput(ResolutionData{})
|
||||
<button type="submit" class="btn btn-primary sm:col-span-2">Add</button>
|
||||
</form>
|
||||
}
|
||||
</main>
|
||||
|
|
|
@ -36,16 +36,8 @@ templ filter(data Data) {
|
|||
<label for="status">Status</label>
|
||||
<select id="status" name="status" class="select select-bordered w-full">
|
||||
<option value="">*No Filter</option>
|
||||
if data.Params.Status == 2 {
|
||||
<option selected value="2">Enabled</option>
|
||||
} else {
|
||||
<option value="2">Enabled</option>
|
||||
}
|
||||
if data.Params.Status == 1 {
|
||||
<option selected value="1">Disabled</option>
|
||||
} else {
|
||||
<option value="1">Disabled</option>
|
||||
}
|
||||
<option value="2" selected?={ data.Params.Status == 2 }>Enabled</option>
|
||||
<option value="1" selected?={ data.Params.Status == 1 }>Disabled</option>
|
||||
</select>
|
||||
<label for="limit">Limit</label>
|
||||
<select id="limit" name="limit" class="select select-bordered w-full">
|
||||
|
|
Loading…
Reference in a new issue