This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / appview / pages / templates / repo / fragments / editLabelPanel.html
10 kB 269 lines
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 {{ $prefix := .Prefix }} 24 {{ $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" }} 25 {{ $hasNullDefs := false }} 26 {{ range $k, $d := $defs }} 27 {{ if $d.ValueType.IsNull }}{{ $hasNullDefs = true }}{{ end }} 28 {{ end }} 29 <div> 30 {{ template "repo/fragments/labelSectionHeaderText" "Labels" }} 31 32 <div class="flex flex-col gap-1 items-start"> 33 {{ range $k, $d := $defs }} 34 {{ if $d.ValueType.IsNull }} 35 {{ $isChecked := $state.ContainsLabel $k }} 36 {{ $fieldName := $d.AtUri.String }} 37 {{ if $prefix }}{{ $fieldName = printf "%s[%s]" $prefix $d.AtUri }}{{ end }} 38 <label class="{{$labelStyle}}"> 39 <input type="checkbox" name="{{ $fieldName }}" value="null" {{if $isChecked}}checked{{end}}> 40 {{ template "labels/fragments/labelDef" $d }} 41 </label> 42 {{ end }} 43 {{ end }} 44 {{ if not $hasNullDefs }} 45 <p class="text-gray-500 dark:text-gray-400 text-sm py-1"> 46 No labels defined. You can choose default labels or define custom 47 labels in <a class="underline" href="/{{ $.RepoInfo.FullName }}/settings">settings</a>. 48 </p> 49 {{ end }} 50 </div> 51 </div> 52{{ end }} 53 54{{ define "editKvLabels" }} 55 {{ $defs := .Defs }} 56 {{ $subject := .Subject }} 57 {{ $state := .State }} 58 {{ $prefix := .Prefix }} 59 {{ $groupSuffix := "" }} 60 {{ if $prefix }}{{ $groupSuffix = printf "-%s" $prefix }}{{ end }} 61 {{ $labelStyle := "font-normal normal-case flex items-center gap-2 p-0" }} 62 63 {{ range $k, $d := $defs }} 64 {{ if (not $d.ValueType.IsNull) }} 65 {{ $fieldName := $d.AtUri.String }} 66 {{ if $prefix }}{{ $fieldName = printf "%s[%s]" $prefix $d.AtUri }}{{ end }} 67 {{ $valset := $state.GetValSet $k }} 68 <div id="label-{{$d.Id}}{{ $groupSuffix }}" class="flex flex-col gap-1"> 69 {{ if not $d.ValueType.IsBool }} 70 {{ template "repo/fragments/labelSectionHeaderText" $d.Name }} 71 {{ end }} 72 {{ if (and $d.Multiple $d.ValueType.IsEnum) }} 73 <!-- checkbox --> 74 {{ range $variant := $d.ValueType.Enum }} 75 <label class="{{$labelStyle}}"> 76 <input type="checkbox" name="{{ $fieldName }}" value="{{$variant}}" {{if $state.ContainsLabelAndVal $k $variant}}checked{{end}}> 77 {{ $variant }} 78 </label> 79 {{ end }} 80 {{ else if $d.Multiple }} 81 <!-- dynamically growing input fields --> 82 {{ range $v, $s := $valset }} 83 {{ template "multipleInputField" (dict "def" $d "value" $v "key" $k "prefix" $prefix) }} 84 {{ else }} 85 {{ template "multipleInputField" (dict "def" $d "value" "" "key" $k "prefix" $prefix) }} 86 {{ end }} 87 {{ template "addFieldButton" (dict "def" $d "prefix" $prefix "groupSuffix" $groupSuffix) }} 88 {{ if and $.LoggedInUser $d.ValueType.IsString $d.ValueType.IsDidFormat }} 89 {{ template "assignToMeButton" (dict "def" $d "user" $.LoggedInUser "groupSuffix" $groupSuffix) }} 90 {{ end }} 91 {{ else if $d.ValueType.IsEnum }} 92 <!-- radio buttons --> 93 {{ $isUsed := $state.ContainsLabel $k }} 94 {{ range $variant := $d.ValueType.Enum }} 95 <label class="{{$labelStyle}}"> 96 <input type="radio" name="{{ $fieldName }}" value="{{$variant}}" {{if $state.ContainsLabelAndVal $k $variant}}checked{{end}}> 97 {{ $variant }} 98 </label> 99 {{ end }} 100 <label class="{{$labelStyle}}"> 101 <input type="radio" name="{{ $fieldName }}" value="" {{ if not $isUsed }}checked{{ end }}> 102 None 103 </label> 104 {{ else }} 105 <!-- single input field based on value type --> 106 {{ range $v, $s := $valset }} 107 {{ template "valueTypeInput" (dict "def" $d "value" $v "key" $k "prefix" $prefix) }} 108 {{ else }} 109 {{ template "valueTypeInput" (dict "def" $d "value" "" "key" $k "prefix" $prefix) }} 110 {{ end }} 111 {{ end }} 112 </div> 113 {{ end }} 114 {{ end }} 115{{ end }} 116 117{{ define "multipleInputField" }} 118 <div class="flex gap-1 items-stretch"> 119 <div class="flex-1 min-w-0"> 120 {{ template "valueTypeInput" . }} 121 </div> 122 {{ template "removeFieldButton" }} 123 </div> 124{{ end }} 125 126{{ define "assignToMeButton" }} 127 {{ $def := .def }} 128 {{ $user := .user }} 129 {{ $groupSuffix := .groupSuffix }} 130 {{ $handle := trimPrefix (resolve $user.Did) "@" }} 131 <button type="button" 132 data-assign-to-me="{{ $def.Id }}{{ $groupSuffix }}" 133 data-handle="{{ $handle }}" 134 onclick="(() => { 135 const group = document.getElementById('label-' + this.dataset.assignToMe); 136 const handle = this.dataset.handle; 137 const inputs = group.querySelectorAll('input[type=text]'); 138 const empty = Array.from(inputs).find(i => !i.value.trim()); 139 if (empty) { empty.value = handle; return; } 140 if (Array.from(inputs).some(i => i.value.trim() === handle)) return; 141 const tpl = document.getElementById('tpl-' + this.dataset.assignToMe); 142 if (!tpl) return; 143 const addBtn = tpl.nextElementSibling; 144 addBtn.insertAdjacentHTML('beforebegin', tpl.innerHTML); 145 const newInput = addBtn.previousElementSibling.querySelector('input[type=text]'); 146 if (newInput) newInput.value = handle; 147 })()" 148 class="text-xs text-gray-500 dark:text-gray-400 hover:underline self-end inline-flex items-center gap-1"> 149 {{ i "user-round-plus" "size-3.5" }} 150 Assign to me 151 </button> 152{{ end }} 153 154{{ define "addFieldButton" }} 155 {{ $def := .def }} 156 {{ $prefix := .prefix }} 157 {{ $groupSuffix := .groupSuffix }} 158 <div style="display:none" id="tpl-{{ $def.Id }}{{ $groupSuffix }}"> 159 {{ template "multipleInputField" (dict "def" $def "value" "" "key" $def.AtUri.String "prefix" $prefix) }} 160 </div> 161 <button type="button" onClick="this.insertAdjacentHTML('beforebegin', document.getElementById('tpl-{{ $def.Id }}{{ $groupSuffix }}').innerHTML)" class="w-full btn flex items-center gap-2"> 162 {{ i "plus" "size-4" }} Add 163 </button> 164{{ end }} 165 166{{ define "removeFieldButton" }} 167 <button type="button" onClick="this.parentElement.remove()" class="btn flex items-center gap-2 text-red-400 dark:text-red-500"> 168 {{ i "trash-2" "size-4" }} 169 </button> 170{{ end }} 171 172{{ define "valueTypeInput" }} 173 {{ $def := .def }} 174 {{ $valueType := $def.ValueType }} 175 {{ $value := .value }} 176 {{ $key := .key }} 177 178 {{ if $valueType.IsBool }} 179 {{ template "boolTypeInput" $ }} 180 {{ else if $valueType.IsInt }} 181 {{ template "intTypeInput" $ }} 182 {{ else if $valueType.IsString }} 183 {{ template "stringTypeInput" $ }} 184 {{ else if $valueType.IsNull }} 185 {{ template "nullTypeInput" $ }} 186 {{ end }} 187{{ end }} 188 189{{ define "boolTypeInput" }} 190 {{ $def := .def }} 191 {{ $prefix := .prefix }} 192 {{ $fieldName := $def.AtUri.String }} 193 {{ if $prefix }}{{ $fieldName = printf "%s[%s]" $prefix $def.AtUri }}{{ end }} 194 {{ $value := .value }} 195 {{ $isOn := eq $value "true" }} 196 <label class="font-normal normal-case flex items-center gap-2"> 197 <input type="checkbox" name="{{ $fieldName }}" value="true" {{ if $isOn }}checked{{ end }}> 198 {{ $def.Name }} 199 </label> 200{{ end }} 201 202{{ define "intTypeInput" }} 203 {{ $def := .def }} 204 {{ $prefix := .prefix }} 205 {{ $fieldName := $def.AtUri.String }} 206 {{ if $prefix }}{{ $fieldName = printf "%s[%s]" $prefix $def.AtUri }}{{ end }} 207 {{ $value := .value }} 208 <input class="p-1 w-full" type="number" name="{{$fieldName}}" value="{{$value}}"> 209{{ end }} 210 211{{ define "stringTypeInput" }} 212 {{ $def := .def }} 213 {{ $prefix := .prefix }} 214 {{ $fieldName := $def.AtUri.String }} 215 {{ if $prefix }}{{ $fieldName = printf "%s[%s]" $prefix $def.AtUri }}{{ end }} 216 {{ $valueType := $def.ValueType }} 217 {{ $value := .value }} 218 219 {{ if $valueType.IsDidFormat }} 220 {{ $value = trimPrefix (resolve .value) "@" }} 221 <actor-typeahead> 222 <input 223 autocapitalize="none" 224 autocorrect="off" 225 autocomplete="off" 226 placeholder="user.tngl.sh" 227 value="{{$value}}" 228 name="{{$fieldName}}" 229 type="text" 230 class="p-1 w-full h-full text-sm" 231 /> 232 </actor-typeahead> 233 {{ else }} 234 <input class="p-1 w-full" type="text" name="{{$fieldName}}" value="{{$value}}"> 235 {{ end }} 236{{ end }} 237 238{{ define "nullTypeInput" }} 239 {{ $def := .def }} 240 {{ $prefix := .prefix }} 241 {{ $fieldName := $def.AtUri.String }} 242 {{ if $prefix }}{{ $fieldName = printf "%s[%s]" $prefix $def.AtUri }}{{ end }} 243 <input class="p-1" type="hidden" name="{{$fieldName}}" value="null"> 244{{ end }} 245 246{{ define "editLabelPanelActions" }} 247 <div class="flex gap-2 pt-2"> 248 <button 249 id="cancel-btn" 250 type="button" 251 hx-get="/{{ .RepoInfo.FullName }}/label" 252 hx-vals='{"subject": "{{.Subject}}"}' 253 hx-swap="outerHTML" 254 hx-target="#edit-label-panel" 255 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"> 256 {{ i "x" "size-4" }} Cancel 257 </button> 258 259 <button 260 id="save-btn" 261 type="submit" 262 class="btn w-1/2 flex items-center"> 263 <span class="inline-flex gap-2 items-center">{{ i "check" "size-4" }} Save</span> 264 <span id="spinner" class="group"> 265 {{ i "loader-circle" "ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 266 </span> 267 </button> 268 </div> 269{{ end }}