go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/deploy/service/templates/includes/base.html (about)

     1  {{define "base"}}
     2  <!DOCTYPE html>
     3  <html lang="en">
     4  
     5  <!-- Copyright 2022 The LUCI Authors. All rights reserved.
     6  Use of this source code is governed under the Apache License, Version 2.0
     7  that can be found in the LICENSE file. -->
     8  <head>
     9    <meta http-equiv="Content-type" content="text/html; charset=UTF-8">
    10    <link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    11    <title>{{block "title" .}}LUCI Deploy{{end}}</title>
    12    <script src="/static/bootstrap/js/bootstrap.bundle.min.js"></script>
    13    <style>
    14      body {
    15        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    16        font-size: 14px;
    17      }
    18      .tooltip {
    19        font-size: 12px;
    20      }
    21      .font-small {
    22        font-size: 12px;
    23      }
    24      a {
    25        text-decoration: none!important;
    26      }
    27      .user-avatar {
    28        width: 30;
    29        height: 30px;
    30        border-radius: 5px;
    31      }
    32      #asset-title {
    33        margin-bottom: 0px;
    34      }
    35      #asset-title img {
    36        width: 40px;
    37        height: 40px;
    38      }
    39      .popover-html-content {
    40        display: none;
    41      }
    42      .popover-big {
    43        max-width: 800px;
    44      }
    45      {{block "style" .}}{{end}}
    46    </style>
    47  
    48    <script type="text/javascript">
    49      function onPageLoaded() {
    50        // Activate all fancy Bootstrap popovers and tooltips.
    51        document.querySelectorAll('[data-bs-toggle="popover"]').forEach(
    52            elem => {
    53              let opts = {container: 'body'};
    54              let content = elem.querySelector('.popover-html-content');
    55              if (content != null) {
    56                content.remove();
    57                content.classList.remove('popover-html-content');
    58                opts['html'] = true;
    59                opts['sanitize'] = false;
    60                opts['content'] = content;
    61                opts['template'] = `
    62                <div class="popover popover-big" role="tooltip">
    63                  <div class="popover-arrow"></div>
    64                  <h3 class="popover-header"></h3>
    65                  <div class="popover-body"></div>
    66                </div>
    67                `;
    68              }
    69              return new bootstrap.Popover(elem, opts);
    70            }
    71        );
    72        document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(
    73            elem => new bootstrap.Tooltip(elem, {container: 'body'})
    74        );
    75  
    76        // Draw percent bars for all elements with "percent-widget" class.
    77        document.querySelectorAll('.percent-widget').forEach(
    78            elem => {
    79              let percent = parseInt(elem.getAttribute('data-percent'), 10);
    80              if (percent != 0 && !isNaN(percent)) {
    81                elem.style.background = `linear-gradient(\
    82                    to right, \
    83                    #b8ffce ${percent}%, \
    84                    #e3ffec ${percent}% 100%)`;
    85              }
    86            }
    87        );
    88      }
    89    </script>
    90  </head>
    91  
    92  <body class="pt-2" onload="onPageLoaded()">
    93    <div class="container">
    94      <nav class="navbar navbar-expand-md navbar-light bg-light rounded border mb-2">
    95        <div class="container-fluid">
    96          <a class="navbar-brand" href="/">LUCI Deploy</a>
    97          <span class="navbar-text">
    98            {{if .User.Picture}}
    99            <img class="user-avatar" referrerpolicy="no-referrer" src="{{.User.Picture}}">
   100            {{end}}
   101            {{.User.Email}} | <a href="{{.LogoutURL}}">Logout</a>
   102          </span>
   103        </div>
   104      </nav>
   105  
   106      <div id="content-box">
   107        {{block "content" .}}{{end}}
   108      </div>
   109  
   110      <footer style="color: #cccccc;">
   111        <hr class="mt-1 mb-1">
   112        <p class="float-end small">
   113          <span class="ms-2">Version: {{.AppVersion}}</span>
   114        </p>
   115      </footer>
   116    </div>
   117  </body>
   118  
   119  </html>
   120  {{end}}
   121  
   122  
   123  {{define "assetTitle"}}
   124  <img src="/static/icons/{{.Icon}}" title="{{.Kind}}"> {{.Name}}
   125  {{end}}
   126  
   127  
   128  {{define "linkHref"}}
   129  {{if .Href}}
   130  <a
   131    href="{{.Href}}" target="{{.Target}}"
   132    {{if .Tooltip}}
   133    data-bs-toggle="tooltip"
   134    data-bs-html="true"
   135    data-bs-placement="top"
   136    data-bs-trigger="hover"
   137    title="{{.Tooltip}}"
   138    {{end}}
   139  >{{if .Text}}{{.Text}}{{else}}-{{end}}</a>
   140  {{else}}
   141  <span
   142    {{if .Tooltip}}
   143    data-bs-toggle="tooltip"
   144    data-bs-html="true"
   145    data-bs-placement="top"
   146    data-bs-trigger="hover"
   147    title="{{.Tooltip}}"
   148    {{end}}
   149  >{{if .Text}}{{.Text}}{{else}}-{{end}}</span>
   150  {{end}}
   151  {{end}}
   152  
   153  
   154  {{define "breadcrumbs"}}
   155  <nav aria-label="breadcrumb">
   156    <ol class="breadcrumb bg-light p-2">
   157      {{range $crumb := .Breadcrumbs }}
   158        {{if $crumb.Last}}
   159        <li class="breadcrumb-item active" aria-current="page">
   160          {{if $crumb.Icon}}
   161          <img src="/static/icons/{{$crumb.Icon}}">
   162          {{end}}
   163          {{$crumb.Title}}
   164        </li>
   165        {{else}}
   166        <li class="breadcrumb-item">
   167          <a href="{{$crumb.Href}}">
   168            {{if $crumb.Icon}}
   169            <img src="/static/icons/{{$crumb.Icon}}">
   170            {{end}}
   171            {{$crumb.Title}}
   172          </a>
   173        </li>
   174        {{end}}
   175      {{end}}
   176    </ol>
   177  </nav>
   178  {{end}}
   179  
   180  
   181  {{define "assetOverview"}}
   182  <div class="row align-items-center pb-3">
   183    <div class="col-8">
   184      <h3 id="asset-title">{{template "assetTitle" .Ref}}</h3>
   185    </div>
   186  
   187    <div class="col-4">
   188      <div class="row">
   189        <div class="col">Status</div>
   190        <div class="col"><span class="badge {{.BadgeClass}}">{{.State}}</span></div>
   191      </div>
   192  
   193      <div class="row">
   194        <div class="col">
   195          <span data-bs-toggle="popover"
   196                data-bs-placement="left"
   197                data-bs-trigger="hover"
   198                data-bs-content="
   199                    The last time the actuator reported the current observed
   200                    state and Infrastructure-as-Code (IaC) configuration of
   201                    this asset.
   202          ">
   203          Last check in
   204          </span>
   205        </div>
   206        <div class="col">{{template "linkHref" .LastCheckIn}}</div>
   207      </div>
   208  
   209      <div class="row">
   210        <div class="col">
   211          <span data-bs-toggle="popover"
   212                data-bs-placement="left"
   213                data-bs-trigger="hover"
   214                data-bs-content="
   215                    The last time the actuator tried to update the asset
   216                    to match the Infrastructure-as-Code (IaC) configuration
   217                    (successfully or not).
   218          ">
   219          Last actuation
   220          </span>
   221        </div>
   222        <div class="col">{{template "linkHref" .LastActuation}}</div>
   223      </div>
   224  
   225      <div class="row">
   226        <div class="col">
   227          <span data-bs-toggle="popover"
   228                data-bs-placement="left"
   229                data-bs-trigger="hover"
   230                data-bs-content="
   231                    The revision of the Infrastructure-as-Code (IaC)
   232                    configuration the actuator successfully applied most
   233                    recently.
   234          ">
   235          Applied revision
   236          </span>
   237        </div>
   238        <div class="col">{{template "linkHref" .Revision}}</div>
   239      </div>
   240    </div>
   241  </div>
   242  {{end}}
   243  
   244  
   245  {{define "historyListing"}}
   246  <div>
   247    {{if .}}
   248    <table class="table table-sm">
   249      <tbody>
   250      {{range .}}
   251        <tr class="{{.TableClass}}">
   252          <td class="col-1">{{template "linkHref" .ID}}</td>
   253          <td class="col-2">{{template "linkHref" .Age}}</td>
   254          <td class="col-7">
   255            <span
   256              data-bs-toggle="popover"
   257              data-bs-placement="top"
   258              data-bs-trigger="hover"
   259            >
   260            <div class="popover-html-content font-monospace font-small lh-sm">
   261              <div><b>Commit: </b>{{.Commit.Rev}}</div>
   262              <div><b>Author: </b>{{.Commit.AuthorEmail}}</div>
   263              <hr class="mt-2 mb-3">
   264              <pre>{{.Commit.CommitMessage}}</pre>
   265            </div>
   266            {{template "linkHref" .Commit.Subject}}
   267            </span>
   268          </td>
   269          <td class="col-2">
   270            <a href="{{.ID.Href}}">
   271              <span class="badge {{.BadgeClass}}">{{.Outcome}}</span>
   272            </a>
   273          </td>
   274        </tr>
   275      {{end}}
   276      </tbody>
   277    </table>
   278    {{else}}
   279    <i>No history</i>
   280    {{end}}
   281  </div>
   282  {{end}}