internal/web/templates/owner.html

e6cd75b5f28bacf51620bb531320c30fd4e66bfd
gitbay/internal/web/templates/owner.html history · blame · raw

191 lines · 11156 bytes

  1{{define "title"}}{{.Owner}} · {{.Site}}{{end}}
  2{{define "content"}}
  3<section class="profilehead">
  4<h1>{{.Owner}} <span class="chip chip-neutral">{{.Kind}}</span></h1>
  5{{if .Profile.Description}}<p class="desc lede">{{.Profile.Description}}</p>{{end}}
  6{{if .Profile.Website}}<p class="meta"><a href="{{.Profile.Website}}" rel="nofollow me">{{.Profile.Website}}</a></p>{{end}}
  7{{if .Profile.Links}}<p class="meta">{{range $i, $l := .Profile.Links}}{{if $i}} · {{end}}<a href="{{$l.URL}}" rel="nofollow me">{{if $l.Label}}{{$l.Label}}{{else}}{{$l.URL}}{{end}}</a>{{end}}</p>{{end}}
  8{{if .Orgs}}<p class="meta">member of {{range .Orgs}}<a class="memberchip" href="/{{.Name}}">{{.Name}}</a> {{end}}</p>{{end}}
  9{{if .Members}}<p class="meta">members {{range .Members}}<a class="memberchip" href="/{{.Name}}">{{.Name}} <span class="role">{{.Role}}</span></a> {{end}}</p>{{end}}
 10{{if and (eq .Kind "org") .Repos}}<p class="meta"><a href="/{{.Owner}}/-/labels">labels</a> · <a href="/{{.Owner}}/-/milestones">milestones</a></p>{{end}}
 11</section>
 12{{if and .Notice (ne .Tab "snippets") (ne .Tab "people")}}<p class="notice" role="status">{{.Notice}}</p>{{end}}
 13{{/* The profile is sections rather than one stack: a long About used to
 14     push the repositories off the bottom of the page (#242). About is
 15     the bare /{owner}; the rest hang off /-/. A tab nobody may open is
 16     not offered and its URL is a 404. */}}
 17<nav class="tabs profiletabs" aria-label="Profile">
 18  <a {{if eq .Tab "about"}}aria-current="page" {{end}}href="/{{.Owner}}">About</a>
 19  <a {{if eq .Tab "repos"}}aria-current="page" {{end}}href="/{{.Owner}}/-/repositories">Repositories{{if .Repos}} <i>{{len .Repos}}</i>{{end}}</a>
 20  {{if .Self}}<a {{if eq .Tab "bookmarks"}}aria-current="page" {{end}}href="/{{.Owner}}/-/bookmarks">Bookmarks</a>{{end}}
 21  {{if and (eq .Kind "user") (or .Snippets .Self)}}<a {{if eq .Tab "snippets"}}aria-current="page" {{end}}href="/{{.Owner}}/-/snippets">Snippets{{if .Snippets}} <i>{{.Snippets}}</i>{{end}}</a>{{end}}
 22  {{if .CanAdmin}}<a {{if eq .Tab "people"}}aria-current="page" {{end}}href="/{{.Owner}}/-/people">People{{if .Members}} <i>{{len .Members}}</i>{{end}}</a>{{end}}
 23</nav>
 24
 25{{if eq .Tab "about"}}
 26{{if .AboutHTML}}<section class="readme"><div class="rendered">{{.AboutHTML}}</div></section>{{end}}
 27<section class="activity">
 28<h2>activity <span class="count">{{.ActivityTotal}} in the last year</span></h2>
 29<div class="actgraph-scroll">
 30<div class="actgraph">
 31{{range .Activity}}<div class="actweek">{{if .Month}}<span class="actmonth">{{.Month}}</span>{{end}}{{range .Days}}<span class="actday{{if .Pad}} pad{{else}} l{{.Level}}{{end}}"{{if not .Pad}} title="{{.Count}} on {{.Date}}"{{end}}></span>{{end}}</div>{{end}}
 32</div>
 33</div>
 34<p class="actlegend"><span>Less</span><span class="actday l0"></span><span class="actday l1"></span><span class="actday l2"></span><span class="actday l3"></span><span class="actday l4"></span><span>More</span></p>
 35{{/* The graph is the year at a glance; the log is what happened lately.
 36     It is the newest events, not all of them — the atom feed is the one
 37     that goes back. */}}
 38{{if .Log}}<h3 class="logsub">recent</h3>
 39<div class="ownerlog">
 40{{range .Log}}<p class="feedline"><a href="/{{.Actor}}">{{.Actor}}</a> {{.Verb}} <a href="{{.URL}}"{{if .Jobs}} title="{{join .Jobs ", "}}"{{end}}>{{.Ref}}</a>{{if .Extra}} {{.Extra}}{{end}}<br><span class="none">{{.Repo}} · <span title="{{whenT .WhenT}}">{{ago .WhenT}}</span></span></p>
 41{{end}}
 42</div>
 43<p class="meta"><a href="{{.Feed}}">activity feed</a></p>
 44{{else}}<p class="none">Nothing yet.</p>{{end}}
 45</section>
 46{{end}}
 47
 48{{if eq .Tab "repos"}}
 49<ul class="repolist rows">
 50{{range .Repos}}{{template "reporow" .}}
 51{{else}}<li class="empty">no visible repositories</li>{{end}}
 52</ul>
 53{{end}}
 54
 55{{if eq .Tab "bookmarks"}}
 56<p class="meta">Repositories you saved to come back to. A pin is private quick
 57  access to your own work; a bookmark is a public vote to save access to another
 58  repo.</p>
 59<ul class="repolist">
 60{{range .Bookmarks}}<li>
 61  <p class="title"><a href="/{{.Path}}">{{.Path}}</a>
 62    {{if eq .Visibility "private"}}<span class="chip">Private</span>{{end}}
 63    <span class="count">{{.Bookmarks}}</span></p>
 64  {{if .Description}}<p class="desc">{{.Description}}</p>{{end}}
 65</li>
 66{{else}}<li class="empty">nothing bookmarked yet. open a repository and press Bookmark</li>{{end}}
 67</ul>
 68{{end}}
 69
 70{{if eq .Tab "snippets"}}
 71{{if .Notice}}<p class="error" role="alert">{{.Notice}}</p>{{end}}
 72{{if .Self}}<p class="meta"><a href="/{{.Owner}}/-/snippets/new">new snippet</a> · or <code>gitbay snippet create &lt;file&gt; &lt; file</code></p>{{end}}
 73{{if .SnippetRows}}<div class="tablewrap"><table class="keys">
 74<tr class="cols"><th scope="col">snippet</th><th scope="col">files</th>{{if .SnippetsAll}}<th scope="col">visibility</th>{{end}}<th scope="col">updated</th></tr>
 75{{range .SnippetRows}}<tr>
 76  <td><a href="/{{$.Owner}}/-/snippets/{{.PublicID}}">{{if .Description}}{{.Description}}{{else}}{{.PublicID}}{{end}}</a></td>
 77  <td><span class="mono">{{.Names}}</span></td>
 78  {{if $.SnippetsAll}}<td><span class="chip chip-neutral">{{.Visibility}}</span></td>{{end}}
 79  <td>{{when .UpdatedAt}}</td>
 80</tr>
 81{{end}}</table></div>
 82{{else}}<p class="none">No snippets yet.</p>{{end}}
 83{{end}}
 84
 85{{if eq .Tab "people"}}{{$org := .Owner}}
 86<h2>people <span class="count">{{len .Members}}</span></h2>
 87{{if .Notice}}<p class="error" role="alert">{{.Notice}}{{if .Reauth}} <a href="/login">Sign in again</a>{{end}}</p>{{end}}
 88<div class="tablewrap"><table class="keys">
 89<tr class="cols"><th scope="col">member</th><th scope="col">role</th><th scope="col"><span class="vh">actions</span></th></tr>
 90{{range .Members}}<tr>
 91  <td><a href="/{{.Name}}">{{.Name}}</a></td>
 92  <td>{{.Role}}</td>
 93  <td class="act"><form method="post" action="/{{$org}}"><input type="hidden" name="field" value="member-remove"><input type="hidden" name="user" value="{{.Name}}">{{template "confirmfield" .Name}} <button type="submit" class="linklike">Remove</button></form></td>
 94</tr>
 95{{end}}</table></div>
 96<details class="editbox">
 97  <summary>Add or change a member</summary>
 98  <form method="post" action="/{{$org}}" class="setform stack">
 99    <input type="hidden" name="field" value="member-add">
