@backstage-community/plugin-azure-devops 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/api/AzureDevOpsApi.esm.js.map +1 -1
- package/dist/api/AzureDevOpsClient.esm.js +14 -0
- package/dist/api/AzureDevOpsClient.esm.js.map +1 -1
- package/dist/components/BuildTable/BuildTable.esm.js +83 -39
- package/dist/components/BuildTable/BuildTable.esm.js.map +1 -1
- package/dist/components/BuildTable/lib/BuildLogDrawer/BuildLogDrawer.esm.js +110 -0
- package/dist/components/BuildTable/lib/BuildLogDrawer/BuildLogDrawer.esm.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AzureDevOpsApi.esm.js","sources":["../../src/api/AzureDevOpsApi.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n BuildRun,\n BuildRunOptions,\n DashboardPullRequest,\n GitTag,\n PullRequest,\n PullRequestOptions,\n Readme,\n ReadmeConfig,\n RepoBuild,\n RepoBuildOptions,\n Team,\n} from '@backstage-community/plugin-azure-devops-common';\n\nimport { createApiRef } from '@backstage/core-plugin-api';\n\n/** @public */\nexport const azureDevOpsApiRef = createApiRef<AzureDevOpsApi>({\n id: 'plugin.azure-devops.service',\n});\n\n/** @public */\nexport interface AzureDevOpsApi {\n getRepoBuilds(\n projectName: string,\n repoName: string,\n host?: string,\n org?: string,\n options?: RepoBuildOptions,\n ): Promise<{ items: RepoBuild[] }>;\n\n getGitTags(\n projectName: string,\n repoName: string,\n entityRef: string,\n host?: string,\n org?: string,\n ): Promise<{ items: GitTag[] }>;\n\n getPullRequests(\n projectName: string,\n repoName: string,\n entityRef: string,\n host?: string,\n org?: string,\n options?: PullRequestOptions,\n ): Promise<{ items: PullRequest[] }>;\n\n getDashboardPullRequests(\n projectName: string,\n teamsLimit?: number,\n ): Promise<DashboardPullRequest[]>;\n\n getAllTeams(limit?: number): Promise<Team[]>;\n\n getUserTeamIds(userId: string): Promise<string[]>;\n\n getBuildRuns(\n projectName: string,\n entityRef: string,\n repoName?: string,\n definitionName?: string,\n host?: string,\n org?: string,\n options?: BuildRunOptions,\n ): Promise<{ items: BuildRun[] }>;\n\n getReadme(opts: ReadmeConfig): Promise<Readme>;\n}\n"],"names":[],"mappings":";;AAiCO,MAAM,oBAAoB,YAA6B,CAAA;AAAA,EAC5D,EAAI,EAAA;AACN,CAAC;;;;"}
|
|
1
|
+
{"version":3,"file":"AzureDevOpsApi.esm.js","sources":["../../src/api/AzureDevOpsApi.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n BuildRun,\n BuildRunOptions,\n DashboardPullRequest,\n GitTag,\n PullRequest,\n PullRequestOptions,\n Readme,\n ReadmeConfig,\n RepoBuild,\n RepoBuildOptions,\n Team,\n} from '@backstage-community/plugin-azure-devops-common';\n\nimport { createApiRef } from '@backstage/core-plugin-api';\n\n/** @public */\nexport const azureDevOpsApiRef = createApiRef<AzureDevOpsApi>({\n id: 'plugin.azure-devops.service',\n});\n\n/** @public */\nexport interface AzureDevOpsApi {\n getRepoBuilds(\n projectName: string,\n repoName: string,\n host?: string,\n org?: string,\n options?: RepoBuildOptions,\n ): Promise<{ items: RepoBuild[] }>;\n\n getGitTags(\n projectName: string,\n repoName: string,\n entityRef: string,\n host?: string,\n org?: string,\n ): Promise<{ items: GitTag[] }>;\n\n getPullRequests(\n projectName: string,\n repoName: string,\n entityRef: string,\n host?: string,\n org?: string,\n options?: PullRequestOptions,\n ): Promise<{ items: PullRequest[] }>;\n\n getDashboardPullRequests(\n projectName: string,\n teamsLimit?: number,\n ): Promise<DashboardPullRequest[]>;\n\n getAllTeams(limit?: number): Promise<Team[]>;\n\n getUserTeamIds(userId: string): Promise<string[]>;\n\n getBuildRuns(\n projectName: string,\n entityRef: string,\n repoName?: string,\n definitionName?: string,\n host?: string,\n org?: string,\n options?: BuildRunOptions,\n ): Promise<{ items: BuildRun[] }>;\n\n getReadme(opts: ReadmeConfig): Promise<Readme>;\n\n getBuildRunLog(\n projectName: string,\n entityRef: string,\n buildId: number,\n host?: string,\n org?: string,\n ): Promise<{ log: string[] }>;\n}\n"],"names":[],"mappings":";;AAiCO,MAAM,oBAAoB,YAA6B,CAAA;AAAA,EAC5D,EAAI,EAAA;AACN,CAAC;;;;"}
|
|
@@ -144,6 +144,20 @@ class AzureDevOpsClient {
|
|
|
144
144
|
)}?${queryString}`
|
|
145
145
|
);
|
|
146
146
|
}
|
|
147
|
+
async getBuildRunLog(projectName, entityRef, buildId, host, org) {
|
|
148
|
+
const queryString = new URLSearchParams();
|
|
149
|
+
queryString.append("entityRef", entityRef);
|
|
150
|
+
if (host) {
|
|
151
|
+
queryString.append("host", host);
|
|
152
|
+
}
|
|
153
|
+
if (org) {
|
|
154
|
+
queryString.append("org", org);
|
|
155
|
+
}
|
|
156
|
+
const urlSegment = `builds/${encodeURIComponent(
|
|
157
|
+
projectName
|
|
158
|
+
)}/build/${buildId}/log?${queryString}`;
|
|
159
|
+
return await this.get(urlSegment);
|
|
160
|
+
}
|
|
147
161
|
async get(path) {
|
|
148
162
|
const baseUrl = `${await this.discoveryApi.getBaseUrl("azure-devops")}/`;
|
|
149
163
|
const url = new URL(path, baseUrl);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AzureDevOpsClient.esm.js","sources":["../../src/api/AzureDevOpsClient.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n BuildRun,\n BuildRunOptions,\n DashboardPullRequest,\n GitTag,\n PullRequest,\n PullRequestOptions,\n Readme,\n ReadmeConfig,\n RepoBuild,\n RepoBuildOptions,\n Team,\n} from '@backstage-community/plugin-azure-devops-common';\nimport { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api';\nimport { ResponseError } from '@backstage/errors';\nimport { AzureDevOpsApi } from './AzureDevOpsApi';\n\n/** @public */\nexport class AzureDevOpsClient implements AzureDevOpsApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n\n public constructor(options: {\n discoveryApi: DiscoveryApi;\n fetchApi: FetchApi;\n }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi;\n }\n\n public async getRepoBuilds(\n projectName: string,\n repoName: string,\n host?: string,\n org?: string,\n options?: RepoBuildOptions,\n ): Promise<{ items: RepoBuild[] }> {\n const queryString = new URLSearchParams();\n if (options?.top) {\n queryString.append('top', options.top.toString());\n }\n if (host) {\n queryString.append('host', host);\n }\n if (org) {\n queryString.append('org', org);\n }\n const urlSegment = `repo-builds/${encodeURIComponent(\n projectName,\n )}/${encodeURIComponent(repoName)}?${queryString}`;\n\n const items = await this.get<RepoBuild[]>(urlSegment);\n return { items };\n }\n\n public async getGitTags(\n projectName: string,\n repoName: string,\n entityRef: string,\n host?: string,\n org?: string,\n ): Promise<{ items: GitTag[] }> {\n const queryString = new URLSearchParams();\n if (host) {\n queryString.append('host', host);\n }\n if (org) {\n queryString.append('org', org);\n }\n queryString.append('entityRef', entityRef);\n const urlSegment = `git-tags/${encodeURIComponent(\n projectName,\n )}/${encodeURIComponent(repoName)}?${queryString}`;\n\n const items = await this.get<GitTag[]>(urlSegment);\n return { items };\n }\n\n public async getPullRequests(\n projectName: string,\n repoName: string,\n entityRef: string,\n host?: string,\n org?: string,\n options?: PullRequestOptions,\n ): Promise<{ items: PullRequest[] }> {\n const queryString = new URLSearchParams();\n if (options?.top) {\n queryString.append('top', options.top.toString());\n }\n if (options?.status) {\n queryString.append('status', options.status.toString());\n }\n if (options?.teamsLimit) {\n queryString.append('teamsLimit', options.teamsLimit.toString());\n }\n if (host) {\n queryString.append('host', host);\n }\n if (org) {\n queryString.append('org', org);\n }\n queryString.append('entityRef', entityRef);\n const urlSegment = `pull-requests/${encodeURIComponent(\n projectName,\n )}/${encodeURIComponent(repoName)}?${queryString}`;\n\n const items = await this.get<PullRequest[]>(urlSegment);\n return { items };\n }\n\n public getDashboardPullRequests(\n projectName: string,\n teamsLimit?: number,\n ): Promise<DashboardPullRequest[]> {\n const queryString = new URLSearchParams();\n queryString.append('top', '100');\n if (teamsLimit) {\n queryString.append('teamsLimit', teamsLimit.toString());\n }\n const urlSegment = `dashboard-pull-requests/${projectName}?${queryString}`;\n return this.get<DashboardPullRequest[]>(urlSegment);\n }\n\n public getAllTeams(limit?: number): Promise<Team[]> {\n const queryString = new URLSearchParams();\n if (limit) {\n queryString.append('limit', limit.toString());\n }\n let urlSegment = 'all-teams';\n if (queryString.toString()) {\n urlSegment += `?${queryString}`;\n }\n return this.get<Team[]>(urlSegment);\n }\n\n public getUserTeamIds(userId: string): Promise<string[]> {\n return this.get<string[]>(`users/${userId}/team-ids`);\n }\n\n public async getBuildRuns(\n projectName: string,\n entityRef: string,\n repoName?: string,\n definitionName?: string,\n host?: string,\n org?: string,\n options?: BuildRunOptions,\n ): Promise<{ items: BuildRun[] }> {\n const queryString = new URLSearchParams();\n queryString.append('entityRef', entityRef);\n if (repoName) {\n queryString.append('repoName', repoName);\n }\n if (host) {\n queryString.append('host', host);\n }\n if (org) {\n queryString.append('org', org);\n }\n if (definitionName) {\n const definitionNames = definitionName.split(',');\n if (definitionNames.length > 1) {\n const buildRuns: BuildRun[] = [];\n for (const name of definitionNames) {\n queryString.set('definitionName', name.trim());\n if (options?.top) {\n queryString.set('top', options.top.toString());\n }\n const urlSegment = `builds/${encodeURIComponent(\n projectName,\n )}?${queryString}`;\n const items = await this.get<BuildRun[]>(urlSegment);\n buildRuns.push(...items);\n }\n return { items: buildRuns };\n }\n queryString.append('definitionName', definitionName.trim());\n }\n if (options?.top) {\n queryString.append('top', options.top.toString());\n }\n const urlSegment = `builds/${encodeURIComponent(\n projectName,\n )}?${queryString}`;\n const items = await this.get<BuildRun[]>(urlSegment);\n return { items };\n }\n\n public async getReadme(opts: ReadmeConfig): Promise<Readme> {\n const queryString = new URLSearchParams();\n if (opts.host) {\n queryString.append('host', opts.host);\n }\n if (opts.org) {\n queryString.append('org', opts.org);\n }\n if (opts.path) {\n queryString.append('path', opts.path);\n }\n queryString.append('entityRef', opts.entityRef);\n return await this.get(\n `readme/${encodeURIComponent(opts.project)}/${encodeURIComponent(\n opts.repo,\n )}?${queryString}`,\n );\n }\n\n private async get<T>(path: string): Promise<T> {\n const baseUrl = `${await this.discoveryApi.getBaseUrl('azure-devops')}/`;\n const url = new URL(path, baseUrl);\n\n const response = await this.fetchApi.fetch(url.toString());\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json() as Promise<T>;\n }\n}\n"],"names":["urlSegment","items"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AzureDevOpsClient.esm.js","sources":["../../src/api/AzureDevOpsClient.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n BuildRun,\n BuildRunOptions,\n DashboardPullRequest,\n GitTag,\n PullRequest,\n PullRequestOptions,\n Readme,\n ReadmeConfig,\n RepoBuild,\n RepoBuildOptions,\n Team,\n} from '@backstage-community/plugin-azure-devops-common';\nimport { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api';\nimport { ResponseError } from '@backstage/errors';\nimport { AzureDevOpsApi } from './AzureDevOpsApi';\n\n/** @public */\nexport class AzureDevOpsClient implements AzureDevOpsApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n\n public constructor(options: {\n discoveryApi: DiscoveryApi;\n fetchApi: FetchApi;\n }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi;\n }\n\n public async getRepoBuilds(\n projectName: string,\n repoName: string,\n host?: string,\n org?: string,\n options?: RepoBuildOptions,\n ): Promise<{ items: RepoBuild[] }> {\n const queryString = new URLSearchParams();\n if (options?.top) {\n queryString.append('top', options.top.toString());\n }\n if (host) {\n queryString.append('host', host);\n }\n if (org) {\n queryString.append('org', org);\n }\n const urlSegment = `repo-builds/${encodeURIComponent(\n projectName,\n )}/${encodeURIComponent(repoName)}?${queryString}`;\n\n const items = await this.get<RepoBuild[]>(urlSegment);\n return { items };\n }\n\n public async getGitTags(\n projectName: string,\n repoName: string,\n entityRef: string,\n host?: string,\n org?: string,\n ): Promise<{ items: GitTag[] }> {\n const queryString = new URLSearchParams();\n if (host) {\n queryString.append('host', host);\n }\n if (org) {\n queryString.append('org', org);\n }\n queryString.append('entityRef', entityRef);\n const urlSegment = `git-tags/${encodeURIComponent(\n projectName,\n )}/${encodeURIComponent(repoName)}?${queryString}`;\n\n const items = await this.get<GitTag[]>(urlSegment);\n return { items };\n }\n\n public async getPullRequests(\n projectName: string,\n repoName: string,\n entityRef: string,\n host?: string,\n org?: string,\n options?: PullRequestOptions,\n ): Promise<{ items: PullRequest[] }> {\n const queryString = new URLSearchParams();\n if (options?.top) {\n queryString.append('top', options.top.toString());\n }\n if (options?.status) {\n queryString.append('status', options.status.toString());\n }\n if (options?.teamsLimit) {\n queryString.append('teamsLimit', options.teamsLimit.toString());\n }\n if (host) {\n queryString.append('host', host);\n }\n if (org) {\n queryString.append('org', org);\n }\n queryString.append('entityRef', entityRef);\n const urlSegment = `pull-requests/${encodeURIComponent(\n projectName,\n )}/${encodeURIComponent(repoName)}?${queryString}`;\n\n const items = await this.get<PullRequest[]>(urlSegment);\n return { items };\n }\n\n public getDashboardPullRequests(\n projectName: string,\n teamsLimit?: number,\n ): Promise<DashboardPullRequest[]> {\n const queryString = new URLSearchParams();\n queryString.append('top', '100');\n if (teamsLimit) {\n queryString.append('teamsLimit', teamsLimit.toString());\n }\n const urlSegment = `dashboard-pull-requests/${projectName}?${queryString}`;\n return this.get<DashboardPullRequest[]>(urlSegment);\n }\n\n public getAllTeams(limit?: number): Promise<Team[]> {\n const queryString = new URLSearchParams();\n if (limit) {\n queryString.append('limit', limit.toString());\n }\n let urlSegment = 'all-teams';\n if (queryString.toString()) {\n urlSegment += `?${queryString}`;\n }\n return this.get<Team[]>(urlSegment);\n }\n\n public getUserTeamIds(userId: string): Promise<string[]> {\n return this.get<string[]>(`users/${userId}/team-ids`);\n }\n\n public async getBuildRuns(\n projectName: string,\n entityRef: string,\n repoName?: string,\n definitionName?: string,\n host?: string,\n org?: string,\n options?: BuildRunOptions,\n ): Promise<{ items: BuildRun[] }> {\n const queryString = new URLSearchParams();\n queryString.append('entityRef', entityRef);\n if (repoName) {\n queryString.append('repoName', repoName);\n }\n if (host) {\n queryString.append('host', host);\n }\n if (org) {\n queryString.append('org', org);\n }\n if (definitionName) {\n const definitionNames = definitionName.split(',');\n if (definitionNames.length > 1) {\n const buildRuns: BuildRun[] = [];\n for (const name of definitionNames) {\n queryString.set('definitionName', name.trim());\n if (options?.top) {\n queryString.set('top', options.top.toString());\n }\n const urlSegment = `builds/${encodeURIComponent(\n projectName,\n )}?${queryString}`;\n const items = await this.get<BuildRun[]>(urlSegment);\n buildRuns.push(...items);\n }\n return { items: buildRuns };\n }\n queryString.append('definitionName', definitionName.trim());\n }\n if (options?.top) {\n queryString.append('top', options.top.toString());\n }\n const urlSegment = `builds/${encodeURIComponent(\n projectName,\n )}?${queryString}`;\n const items = await this.get<BuildRun[]>(urlSegment);\n return { items };\n }\n\n public async getReadme(opts: ReadmeConfig): Promise<Readme> {\n const queryString = new URLSearchParams();\n if (opts.host) {\n queryString.append('host', opts.host);\n }\n if (opts.org) {\n queryString.append('org', opts.org);\n }\n if (opts.path) {\n queryString.append('path', opts.path);\n }\n queryString.append('entityRef', opts.entityRef);\n\n return await this.get(\n `readme/${encodeURIComponent(opts.project)}/${encodeURIComponent(\n opts.repo,\n )}?${queryString}`,\n );\n }\n\n public async getBuildRunLog(\n projectName: string,\n entityRef: string,\n buildId: number,\n host?: string,\n org?: string,\n ): Promise<{ log: string[] }> {\n const queryString = new URLSearchParams();\n queryString.append('entityRef', entityRef);\n if (host) {\n queryString.append('host', host);\n }\n if (org) {\n queryString.append('org', org);\n }\n const urlSegment = `builds/${encodeURIComponent(\n projectName,\n )}/build/${buildId}/log?${queryString}`;\n return await this.get<{ log: string[] }>(urlSegment);\n }\n\n private async get<T>(path: string): Promise<T> {\n const baseUrl = `${await this.discoveryApi.getBaseUrl('azure-devops')}/`;\n const url = new URL(path, baseUrl);\n\n const response = await this.fetchApi.fetch(url.toString());\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json() as Promise<T>;\n }\n}\n"],"names":["urlSegment","items"],"mappings":"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"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
1
2
|
import Box from '@material-ui/core/Box';
|
|
3
|
+
import Button from '@material-ui/core/Button';
|
|
2
4
|
import Typography from '@material-ui/core/Typography';
|
|
3
5
|
import { BuildStatus, BuildResult } from '@backstage-community/plugin-azure-devops-common';
|
|
4
6
|
import { ResponseErrorPanel, Table, Link, StatusWarning, StatusAborted, StatusPending, StatusRunning, StatusError, StatusOK } from '@backstage/core-components';
|
|
5
7
|
import { AzurePipelinesIcon } from '../AzurePipelinesIcon/AzurePipelinesIcon.esm.js';
|
|
6
8
|
import { DateTime } from 'luxon';
|
|
7
|
-
import React from 'react';
|
|
8
9
|
import { getDurationFromDates } from '../../utils/getDurationFromDates.esm.js';
|
|
10
|
+
import { BuildLogDrawer } from './lib/BuildLogDrawer/BuildLogDrawer.esm.js';
|
|
9
11
|
|
|
10
12
|
const getBuildResultComponent = (result) => {
|
|
11
13
|
switch (result) {
|
|
@@ -39,47 +41,80 @@ const getBuildStateComponent = (status, result) => {
|
|
|
39
41
|
return /* @__PURE__ */ React.createElement(Typography, { component: "span" }, /* @__PURE__ */ React.createElement(StatusWarning, null), " Unknown");
|
|
40
42
|
}
|
|
41
43
|
};
|
|
42
|
-
const columns = [
|
|
43
|
-
{
|
|
44
|
-
title: "ID",
|
|
45
|
-
field: "id",
|
|
46
|
-
highlight: false,
|
|
47
|
-
width: "auto"
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
title: "Build",
|
|
51
|
-
field: "title",
|
|
52
|
-
width: "auto",
|
|
53
|
-
render: (row) => /* @__PURE__ */ React.createElement(Link, { to: row.link || "" }, row.title)
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
title: "Source",
|
|
57
|
-
field: "source",
|
|
58
|
-
width: "auto"
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
title: "State",
|
|
62
|
-
width: "auto",
|
|
63
|
-
render: (row) => /* @__PURE__ */ React.createElement(Box, { display: "flex", alignItems: "center" }, /* @__PURE__ */ React.createElement(Typography, { variant: "button" }, getBuildStateComponent(row.status, row.result)))
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
title: "Duration",
|
|
67
|
-
field: "queueTime",
|
|
68
|
-
width: "auto",
|
|
69
|
-
render: (row) => /* @__PURE__ */ React.createElement(Box, { display: "flex", alignItems: "center" }, /* @__PURE__ */ React.createElement(Typography, null, getDurationFromDates(row.startTime, row.finishTime)))
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
title: "Age",
|
|
73
|
-
field: "queueTime",
|
|
74
|
-
width: "auto",
|
|
75
|
-
render: (row) => (row.queueTime ? DateTime.fromISO(row.queueTime) : DateTime.now()).toRelative()
|
|
76
|
-
}
|
|
77
|
-
];
|
|
78
44
|
const BuildTable = ({ items, loading, error }) => {
|
|
45
|
+
const [selectedBuildId, setSelectedBuildId] = useState(
|
|
46
|
+
void 0
|
|
47
|
+
);
|
|
48
|
+
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
|
|
49
|
+
const handleOpenDrawer = (buildId) => {
|
|
50
|
+
setSelectedBuildId(buildId);
|
|
51
|
+
setIsDrawerOpen(true);
|
|
52
|
+
};
|
|
53
|
+
const handleCloseDrawer = () => {
|
|
54
|
+
setIsDrawerOpen(false);
|
|
55
|
+
};
|
|
56
|
+
const [logsCache, setLogsCache] = useState({});
|
|
57
|
+
const updateLogsCache = (buildId, logs) => {
|
|
58
|
+
setLogsCache((prev) => ({
|
|
59
|
+
...prev,
|
|
60
|
+
[buildId]: logs
|
|
61
|
+
}));
|
|
62
|
+
};
|
|
79
63
|
if (error) {
|
|
80
64
|
return /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(ResponseErrorPanel, { error }));
|
|
81
65
|
}
|
|
82
|
-
|
|
66
|
+
const columns = [
|
|
67
|
+
{
|
|
68
|
+
title: "ID",
|
|
69
|
+
field: "id",
|
|
70
|
+
highlight: false,
|
|
71
|
+
width: "auto"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
title: "Build",
|
|
75
|
+
field: "title",
|
|
76
|
+
width: "auto",
|
|
77
|
+
render: (row) => /* @__PURE__ */ React.createElement(Link, { to: row.link || "" }, row.title)
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
title: "Source",
|
|
81
|
+
field: "source",
|
|
82
|
+
width: "auto"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
title: "State",
|
|
86
|
+
width: "auto",
|
|
87
|
+
render: (row) => /* @__PURE__ */ React.createElement(Box, { display: "flex", alignItems: "center" }, /* @__PURE__ */ React.createElement(Typography, { variant: "button" }, getBuildStateComponent(row.status, row.result)))
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
title: "Duration",
|
|
91
|
+
field: "queueTime",
|
|
92
|
+
width: "auto",
|
|
93
|
+
render: (row) => /* @__PURE__ */ React.createElement(Box, { display: "flex", alignItems: "center" }, /* @__PURE__ */ React.createElement(Typography, null, getDurationFromDates(row.startTime, row.finishTime)))
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
title: "Age",
|
|
97
|
+
field: "queueTime",
|
|
98
|
+
width: "auto",
|
|
99
|
+
render: (row) => (row.queueTime ? DateTime.fromISO(row.queueTime) : DateTime.now()).toRelative()
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
title: "Logs",
|
|
103
|
+
width: "auto",
|
|
104
|
+
render: (row) => /* @__PURE__ */ React.createElement(
|
|
105
|
+
Button,
|
|
106
|
+
{
|
|
107
|
+
variant: "contained",
|
|
108
|
+
color: "primary",
|
|
109
|
+
size: "small",
|
|
110
|
+
onClick: () => handleOpenDrawer(row.id),
|
|
111
|
+
disabled: !row.id
|
|
112
|
+
},
|
|
113
|
+
"View Logs"
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
];
|
|
117
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
83
118
|
Table,
|
|
84
119
|
{
|
|
85
120
|
isLoading: loading,
|
|
@@ -93,7 +128,16 @@ const BuildTable = ({ items, loading, error }) => {
|
|
|
93
128
|
title: /* @__PURE__ */ React.createElement(Box, { display: "flex", alignItems: "center" }, /* @__PURE__ */ React.createElement(AzurePipelinesIcon, { style: { fontSize: 30 } }), /* @__PURE__ */ React.createElement(Box, { mr: 1 }), "Azure Pipelines - Builds (", items ? items.length : 0, ")"),
|
|
94
129
|
data: items ?? []
|
|
95
130
|
}
|
|
96
|
-
)
|
|
131
|
+
), /* @__PURE__ */ React.createElement(
|
|
132
|
+
BuildLogDrawer,
|
|
133
|
+
{
|
|
134
|
+
buildId: selectedBuildId,
|
|
135
|
+
open: isDrawerOpen,
|
|
136
|
+
onClose: handleCloseDrawer,
|
|
137
|
+
logsCache,
|
|
138
|
+
updateCache: updateLogsCache
|
|
139
|
+
}
|
|
140
|
+
));
|
|
97
141
|
};
|
|
98
142
|
|
|
99
143
|
export { BuildTable, getBuildResultComponent, getBuildStateComponent };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BuildTable.esm.js","sources":["../../../src/components/BuildTable/BuildTable.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Box from '@material-ui/core/Box';\nimport Typography from '@material-ui/core/Typography';\nimport {\n BuildResult,\n BuildRun,\n BuildStatus,\n} from '@backstage-community/plugin-azure-devops-common';\nimport {\n Link,\n ResponseErrorPanel,\n StatusAborted,\n StatusError,\n StatusOK,\n StatusPending,\n StatusRunning,\n StatusWarning,\n Table,\n TableColumn,\n} from '@backstage/core-components';\n\nimport { AzurePipelinesIcon } from '../AzurePipelinesIcon';\nimport { DateTime } from 'luxon';\nimport React from 'react';\nimport { getDurationFromDates } from '../../utils/getDurationFromDates';\n\nexport const getBuildResultComponent = (result: number | undefined) => {\n switch (result) {\n case BuildResult.Succeeded:\n return (\n <Typography component=\"span\">\n <StatusOK /> Succeeded\n </Typography>\n );\n case BuildResult.PartiallySucceeded:\n return (\n <Typography component=\"span\">\n <StatusWarning /> Partially Succeeded\n </Typography>\n );\n case BuildResult.Failed:\n return (\n <Typography component=\"span\">\n <StatusError /> Failed\n </Typography>\n );\n case BuildResult.Canceled:\n return (\n <Typography component=\"span\">\n <StatusAborted /> Canceled\n </Typography>\n );\n case BuildResult.None:\n default:\n return (\n <Typography component=\"span\">\n <StatusWarning /> Unknown\n </Typography>\n );\n }\n};\n\nexport const getBuildStateComponent = (\n status: number | undefined,\n result: number | undefined,\n) => {\n switch (status) {\n case BuildStatus.InProgress:\n return (\n <Typography component=\"span\">\n <StatusRunning /> In Progress\n </Typography>\n );\n case BuildStatus.Completed:\n return getBuildResultComponent(result);\n case BuildStatus.Cancelling:\n return (\n <Typography component=\"span\">\n <StatusAborted /> Cancelling\n </Typography>\n );\n case BuildStatus.Postponed:\n return (\n <Typography component=\"span\">\n <StatusPending /> Postponed\n </Typography>\n );\n case BuildStatus.NotStarted:\n return (\n <Typography component=\"span\">\n <StatusAborted /> Not Started\n </Typography>\n );\n case BuildStatus.None:\n default:\n return (\n <Typography component=\"span\">\n <StatusWarning /> Unknown\n </Typography>\n );\n }\n};\n\nconst columns: TableColumn[] = [\n {\n title: 'ID',\n field: 'id',\n highlight: false,\n width: 'auto',\n },\n {\n title: 'Build',\n field: 'title',\n width: 'auto',\n render: (row: Partial<BuildRun>) => (\n <Link to={row.link || ''}>{row.title}</Link>\n ),\n },\n {\n title: 'Source',\n field: 'source',\n width: 'auto',\n },\n {\n title: 'State',\n width: 'auto',\n render: (row: Partial<BuildRun>) => (\n <Box display=\"flex\" alignItems=\"center\">\n <Typography variant=\"button\">\n {getBuildStateComponent(row.status, row.result)}\n </Typography>\n </Box>\n ),\n },\n {\n title: 'Duration',\n field: 'queueTime',\n width: 'auto',\n render: (row: Partial<BuildRun>) => (\n <Box display=\"flex\" alignItems=\"center\">\n <Typography>\n {getDurationFromDates(row.startTime, row.finishTime)}\n </Typography>\n </Box>\n ),\n },\n {\n title: 'Age',\n field: 'queueTime',\n width: 'auto',\n render: (row: Partial<BuildRun>) =>\n (row.queueTime\n ? DateTime.fromISO(row.queueTime)\n : DateTime.now()\n ).toRelative(),\n },\n];\n\ntype BuildTableProps = {\n items?: BuildRun[];\n loading: boolean;\n error?: Error;\n};\n\nexport const BuildTable = ({ items, loading, error }: BuildTableProps) => {\n if (error) {\n return (\n <div>\n <ResponseErrorPanel error={error} />\n </div>\n );\n }\n\n return (\n <Table\n isLoading={loading}\n columns={columns}\n options={{\n search: true,\n paging: true,\n pageSize: 5,\n showEmptyDataSourceMessage: !loading,\n }}\n title={\n <Box display=\"flex\" alignItems=\"center\">\n <AzurePipelinesIcon style={{ fontSize: 30 }} />\n <Box mr={1} />\n Azure Pipelines - Builds ({items ? items.length : 0})\n </Box>\n }\n data={items ?? []}\n />\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BuildTable.esm.js","sources":["../../../src/components/BuildTable/BuildTable.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useState } from 'react';\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport Typography from '@material-ui/core/Typography';\nimport {\n BuildResult,\n BuildRun,\n BuildStatus,\n} from '@backstage-community/plugin-azure-devops-common';\nimport {\n Link,\n ResponseErrorPanel,\n StatusAborted,\n StatusError,\n StatusOK,\n StatusPending,\n StatusRunning,\n StatusWarning,\n Table,\n TableColumn,\n} from '@backstage/core-components';\n\nimport { AzurePipelinesIcon } from '../AzurePipelinesIcon';\nimport { DateTime } from 'luxon';\nimport React from 'react';\nimport { getDurationFromDates } from '../../utils/getDurationFromDates';\nimport { BuildLogDrawer } from './lib/BuildLogDrawer';\n\nexport const getBuildResultComponent = (result: number | undefined) => {\n switch (result) {\n case BuildResult.Succeeded:\n return (\n <Typography component=\"span\">\n <StatusOK /> Succeeded\n </Typography>\n );\n case BuildResult.PartiallySucceeded:\n return (\n <Typography component=\"span\">\n <StatusWarning /> Partially Succeeded\n </Typography>\n );\n case BuildResult.Failed:\n return (\n <Typography component=\"span\">\n <StatusError /> Failed\n </Typography>\n );\n case BuildResult.Canceled:\n return (\n <Typography component=\"span\">\n <StatusAborted /> Canceled\n </Typography>\n );\n case BuildResult.None:\n default:\n return (\n <Typography component=\"span\">\n <StatusWarning /> Unknown\n </Typography>\n );\n }\n};\n\nexport const getBuildStateComponent = (\n status: number | undefined,\n result: number | undefined,\n) => {\n switch (status) {\n case BuildStatus.InProgress:\n return (\n <Typography component=\"span\">\n <StatusRunning /> In Progress\n </Typography>\n );\n case BuildStatus.Completed:\n return getBuildResultComponent(result);\n case BuildStatus.Cancelling:\n return (\n <Typography component=\"span\">\n <StatusAborted /> Cancelling\n </Typography>\n );\n case BuildStatus.Postponed:\n return (\n <Typography component=\"span\">\n <StatusPending /> Postponed\n </Typography>\n );\n case BuildStatus.NotStarted:\n return (\n <Typography component=\"span\">\n <StatusAborted /> Not Started\n </Typography>\n );\n case BuildStatus.None:\n default:\n return (\n <Typography component=\"span\">\n <StatusWarning /> Unknown\n </Typography>\n );\n }\n};\n\ntype BuildTableProps = {\n items?: BuildRun[];\n loading: boolean;\n error?: Error;\n};\n\nexport const BuildTable = ({ items, loading, error }: BuildTableProps) => {\n // State for log drawer\n const [selectedBuildId, setSelectedBuildId] = useState<number | undefined>(\n undefined,\n );\n const [isDrawerOpen, setIsDrawerOpen] = useState(false);\n\n const handleOpenDrawer = (buildId?: number) => {\n setSelectedBuildId(buildId);\n setIsDrawerOpen(true);\n };\n\n const handleCloseDrawer = () => {\n setIsDrawerOpen(false);\n };\n\n // Cache build logs\n const [logsCache, setLogsCache] = useState<Record<number, string[]>>({});\n\n const updateLogsCache = (buildId: number, logs: string[]) => {\n setLogsCache(prev => ({\n ...prev,\n [buildId]: logs,\n }));\n };\n\n if (error) {\n return (\n <div>\n <ResponseErrorPanel error={error} />\n </div>\n );\n }\n\n const columns: TableColumn[] = [\n {\n title: 'ID',\n field: 'id',\n highlight: false,\n width: 'auto',\n },\n {\n title: 'Build',\n field: 'title',\n width: 'auto',\n render: (row: Partial<BuildRun>) => (\n <Link to={row.link || ''}>{row.title}</Link>\n ),\n },\n {\n title: 'Source',\n field: 'source',\n width: 'auto',\n },\n {\n title: 'State',\n width: 'auto',\n render: (row: Partial<BuildRun>) => (\n <Box display=\"flex\" alignItems=\"center\">\n <Typography variant=\"button\">\n {getBuildStateComponent(row.status, row.result)}\n </Typography>\n </Box>\n ),\n },\n {\n title: 'Duration',\n field: 'queueTime',\n width: 'auto',\n render: (row: Partial<BuildRun>) => (\n <Box display=\"flex\" alignItems=\"center\">\n <Typography>\n {getDurationFromDates(row.startTime, row.finishTime)}\n </Typography>\n </Box>\n ),\n },\n {\n title: 'Age',\n field: 'queueTime',\n width: 'auto',\n render: (row: Partial<BuildRun>) =>\n (row.queueTime\n ? DateTime.fromISO(row.queueTime)\n : DateTime.now()\n ).toRelative(),\n },\n {\n title: 'Logs',\n width: 'auto',\n render: (row: Partial<BuildRun>) => (\n <Button\n variant=\"contained\"\n color=\"primary\"\n size=\"small\"\n onClick={() => handleOpenDrawer(row.id)}\n disabled={!row.id}\n >\n View Logs\n </Button>\n ),\n },\n ];\n\n return (\n <>\n <Table\n isLoading={loading}\n columns={columns}\n options={{\n search: true,\n paging: true,\n pageSize: 5,\n showEmptyDataSourceMessage: !loading,\n }}\n title={\n <Box display=\"flex\" alignItems=\"center\">\n <AzurePipelinesIcon style={{ fontSize: 30 }} />\n <Box mr={1} />\n Azure Pipelines - Builds ({items ? items.length : 0})\n </Box>\n }\n data={items ?? []}\n />\n\n <BuildLogDrawer\n buildId={selectedBuildId}\n open={isDrawerOpen}\n onClose={handleCloseDrawer}\n logsCache={logsCache}\n updateCache={updateLogsCache}\n />\n </>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import React, { useState, useCallback, useEffect } from 'react';
|
|
2
|
+
import Drawer from '@material-ui/core/Drawer';
|
|
3
|
+
import Typography from '@material-ui/core/Typography';
|
|
4
|
+
import LinearProgress from '@material-ui/core/LinearProgress';
|
|
5
|
+
import Box from '@material-ui/core/Box';
|
|
6
|
+
import IconButton from '@material-ui/core/IconButton';
|
|
7
|
+
import { makeStyles } from '@material-ui/core/styles';
|
|
8
|
+
import CloseIcon from '@material-ui/icons/Close';
|
|
9
|
+
import { useApi } from '@backstage/core-plugin-api';
|
|
10
|
+
import { azureDevOpsApiRef } from '../../../../api/AzureDevOpsApi.esm.js';
|
|
11
|
+
import '@backstage/errors';
|
|
12
|
+
import 'luxon';
|
|
13
|
+
import 'humanize-duration';
|
|
14
|
+
import { getAnnotationValuesFromEntity } from '../../../../utils/getAnnotationValuesFromEntity.esm.js';
|
|
15
|
+
import { stringifyEntityRef } from '@backstage/catalog-model';
|
|
16
|
+
import { useEntity } from '@backstage/plugin-catalog-react';
|
|
17
|
+
|
|
18
|
+
const useDrawerStyles = makeStyles((theme) => ({
|
|
19
|
+
logDrawer: {
|
|
20
|
+
width: "40%",
|
|
21
|
+
minWidth: "500px",
|
|
22
|
+
padding: theme.spacing(2)
|
|
23
|
+
},
|
|
24
|
+
header: {
|
|
25
|
+
display: "flex",
|
|
26
|
+
justifyContent: "space-between",
|
|
27
|
+
alignItems: "center",
|
|
28
|
+
marginBottom: theme.spacing(2),
|
|
29
|
+
borderBottom: `1px solid ${theme.palette.divider}`,
|
|
30
|
+
paddingBottom: theme.spacing(1)
|
|
31
|
+
},
|
|
32
|
+
content: {
|
|
33
|
+
height: "100%",
|
|
34
|
+
display: "flex",
|
|
35
|
+
flexDirection: "column"
|
|
36
|
+
},
|
|
37
|
+
logContainer: {
|
|
38
|
+
flexGrow: 1,
|
|
39
|
+
overflow: "auto",
|
|
40
|
+
backgroundColor: theme.palette.background.default,
|
|
41
|
+
padding: theme.spacing(2),
|
|
42
|
+
borderRadius: theme.shape.borderRadius,
|
|
43
|
+
marginTop: theme.spacing(2),
|
|
44
|
+
fontFamily: theme.typography.fontFamily,
|
|
45
|
+
fontSize: theme.typography.fontSize
|
|
46
|
+
}
|
|
47
|
+
}));
|
|
48
|
+
const BuildLogDrawer = ({
|
|
49
|
+
buildId,
|
|
50
|
+
open,
|
|
51
|
+
onClose,
|
|
52
|
+
logsCache,
|
|
53
|
+
updateCache
|
|
54
|
+
}) => {
|
|
55
|
+
const [loading, setLoading] = useState(false);
|
|
56
|
+
const [logs, setLogs] = useState([]);
|
|
57
|
+
const [error, setError] = useState();
|
|
58
|
+
const { entity } = useEntity();
|
|
59
|
+
const azureApi = useApi(azureDevOpsApiRef);
|
|
60
|
+
const classes = useDrawerStyles();
|
|
61
|
+
const fetchLogs = useCallback(async () => {
|
|
62
|
+
if (!buildId) {
|
|
63
|
+
setError(new Error("Missing ID for build"));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
setLoading(true);
|
|
67
|
+
setError(void 0);
|
|
68
|
+
setLogs([]);
|
|
69
|
+
try {
|
|
70
|
+
const { project, host, org } = getAnnotationValuesFromEntity(entity);
|
|
71
|
+
const response = await azureApi.getBuildRunLog(
|
|
72
|
+
project,
|
|
73
|
+
stringifyEntityRef(entity),
|
|
74
|
+
buildId,
|
|
75
|
+
host,
|
|
76
|
+
org
|
|
77
|
+
);
|
|
78
|
+
setLogs(response.log);
|
|
79
|
+
updateCache(buildId, response.log);
|
|
80
|
+
} catch (err) {
|
|
81
|
+
setError(err);
|
|
82
|
+
} finally {
|
|
83
|
+
setLoading(false);
|
|
84
|
+
}
|
|
85
|
+
}, [buildId, entity, azureApi, updateCache]);
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
if (buildId && open) {
|
|
88
|
+
if (logsCache[buildId]) {
|
|
89
|
+
setLogs(logsCache[buildId]);
|
|
90
|
+
} else {
|
|
91
|
+
fetchLogs();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}, [buildId, open, fetchLogs, logsCache]);
|
|
95
|
+
return /* @__PURE__ */ React.createElement(
|
|
96
|
+
Drawer,
|
|
97
|
+
{
|
|
98
|
+
anchor: "right",
|
|
99
|
+
open,
|
|
100
|
+
onClose,
|
|
101
|
+
classes: {
|
|
102
|
+
paper: classes.logDrawer
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
/* @__PURE__ */ React.createElement("div", { className: classes.content }, /* @__PURE__ */ React.createElement("div", { className: classes.header }, /* @__PURE__ */ React.createElement(Typography, { variant: "h6" }, "Build Logs ", buildId ? `(Build #${buildId})` : ""), /* @__PURE__ */ React.createElement(IconButton, { onClick: onClose, "aria-label": "close" }, /* @__PURE__ */ React.createElement(CloseIcon, null))), loading && /* @__PURE__ */ React.createElement(LinearProgress, null), error && /* @__PURE__ */ React.createElement(Typography, { color: "error" }, "Error loading logs: ", error.message), !loading && !error && logs.length === 0 && /* @__PURE__ */ React.createElement(Typography, null, "No logs available"), !loading && !error && logs.length > 0 && /* @__PURE__ */ React.createElement(Box, { component: "pre", className: classes.logContainer }, logs.join("\n")))
|
|
106
|
+
);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export { BuildLogDrawer };
|
|
110
|
+
//# sourceMappingURL=BuildLogDrawer.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuildLogDrawer.esm.js","sources":["../../../../../src/components/BuildTable/lib/BuildLogDrawer/BuildLogDrawer.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React, { useState, useEffect, useCallback } from 'react';\nimport Drawer from '@material-ui/core/Drawer';\nimport Typography from '@material-ui/core/Typography';\nimport LinearProgress from '@material-ui/core/LinearProgress';\nimport Box from '@material-ui/core/Box';\nimport IconButton from '@material-ui/core/IconButton';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CloseIcon from '@material-ui/icons/Close';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { azureDevOpsApiRef } from '../../../../api';\nimport { getAnnotationValuesFromEntity } from '../../../../utils';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { useEntity } from '@backstage/plugin-catalog-react';\n\nconst useDrawerStyles = makeStyles(theme => ({\n logDrawer: {\n width: '40%',\n minWidth: '500px',\n padding: theme.spacing(2),\n },\n header: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginBottom: theme.spacing(2),\n borderBottom: `1px solid ${theme.palette.divider}`,\n paddingBottom: theme.spacing(1),\n },\n content: {\n height: '100%',\n display: 'flex',\n flexDirection: 'column',\n },\n logContainer: {\n flexGrow: 1,\n overflow: 'auto',\n backgroundColor: theme.palette.background.default,\n padding: theme.spacing(2),\n borderRadius: theme.shape.borderRadius,\n marginTop: theme.spacing(2),\n fontFamily: theme.typography.fontFamily,\n fontSize: theme.typography.fontSize,\n },\n}));\n\ntype BuildLogDrawerProps = {\n buildId?: number;\n open: boolean;\n onClose: () => void;\n logsCache: Record<number, string[]>;\n updateCache: (buildId: number, logs: string[]) => void;\n};\n\nexport const BuildLogDrawer = ({\n buildId,\n open,\n onClose,\n logsCache,\n updateCache,\n}: BuildLogDrawerProps) => {\n const [loading, setLoading] = useState(false);\n const [logs, setLogs] = useState<string[]>([]);\n const [error, setError] = useState<Error | undefined>();\n const { entity } = useEntity();\n const azureApi = useApi(azureDevOpsApiRef);\n const classes = useDrawerStyles();\n\n const fetchLogs = useCallback(async () => {\n if (!buildId) {\n setError(new Error('Missing ID for build'));\n return;\n }\n\n setLoading(true);\n setError(undefined);\n setLogs([]);\n\n try {\n const { project, host, org } = getAnnotationValuesFromEntity(entity);\n const response = await azureApi.getBuildRunLog(\n project,\n stringifyEntityRef(entity),\n buildId,\n host,\n org,\n );\n\n setLogs(response.log);\n updateCache(buildId, response.log);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [buildId, entity, azureApi, updateCache]);\n\n // Reset logs when a different build is selected\n useEffect(() => {\n if (buildId && open) {\n // Check logs in cache first\n if (logsCache[buildId]) {\n setLogs(logsCache[buildId]);\n } else {\n fetchLogs();\n }\n }\n }, [buildId, open, fetchLogs, logsCache]);\n\n return (\n <Drawer\n anchor=\"right\"\n open={open}\n onClose={onClose}\n classes={{\n paper: classes.logDrawer,\n }}\n >\n <div className={classes.content}>\n <div className={classes.header}>\n <Typography variant=\"h6\">\n Build Logs {buildId ? `(Build #${buildId})` : ''}\n </Typography>\n <IconButton onClick={onClose} aria-label=\"close\">\n <CloseIcon />\n </IconButton>\n </div>\n\n {loading && <LinearProgress />}\n\n {error && (\n <Typography color=\"error\">\n Error loading logs: {error.message}\n </Typography>\n )}\n\n {!loading && !error && logs.length === 0 && (\n <Typography>No logs available</Typography>\n )}\n\n {!loading && !error && logs.length > 0 && (\n <Box component=\"pre\" className={classes.logContainer}>\n {logs.join('\\n')}\n </Box>\n )}\n </div>\n </Drawer>\n );\n};\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -148,6 +148,9 @@ interface AzureDevOpsApi {
|
|
|
148
148
|
items: BuildRun[];
|
|
149
149
|
}>;
|
|
150
150
|
getReadme(opts: ReadmeConfig): Promise<Readme>;
|
|
151
|
+
getBuildRunLog(projectName: string, entityRef: string, buildId: number, host?: string, org?: string): Promise<{
|
|
152
|
+
log: string[];
|
|
153
|
+
}>;
|
|
151
154
|
}
|
|
152
155
|
|
|
153
156
|
/** @public */
|
|
@@ -174,6 +177,9 @@ declare class AzureDevOpsClient implements AzureDevOpsApi {
|
|
|
174
177
|
items: BuildRun[];
|
|
175
178
|
}>;
|
|
176
179
|
getReadme(opts: ReadmeConfig): Promise<Readme>;
|
|
180
|
+
getBuildRunLog(projectName: string, entityRef: string, buildId: number, host?: string, org?: string): Promise<{
|
|
181
|
+
log: string[];
|
|
182
|
+
}>;
|
|
177
183
|
private get;
|
|
178
184
|
}
|
|
179
185
|
|