xtablo-source/backend/templates/etapes.templ
2026-05-15 22:40:25 +02:00

116 lines
3.8 KiB
Text

package templates
import (
"backend/internal/db/sqlc"
"backend/internal/web/ui"
"strconv"
"github.com/google/uuid"
)
templ EtapeStrip(tabloID uuid.UUID, etapes []sqlc.Etape, counts EtapeTaskCounts, filter EtapeFilter, csrfToken string) {
<div id="etape-strip" class="mb-4 space-y-3">
<div class="flex items-center gap-2 overflow-x-auto pb-1">
<a
href={ templ.SafeURL("/tablos/" + tabloID.String() + "/tasks") }
hx-get={ "/tablos/" + tabloID.String() + "/tasks" }
hx-target="#tab-content"
hx-swap="innerHTML"
hx-push-url={ "/tablos/" + tabloID.String() + "/tasks" }
class={ etapeChipClasses(filter.IsAll()) }
>
<span>All</span>
<span class="rounded bg-slate-100 px-1.5 py-0.5 text-xs text-slate-700">{ strconv.Itoa(counts.All) }</span>
</a>
<a
href={ templ.SafeURL("/tablos/" + tabloID.String() + "/tasks?etape=unassigned") }
hx-get={ "/tablos/" + tabloID.String() + "/tasks?etape=unassigned" }
hx-target="#tab-content"
hx-swap="innerHTML"
hx-push-url={ "/tablos/" + tabloID.String() + "/tasks?etape=unassigned" }
class={ etapeChipClasses(filter.IsUnassigned()) }
>
<span>Unassigned</span>
<span class="rounded bg-slate-100 px-1.5 py-0.5 text-xs text-slate-700">{ strconv.Itoa(counts.Unassigned) }</span>
</a>
for _, etape := range etapes {
<a
href={ templ.SafeURL("/tablos/" + tabloID.String() + "/tasks?etape=" + etape.ID.String()) }
hx-get={ "/tablos/" + tabloID.String() + "/tasks?etape=" + etape.ID.String() }
hx-target="#tab-content"
hx-swap="innerHTML"
hx-push-url={ "/tablos/" + tabloID.String() + "/tasks?etape=" + etape.ID.String() }
class={ etapeChipClasses(filter.IsEtape(etape.ID)) }
>
<span>{ etape.Title }</span>
<span class="rounded bg-slate-100 px-1.5 py-0.5 text-xs text-slate-700">{ strconv.Itoa(etapeCount(counts, etape.ID)) }</span>
</a>
}
<button
type="button"
class="ui-button ui-button-soft-neutral-md flex-shrink-0"
hx-get={ "/tablos/" + tabloID.String() + "/etapes/new" }
hx-target="#etape-form-slot"
hx-swap="innerHTML"
>+ Etape</button>
</div>
<div id="etape-form-slot"></div>
</div>
}
templ EtapeCreateFormFragment(tabloID uuid.UUID, form EtapeCreateForm, errs EtapeCreateErrors, csrfToken string) {
<form
method="POST"
action={ templ.SafeURL("/tablos/" + tabloID.String() + "/etapes") }
hx-post={ "/tablos/" + tabloID.String() + "/etapes" }
hx-target="#tasks-tab"
hx-swap="outerHTML"
class="rounded border border-slate-200 bg-white p-3 shadow-sm space-y-3"
>
@ui.CSRFField(csrfToken)
<div>
<input
type="text"
name="title"
value={ form.Title }
maxlength="255"
required
placeholder="Etape title"
class="block w-full rounded border border-slate-300 px-2 py-1 text-sm placeholder-slate-400 focus:border-slate-500 focus:outline-none"
/>
@FieldError(errs.Title)
</div>
<div>
<textarea
name="description"
rows="2"
placeholder="Description (optional)"
class="block w-full rounded border border-slate-300 px-2 py-1 text-sm placeholder-slate-400 focus:border-slate-500 focus:outline-none"
>{ form.Description }</textarea>
</div>
if errs.General != "" {
@FieldError(errs.General)
}
<div class="flex items-center gap-2">
@ui.Button(ui.ButtonProps{
Label: "Save",
Variant: ui.ButtonVariantDefault,
Tone: ui.ButtonToneSolid,
Size: ui.SizeMD,
Type: "submit",
})
@ui.Button(ui.ButtonProps{
Label: "Discard",
Variant: ui.ButtonVariantNeutral,
Tone: ui.ButtonToneSoft,
Size: ui.SizeMD,
Type: "button",
Attrs: templ.Attributes{
"hx-get": "/tablos/" + tabloID.String() + "/etapes/cancel-new",
"hx-target": "#etape-form-slot",
"hx-swap": "innerHTML",
},
})
</div>
</form>
}