100    <label for="member">Username</label>
101    <input type="text" id="member" name="user" required autocomplete="off" spellcheck="false">
102    <label class="none" for="memberrole">Role</label>
103    <select id="memberrole" name="role">
104      <option value="member">member</option>
105      <option value="admin">admin</option>
106    </select>
107    <button type="submit" class="btn">Apply</button>
108  </form>
109</details>
110
111<h2>teams <span class="count">{{len .Teams}}</span></h2>
112<p class="meta">Teams scope repository access inside the organization: members
113of a team get its role on every repository it is granted.</p>
114{{range .Teams}}<details class="difffold" open>
115  <summary><span class="fpath">{{.Name}}</span>
116    <span class="fstat">{{len .Members}} member{{if ne (len .Members) 1}}s{{end}} · {{len .Grants}} repo{{if ne (len .Grants) 1}}s{{end}}</span>
117  </summary>
118  <div class="teambody">
119    <p class="meta">members: {{range .Members}}<a class="memberchip" href="/{{.}}">{{.}}</a> {{else}}<span class="none">none yet</span>{{end}}</p>
120    <p class="meta">repositories: {{range .Grants}}<span class="memberchip"><a href="/{{.RepoPath}}">{{.RepoPath}}</a> <span class="role">{{.Role}}</span></span> {{else}}<span class="none">none yet</span>{{end}}</p>
121    <form method="post" action="/{{$org}}" class="setform stack">
122      <input type="hidden" name="field" value="team-add">
123      <input type="hidden" name="team" value="{{.Name}}">
124      <label class="none" for="tm-{{.Name}}">Add members</label>
125      <input type="text" id="tm-{{.Name}}" name="user" placeholder="usernames, space-separated" autocomplete="off" spellcheck="false">
126      <button type="submit" class="btn">Add</button>
127    </form>
128    {{if .Members}}<form method="post" action="/{{$org}}" class="setform stack">
129      <input type="hidden" name="field" value="team-remove">
130      <input type="hidden" name="team" value="{{.Name}}">
131      <label class="none" for="tmr-{{.Name}}">Remove members</label>
132      <input type="text" id="tmr-{{.Name}}" name="user" placeholder="usernames, space-separated" autocomplete="off" spellcheck="false">
133      {{template "confirmfield" .Name}}
134      <button type="submit" class="btn">Remove</button>
135    </form>{{end}}
136    <form method="post" action="/{{$org}}" class="setform stack">
137      <input type="hidden" name="field" value="team-grant">
138      <input type="hidden" name="team" value="{{.Name}}">
139      <label class="none" for="tr-{{.Name}}">Grant a repository</label>
140      <input type="text" id="tr-{{.Name}}" name="repo" placeholder="owner/name" autocomplete="off" spellcheck="false">
141      <label class="none" for="trr-{{.Name}}">Role</label>
142      <select id="trr-{{.Name}}" name="role">
143        <option value="read">read</option>
144        <option value="write">write</option>
145        <option value="admin">admin</option>
146      </select>
147      <button type="submit" class="btn">Grant</button>
148    </form>
149    {{if .Grants}}<form method="post" action="/{{$org}}" class="setform stack">
150      <input type="hidden" name="field" value="team-revoke">
151      <input type="hidden" name="team" value="{{.Name}}">
152      <label class="none" for="trv-{{.Name}}">Revoke a repository</label>
153      <input type="text" id="trv-{{.Name}}" name="repo" placeholder="owner/name" autocomplete="off" spellcheck="false">
154      {{template "confirmfield" .Name}}
155      <button type="submit" class="btn">Revoke</button>
156    </form>{{end}}
157    <form method="post" action="/{{$org}}" class="setform">
158      <input type="hidden" name="field" value="team-delete">
159      <input type="hidden" name="team" value="{{.Name}}">
160      {{template "confirmfield" .Name}}
161      <button type="submit" class="danger">Delete this team</button>
162    </form>
163  </div>
164</details>
165{{else}}<p class="none">No teams yet.</p>{{end}}
166<details class="editbox">
167  <summary>Create a team</summary>
168  <form method="post" action="/{{$org}}" class="setform">
169    <input type="hidden" name="field" value="team-create">
170    <label for="newteam">Name</label>
171    <input type="text" id="newteam" name="team" required>
172    <button type="submit" class="btn">Create</button>
173  </form>
174</details>
175
176<h2>organization</h2>
177<details class="editbox">
178  <summary>Rename</summary>
179  <form method="post" action="/{{$org}}" class="setform">
180    <input type="hidden" name="field" value="org-rename">
181    <label for="orgrename">New name</label>
182    <input type="text" id="orgrename" name="name" value="{{$org}}" required autocomplete="off" spellcheck="false">
183    <button type="submit" class="btn">Rename</button>
184  </form>
185  <p class="meta">Every clone URL under this organization changes with the name.</p>
186</details>
187<p class="meta">Deleting an organization is a CLI operation, like deleting a
188repository: it wants a typed confirmation rather than a button.</p>
189<pre class="message" tabindex="0">gitbay org delete {{$org}} --yes</pre>
190{{end}}
191{{end}}