this repo has no description

appview/pages: use duration time component

Builds on the last commit to introduce a variant of the time component but for durations. I added a verbose/long duration fmt function based on the existing short duration fmt one, and also renamed the other time fmt functions for clarity.

authored by uncenter and committed by Tangled dce4b41d aea12462

Changed files
+67 -63
appview
pages
templates
repo
fragments
pipelines
pulls
+44 -30
appview/pages/funcmap.go
··· 105 s = append(s, values...) 106 return s 107 }, 108 - "timeFmt": humanize.Time, 109 - "longTimeFmt": func(t time.Time) string { 110 - return t.Format("Jan 2, 2006, 3:04 PM MST") 111 - }, 112 - "iso8601Fmt": func(t time.Time) string { 113 - return t.Format("2006-01-02T15:04:05-07:00") 114 - }, 115 - "commaFmt": humanize.Comma, 116 - "shortTimeFmt": func(t time.Time) string { 117 return humanize.CustomRelTime(t, time.Now(), "", "", []humanize.RelTimeMagnitude{ 118 {time.Second, "now", time.Second}, 119 {2 * time.Second, "1s %s", 1}, ··· 132 {math.MaxInt64, "a long while %s", 1}, 133 }) 134 }, 135 - "durationFmt": func(duration time.Duration) string { 136 days := int64(duration.Hours() / 24) 137 hours := int64(math.Mod(duration.Hours(), 24)) 138 minutes := int64(math.Mod(duration.Minutes(), 60)) 139 seconds := int64(math.Mod(duration.Seconds(), 60)) 140 - 141 - chunks := []struct { 142 - name string 143 - amount int64 144 - }{ 145 - {"d", days}, 146 - {"hr", hours}, 147 - {"min", minutes}, 148 - {"s", seconds}, 149 - } 150 - 151 - parts := []string{} 152 - 153 - for _, chunk := range chunks { 154 - if chunk.amount != 0 { 155 - parts = append(parts, fmt.Sprintf("%d%s", chunk.amount, chunk.name)) 156 - } 157 - } 158 - 159 - return strings.Join(parts, " ") 160 }, 161 "byteFmt": humanize.Bytes, 162 "length": func(slice any) int { ··· 291 modifiedSVG := svgStr[:svgTagEnd] + classTag + svgStr[svgTagEnd:] 292 return template.HTML(modifiedSVG), nil 293 }
··· 105 s = append(s, values...) 106 return s 107 }, 108 + "commaFmt": humanize.Comma, 109 + "relTimeFmt": humanize.Time, 110 + "shortRelTimeFmt": func(t time.Time) string { 111 return humanize.CustomRelTime(t, time.Now(), "", "", []humanize.RelTimeMagnitude{ 112 {time.Second, "now", time.Second}, 113 {2 * time.Second, "1s %s", 1}, ··· 126 {math.MaxInt64, "a long while %s", 1}, 127 }) 128 }, 129 + "longTimeFmt": func(t time.Time) string { 130 + return t.Format("Jan 2, 2006, 3:04 PM MST") 131 + }, 132 + "iso8601DateTimeFmt": func(t time.Time) string { 133 + return t.Format("2006-01-02T15:04:05-07:00") 134 + }, 135 + "iso8601DurationFmt": func(duration time.Duration) string { 136 days := int64(duration.Hours() / 24) 137 hours := int64(math.Mod(duration.Hours(), 24)) 138 minutes := int64(math.Mod(duration.Minutes(), 60)) 139 seconds := int64(math.Mod(duration.Seconds(), 60)) 140 + return fmt.Sprintf("P%dD%dH%dM%dS", days, hours, minutes, seconds) 141 + }, 142 + "durationFmt": func(duration time.Duration) string { 143 + return durationFmt(duration, [4]string{"d", "hr", "min", "s"}) 144 + }, 145 + "longDurationFmt": func(duration time.Duration) string { 146 + return durationFmt(duration, [4]string{"days", "hours", "minutes", "seconds"}) 147 }, 148 "byteFmt": humanize.Bytes, 149 "length": func(slice any) int { ··· 278 modifiedSVG := svgStr[:svgTagEnd] + classTag + svgStr[svgTagEnd:] 279 return template.HTML(modifiedSVG), nil 280 } 281 + 282 + func durationFmt(duration time.Duration, names [4]string) string { 283 + days := int64(duration.Hours() / 24) 284 + hours := int64(math.Mod(duration.Hours(), 24)) 285 + minutes := int64(math.Mod(duration.Minutes(), 60)) 286 + seconds := int64(math.Mod(duration.Seconds(), 60)) 287 + 288 + chunks := []struct { 289 + name string 290 + amount int64 291 + }{ 292 + {names[0], days}, 293 + {names[1], hours}, 294 + {names[2], minutes}, 295 + {names[3], seconds}, 296 + } 297 + 298 + parts := []string{} 299 + 300 + for _, chunk := range chunks { 301 + if chunk.amount != 0 { 302 + parts = append(parts, fmt.Sprintf("%d%s", chunk.amount, chunk.name)) 303 + } 304 + } 305 + 306 + return strings.Join(parts, " ") 307 + }
+8 -4
appview/pages/templates/repo/fragments/time.html
··· 1 {{ define "repo/fragments/timeWrapper" }} 2 - <time datetime="{{ .Time | iso8601Fmt }}" title="{{ .Time | longTimeFmt }}">{{ .Content }}</time> 3 {{ end }} 4 5 {{ define "repo/fragments/time" }} 6 - {{ template "repo/fragments/timeWrapper" (dict "Time" . "Content" (. | timeFmt)) }} 7 {{ end }} 8 9 {{ define "repo/fragments/shortTime" }} 10 - {{ template "repo/fragments/timeWrapper" (dict "Time" . "Content" (. | shortTimeFmt)) }} 11 {{ end }} 12 13 {{ define "repo/fragments/shortTimeAgo" }} 14 - {{ template "repo/fragments/timeWrapper" (dict "Time" . "Content" (print (. | shortTimeFmt) " ago")) }} 15 {{ end }}
··· 1 {{ define "repo/fragments/timeWrapper" }} 2 + <time datetime="{{ .Time | iso8601DateTimeFmt }}" title="{{ .Time | longTimeFmt }}">{{ .Content }}</time> 3 {{ end }} 4 5 {{ define "repo/fragments/time" }} 6 + {{ template "repo/fragments/timeWrapper" (dict "Time" . "Content" (. | relTimeFmt)) }} 7 {{ end }} 8 9 {{ define "repo/fragments/shortTime" }} 10 + {{ template "repo/fragments/timeWrapper" (dict "Time" . "Content" (. | shortRelTimeFmt)) }} 11 {{ end }} 12 13 {{ define "repo/fragments/shortTimeAgo" }} 14 + {{ template "repo/fragments/timeWrapper" (dict "Time" . "Content" (print (. | shortRelTimeFmt) " ago")) }} 15 + {{ end }} 16 + 17 + {{ define "repo/fragments/duration" }} 18 + <time datetime="{{ . | iso8601DurationFmt }}" title="{{ . | longDurationFmt }}">{{ . | durationFmt }}</time> 19 {{ end }}
+5 -9
appview/pages/templates/repo/pipelines/fragments/tooltip.html
··· 10 {{ $lastStatus := $all.Latest }} 11 {{ $kind := $lastStatus.Status.String }} 12 13 - {{ $t := .TimeTaken }} 14 - {{ $time := "" }} 15 - {{ if $t }} 16 - {{ $time = durationFmt $t }} 17 - {{ else }} 18 - {{ $time = printf "%s ago" (shortTimeFmt $pipeline.Created) }} 19 - {{ end }} 20 - 21 <div id="left" class="flex items-center gap-2 flex-shrink-0"> 22 {{ template "repo/pipelines/fragments/workflowSymbol" $all }} 23 {{ $name }} 24 </div> 25 <div id="right" class="flex items-center gap-2 flex-shrink-0"> 26 <span class="font-bold">{{ $kind }}</span> 27 - <time>{{ $time }}</time> 28 </div> 29 </div> 30 </a>
··· 10 {{ $lastStatus := $all.Latest }} 11 {{ $kind := $lastStatus.Status.String }} 12 13 <div id="left" class="flex items-center gap-2 flex-shrink-0"> 14 {{ template "repo/pipelines/fragments/workflowSymbol" $all }} 15 {{ $name }} 16 </div> 17 <div id="right" class="flex items-center gap-2 flex-shrink-0"> 18 <span class="font-bold">{{ $kind }}</span> 19 + {{ if .TimeTaken }} 20 + {{ template "repo/fragments/duration" .TimeTaken }} 21 + {{ else }} 22 + {{ template "repo/fragments/shortTimeAgo" $pipeline.Created }} 23 + {{ end }} 24 </div> 25 </div> 26 </a>
+5 -10
appview/pages/templates/repo/pipelines/workflow.html
··· 32 {{ $lastStatus := $all.Latest }} 33 {{ $kind := $lastStatus.Status.String }} 34 35 - {{ $t := .TimeTaken }} 36 - {{ $time := "" }} 37 - 38 - {{ if $t }} 39 - {{ $time = durationFmt $t }} 40 - {{ else }} 41 - {{ $time = printf "%s ago" (shortTimeFmt $lastStatus.Created) }} 42 - {{ end }} 43 - 44 <div id="left" class="flex items-center gap-2 flex-shrink-0"> 45 {{ template "repo/pipelines/fragments/workflowSymbol" $all }} 46 {{ $name }} 47 </div> 48 <div id="right" class="flex items-center gap-2 flex-shrink-0"> 49 <span class="font-bold">{{ $kind }}</span> 50 - <time>{{ $time }}</time> 51 </div> 52 </div> 53 </a>
··· 32 {{ $lastStatus := $all.Latest }} 33 {{ $kind := $lastStatus.Status.String }} 34 35 <div id="left" class="flex items-center gap-2 flex-shrink-0"> 36 {{ template "repo/pipelines/fragments/workflowSymbol" $all }} 37 {{ $name }} 38 </div> 39 <div id="right" class="flex items-center gap-2 flex-shrink-0"> 40 <span class="font-bold">{{ $kind }}</span> 41 + {{ if .TimeTaken }} 42 + {{ template "repo/fragments/duration" .TimeTaken }} 43 + {{ else }} 44 + {{ template "repo/fragments/shortTimeAgo" $lastStatus.Created }} 45 + {{ end }} 46 </div> 47 </div> 48 </a>
+5 -10
appview/pages/templates/repo/pulls/pull.html
··· 277 {{ $lastStatus := $all.Latest }} 278 {{ $kind := $lastStatus.Status.String }} 279 280 - {{ $t := .TimeTaken }} 281 - {{ $time := "" }} 282 - 283 - {{ if $t }} 284 - {{ $time = durationFmt $t }} 285 - {{ else }} 286 - {{ $time = printf "%s ago" (shortTimeFmt $lastStatus.Created) }} 287 - {{ end }} 288 - 289 <div id="left" class="flex items-center gap-2 flex-shrink-0"> 290 {{ template "repo/pipelines/fragments/workflowSymbol" $all }} 291 {{ $name }} 292 </div> 293 <div id="right" class="flex items-center gap-2 flex-shrink-0"> 294 <span class="font-bold">{{ $kind }}</span> 295 - <time>{{ $time }}</time> 296 </div> 297 </div> 298 </a>
··· 277 {{ $lastStatus := $all.Latest }} 278 {{ $kind := $lastStatus.Status.String }} 279 280 <div id="left" class="flex items-center gap-2 flex-shrink-0"> 281 {{ template "repo/pipelines/fragments/workflowSymbol" $all }} 282 {{ $name }} 283 </div> 284 <div id="right" class="flex items-center gap-2 flex-shrink-0"> 285 <span class="font-bold">{{ $kind }}</span> 286 + {{ if .TimeTaken }} 287 + {{ template "repo/fragments/duration" .TimeTaken }} 288 + {{ else }} 289 + {{ template "repo/fragments/shortTimeAgo" $lastStatus.Created }} 290 + {{ end }} 291 </div> 292 </div> 293 </a>