forked from tangled.org/core
Monorepo for Tangled — https://tangled.org
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 }}