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