| /** |
| * @license |
| * Copyright 2018 Google LLC |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| import {RepoName, DashboardId, DashboardInfo} from '../../../types/common'; |
| import {firePageError} from '../../../utils/event-util'; |
| import {getAppContext} from '../../../services/app-context'; |
| import {ErrorCallback} from '../../../api/rest'; |
| import {sharedStyles} from '../../../styles/shared-styles'; |
| import {tableStyles} from '../../../styles/gr-table-styles'; |
| import {LitElement, css, html, PropertyValues} from 'lit'; |
| import {customElement, property} from 'lit/decorators.js'; |
| import {createDashboardUrl} from '../../../models/views/dashboard'; |
| |
| interface DashboardRef { |
| section: string; |
| dashboards: DashboardInfo[]; |
| } |
| |
| @customElement('gr-repo-dashboards') |
| export class GrRepoDashboards extends LitElement { |
| @property({type: String}) |
| repo?: RepoName; |
| |
| @property({type: Boolean}) |
| _loading = true; |
| |
| @property({type: Array}) |
| _dashboards?: DashboardRef[]; |
| |
| private readonly restApiService = getAppContext().restApiService; |
| |
| static override get styles() { |
| return [ |
| sharedStyles, |
| tableStyles, |
| css` |
| :host { |
| display: block; |
| margin-bottom: var(--spacing-xxl); |
| } |
| .loading #dashboards, |
| #loadingContainer { |
| display: none; |
| } |
| .loading #loadingContainer { |
| display: block; |
| } |
| `, |
| ]; |
| } |
| |
| override render() { |
| return html` <table |
| id="list" |
| class="genericList ${this._computeLoadingClass(this._loading)}" |
| > |
| <tbody> |
| <tr class="headerRow"> |
| <th class="topHeader">Dashboard name</th> |
| <th class="topHeader">Dashboard title</th> |
| <th class="topHeader">Dashboard description</th> |
| <th class="topHeader">Inherited from</th> |
| <th class="topHeader">Default</th> |
| </tr> |
| <tr id="loadingContainer"> |
| <td>Loading...</td> |
| </tr> |
| </tbody> |
| <tbody id="dashboards"> |
| ${(this._dashboards ?? []).map( |
| item => html` |
| <tr class="groupHeader"> |
| <td colspan="5">${item.section}</td> |
| </tr> |
| ${(item.dashboards ?? []).map( |
| info => html` |
| <tr class="table"> |
| <td class="name"> |
| <a href=${this._getUrl(info.project, info.id)} |
| >${info.path}</a |
| > |
| </td> |
| <td class="title">${info.title}</td> |
| <td class="desc">${info.description}</td> |
| <td class="inherited"> |
| ${this._computeInheritedFrom( |
| info.project, |
| info.defining_project |
| )} |
| </td> |
| <td class="default"> |
| ${this._computeIsDefault(info.is_default)} |
| </td> |
| </tr> |
| ` |
| )} |
| ` |
| )} |
| </tbody> |
| </table>`; |
| } |
| |
| override updated(changedProperties: PropertyValues) { |
| if (changedProperties.has('repo')) { |
| this.repoChanged(); |
| } |
| } |
| |
| private repoChanged() { |
| const repo = this.repo; |
| this._loading = true; |
| if (!repo) { |
| return Promise.resolve(); |
| } |
| |
| const errFn: ErrorCallback = response => { |
| firePageError(response); |
| }; |
| |
| return this.restApiService |
| .getRepoDashboards(repo, errFn) |
| .then((res?: DashboardInfo[]) => { |
| if (!res) { |
| return; |
| } |
| |
| // Group by ref and sort by id. |
| const dashboards = res.concat |
| .apply([], res) |
| .sort((a, b) => (a.id < b.id ? -1 : 1)); |
| const dashboardsByRef: Record<string, DashboardInfo[]> = {}; |
| dashboards.forEach(d => { |
| if (!dashboardsByRef[d.ref]) { |
| dashboardsByRef[d.ref] = []; |
| } |
| dashboardsByRef[d.ref].push(d); |
| }); |
| |
| const dashboardBuilder: DashboardRef[] = []; |
| Object.keys(dashboardsByRef) |
| .sort() |
| .forEach(ref => { |
| dashboardBuilder.push({ |
| section: ref, |
| dashboards: dashboardsByRef[ref], |
| }); |
| }); |
| |
| this._dashboards = dashboardBuilder; |
| this._loading = false; |
| }); |
| } |
| |
| _getUrl(project?: RepoName, dashboard?: DashboardId) { |
| if (!project || !dashboard) return ''; |
| |
| return createDashboardUrl({project, dashboard}); |
| } |
| |
| _computeLoadingClass(loading: boolean) { |
| return loading ? 'loading' : ''; |
| } |
| |
| _computeInheritedFrom(project: RepoName, definingProject: RepoName) { |
| return project === definingProject ? '' : definingProject; |
| } |
| |
| _computeIsDefault(isDefault?: boolean) { |
| return isDefault ? '✓' : ''; |
| } |
| } |
| |
| declare global { |
| interface HTMLElementTagNameMap { |
| 'gr-repo-dashboards': GrRepoDashboards; |
| } |
| } |