1{{ define "repo/fragments/editLabelPanel" }}
2 <form
3 id="edit-label-panel"
4 hx-put="/{{ .RepoInfo.FullName }}/labels/perform"
5 hx-indicator="#spinner"
6 hx-disabled-elt="#save-btn,#cancel-btn"
7 hx-swap="none"
8 class="flex flex-col gap-6"
9 >
10 <input type="hidden" name="repo" value="{{ .RepoInfo.RepoAt }}">
11 <input type="hidden" name="subject" value="{{ .Subject }}">
12 {{ template "editBasicLabels" . }}
13 {{ template "editKvLabels" . }}
14 {{ template "editLabelPanelActions" . }}
15 <div id="add-label-error" class="text-red-500 dark:text-red-400"></div>
16 </form>
17{{ end }}
18
19{{ define "editBasicLabels" }}
20 {{ $defs := .Defs }}
21 {{ $subject := .Subject }}
22 {{ $state := .State }}
23 {{ $labelStyle := "flex items-center gap-2 rounded py-1 px-2 border border-gray-200 dark:border-gray-700 text-sm bg-white dark:bg-gray-800 text-black dark:text-white" }}
24 <div>
25 {{ template "repo/fragments/labelSectionHeaderText" "Labels" }}
26
27 <div class="flex gap-1 items-center flex-wrap">
28 {{ range $k, $d := $defs }}
29 {{ $isChecked := $state.ContainsLabel $k }}
30 {{ if $d.ValueType.IsNull }}
31 {{ $fieldName := $d.AtUri }}
32 <label class="{{$labelStyle}}">
33 <input type="checkbox" id="{{ $fieldName }}" name="{{ $fieldName }}" value="null" {{if $isChecked}}checked{{end}}>
34 {{ template "labels/fragments/labelDef" $d }}
35 </label>
36 {{ end }}
37 {{ else }}
38 <p class="text-gray-500 dark:text-gray-400 text-sm py-1">
39 No labels defined yet. You can choose default labels or define custom
40 labels in <a class="underline" href="/{{ $.RepoInfo.FullName }}/settings">settings</a>.
41 </p>
42 {{ end }}
43 </div>
44 </div>
45{{ end }}
46
47{{ define "editKvLabels" }}
48 {{ $defs := .Defs }}
49 {{ $subject := .Subject }}
50 {{ $state := .State }}
51 {{ $labelStyle := "font-normal normal-case flex items-center gap-2 p-0" }}
52
53 {{ range $k, $d := $defs }}
54 {{ if (not $d.ValueType.IsNull) }}
55 {{ $fieldName := $d.AtUri }}
56 {{ $valset := $state.GetValSet $k }}
57 <div id="label-{{$d.Id}}" class="flex flex-col gap-1">
58 {{ template "repo/fragments/labelSectionHeaderText" $d.Name }}
59 {{ if (and $d.Multiple $d.ValueType.IsEnum) }}
60 <!-- checkbox -->
61 {{ range $variant := $d.ValueType.Enum }}
62 <label class="{{$labelStyle}}">
63 <input type="checkbox" name="{{ $fieldName }}" value="{{$variant}}" {{if $state.ContainsLabelAndVal $k $variant}}checked{{end}}>
64 {{ $variant }}
65 </label>
66 {{ end }}
67 {{ else if $d.Multiple }}
68 <!-- dynamically growing input fields -->
69 {{ range $v, $s := $valset }}
70 {{ template "multipleInputField" (dict "def" $d "value" $v "key" $k) }}
71 {{ else }}
72 {{ template "multipleInputField" (dict "def" $d "value" "" "key" $k) }}
73 {{ end }}
74 {{ template "addFieldButton" $d }}
75 {{ else if $d.ValueType.IsEnum }}
76 <!-- radio buttons -->
77 {{ $isUsed := $state.ContainsLabel $k }}
78 {{ range $variant := $d.ValueType.Enum }}
79 <label class="{{$labelStyle}}">
80 <input type="radio" name="{{ $fieldName }}" value="{{$variant}}" {{if $state.ContainsLabelAndVal $k $variant}}checked{{end}}>
81 {{ $variant }}
82 </label>
83 {{ end }}
84 <label class="{{$labelStyle}}">
85 <input type="radio" name="{{ $fieldName }}" value="" {{ if not $isUsed }}checked{{ end }}>
86 None
87 </label>
88 {{ else }}
89 <!-- single input field based on value type -->
90 {{ range $v, $s := $valset }}
91 {{ template "valueTypeInput" (dict "def" $d "value" $v "key" $k) }}
92 {{ else }}
93 {{ template "valueTypeInput" (dict "def" $d "value" "" "key" $k) }}
94 {{ end }}
95 {{ end }}
96 </div>
97 {{ end }}
98 {{ end }}
99{{ end }}
100
101{{ define "multipleInputField" }}
102 <div class="flex gap-1 items-stretch">
103 {{ template "valueTypeInput" . }}
104 {{ template "removeFieldButton" }}
105 </div>
106{{ end }}
107
108{{ define "addFieldButton" }}
109 <div style="display:none" id="tpl-{{ .Id }}">
110 {{ template "multipleInputField" (dict "def" . "value" "" "key" .AtUri.String) }}
111 </div>
112 <button type="button" onClick="this.insertAdjacentHTML('beforebegin', document.getElementById('tpl-{{ .Id }}').innerHTML)" class="w-full btn flex items-center gap-2">
113 {{ i "plus" "size-4" }} add
114 </button>
115{{ end }}
116
117{{ define "removeFieldButton" }}
118 <button type="button" onClick="this.parentElement.remove()" class="btn flex items-center gap-2 text-red-400 dark:text-red-500">
119 {{ i "trash-2" "size-4" }}
120 </button>
121{{ end }}
122
123{{ define "valueTypeInput" }}
124 {{ $def := .def }}
125 {{ $valueType := $def.ValueType }}
126 {{ $value := .value }}
127 {{ $key := .key }}
128
129 {{ if $valueType.IsBool }}
130 {{ template "boolTypeInput" $ }}
131 {{ else if $valueType.IsInt }}
132 {{ template "intTypeInput" $ }}
133 {{ else if $valueType.IsString }}
134 {{ template "stringTypeInput" $ }}
135 {{ else if $valueType.IsNull }}
136 {{ template "nullTypeInput" $ }}
137 {{ end }}
138{{ end }}
139
140{{ define "boolTypeInput" }}
141 {{ $def := .def }}
142 {{ $fieldName := $def.AtUri }}
143 {{ $value := .value }}
144 {{ $labelStyle = "font-normal normal-case flex items-center gap-2" }}
145 <div class="flex flex-col gap-1">
146 <label class="{{$labelStyle}}">
147 <input type="radio" name="{{ $fieldName }}" value="true" {{ if not $value }}checked{{ end }}>
148 None
149 </label>
150 <label class="{{$labelStyle}}">
151 <input type="radio" name="{{ $fieldName }}" value="true" {{ if not $value }}checked{{ end }}>
152 None
153 </label>
154 <label class="{{$labelStyle}}">
155 <input type="radio" name="{{ $fieldName }}" value="true" {{ if not $value }}checked{{ end }}>
156 None
157 </label>
158 </div>
159{{ end }}
160
161{{ define "intTypeInput" }}
162 {{ $def := .def }}
163 {{ $fieldName := $def.AtUri }}
164 {{ $value := .value }}
165 <input class="p-1 w-full" type="number" name="{{$fieldName}}" value="{{$value}}">
166{{ end }}
167
168{{ define "stringTypeInput" }}
169 {{ $def := .def }}
170 {{ $fieldName := $def.AtUri }}
171 {{ $valueType := $def.ValueType }}
172 {{ $value := .value }}
173 {{ if $valueType.IsDidFormat }}
174 {{ $value = trimPrefix (resolve .value) "@" }}
175 {{ end }}
176 <input class="p-1 w-full" type="text" name="{{$fieldName}}" value="{{$value}}">
177{{ end }}
178
179{{ define "nullTypeInput" }}
180 {{ $def := .def }}
181 {{ $fieldName := $def.AtUri }}
182 <input class="p-1" type="hidden" name="{{$fieldName}}" value="null">
183{{ end }}
184
185{{ define "editLabelPanelActions" }}
186 <div class="flex gap-2 pt-2">
187 <button
188 id="cancel-btn"
189 type="button"
190 hx-get="/{{ .RepoInfo.FullName }}/label"
191 hx-vals='{"subject": "{{.Subject}}"}'
192 hx-swap="outerHTML"
193 hx-target="#edit-label-panel"
194 class="btn w-1/2 flex items-center gap-2 text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 group">
195 {{ i "x" "size-4" }} cancel
196 </button>
197
198 <button
199 id="save-btn"
200 type="submit"
201 class="btn w-1/2 flex items-center">
202 <span class="inline-flex gap-2 items-center">{{ i "check" "size-4" }} save</span>
203 <span id="spinner" class="group">
204 {{ i "loader-circle" "ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
205 </span>
206 </button>
207 </div>
208{{ end }}