Monorepo for Tangled
at 74318eac9fdd72cf69e916276814351931ed0dcb 231 lines 9.0 kB view raw
1{{ define "repo/fragments/diff" }} 2 <style> 3 #filesToggle:checked ~ div label[for="filesToggle"] .show-text { display: none; } 4 #filesToggle:checked ~ div label[for="filesToggle"] .hide-text { display: inline; } 5 #filesToggle:not(:checked) ~ div label[for="filesToggle"] .hide-text { display: none; } 6 #filesToggle:checked ~ div div#files { width: fit-content; max-width: 15vw; } 7 #filesToggle:not(:checked) ~ div div#files { width: 0; display: none; margin-right: 0; } 8 #filesToggle:not(:checked) ~ div div#resize-files { display: none; } 9 </style> 10 11 {{ template "diffTopbar" . }} 12 {{ block "diffLayout" . }} {{ end }} 13 {{ template "fragments/resizable" }} 14{{ end }} 15 16{{ define "diffTopbar" }} 17 {{ $diff := index . 0 }} 18 {{ $opts := index . 1 }} 19 {{ $root := "" }} 20 {{ if gt (len .) 2 }} 21 {{ $root = index . 2 }} 22 {{ end }} 23 24 {{ block "filesCheckbox" $ }} {{ end }} 25 {{ block "subsCheckbox" $ }} {{ end }} 26 27 <!-- top bar --> 28 <div class="sticky top-0 z-30 bg-slate-100 dark:bg-gray-900 flex items-center gap-2 col-span-full h-12 p-2 {{ if $root }}mt-4{{ end }}"> 29 <!-- left panel toggle --> 30 {{ template "filesToggle" . }} 31 32 <!-- stats --> 33 {{ $stat := $diff.Stats }} 34 {{ $count := len $diff.ChangedFiles }} 35 {{ template "repo/fragments/diffStatPill" $stat }} 36 <span class="text-xs text-gray-600 dark:text-gray-400 hidden md:inline-flex">{{ $count }} changed file{{ if ne $count 1 }}s{{ end }}</span> 37 38 {{ if $root }} 39 {{ if $root.IsInterdiff }} 40 <!-- interdiff indicator --> 41 <div class="flex items-center gap-2 before:content-['|'] before:text-gray-300 dark:before:text-gray-600 before:mr-2"> 42 <span class="text-xs text-gray-600 dark:text-gray-400 uppercase tracking-wide">Interdiff</span> 43 <a 44 href="/{{ $root.RepoInfo.FullName }}/pulls/{{ $root.Pull.PullId }}/round/{{ sub $root.ActiveRound 1 }}" 45 class="px-2 py-0.5 bg-white dark:bg-gray-700 rounded font-mono text-xs hover:bg-gray-50 dark:hover:bg-gray-600 border border-gray-300 dark:border-gray-600" 46 > 47 #{{ sub $root.ActiveRound 1 }} 48 </a> 49 <span class="text-gray-400 text-xs"></span> 50 <a 51 href="/{{ $root.RepoInfo.FullName }}/pulls/{{ $root.Pull.PullId }}/round/{{ $root.ActiveRound }}" 52 class="px-2 py-0.5 bg-white dark:bg-gray-700 rounded font-mono text-xs hover:bg-gray-50 dark:hover:bg-gray-600 border border-gray-300 dark:border-gray-600" 53 > 54 #{{ $root.ActiveRound }} 55 </a> 56 </div> 57 {{ else if ne $root.ActiveRound nil }} 58 <!-- diff round indicator --> 59 <div class="flex items-center gap-2 before:content-['|'] before:text-gray-300 dark:before:text-gray-600 before:mr-2"> 60 <span class="text-xs text-gray-600 dark:text-gray-400 uppercase tracking-wide">Diff</span> 61 <span class="px-2 py-0.5 bg-white dark:bg-gray-700 rounded font-mono text-xs border border-gray-300 dark:border-gray-600"> 62 <span class="hidden md:inline">round </span>#{{ $root.ActiveRound }} 63 </span> 64 </div> 65 {{ end }} 66 {{ end }} 67 68 <!-- spacer --> 69 <div class="flex-grow"></div> 70 71 <!-- collapse diffs --> 72 {{ template "collapseToggle" }} 73 74 <!-- diff options --> 75 {{ template "repo/fragments/diffOpts" $opts }} 76 77 <!-- right panel toggle --> 78 {{ block "subsToggle" $ }} {{ end }} 79 </div> 80 81{{ end }} 82 83{{ define "resize-grip" }} 84 {{ $id := index . 0 }} 85 {{ $target := index . 1 }} 86 {{ $direction := index . 2 }} 87 <div id="{{ $id }}" 88 data-resizer="vertical" 89 data-target="{{ $target }}" 90 data-direction="{{ $direction }}" 91 class="resizer-vertical hidden md:flex w-4 sticky top-12 max-h-screen flex-col items-center justify-center group"> 92 <div class="w-1 h-16 group-hover:h-24 group-[.resizing]:h-24 transition-all rounded-full bg-gray-400 dark:bg-gray-500 group-hover:bg-gray-500 group-hover:dark:bg-gray-400"></div> 93 </div> 94{{ end }} 95 96{{ define "diffLayout" }} 97 {{ $diff := index . 0 }} 98 {{ $opts := index . 1 }} 99 100 <div class="flex col-span-full flex-grow"> 101 <!-- left panel --> 102 <div id="files" class="w-0 hidden md:block overflow-hidden sticky top-12 max-h-screen overflow-y-auto pb-12"> 103 <section class="overflow-x-auto text-sm px-6 py-2 border border-gray-200 dark:border-gray-700 w-full mx-auto min-h-full rounded bg-white dark:bg-gray-800 drop-shadow-sm"> 104 {{ template "repo/fragments/fileTree" $diff.FileTree }} 105 </section> 106 </div> 107 108 {{ template "resize-grip" (list "resize-files" "files" "before") }} 109 110 <!-- main content --> 111 <div id="diff-files" class="flex-1 min-w-0 sticky top-12 pb-12"> 112 {{ template "diffFiles" (list $diff $opts) }} 113 </div> 114 115 </div> 116{{ end }} 117 118{{ define "diffFiles" }} 119 {{ $diff := index . 0 }} 120 {{ $opts := index . 1 }} 121 {{ $files := $diff.ChangedFiles }} 122 {{ $isSplit := $opts.Split }} 123 <div class="flex flex-col gap-4"> 124 {{ if eq (len $files) 0 }} 125 <div class="text-center text-gray-500 dark:text-gray-400 py-8"> 126 <p>No differences found between the selected revisions.</p> 127 </div> 128 {{ else }} 129 {{ range $idx, $file := $files }} 130 {{ template "diffFile" (list $idx $file $isSplit) }} 131 {{ end }} 132 {{ end }} 133 </div> 134{{ end }} 135 136{{ define "diffFile" }} 137 {{ $idx := index . 0 }} 138 {{ $file := index . 1 }} 139 {{ $isSplit := index . 2 }} 140 {{ with $file }} 141 <details open id="file-{{ .Id }}" class="group border border-gray-200 dark:border-gray-700 w-full mx-auto rounded bg-white dark:bg-gray-800 drop-shadow-sm" tabindex="{{ add $idx 1 }}"> 142 <summary class="list-none cursor-pointer sticky top-12 group-open:border-b border-gray-200 dark:border-gray-700"> 143 <div id="diff-file-header" class="rounded cursor-pointer bg-white dark:bg-gray-800 flex justify-between"> 144 <div id="left-side-items" class="p-2 flex gap-2 items-center overflow-x-auto"> 145 <span class="group-open:hidden inline">{{ i "chevron-right" "w-4 h-4" }}</span> 146 <span class="hidden group-open:inline">{{ i "chevron-down" "w-4 h-4" }}</span> 147 {{ template "repo/fragments/diffStatPill" .Stats }} 148 149 <div class="flex gap-2 items-center overflow-x-auto"> 150 {{ $n := .Names }} 151 {{ if and $n.New $n.Old (ne $n.New $n.Old)}} 152 {{ $n.Old }} {{ i "arrow-right" "w-4 h-4" }} {{ $n.New }} 153 {{ else if $n.New }} 154 {{ $n.New }} 155 {{ else }} 156 {{ $n.Old }} 157 {{ end }} 158 </div> 159 </div> 160 </div> 161 </summary> 162 163 <div class="transition-all duration-700 ease-in-out"> 164 {{ $reason := .CanRender }} 165 {{ if $reason }} 166 <p class="text-center text-gray-400 dark:text-gray-500 p-4">{{ $reason }}</p> 167 {{ else }} 168 {{ if $isSplit }} 169 {{- template "repo/fragments/splitDiff" .Split -}} 170 {{ else }} 171 {{- template "repo/fragments/unifiedDiff" . -}} 172 {{ end }} 173 {{- end -}} 174 </div> 175 </details> 176 {{ end }} 177{{ end }} 178 179{{ define "filesCheckbox" }} 180 <input type="checkbox" id="filesToggle" class="peer/files hidden" checked/> 181{{ end }} 182 183{{ define "filesToggle" }} 184 <label title="Toggle filetree panel" for="filesToggle" class="hidden md:inline-flex items-center justify-center rounded cursor-pointer text-normal font-normal normalcase"> 185 <span class="show-text">{{ i "panel-left-open" "size-4" }}</span> 186 <span class="hide-text">{{ i "panel-left-close" "size-4" }}</span> 187 </label> 188{{ end }} 189 190{{ define "collapseToggle" }} 191 <label 192 title="Expand/Collapse diffs" 193 for="collapseToggle" 194 class="btn font-normal normal-case p-2" 195 > 196 <input type="checkbox" id="collapseToggle" class="peer/collapse hidden" checked/> 197 <span class="peer-checked/collapse:hidden inline-flex items-center gap-2"> 198 {{ i "fold-vertical" "w-4 h-4" }} 199 <span class="hidden md:inline">expand all</span> 200 </span> 201 <span class="peer-checked/collapse:inline-flex hidden flex items-center gap-2"> 202 {{ i "unfold-vertical" "w-4 h-4" }} 203 <span class="hidden md:inline">collapse all</span> 204 </span> 205 </label> 206 <script> 207 document.addEventListener('DOMContentLoaded', function() { 208 const checkbox = document.getElementById('collapseToggle'); 209 const details = document.querySelectorAll('details[id^="file-"]'); 210 211 checkbox.addEventListener('change', function() { 212 details.forEach(detail => { 213 detail.open = checkbox.checked; 214 }); 215 }); 216 217 details.forEach(detail => { 218 detail.addEventListener('toggle', function() { 219 const allOpen = Array.from(details).every(d => d.open); 220 const allClosed = Array.from(details).every(d => !d.open); 221 222 if (allOpen) { 223 checkbox.checked = true; 224 } else if (allClosed) { 225 checkbox.checked = false; 226 } 227 }); 228 }); 229 }); 230 </script> 231{{ end }}