github.com/GoogleCloudPlatform/testgrid@v0.0.174/web/src/testgrid-index.ts (about)

     1  import { LitElement, html, css } from 'lit';
     2  // eslint-disable-next-line @typescript-eslint/no-unused-vars
     3  import { customElement, property } from 'lit/decorators.js';
     4  import { map } from 'lit/directives/map.js';
     5  import { ListDashboardsResponse, ListDashboardGroupsResponse } from './gen/pb/api/v1/data.js';
     6  import { navigate } from './utils/navigation';
     7  import '@material/mwc-button';
     8  import '@material/mwc-list';
     9  
    10  
    11  // dashboards template
    12  // clicking on any dashboard should navigate to the /dashboards view
    13  const dashboardTemplate = (dashboards: Array<string>) => html`
    14    <div>
    15      <mwc-list activatable style="min-width: 755px">
    16        ${map(
    17          dashboards,
    18          (dash: string, index: number) => html`
    19            <mwc-list-item id=${index} @click=${() => navigate(dash)} class="column card dashboard">
    20                <div class="container">
    21                  <p>${dash}</p>
    22                </div>
    23              </a>
    24            </mwc-list-item>
    25          `
    26        )}
    27      </mwc-list>
    28    </div>
    29  `;
    30  
    31  /**
    32   * Class definition for the `testgrid-index` element.
    33   * Renders the list of dashboards and dashboard groups available.
    34   */
    35  @customElement('testgrid-index')
    36  // eslint-disable-next-line @typescript-eslint/no-unused-vars
    37  export class TestgridIndex extends LitElement {
    38  
    39    @property({ type: Array<string> }) 
    40    dashboards: Array<string> = [];
    41  
    42    @property({ type: Array<string> }) 
    43    dashboardGroups: Array<string> = [];
    44  
    45    @property({ type: Array<string> }) 
    46    respectiveDashboards: Array<string> = [];
    47  
    48    // toggles between the dashboards of a particular group or a dashboard without a group
    49    @property({ type: Boolean }) 
    50    show = true;
    51  
    52    /**
    53     * Lit-element lifecycle method.
    54     * Invoked when a component is added to the document's DOM.
    55     */
    56    connectedCallback() {
    57      super.connectedCallback();
    58      this.fetchDashboardGroups();
    59      this.fetchDashboards();
    60    }
    61  
    62    /**
    63     * Lit-element lifecycle method.
    64     * Invoked on each update to perform rendering tasks.
    65     */
    66    render() {
    67      return html`
    68        <div class="flex-container">
    69          <!-- loading dashboard groups -->
    70          <mwc-list style="min-width: 760px">
    71            ${map(this.dashboardGroups, (dash: string, index: number) => 
    72              html`
    73                <mwc-list-item
    74                  id=${index}
    75                  class="column card dashboard-group"
    76                  raised
    77                  @click="${() => this.fetchRespectiveDashboards(dash)}"
    78                >
    79                  <div class="container">
    80                    <p>${dash}</p>
    81                  </div>
    82                </mwc-list-item>
    83              `)}
    84          </mwc-list>
    85  
    86          <!-- loading dashboards -->
    87          ${this.show ? dashboardTemplate(this.dashboards) : ''}
    88  
    89          <!-- loading respective dashboards -->
    90          ${!this.show ? dashboardTemplate(this.respectiveDashboards) : ''}
    91          ${!this.show ? html`
    92                <mwc-button class="column" raised @click="${() => this.show = !this.show }">X</mwc-button>
    93              `
    94            : ''}
    95        </div>
    96      `;
    97    }
    98  
    99    // fetch the the list of dashboards from the API
   100    async fetchDashboards() {
   101      try{
   102        fetch(`http://${process.env.API_HOST}:${process.env.API_PORT}/api/v1/dashboards`).then(
   103          async response => {
   104            const resp = ListDashboardsResponse.fromJson(await response.json());
   105            const dashboards: string[] = [];
   106  
   107            resp.dashboards.forEach(db => {
   108              if (db.dashboardGroupName === ""){
   109                dashboards.push(db.name);
   110              }
   111            });
   112            this.dashboards = dashboards;
   113          }
   114        );
   115      } catch (error) {
   116        console.log(`failed to fetch: ${error}`);
   117      }
   118    }
   119  
   120    // fetch the list of dashboard groups from API
   121    async fetchDashboardGroups() {
   122      try{
   123        fetch(`http://${process.env.API_HOST}:${process.env.API_PORT}/api/v1/dashboard-groups`).then(
   124          async response => {
   125            const resp = ListDashboardGroupsResponse.fromJson(await response.json());
   126            const dashboardGroups: string[] = [];
   127  
   128            resp.dashboardGroups.forEach(db => {
   129              dashboardGroups.push(db.name);
   130            });
   131  
   132            this.dashboardGroups = dashboardGroups;
   133          }
   134        );
   135      } catch(error){
   136        console.log(`failed to fetch: ${error}`);
   137      }
   138    }
   139  
   140    // fetch the list of respective dashboards for a group from API
   141    async fetchRespectiveDashboards(name: string) {
   142      this.show = false;
   143      try {
   144        fetch(`http://${process.env.API_HOST}:${process.env.API_PORT}/api/v1/dashboard-groups/${name}`).then(
   145          async response => {
   146            const resp = ListDashboardsResponse.fromJson(await response.json());
   147            const respectiveDashboards: string[] = [];
   148  
   149            resp.dashboards.forEach(ts => {
   150              respectiveDashboards.push(ts.name);
   151            });
   152  
   153            this.respectiveDashboards = respectiveDashboards;
   154          }
   155        );
   156      } catch (error) {
   157        console.error(`Could not get dashboard summaries: ${error}`);
   158      }
   159    }
   160  
   161    static styles = css`
   162      :host {
   163        overflow: auto;
   164        min-height: 100vh;
   165        display: flex;
   166        flex-direction: column;
   167        justify-content: flex;
   168        font-size: calc(10px + 2vmin);
   169        color: #1a2b42;
   170        margin: 0 auto;
   171        text-align: center;
   172        background-color: var(--example-app-background-color);
   173      }
   174  
   175      .flex-container {
   176        display: grid;
   177        gap: 30px;
   178        grid-template-columns: auto auto auto;
   179      }
   180  
   181      .column {
   182        display: inline-grid;
   183        padding: 10px;
   184      }
   185  
   186      .card {
   187        /* Add shadows to create the "card" effect */
   188        width: 350px;
   189        height: 80px;
   190        margin-bottom: 10px;
   191        box-shadow: 0 30px 30px -25px rgba(#7168c9, 0.25);
   192      }
   193  
   194      .dashboard {
   195        background-color: #9e60eb;
   196        color: #fff;
   197      }
   198  
   199      .dashboard-group {
   200        background-color: #707df1;
   201        color: #fff;
   202      }
   203  
   204      .dashboard-group:focus,
   205      .dashboard-group:hover {
   206        background-color: #fff;
   207        color: #707df1;
   208        border-style: solid;
   209        border-color: #707df1;
   210      }
   211  
   212      .dashboard:hover,
   213      .dashboard:focus {
   214        background-color: #fff;
   215        color: #9e60eb;
   216        border-style: solid;
   217        border-color: #9e60eb;
   218      }
   219  
   220      /* Add some padding inside the card container */
   221      .container {
   222        padding: 2px 16px;
   223      }
   224    `;
   225  }