Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(471)

Side by Side Diff: appengine/cmd/milo/settings/funcs.go

Issue 2196453002: Milo: Console view prototype (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-go@master
Patch Set: Reviews Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « appengine/cmd/milo/resp/console.go ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The LUCI Authors. All rights reserved. 1 // Copyright 2016 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package settings 5 package settings
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "fmt" 9 "fmt"
10 "html/template" 10 "html/template"
11 "strings" 11 "strings"
12 "time" 12 "time"
13 13
14 "github.com/luci/luci-go/appengine/cmd/milo/resp" 14 "github.com/luci/luci-go/appengine/cmd/milo/resp"
15 ) 15 )
16 16
17 // A collection of useful templating functions 17 // A collection of useful templating functions
18 18
19 // funcMap is what gets fed into the template bundle. 19 // funcMap is what gets fed into the template bundle.
20 var funcMap = template.FuncMap{ 20 var funcMap = template.FuncMap{
21 "humanDuration": humanDuration, 21 "humanDuration": humanDuration,
22 "parseRFC3339": parseRFC3339, 22 "parseRFC3339": parseRFC3339,
23 "linkify": linkify, 23 "linkify": linkify,
24 "obfuscateEmail": obfuscateEmail, 24 "obfuscateEmail": obfuscateEmail,
25 "localTime": localTime, 25 "localTime": localTime,
26 "shortHash": shortHash, 26 "shortHash": shortHash,
27 "startswith": strings.HasPrefix, 27 "startswith": strings.HasPrefix,
28 "sub": sub, 28 "sub": sub,
29 "consoleHeader": consoleHeader,
29 } 30 }
30 31
31 // localTime returns a <span> element with t in human format 32 // localTime returns a <span> element with t in human format
32 // that will be converted to local timezone in the browser. 33 // that will be converted to local timezone in the browser.
33 // Recommended usage: {{ .Date | localTime "N/A" }} 34 // Recommended usage: {{ .Date | localTime "N/A" }}
34 func localTime(ifZero string, t time.Time) template.HTML { 35 func localTime(ifZero string, t time.Time) template.HTML {
35 if t.IsZero() { 36 if t.IsZero() {
36 return template.HTML(template.HTMLEscapeString(ifZero)) 37 return template.HTML(template.HTMLEscapeString(ifZero))
37 } 38 }
38 milliseconds := t.UnixNano() / 1e6 39 milliseconds := t.UnixNano() / 1e6
39 return template.HTML(fmt.Sprintf( 40 return template.HTML(fmt.Sprintf(
40 `<span class="local-time" data-timestamp="%d">%s</span>`, 41 `<span class="local-time" data-timestamp="%d">%s</span>`,
41 milliseconds, 42 milliseconds,
42 t.Format(time.RFC850))) 43 t.Format(time.RFC850)))
43 } 44 }
44 45
46 func consoleHeader(brs []resp.BuilderRef) template.HTML {
47 // First, split things into nice rows and find the max depth.
48 cat := make([][]string, len(brs))
49 depth := 0
50 for i, b := range brs {
51 cat[i] = b.Category
52 if len(cat[i]) > depth {
53 depth = len(cat[i])
54 }
55 }
56
57 result := ""
58 for row := 0; row < depth; row++ {
59 result += "<tr><th></th>"
60 // "" is the first node, " " is an empty node.
61 current := ""
62 colspan := 0
63 for _, br := range cat {
64 colspan++
65 var s string
66 if row >= len(br) {
67 s = " "
68 } else {
69 s = br[row]
70 }
71 if s != current || current == " " {
72 if current != "" || current == " " {
73 result += fmt.Sprintf(`<th colspan="%d"> %s</th>`, colspan, current)
74 colspan = 0
75 }
76 current = s
77 }
78 }
79 if colspan != 0 {
80 result += fmt.Sprintf(`<th colspan="%d">%s</th>`, colspa n, current)
81 }
82 result += "</tr>"
83 }
84
85 // Last row: The actual builder shortnames.
86 result += "<tr><th></th>"
87 for _, br := range brs {
88 result += fmt.Sprintf("<th>%s</th>", br.ShortName)
89 }
90 result += "</tr>"
91 return template.HTML(result)
92 }
93
45 // humanDuration translates d into a human readable string of x units y units, 94 // humanDuration translates d into a human readable string of x units y units,
46 // where x and y could be in days, hours, minutes, or seconds, whichever is the 95 // where x and y could be in days, hours, minutes, or seconds, whichever is the
47 // largest. 96 // largest.
48 func humanDuration(d time.Duration) string { 97 func humanDuration(d time.Duration) string {
49 t := int64(d.Seconds()) 98 t := int64(d.Seconds())
50 day := t / 86400 99 day := t / 86400
51 hr := (t % 86400) / 3600 100 hr := (t % 86400) / 3600
52 101
53 if day > 0 { 102 if day > 0 {
54 if hr != 0 { 103 if hr != 0 {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 return a - b 178 return a - b
130 } 179 }
131 180
132 // shortHash abbriviates a git hash into 6 characters. 181 // shortHash abbriviates a git hash into 6 characters.
133 func shortHash(s string) string { 182 func shortHash(s string) string {
134 if len(s) > 6 { 183 if len(s) > 6 {
135 return s[0:6] 184 return s[0:6]
136 } 185 }
137 return s 186 return s
138 } 187 }
OLDNEW
« no previous file with comments | « appengine/cmd/milo/resp/console.go ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698