@backstage-community/plugin-tekton 3.16.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 +801 -0
- package/README.md +369 -0
- package/app-config.dynamic.yaml +12 -0
- package/dist/components/Charts/PipelineBars.esm.js +49 -0
- package/dist/components/Charts/PipelineBars.esm.js.map +1 -0
- package/dist/components/Icons/CriticalRiskIcon.esm.js +22 -0
- package/dist/components/Icons/CriticalRiskIcon.esm.js.map +1 -0
- package/dist/components/Icons/EqualsIcon.esm.js +22 -0
- package/dist/components/Icons/EqualsIcon.esm.js.map +1 -0
- package/dist/components/Icons/LinkToSbomIcon.esm.js +37 -0
- package/dist/components/Icons/LinkToSbomIcon.esm.js.map +1 -0
- package/dist/components/Icons/OutputIcon.esm.js +36 -0
- package/dist/components/Icons/OutputIcon.esm.js.map +1 -0
- package/dist/components/Icons/SignedBadge.esm.js +16 -0
- package/dist/components/Icons/SignedBadge.esm.js.map +1 -0
- package/dist/components/Icons/ViewLogsIcon.esm.js +35 -0
- package/dist/components/Icons/ViewLogsIcon.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunColumnHeader.esm.js +43 -0
- package/dist/components/PipelineRunList/PipelineRunColumnHeader.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunList.esm.js +185 -0
- package/dist/components/PipelineRunList/PipelineRunList.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunListSearchBar.esm.js +42 -0
- package/dist/components/PipelineRunList/PipelineRunListSearchBar.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunOutput.esm.js +70 -0
- package/dist/components/PipelineRunList/PipelineRunOutput.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunRow.css.esm.js +7 -0
- package/dist/components/PipelineRunList/PipelineRunRow.css.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunRow.esm.js +110 -0
- package/dist/components/PipelineRunList/PipelineRunRow.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunRowActions.esm.js +137 -0
- package/dist/components/PipelineRunList/PipelineRunRowActions.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunSBOMLink.esm.js +25 -0
- package/dist/components/PipelineRunList/PipelineRunSBOMLink.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunTableBody.esm.js +32 -0
- package/dist/components/PipelineRunList/PipelineRunTableBody.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunTaskStatus.esm.js +11 -0
- package/dist/components/PipelineRunList/PipelineRunTaskStatus.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunVulnerabilities.esm.js +81 -0
- package/dist/components/PipelineRunList/PipelineRunVulnerabilities.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineTableHeader.esm.js +53 -0
- package/dist/components/PipelineRunList/PipelineTableHeader.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PlrStatus.css.esm.js +7 -0
- package/dist/components/PipelineRunList/PlrStatus.css.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PlrStatus.esm.js +11 -0
- package/dist/components/PipelineRunList/PlrStatus.esm.js.map +1 -0
- package/dist/components/PipelineRunList/ResourceBadge.css.esm.js +7 -0
- package/dist/components/PipelineRunList/ResourceBadge.css.esm.js.map +1 -0
- package/dist/components/PipelineRunList/ResourceBadge.esm.js +15 -0
- package/dist/components/PipelineRunList/ResourceBadge.esm.js.map +1 -0
- package/dist/components/PipelineRunLogs/PipelineRunLogDialog.esm.js +82 -0
- package/dist/components/PipelineRunLogs/PipelineRunLogDialog.esm.js.map +1 -0
- package/dist/components/PipelineRunLogs/PipelineRunLogDownloader.esm.js +47 -0
- package/dist/components/PipelineRunLogs/PipelineRunLogDownloader.esm.js.map +1 -0
- package/dist/components/PipelineRunLogs/PipelineRunLogViewer.esm.js +53 -0
- package/dist/components/PipelineRunLogs/PipelineRunLogViewer.esm.js.map +1 -0
- package/dist/components/PipelineRunLogs/PipelineRunLogs.esm.js +69 -0
- package/dist/components/PipelineRunLogs/PipelineRunLogs.esm.js.map +1 -0
- package/dist/components/PipelineRunLogs/PodLogsDownloadLink.esm.js +69 -0
- package/dist/components/PipelineRunLogs/PodLogsDownloadLink.esm.js.map +1 -0
- package/dist/components/PipelineRunLogs/TaskStatusStepper.esm.js +128 -0
- package/dist/components/PipelineRunLogs/TaskStatusStepper.esm.js.map +1 -0
- package/dist/components/PipelineRunOutput/PipelineRunOutputDialog.esm.js +62 -0
- package/dist/components/PipelineRunOutput/PipelineRunOutputDialog.esm.js.map +1 -0
- package/dist/components/Router.esm.js +16 -0
- package/dist/components/Router.esm.js.map +1 -0
- package/dist/components/Tekton/TektonCIComponent.esm.js +53 -0
- package/dist/components/Tekton/TektonCIComponent.esm.js.map +1 -0
- package/dist/components/common/ClusterSelector.css.esm.js +7 -0
- package/dist/components/common/ClusterSelector.css.esm.js.map +1 -0
- package/dist/components/common/ClusterSelector.esm.js +46 -0
- package/dist/components/common/ClusterSelector.esm.js.map +1 -0
- package/dist/components/common/ErrorPanel.esm.js +33 -0
- package/dist/components/common/ErrorPanel.esm.js.map +1 -0
- package/dist/components/common/PermissionAlert.esm.js +9 -0
- package/dist/components/common/PermissionAlert.esm.js.map +1 -0
- package/dist/components/common/ResourceStatus.css.esm.js +7 -0
- package/dist/components/common/ResourceStatus.css.esm.js.map +1 -0
- package/dist/components/common/StatusSelector.css.esm.js +7 -0
- package/dist/components/common/StatusSelector.css.esm.js.map +1 -0
- package/dist/components/common/StatusSelector.esm.js +48 -0
- package/dist/components/common/StatusSelector.esm.js.map +1 -0
- package/dist/components/common/TableExpandCollapse.esm.js +44 -0
- package/dist/components/common/TableExpandCollapse.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineLayout.esm.js +126 -0
- package/dist/components/pipeline-topology/PipelineLayout.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineRunVisualization.esm.js +13 -0
- package/dist/components/pipeline-topology/PipelineRunVisualization.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineTaskNode.css.esm.js +7 -0
- package/dist/components/pipeline-topology/PipelineTaskNode.css.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineTaskNode.esm.js +132 -0
- package/dist/components/pipeline-topology/PipelineTaskNode.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineVisualization.css.esm.js +7 -0
- package/dist/components/pipeline-topology/PipelineVisualization.css.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineVisualization.esm.js +24 -0
- package/dist/components/pipeline-topology/PipelineVisualization.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineVisualizationStepList.css.esm.js +7 -0
- package/dist/components/pipeline-topology/PipelineVisualizationStepList.css.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineVisualizationStepList.esm.js +39 -0
- package/dist/components/pipeline-topology/PipelineVisualizationStepList.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineVisualizationView.esm.js +41 -0
- package/dist/components/pipeline-topology/PipelineVisualizationView.esm.js.map +1 -0
- package/dist/components/pipeline-topology/TaskGroupEdge.esm.js +16 -0
- package/dist/components/pipeline-topology/TaskGroupEdge.esm.js.map +1 -0
- package/dist/components/pipeline-topology/dag.esm.js +119 -0
- package/dist/components/pipeline-topology/dag.esm.js.map +1 -0
- package/dist/components/pipeline-topology/pipelineComponentFactory.esm.js +60 -0
- package/dist/components/pipeline-topology/pipelineComponentFactory.esm.js.map +1 -0
- package/dist/consts/pipeline-topology-const.esm.js +66 -0
- package/dist/consts/pipeline-topology-const.esm.js.map +1 -0
- package/dist/consts/tekton-const.esm.js +7 -0
- package/dist/consts/tekton-const.esm.js.map +1 -0
- package/dist/hooks/TektonResourcesContext.esm.js +16 -0
- package/dist/hooks/TektonResourcesContext.esm.js.map +1 -0
- package/dist/hooks/useAllWatchResources.esm.js +35 -0
- package/dist/hooks/useAllWatchResources.esm.js.map +1 -0
- package/dist/hooks/useDarkTheme.esm.js +21 -0
- package/dist/hooks/useDarkTheme.esm.js.map +1 -0
- package/dist/hooks/usePipelineRunScanResults.esm.js +35 -0
- package/dist/hooks/usePipelineRunScanResults.esm.js.map +1 -0
- package/dist/hooks/usePodLogsOfPipelineRun.esm.js +67 -0
- package/dist/hooks/usePodLogsOfPipelineRun.esm.js.map +1 -0
- package/dist/hooks/useResourcesClusters.esm.js +24 -0
- package/dist/hooks/useResourcesClusters.esm.js.map +1 -0
- package/dist/hooks/useTektonObjectsResponse.esm.js +78 -0
- package/dist/hooks/useTektonObjectsResponse.esm.js.map +1 -0
- package/dist/hooks/useTektonViewPermission.esm.js +12 -0
- package/dist/hooks/useTektonViewPermission.esm.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.esm.js +3 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/models.esm.js +21 -0
- package/dist/models.esm.js.map +1 -0
- package/dist/plugin.esm.js +72 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/types/types.esm.js +15 -0
- package/dist/types/types.esm.js.map +1 -0
- package/dist/utils/isTektonCIAvailable.esm.js +7 -0
- package/dist/utils/isTektonCIAvailable.esm.js.map +1 -0
- package/dist/utils/log-downloader-utils.esm.js +33 -0
- package/dist/utils/log-downloader-utils.esm.js.map +1 -0
- package/dist/utils/pipeline-step-utils.esm.js +53 -0
- package/dist/utils/pipeline-step-utils.esm.js.map +1 -0
- package/dist/utils/pipeline-topology-utils.esm.js +250 -0
- package/dist/utils/pipeline-topology-utils.esm.js.map +1 -0
- package/dist/utils/pipelineRun-utils.esm.js +128 -0
- package/dist/utils/pipelineRun-utils.esm.js.map +1 -0
- package/dist/utils/taskRun-utils.esm.js +50 -0
- package/dist/utils/taskRun-utils.esm.js.map +1 -0
- package/dist/utils/tekton-utils.esm.js +191 -0
- package/dist/utils/tekton-utils.esm.js.map +1 -0
- package/package.json +114 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { Flex, FlexItem } from '@patternfly/react-core';
|
|
3
|
+
import { TEKTON_PIPELINE_RUN, TEKTON_PIPELINE_TASKRUN, TEKTON_PIPELINE_TASK } from '../../consts/tekton-const.esm.js';
|
|
4
|
+
import PodLogsDownloadLink from './PodLogsDownloadLink.esm.js';
|
|
5
|
+
|
|
6
|
+
const PipelineRunLogDownloader = ({ pods, pipelineRun, activeTask }) => {
|
|
7
|
+
const filteredPods = pods?.filter(
|
|
8
|
+
(p) => p?.metadata?.labels?.[TEKTON_PIPELINE_RUN] === pipelineRun?.metadata?.name
|
|
9
|
+
);
|
|
10
|
+
const sortedPods = React__default.useMemo(
|
|
11
|
+
() => Array.from(filteredPods)?.sort(
|
|
12
|
+
(a, b) => new Date(a?.status?.startTime).getTime() - new Date(b?.status?.startTime).getTime()
|
|
13
|
+
),
|
|
14
|
+
[filteredPods]
|
|
15
|
+
);
|
|
16
|
+
const activeTaskPod = sortedPods.find(
|
|
17
|
+
(sp) => sp.metadata?.labels?.[TEKTON_PIPELINE_TASKRUN] === activeTask
|
|
18
|
+
) ?? sortedPods[sortedPods.length - 1];
|
|
19
|
+
return sortedPods.length > 0 ? /* @__PURE__ */ React__default.createElement(
|
|
20
|
+
Flex,
|
|
21
|
+
{
|
|
22
|
+
"data-testid": "pipelinerun-logs-downloader",
|
|
23
|
+
justifyContent: { default: "justifyContentFlexEnd" }
|
|
24
|
+
},
|
|
25
|
+
/* @__PURE__ */ React__default.createElement(FlexItem, null, /* @__PURE__ */ React__default.createElement(
|
|
26
|
+
PodLogsDownloadLink,
|
|
27
|
+
{
|
|
28
|
+
"data-testid": "download-task-logs",
|
|
29
|
+
pods: activeTaskPod ? [activeTaskPod] : [],
|
|
30
|
+
fileName: `${activeTaskPod?.metadata?.labels?.[TEKTON_PIPELINE_TASK] ?? "task"}.log`,
|
|
31
|
+
downloadTitle: "Download"
|
|
32
|
+
}
|
|
33
|
+
)),
|
|
34
|
+
/* @__PURE__ */ React__default.createElement(FlexItem, null, /* @__PURE__ */ React__default.createElement(
|
|
35
|
+
PodLogsDownloadLink,
|
|
36
|
+
{
|
|
37
|
+
"data-testid": "download-pipelinerun-logs",
|
|
38
|
+
pods: sortedPods,
|
|
39
|
+
fileName: `${pipelineRun?.metadata?.name ?? "pipelinerun"}.log`,
|
|
40
|
+
downloadTitle: "Download all tasks logs"
|
|
41
|
+
}
|
|
42
|
+
))
|
|
43
|
+
) : null;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export { PipelineRunLogDownloader as default };
|
|
47
|
+
//# sourceMappingURL=PipelineRunLogDownloader.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PipelineRunLogDownloader.esm.js","sources":["../../../src/components/PipelineRunLogs/PipelineRunLogDownloader.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 from 'react';\n\nimport { V1Pod } from '@kubernetes/client-node';\nimport { Flex, FlexItem } from '@patternfly/react-core';\n\nimport { PipelineRunKind } from '@janus-idp/shared-react';\n\nimport {\n TEKTON_PIPELINE_RUN,\n TEKTON_PIPELINE_TASK,\n TEKTON_PIPELINE_TASKRUN,\n} from '../../consts/tekton-const';\nimport PodLogsDownloadLink from './PodLogsDownloadLink';\n\nconst PipelineRunLogDownloader: React.FC<{\n pods: V1Pod[];\n pipelineRun: PipelineRunKind;\n activeTask: string | undefined;\n}> = ({ pods, pipelineRun, activeTask }) => {\n const filteredPods: V1Pod[] = pods?.filter(\n (p: V1Pod) =>\n p?.metadata?.labels?.[TEKTON_PIPELINE_RUN] ===\n pipelineRun?.metadata?.name,\n );\n\n const sortedPods: V1Pod[] = React.useMemo(\n () =>\n Array.from(filteredPods)?.sort(\n (a: V1Pod, b: V1Pod) =>\n new Date(a?.status?.startTime as Date).getTime() -\n new Date(b?.status?.startTime as Date).getTime(),\n ),\n [filteredPods],\n );\n\n const activeTaskPod: V1Pod =\n sortedPods.find(\n (sp: V1Pod) =>\n sp.metadata?.labels?.[TEKTON_PIPELINE_TASKRUN] === activeTask,\n ) ?? sortedPods[sortedPods.length - 1];\n\n return sortedPods.length > 0 ? (\n <Flex\n data-testid=\"pipelinerun-logs-downloader\"\n justifyContent={{ default: 'justifyContentFlexEnd' }}\n >\n <FlexItem>\n <PodLogsDownloadLink\n data-testid=\"download-task-logs\"\n pods={activeTaskPod ? [activeTaskPod] : []}\n fileName={`${\n activeTaskPod?.metadata?.labels?.[TEKTON_PIPELINE_TASK] ?? 'task'\n }.log`}\n downloadTitle=\"Download\"\n />\n </FlexItem>\n <FlexItem>\n <PodLogsDownloadLink\n data-testid=\"download-pipelinerun-logs\"\n pods={sortedPods}\n fileName={`${pipelineRun?.metadata?.name ?? 'pipelinerun'}.log`}\n downloadTitle=\"Download all tasks logs\"\n />\n </FlexItem>\n </Flex>\n ) : null;\n};\nexport default PipelineRunLogDownloader;\n"],"names":["React"],"mappings":";;;;;AA6BA,MAAM,2BAID,CAAC,EAAE,IAAM,EAAA,WAAA,EAAa,YAAiB,KAAA;AAC1C,EAAA,MAAM,eAAwB,IAAM,EAAA,MAAA;AAAA,IAClC,CAAC,MACC,CAAG,EAAA,QAAA,EAAU,SAAS,mBAAmB,CAAA,KACzC,aAAa,QAAU,EAAA;AAAA,GAC3B;AAEA,EAAA,MAAM,aAAsBA,cAAM,CAAA,OAAA;AAAA,IAChC,MACE,KAAA,CAAM,IAAK,CAAA,YAAY,CAAG,EAAA,IAAA;AAAA,MACxB,CAAC,CAAU,EAAA,CAAA,KACT,IAAI,IAAA,CAAK,GAAG,MAAQ,EAAA,SAAiB,CAAE,CAAA,OAAA,KACvC,IAAI,IAAA,CAAK,GAAG,MAAQ,EAAA,SAAiB,EAAE,OAAQ;AAAA,KACnD;AAAA,IACF,CAAC,YAAY;AAAA,GACf;AAEA,EAAA,MAAM,gBACJ,UAAW,CAAA,IAAA;AAAA,IACT,CAAC,EACC,KAAA,EAAA,CAAG,QAAU,EAAA,MAAA,GAAS,uBAAuB,CAAM,KAAA;AAAA,GAClD,IAAA,UAAA,CAAW,UAAW,CAAA,MAAA,GAAS,CAAC,CAAA;AAEvC,EAAO,OAAA,UAAA,CAAW,SAAS,CACzB,mBAAAA,cAAA,CAAA,aAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,aAAY,EAAA,6BAAA;AAAA,MACZ,cAAA,EAAgB,EAAE,OAAA,EAAS,uBAAwB;AAAA,KAAA;AAAA,iDAElD,QACC,EAAA,IAAA,kBAAAA,cAAA,CAAA,aAAA;AAAA,MAAC,mBAAA;AAAA,MAAA;AAAA,QACC,aAAY,EAAA,oBAAA;AAAA,QACZ,IAAM,EAAA,aAAA,GAAgB,CAAC,aAAa,IAAI,EAAC;AAAA,QACzC,UAAU,CACR,EAAA,aAAA,EAAe,UAAU,MAAS,GAAA,oBAAoB,KAAK,MAC7D,CAAA,IAAA,CAAA;AAAA,QACA,aAAc,EAAA;AAAA;AAAA,KAElB,CAAA;AAAA,iDACC,QACC,EAAA,IAAA,kBAAAA,cAAA,CAAA,aAAA;AAAA,MAAC,mBAAA;AAAA,MAAA;AAAA,QACC,aAAY,EAAA,2BAAA;AAAA,QACZ,IAAM,EAAA,UAAA;AAAA,QACN,QAAU,EAAA,CAAA,EAAG,WAAa,EAAA,QAAA,EAAU,QAAQ,aAAa,CAAA,IAAA,CAAA;AAAA,QACzD,aAAc,EAAA;AAAA;AAAA,KAElB;AAAA,GAEA,GAAA,IAAA;AACN;;;;"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { DismissableBanner, LogViewer } from '@backstage/core-components';
|
|
3
|
+
import { Paper } from '@material-ui/core';
|
|
4
|
+
import { Skeleton } from '@material-ui/lab';
|
|
5
|
+
import { usePodLogsOfPipelineRun } from '../../hooks/usePodLogsOfPipelineRun.esm.js';
|
|
6
|
+
|
|
7
|
+
const PipelineRunLogViewer = ({ pod }) => {
|
|
8
|
+
const { value, error, loading } = usePodLogsOfPipelineRun({
|
|
9
|
+
pod
|
|
10
|
+
});
|
|
11
|
+
const containersList = pod?.spec?.containers || [];
|
|
12
|
+
let text = "";
|
|
13
|
+
text = containersList.reduce(
|
|
14
|
+
(acc, container, idx) => {
|
|
15
|
+
if (container?.name && value?.[idx]?.text) {
|
|
16
|
+
return acc.concat(
|
|
17
|
+
`${container.name.toLocaleUpperCase("en-US")}
|
|
18
|
+
${value[idx].text}`
|
|
19
|
+
).concat(idx === containersList.length - 1 ? "" : "\n");
|
|
20
|
+
}
|
|
21
|
+
return acc;
|
|
22
|
+
},
|
|
23
|
+
""
|
|
24
|
+
);
|
|
25
|
+
return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, error && /* @__PURE__ */ React__default.createElement(
|
|
26
|
+
DismissableBanner,
|
|
27
|
+
{
|
|
28
|
+
message: error?.message,
|
|
29
|
+
variant: "error",
|
|
30
|
+
fixed: false,
|
|
31
|
+
id: "pod-logs"
|
|
32
|
+
}
|
|
33
|
+
), /* @__PURE__ */ React__default.createElement(
|
|
34
|
+
Paper,
|
|
35
|
+
{
|
|
36
|
+
elevation: 1,
|
|
37
|
+
style: { height: "100%", width: "100%", minHeight: "30rem" }
|
|
38
|
+
},
|
|
39
|
+
loading && /* @__PURE__ */ React__default.createElement(
|
|
40
|
+
Skeleton,
|
|
41
|
+
{
|
|
42
|
+
"data-testid": "logs-skeleton",
|
|
43
|
+
variant: "rect",
|
|
44
|
+
width: "100%",
|
|
45
|
+
height: "100%"
|
|
46
|
+
}
|
|
47
|
+
),
|
|
48
|
+
pod && !loading && /* @__PURE__ */ React__default.createElement(LogViewer, { text: text || "No Logs found" })
|
|
49
|
+
));
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export { PipelineRunLogViewer };
|
|
53
|
+
//# sourceMappingURL=PipelineRunLogViewer.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PipelineRunLogViewer.esm.js","sources":["../../../src/components/PipelineRunLogs/PipelineRunLogViewer.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 from 'react';\n\nimport { DismissableBanner, LogViewer } from '@backstage/core-components';\n\nimport { V1Container, V1Pod } from '@kubernetes/client-node';\nimport { Paper } from '@material-ui/core';\nimport { Skeleton } from '@material-ui/lab';\n\nimport { usePodLogsOfPipelineRun } from '../../hooks/usePodLogsOfPipelineRun';\n\ntype PipelineRunLogViewerProps = { pod: V1Pod };\n\nexport const PipelineRunLogViewer = ({ pod }: PipelineRunLogViewerProps) => {\n const { value, error, loading } = usePodLogsOfPipelineRun({\n pod,\n });\n\n const containersList = pod?.spec?.containers || [];\n let text = '';\n\n text = containersList.reduce(\n (acc: string, container: V1Container, idx: number) => {\n if (container?.name && value?.[idx]?.text) {\n return acc\n .concat(\n `${container.name.toLocaleUpperCase('en-US')}\\n${value[idx].text}`,\n )\n .concat(idx === containersList.length - 1 ? '' : '\\n');\n }\n return acc;\n },\n '',\n );\n\n return (\n <>\n {error && (\n <DismissableBanner\n message={error?.message}\n variant=\"error\"\n fixed={false}\n id=\"pod-logs\"\n />\n )}\n <Paper\n elevation={1}\n style={{ height: '100%', width: '100%', minHeight: '30rem' }}\n >\n {loading && (\n <Skeleton\n data-testid=\"logs-skeleton\"\n variant=\"rect\"\n width=\"100%\"\n height=\"100%\"\n />\n )}\n {pod && !loading && <LogViewer text={text || 'No Logs found'} />}\n </Paper>\n </>\n );\n};\n"],"names":["React"],"mappings":";;;;;;AA2BO,MAAM,oBAAuB,GAAA,CAAC,EAAE,GAAA,EAAqC,KAAA;AAC1E,EAAA,MAAM,EAAE,KAAA,EAAO,KAAO,EAAA,OAAA,KAAY,uBAAwB,CAAA;AAAA,IACxD;AAAA,GACD,CAAA;AAED,EAAA,MAAM,cAAiB,GAAA,GAAA,EAAK,IAAM,EAAA,UAAA,IAAc,EAAC;AACjD,EAAA,IAAI,IAAO,GAAA,EAAA;AAEX,EAAA,IAAA,GAAO,cAAe,CAAA,MAAA;AAAA,IACpB,CAAC,GAAa,EAAA,SAAA,EAAwB,GAAgB,KAAA;AACpD,MAAA,IAAI,SAAW,EAAA,IAAA,IAAQ,KAAQ,GAAA,GAAG,GAAG,IAAM,EAAA;AACzC,QAAA,OAAO,GACJ,CAAA,MAAA;AAAA,UACC,CAAG,EAAA,SAAA,CAAU,IAAK,CAAA,iBAAA,CAAkB,OAAO,CAAC;AAAA,EAAK,KAAA,CAAM,GAAG,CAAA,CAAE,IAAI,CAAA;AAAA,UAEjE,MAAO,CAAA,GAAA,KAAQ,eAAe,MAAS,GAAA,CAAA,GAAI,KAAK,IAAI,CAAA;AAAA;AAEzD,MAAO,OAAA,GAAA;AAAA,KACT;AAAA,IACA;AAAA,GACF;AAEA,EAAA,mFAEK,KACC,oBAAAA,cAAA,CAAA,aAAA;AAAA,IAAC,iBAAA;AAAA,IAAA;AAAA,MACC,SAAS,KAAO,EAAA,OAAA;AAAA,MAChB,OAAQ,EAAA,OAAA;AAAA,MACR,KAAO,EAAA,KAAA;AAAA,MACP,EAAG,EAAA;AAAA;AAAA,GAGP,kBAAAA,cAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAW,EAAA,CAAA;AAAA,MACX,OAAO,EAAE,MAAA,EAAQ,QAAQ,KAAO,EAAA,MAAA,EAAQ,WAAW,OAAQ;AAAA,KAAA;AAAA,IAE1D,OACC,oBAAAA,cAAA,CAAA,aAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,aAAY,EAAA,eAAA;AAAA,QACZ,OAAQ,EAAA,MAAA;AAAA,QACR,KAAM,EAAA,MAAA;AAAA,QACN,MAAO,EAAA;AAAA;AAAA,KACT;AAAA,IAED,OAAO,CAAC,OAAA,iDAAY,SAAU,EAAA,EAAA,IAAA,EAAM,QAAQ,eAAiB,EAAA;AAAA,GAElE,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { Progress, LogViewer } from '@backstage/core-components';
|
|
3
|
+
import { Paper } from '@material-ui/core';
|
|
4
|
+
import Grid from '@material-ui/core/Grid';
|
|
5
|
+
import { getTaskRunsForPipelineRun, pipelineRunFilterReducer } from '@janus-idp/shared-react';
|
|
6
|
+
import { getSortedTaskRuns, getActiveTaskRun } from '../../utils/taskRun-utils.esm.js';
|
|
7
|
+
import { PipelineRunLogViewer } from './PipelineRunLogViewer.esm.js';
|
|
8
|
+
import { TaskStatusStepper } from './TaskStatusStepper.esm.js';
|
|
9
|
+
|
|
10
|
+
const PipelineRunLogs = ({
|
|
11
|
+
pipelineRun,
|
|
12
|
+
taskRuns,
|
|
13
|
+
pods,
|
|
14
|
+
activeTask,
|
|
15
|
+
setActiveTask
|
|
16
|
+
}) => {
|
|
17
|
+
const PLRTaskRuns = getTaskRunsForPipelineRun(pipelineRun, taskRuns);
|
|
18
|
+
const sortedTaskRuns = getSortedTaskRuns(PLRTaskRuns);
|
|
19
|
+
const taskRunFromYaml = PLRTaskRuns?.reduce(
|
|
20
|
+
(acc, value) => {
|
|
21
|
+
if (value?.metadata?.name) {
|
|
22
|
+
acc[value.metadata.name] = value;
|
|
23
|
+
}
|
|
24
|
+
return acc;
|
|
25
|
+
},
|
|
26
|
+
{}
|
|
27
|
+
);
|
|
28
|
+
const completed = pipelineRunFilterReducer(pipelineRun);
|
|
29
|
+
const [lastActiveStepId, setLastActiveStepId] = React__default.useState("");
|
|
30
|
+
React__default.useEffect(() => {
|
|
31
|
+
const mostRecentFailedOrActiveStep = sortedTaskRuns.find(
|
|
32
|
+
(tr) => ["Failed", "Running"].includes(tr.status)
|
|
33
|
+
);
|
|
34
|
+
if (completed && !mostRecentFailedOrActiveStep && !activeTask) {
|
|
35
|
+
setLastActiveStepId(sortedTaskRuns[sortedTaskRuns.length - 1]?.id);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
setLastActiveStepId(
|
|
39
|
+
!activeTask ? mostRecentFailedOrActiveStep?.id : ""
|
|
40
|
+
);
|
|
41
|
+
}, [sortedTaskRuns, completed, activeTask]);
|
|
42
|
+
const currentStepId = activeTask || lastActiveStepId;
|
|
43
|
+
const activeItem = getActiveTaskRun(sortedTaskRuns, currentStepId);
|
|
44
|
+
const podName = activeItem && taskRunFromYaml?.[currentStepId]?.status?.podName;
|
|
45
|
+
const podData = React__default.useMemo(
|
|
46
|
+
() => pods.find((pod) => {
|
|
47
|
+
return pod?.metadata?.name === podName;
|
|
48
|
+
}),
|
|
49
|
+
[pods, podName]
|
|
50
|
+
);
|
|
51
|
+
return /* @__PURE__ */ React__default.createElement(Grid, { container: true }, /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 3 }, /* @__PURE__ */ React__default.createElement(Paper, null, /* @__PURE__ */ React__default.createElement(
|
|
52
|
+
TaskStatusStepper,
|
|
53
|
+
{
|
|
54
|
+
steps: sortedTaskRuns,
|
|
55
|
+
currentStepId,
|
|
56
|
+
onUserStepChange: setActiveTask
|
|
57
|
+
}
|
|
58
|
+
))), /* @__PURE__ */ React__default.createElement(Grid, { item: true, xs: 9 }, !currentStepId && /* @__PURE__ */ React__default.createElement(Progress, null), /* @__PURE__ */ React__default.createElement("div", { style: { height: "80vh" } }, !podData ? /* @__PURE__ */ React__default.createElement(
|
|
59
|
+
Paper,
|
|
60
|
+
{
|
|
61
|
+
elevation: 1,
|
|
62
|
+
style: { height: "100%", width: "100%", minHeight: "30rem" }
|
|
63
|
+
},
|
|
64
|
+
/* @__PURE__ */ React__default.createElement(LogViewer, { text: "No Logs found" })
|
|
65
|
+
) : /* @__PURE__ */ React__default.createElement(PipelineRunLogViewer, { pod: podData }))));
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export { PipelineRunLogs, PipelineRunLogs as default };
|
|
69
|
+
//# sourceMappingURL=PipelineRunLogs.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PipelineRunLogs.esm.js","sources":["../../../src/components/PipelineRunLogs/PipelineRunLogs.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 from 'react';\n\nimport { LogViewer, Progress } from '@backstage/core-components';\n\nimport { V1Pod } from '@kubernetes/client-node';\nimport { Paper } from '@material-ui/core';\nimport Grid from '@material-ui/core/Grid';\n\nimport {\n getTaskRunsForPipelineRun,\n pipelineRunFilterReducer,\n PipelineRunKind,\n TaskRunKind,\n} from '@janus-idp/shared-react';\n\nimport { getActiveTaskRun, getSortedTaskRuns } from '../../utils/taskRun-utils';\nimport { PipelineRunLogViewer } from './PipelineRunLogViewer';\nimport { TaskStatusStepper } from './TaskStatusStepper';\n\ntype PipelineRunLogsProps = {\n pipelineRun: PipelineRunKind;\n taskRuns: TaskRunKind[];\n pods: V1Pod[];\n activeTask?: string;\n setActiveTask: (t: string) => void;\n};\nexport const PipelineRunLogs = ({\n pipelineRun,\n taskRuns,\n pods,\n activeTask,\n setActiveTask,\n}: PipelineRunLogsProps) => {\n const PLRTaskRuns = getTaskRunsForPipelineRun(pipelineRun, taskRuns);\n const sortedTaskRuns = getSortedTaskRuns(PLRTaskRuns);\n const taskRunFromYaml = PLRTaskRuns?.reduce(\n (acc: { [value: string]: TaskRunKind }, value) => {\n if (value?.metadata?.name) {\n acc[value.metadata.name] = value;\n }\n return acc;\n },\n {},\n );\n\n const completed = pipelineRunFilterReducer(pipelineRun);\n const [lastActiveStepId, setLastActiveStepId] = React.useState<string>('');\n\n React.useEffect(() => {\n const mostRecentFailedOrActiveStep = sortedTaskRuns.find(tr =>\n ['Failed', 'Running'].includes(tr.status),\n );\n\n if (completed && !mostRecentFailedOrActiveStep && !activeTask) {\n setLastActiveStepId(sortedTaskRuns[sortedTaskRuns.length - 1]?.id);\n return;\n }\n\n setLastActiveStepId(\n !activeTask ? (mostRecentFailedOrActiveStep?.id as string) : '',\n );\n }, [sortedTaskRuns, completed, activeTask]);\n\n const currentStepId = activeTask || lastActiveStepId;\n const activeItem = getActiveTaskRun(sortedTaskRuns, currentStepId);\n const podName =\n activeItem && taskRunFromYaml?.[currentStepId]?.status?.podName;\n const podData = React.useMemo(\n () =>\n pods.find(pod => {\n return pod?.metadata?.name === podName;\n }),\n [pods, podName],\n );\n\n return (\n <Grid container>\n <Grid item xs={3}>\n <Paper>\n <TaskStatusStepper\n steps={sortedTaskRuns}\n currentStepId={currentStepId}\n onUserStepChange={setActiveTask}\n />\n </Paper>\n </Grid>\n <Grid item xs={9}>\n {!currentStepId && <Progress />}\n <div style={{ height: '80vh' }}>\n {!podData ? (\n <Paper\n elevation={1}\n style={{ height: '100%', width: '100%', minHeight: '30rem' }}\n >\n <LogViewer text=\"No Logs found\" />\n </Paper>\n ) : (\n <PipelineRunLogViewer pod={podData} />\n )}\n </div>\n </Grid>\n </Grid>\n );\n};\n\nexport default PipelineRunLogs;\n"],"names":["React"],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { useApi } from '@backstage/core-plugin-api';
|
|
3
|
+
import { makeStyles, createStyles, Link } from '@material-ui/core';
|
|
4
|
+
import DownloadIcon from '@mui/icons-material/FileDownloadOutlined';
|
|
5
|
+
import classNames from 'classnames';
|
|
6
|
+
import { downloadLogFile } from '@janus-idp/shared-react';
|
|
7
|
+
import { TektonResourcesContext } from '../../hooks/TektonResourcesContext.esm.js';
|
|
8
|
+
import { kubernetesProxyApiRef } from '../../types/types.esm.js';
|
|
9
|
+
import { getPodLogs } from '../../utils/log-downloader-utils.esm.js';
|
|
10
|
+
|
|
11
|
+
const useStyles = makeStyles(
|
|
12
|
+
(theme) => createStyles({
|
|
13
|
+
downloadAction: {
|
|
14
|
+
position: "relative",
|
|
15
|
+
marginBottom: "var(--pf-v5-global--spacer--sm)",
|
|
16
|
+
color: "var(--pf-v5-global--color--100)",
|
|
17
|
+
cursor: "pointer"
|
|
18
|
+
},
|
|
19
|
+
buttonDisabled: {
|
|
20
|
+
color: theme.palette.grey[400],
|
|
21
|
+
cursor: "not-allowed"
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
);
|
|
25
|
+
const PodLogsDownloadLink = ({ pods, fileName, downloadTitle, ...props }) => {
|
|
26
|
+
const classes = useStyles();
|
|
27
|
+
const [downloading, setDownloading] = React__default.useState(false);
|
|
28
|
+
const kubernetesProxyApi = useApi(kubernetesProxyApiRef);
|
|
29
|
+
const { clusters, selectedCluster = 0 } = React__default.useContext(TektonResourcesContext);
|
|
30
|
+
const currCluster = clusters.length > 0 ? clusters[selectedCluster] : "";
|
|
31
|
+
const getLogs = (podScope) => {
|
|
32
|
+
const { podName, podNamespace, containerName, clusterName } = podScope;
|
|
33
|
+
return kubernetesProxyApi.getPodLogs({
|
|
34
|
+
podName,
|
|
35
|
+
namespace: podNamespace,
|
|
36
|
+
containerName,
|
|
37
|
+
clusterName
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
41
|
+
Link,
|
|
42
|
+
{
|
|
43
|
+
component: "button",
|
|
44
|
+
variant: "body2",
|
|
45
|
+
underline: "none",
|
|
46
|
+
disabled: downloading,
|
|
47
|
+
title: downloading ? "downloading logs" : downloadTitle,
|
|
48
|
+
onClick: () => {
|
|
49
|
+
setDownloading(true);
|
|
50
|
+
getPodLogs(pods, getLogs, currCluster).then((logs) => {
|
|
51
|
+
setDownloading(false);
|
|
52
|
+
downloadLogFile(logs || "", fileName);
|
|
53
|
+
}).catch((err) => {
|
|
54
|
+
console.warn("Download failed", err);
|
|
55
|
+
setDownloading(false);
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
className: classNames(classes.downloadAction, {
|
|
59
|
+
[classes.buttonDisabled]: downloading
|
|
60
|
+
}),
|
|
61
|
+
...props
|
|
62
|
+
},
|
|
63
|
+
/* @__PURE__ */ React__default.createElement(DownloadIcon, { style: { verticalAlign: "-0.180em" } }),
|
|
64
|
+
downloadTitle || "Download "
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export { PodLogsDownloadLink as default };
|
|
69
|
+
//# sourceMappingURL=PodLogsDownloadLink.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PodLogsDownloadLink.esm.js","sources":["../../../src/components/PipelineRunLogs/PodLogsDownloadLink.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 from 'react';\n\nimport { useApi } from '@backstage/core-plugin-api';\n\nimport { V1Pod } from '@kubernetes/client-node';\nimport { createStyles, Link, makeStyles, Theme } from '@material-ui/core';\nimport DownloadIcon from '@mui/icons-material/FileDownloadOutlined';\nimport classNames from 'classnames';\n\nimport { downloadLogFile } from '@janus-idp/shared-react';\n\nimport { TektonResourcesContext } from '../../hooks/TektonResourcesContext';\nimport { ContainerScope } from '../../hooks/usePodLogsOfPipelineRun';\nimport {\n kubernetesProxyApiRef,\n TektonResourcesContextData,\n} from '../../types/types';\nimport { getPodLogs } from '../../utils/log-downloader-utils';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n downloadAction: {\n position: 'relative',\n marginBottom: 'var(--pf-v5-global--spacer--sm)',\n color: 'var(--pf-v5-global--color--100)',\n cursor: 'pointer',\n },\n buttonDisabled: {\n color: theme.palette.grey[400],\n cursor: 'not-allowed',\n },\n }),\n);\n\nconst PodLogsDownloadLink: React.FC<{\n pods: V1Pod[];\n fileName: string;\n downloadTitle: string;\n}> = ({ pods, fileName, downloadTitle, ...props }): React.ReactElement => {\n const classes = useStyles();\n const [downloading, setDownloading] = React.useState<boolean>(false);\n const kubernetesProxyApi = useApi(kubernetesProxyApiRef);\n\n const { clusters, selectedCluster = 0 } =\n React.useContext<TektonResourcesContextData>(TektonResourcesContext);\n const currCluster = clusters.length > 0 ? clusters[selectedCluster] : '';\n\n const getLogs = (podScope: ContainerScope): Promise<{ text: string }> => {\n const { podName, podNamespace, containerName, clusterName } = podScope;\n return kubernetesProxyApi.getPodLogs({\n podName: podName,\n namespace: podNamespace,\n containerName: containerName,\n clusterName: clusterName,\n });\n };\n\n return (\n <Link\n component=\"button\"\n variant=\"body2\"\n underline=\"none\"\n disabled={downloading}\n title={downloading ? 'downloading logs' : downloadTitle}\n onClick={() => {\n setDownloading(true);\n getPodLogs(pods, getLogs, currCluster)\n .then((logs: string) => {\n setDownloading(false);\n downloadLogFile(logs || '', fileName);\n })\n .catch(err => {\n // eslint-disable-next-line no-console\n console.warn('Download failed', err);\n setDownloading(false);\n });\n }}\n className={classNames(classes.downloadAction, {\n [classes.buttonDisabled]: downloading,\n })}\n {...props}\n >\n <DownloadIcon style={{ verticalAlign: '-0.180em' }} />\n {downloadTitle || 'Download '}\n </Link>\n );\n};\nexport default PodLogsDownloadLink;\n"],"names":["React"],"mappings":";;;;;;;;;;AAkCA,MAAM,SAAY,GAAA,UAAA;AAAA,EAAW,CAAC,UAC5B,YAAa,CAAA;AAAA,IACX,cAAgB,EAAA;AAAA,MACd,QAAU,EAAA,UAAA;AAAA,MACV,YAAc,EAAA,iCAAA;AAAA,MACd,KAAO,EAAA,iCAAA;AAAA,MACP,MAAQ,EAAA;AAAA,KACV;AAAA,IACA,cAAgB,EAAA;AAAA,MACd,KAAO,EAAA,KAAA,CAAM,OAAQ,CAAA,IAAA,CAAK,GAAG,CAAA;AAAA,MAC7B,MAAQ,EAAA;AAAA;AACV,GACD;AACH,CAAA;AAEM,MAAA,mBAAA,GAID,CAAC,EAAE,IAAA,EAAM,UAAU,aAAe,EAAA,GAAG,OAAgC,KAAA;AACxE,EAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,EAAA,MAAM,CAAC,WAAa,EAAA,cAAc,CAAI,GAAAA,cAAA,CAAM,SAAkB,KAAK,CAAA;AACnE,EAAM,MAAA,kBAAA,GAAqB,OAAO,qBAAqB,CAAA;AAEvD,EAAA,MAAM,EAAE,QAAU,EAAA,eAAA,GAAkB,GAClC,GAAAA,cAAA,CAAM,WAAuC,sBAAsB,CAAA;AACrE,EAAA,MAAM,cAAc,QAAS,CAAA,MAAA,GAAS,CAAI,GAAA,QAAA,CAAS,eAAe,CAAI,GAAA,EAAA;AAEtE,EAAM,MAAA,OAAA,GAAU,CAAC,QAAwD,KAAA;AACvE,IAAA,MAAM,EAAE,OAAA,EAAS,YAAc,EAAA,aAAA,EAAe,aAAgB,GAAA,QAAA;AAC9D,IAAA,OAAO,mBAAmB,UAAW,CAAA;AAAA,MACnC,OAAA;AAAA,MACA,SAAW,EAAA,YAAA;AAAA,MACX,aAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,GACH;AAEA,EACE,uBAAAA,cAAA,CAAA,aAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,SAAU,EAAA,QAAA;AAAA,MACV,OAAQ,EAAA,OAAA;AAAA,MACR,SAAU,EAAA,MAAA;AAAA,MACV,QAAU,EAAA,WAAA;AAAA,MACV,KAAA,EAAO,cAAc,kBAAqB,GAAA,aAAA;AAAA,MAC1C,SAAS,MAAM;AACb,QAAA,cAAA,CAAe,IAAI,CAAA;AACnB,QAAA,UAAA,CAAW,MAAM,OAAS,EAAA,WAAW,CAClC,CAAA,IAAA,CAAK,CAAC,IAAiB,KAAA;AACtB,UAAA,cAAA,CAAe,KAAK,CAAA;AACpB,UAAgB,eAAA,CAAA,IAAA,IAAQ,IAAI,QAAQ,CAAA;AAAA,SACrC,CACA,CAAA,KAAA,CAAM,CAAO,GAAA,KAAA;AAEZ,UAAQ,OAAA,CAAA,IAAA,CAAK,mBAAmB,GAAG,CAAA;AACnC,UAAA,cAAA,CAAe,KAAK,CAAA;AAAA,SACrB,CAAA;AAAA,OACL;AAAA,MACA,SAAA,EAAW,UAAW,CAAA,OAAA,CAAQ,cAAgB,EAAA;AAAA,QAC5C,CAAC,OAAQ,CAAA,cAAc,GAAG;AAAA,OAC3B,CAAA;AAAA,MACA,GAAG;AAAA,KAAA;AAAA,iDAEH,YAAa,EAAA,EAAA,KAAA,EAAO,EAAE,aAAA,EAAe,YAAc,EAAA,CAAA;AAAA,IACnD,aAAiB,IAAA;AAAA,GACpB;AAEJ;;;;"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import useInterval from 'react-use/lib/useInterval';
|
|
3
|
+
import { makeStyles, createStyles, StepButton, CircularProgress } from '@material-ui/core';
|
|
4
|
+
import Step from '@material-ui/core/Step';
|
|
5
|
+
import StepLabel from '@material-ui/core/StepLabel';
|
|
6
|
+
import Stepper from '@material-ui/core/Stepper';
|
|
7
|
+
import Typography from '@material-ui/core/Typography';
|
|
8
|
+
import Cancel from '@material-ui/icons/Cancel';
|
|
9
|
+
import Check from '@material-ui/icons/Check';
|
|
10
|
+
import FiberManualRecordIcon from '@material-ui/icons/FiberManualRecord';
|
|
11
|
+
import classNames from 'classnames';
|
|
12
|
+
import { ComputedStatus } from '@janus-idp/shared-react';
|
|
13
|
+
import { calculateDuration } from '../../utils/tekton-utils.esm.js';
|
|
14
|
+
|
|
15
|
+
const useStyles = makeStyles(
|
|
16
|
+
(theme) => createStyles({
|
|
17
|
+
root: {
|
|
18
|
+
width: "100%"
|
|
19
|
+
},
|
|
20
|
+
titleContainer: {
|
|
21
|
+
display: "flex",
|
|
22
|
+
alignItems: "center",
|
|
23
|
+
gap: theme.spacing(1)
|
|
24
|
+
},
|
|
25
|
+
closeButton: {
|
|
26
|
+
position: "absolute",
|
|
27
|
+
right: theme.spacing(1),
|
|
28
|
+
top: theme.spacing(1),
|
|
29
|
+
color: theme.palette.grey[500]
|
|
30
|
+
},
|
|
31
|
+
labelWrapper: {
|
|
32
|
+
display: "flex",
|
|
33
|
+
flex: 1,
|
|
34
|
+
flexDirection: "row",
|
|
35
|
+
justifyContent: "space-between"
|
|
36
|
+
},
|
|
37
|
+
stepWrapper: {
|
|
38
|
+
width: "100%"
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
);
|
|
42
|
+
const StepTimeTicker = ({ step }) => {
|
|
43
|
+
const [time, setTime] = React__default.useState("");
|
|
44
|
+
useInterval(() => {
|
|
45
|
+
if (!step.startedAt) {
|
|
46
|
+
setTime("");
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
setTime(calculateDuration(step.startedAt, step.endedAt));
|
|
50
|
+
}, 1e3);
|
|
51
|
+
return /* @__PURE__ */ React__default.createElement(Typography, { variant: "caption" }, time);
|
|
52
|
+
};
|
|
53
|
+
const useStepIconStyles = makeStyles(
|
|
54
|
+
(theme) => createStyles({
|
|
55
|
+
root: {
|
|
56
|
+
color: theme.palette.text.disabled,
|
|
57
|
+
display: "flex",
|
|
58
|
+
height: 22,
|
|
59
|
+
alignItems: "center"
|
|
60
|
+
},
|
|
61
|
+
completed: {
|
|
62
|
+
color: theme.palette.status.ok
|
|
63
|
+
},
|
|
64
|
+
error: {
|
|
65
|
+
color: theme.palette.status.error
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
);
|
|
69
|
+
const TaskStepIconComponent = ({ active, completed, error }) => {
|
|
70
|
+
const classes = useStepIconStyles();
|
|
71
|
+
const getMiddle = () => {
|
|
72
|
+
if (active) {
|
|
73
|
+
return /* @__PURE__ */ React__default.createElement(CircularProgress, { size: "24px" });
|
|
74
|
+
}
|
|
75
|
+
if (completed) {
|
|
76
|
+
return /* @__PURE__ */ React__default.createElement(Check, null);
|
|
77
|
+
}
|
|
78
|
+
if (error) {
|
|
79
|
+
return /* @__PURE__ */ React__default.createElement(Cancel, null);
|
|
80
|
+
}
|
|
81
|
+
return /* @__PURE__ */ React__default.createElement(FiberManualRecordIcon, null);
|
|
82
|
+
};
|
|
83
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
84
|
+
"div",
|
|
85
|
+
{
|
|
86
|
+
className: classNames(classes.root, {
|
|
87
|
+
[classes.completed]: completed,
|
|
88
|
+
[classes.error]: error
|
|
89
|
+
})
|
|
90
|
+
},
|
|
91
|
+
getMiddle()
|
|
92
|
+
);
|
|
93
|
+
};
|
|
94
|
+
const TaskStatusStepper = React__default.memo((props) => {
|
|
95
|
+
const { steps, currentStepId, onUserStepChange } = props;
|
|
96
|
+
const classes = useStyles(props);
|
|
97
|
+
return /* @__PURE__ */ React__default.createElement("div", { className: classes.root }, /* @__PURE__ */ React__default.createElement(
|
|
98
|
+
Stepper,
|
|
99
|
+
{
|
|
100
|
+
activeStep: steps.findIndex((s) => s.id === currentStepId),
|
|
101
|
+
orientation: "vertical",
|
|
102
|
+
nonLinear: true
|
|
103
|
+
},
|
|
104
|
+
steps.map((step, _) => {
|
|
105
|
+
const isCancelled = step.status === ComputedStatus.Cancelled;
|
|
106
|
+
const isActive = step.status === ComputedStatus.Running;
|
|
107
|
+
const isCompleted = step.status === ComputedStatus.Succeeded;
|
|
108
|
+
const isFailed = step.status === ComputedStatus.Failed;
|
|
109
|
+
const isSkipped = step.status === ComputedStatus.Skipped;
|
|
110
|
+
return /* @__PURE__ */ React__default.createElement(Step, { key: step.id, expanded: true }, /* @__PURE__ */ React__default.createElement(StepButton, { onClick: () => onUserStepChange(step.id) }, /* @__PURE__ */ React__default.createElement(
|
|
111
|
+
StepLabel,
|
|
112
|
+
{
|
|
113
|
+
StepIconProps: {
|
|
114
|
+
completed: isCompleted,
|
|
115
|
+
error: isFailed || isCancelled,
|
|
116
|
+
active: isActive
|
|
117
|
+
},
|
|
118
|
+
StepIconComponent: TaskStepIconComponent,
|
|
119
|
+
className: classes.stepWrapper
|
|
120
|
+
},
|
|
121
|
+
/* @__PURE__ */ React__default.createElement("div", { className: classes.labelWrapper }, /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle2" }, step.name), isSkipped ? /* @__PURE__ */ React__default.createElement(Typography, { variant: "caption" }, "Skipped") : /* @__PURE__ */ React__default.createElement(StepTimeTicker, { step }))
|
|
122
|
+
)));
|
|
123
|
+
})
|
|
124
|
+
));
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
export { TaskStatusStepper };
|
|
128
|
+
//# sourceMappingURL=TaskStatusStepper.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaskStatusStepper.esm.js","sources":["../../../src/components/PipelineRunLogs/TaskStatusStepper.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 from 'react';\nimport useInterval from 'react-use/lib/useInterval';\n\nimport {\n CircularProgress,\n createStyles,\n makeStyles,\n StepButton,\n StepIconProps,\n Theme,\n} from '@material-ui/core';\nimport Step from '@material-ui/core/Step';\nimport StepLabel from '@material-ui/core/StepLabel';\nimport Stepper from '@material-ui/core/Stepper';\nimport Typography from '@material-ui/core/Typography';\nimport Cancel from '@material-ui/icons/Cancel';\nimport Check from '@material-ui/icons/Check';\nimport FiberManualRecordIcon from '@material-ui/icons/FiberManualRecord';\nimport classNames from 'classnames';\n\nimport { ComputedStatus } from '@janus-idp/shared-react';\n\nimport { TaskStep } from '../../utils/taskRun-utils';\nimport { calculateDuration } from '../../utils/tekton-utils';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n root: {\n width: '100%',\n },\n titleContainer: {\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n },\n closeButton: {\n position: 'absolute',\n right: theme.spacing(1),\n top: theme.spacing(1),\n color: theme.palette.grey[500],\n },\n labelWrapper: {\n display: 'flex',\n flex: 1,\n flexDirection: 'row',\n justifyContent: 'space-between',\n },\n stepWrapper: {\n width: '100%',\n },\n }),\n);\n\nconst StepTimeTicker = ({ step }: { step: TaskStep }) => {\n const [time, setTime] = React.useState('');\n\n useInterval(() => {\n if (!step.startedAt) {\n setTime('');\n return;\n }\n\n setTime(calculateDuration(step.startedAt, step.endedAt));\n }, 1000);\n\n return <Typography variant=\"caption\">{time}</Typography>;\n};\n\nconst useStepIconStyles = makeStyles((theme: Theme) =>\n createStyles({\n root: {\n color: theme.palette.text.disabled,\n display: 'flex',\n height: 22,\n alignItems: 'center',\n },\n completed: {\n color: theme.palette.status.ok,\n },\n error: {\n color: theme.palette.status.error,\n },\n }),\n);\n\nconst TaskStepIconComponent = ({ active, completed, error }: StepIconProps) => {\n const classes = useStepIconStyles();\n\n const getMiddle = () => {\n if (active) {\n return <CircularProgress size=\"24px\" />;\n }\n if (completed) {\n return <Check />;\n }\n if (error) {\n return <Cancel />;\n }\n return <FiberManualRecordIcon />;\n };\n\n return (\n <div\n className={classNames(classes.root, {\n [classes.completed]: completed,\n [classes.error]: error,\n })}\n >\n {getMiddle()}\n </div>\n );\n};\n\ntype TaskStatusStepperProps = {\n steps: TaskStep[];\n currentStepId: string | undefined;\n onUserStepChange: (id: string) => void;\n classes?: {\n root?: string;\n };\n};\n\nexport const TaskStatusStepper = React.memo((props: TaskStatusStepperProps) => {\n const { steps, currentStepId, onUserStepChange } = props;\n const classes = useStyles(props);\n\n return (\n <div className={classes.root}>\n <Stepper\n activeStep={steps.findIndex(s => s.id === currentStepId)}\n orientation=\"vertical\"\n nonLinear\n >\n {steps.map((step, _) => {\n const isCancelled = step.status === ComputedStatus.Cancelled;\n const isActive = step.status === ComputedStatus.Running;\n const isCompleted = step.status === ComputedStatus.Succeeded;\n const isFailed = step.status === ComputedStatus.Failed;\n const isSkipped = step.status === ComputedStatus.Skipped;\n\n return (\n <Step key={step.id} expanded>\n <StepButton onClick={() => onUserStepChange(step.id)}>\n <StepLabel\n StepIconProps={{\n completed: isCompleted,\n error: isFailed || isCancelled,\n active: isActive,\n }}\n StepIconComponent={TaskStepIconComponent}\n className={classes.stepWrapper}\n >\n <div className={classes.labelWrapper}>\n <Typography variant=\"subtitle2\">{step.name}</Typography>\n {isSkipped ? (\n <Typography variant=\"caption\">Skipped</Typography>\n ) : (\n <StepTimeTicker step={step} />\n )}\n </div>\n </StepLabel>\n </StepButton>\n </Step>\n );\n })}\n </Stepper>\n </div>\n );\n});\n"],"names":["React"],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { ErrorBoundary } from '@backstage/core-components';
|
|
3
|
+
import { makeStyles, createStyles, Dialog, DialogTitle, Box, IconButton, DialogContent } from '@material-ui/core';
|
|
4
|
+
import CloseIcon from '@mui/icons-material/Close';
|
|
5
|
+
import { tektonGroupColor } from '../../types/types.esm.js';
|
|
6
|
+
import PipelineRunOutput from '../PipelineRunList/PipelineRunOutput.esm.js';
|
|
7
|
+
import ResourceBadge from '../PipelineRunList/ResourceBadge.esm.js';
|
|
8
|
+
|
|
9
|
+
const useStyles = makeStyles(
|
|
10
|
+
(theme) => createStyles({
|
|
11
|
+
titleContainer: {
|
|
12
|
+
display: "flex",
|
|
13
|
+
alignItems: "center",
|
|
14
|
+
gap: theme.spacing(1)
|
|
15
|
+
},
|
|
16
|
+
closeButton: {
|
|
17
|
+
position: "absolute",
|
|
18
|
+
right: theme.spacing(1),
|
|
19
|
+
top: theme.spacing(1),
|
|
20
|
+
color: theme.palette.grey[500]
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
);
|
|
24
|
+
const PipelineRunOutputDialog = ({
|
|
25
|
+
open,
|
|
26
|
+
closeDialog,
|
|
27
|
+
pipelineRun,
|
|
28
|
+
taskRuns
|
|
29
|
+
}) => {
|
|
30
|
+
const classes = useStyles();
|
|
31
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
32
|
+
Dialog,
|
|
33
|
+
{
|
|
34
|
+
"data-testid": "pipelinerun-output-dialog",
|
|
35
|
+
maxWidth: "xl",
|
|
36
|
+
fullWidth: true,
|
|
37
|
+
open,
|
|
38
|
+
onClose: closeDialog
|
|
39
|
+
},
|
|
40
|
+
/* @__PURE__ */ React__default.createElement(DialogTitle, { id: "pipelinerun-output", title: "PipelineRun Output" }, /* @__PURE__ */ React__default.createElement(Box, { className: classes.titleContainer }, /* @__PURE__ */ React__default.createElement(
|
|
41
|
+
ResourceBadge,
|
|
42
|
+
{
|
|
43
|
+
color: tektonGroupColor,
|
|
44
|
+
abbr: "PLR",
|
|
45
|
+
name: pipelineRun?.metadata?.name ?? ""
|
|
46
|
+
}
|
|
47
|
+
), " ", /* @__PURE__ */ React__default.createElement(
|
|
48
|
+
IconButton,
|
|
49
|
+
{
|
|
50
|
+
"aria-label": "close",
|
|
51
|
+
className: classes.closeButton,
|
|
52
|
+
onClick: closeDialog
|
|
53
|
+
},
|
|
54
|
+
/* @__PURE__ */ React__default.createElement(CloseIcon, null)
|
|
55
|
+
))),
|
|
56
|
+
/* @__PURE__ */ React__default.createElement(DialogContent, null, /* @__PURE__ */ React__default.createElement(ErrorBoundary, null, /* @__PURE__ */ React__default.createElement(PipelineRunOutput, { pipelineRun, taskRuns })))
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
var PipelineRunOutputDialog$1 = React__default.memo(PipelineRunOutputDialog);
|
|
60
|
+
|
|
61
|
+
export { PipelineRunOutputDialog$1 as default };
|
|
62
|
+
//# sourceMappingURL=PipelineRunOutputDialog.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PipelineRunOutputDialog.esm.js","sources":["../../../src/components/PipelineRunOutput/PipelineRunOutputDialog.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 from 'react';\n\nimport { ErrorBoundary } from '@backstage/core-components';\n\nimport {\n Box,\n createStyles,\n Dialog,\n DialogContent,\n DialogTitle,\n IconButton,\n makeStyles,\n Theme,\n} from '@material-ui/core';\nimport CloseIcon from '@mui/icons-material/Close';\n\nimport { PipelineRunKind, TaskRunKind } from '@janus-idp/shared-react';\n\nimport { tektonGroupColor } from '../../types/types';\nimport PipelineRunOutput from '../PipelineRunList/PipelineRunOutput';\nimport ResourceBadge from '../PipelineRunList/ResourceBadge';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n titleContainer: {\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n },\n closeButton: {\n position: 'absolute',\n right: theme.spacing(1),\n top: theme.spacing(1),\n color: theme.palette.grey[500],\n },\n }),\n);\n\ntype PipelineRunOutputDialogProps = {\n open: boolean;\n closeDialog: () => void;\n pipelineRun: PipelineRunKind;\n taskRuns: TaskRunKind[];\n};\nconst PipelineRunOutputDialog = ({\n open,\n closeDialog,\n pipelineRun,\n taskRuns,\n}: PipelineRunOutputDialogProps) => {\n const classes = useStyles();\n\n return (\n <Dialog\n data-testid=\"pipelinerun-output-dialog\"\n maxWidth=\"xl\"\n fullWidth\n open={open}\n onClose={closeDialog}\n >\n <DialogTitle id=\"pipelinerun-output\" title=\"PipelineRun Output\">\n <Box className={classes.titleContainer}>\n <ResourceBadge\n color={tektonGroupColor}\n abbr=\"PLR\"\n name={pipelineRun?.metadata?.name ?? ''}\n />{' '}\n <IconButton\n aria-label=\"close\"\n className={classes.closeButton}\n onClick={closeDialog}\n >\n <CloseIcon />\n </IconButton>\n </Box>\n </DialogTitle>\n <DialogContent>\n <ErrorBoundary>\n <PipelineRunOutput pipelineRun={pipelineRun} taskRuns={taskRuns} />\n </ErrorBoundary>\n </DialogContent>\n </Dialog>\n );\n};\n\nexport default React.memo(PipelineRunOutputDialog);\n"],"names":["React"],"mappings":";;;;;;;;AAqCA,MAAM,SAAY,GAAA,UAAA;AAAA,EAAW,CAAC,UAC5B,YAAa,CAAA;AAAA,IACX,cAAgB,EAAA;AAAA,MACd,OAAS,EAAA,MAAA;AAAA,MACT,UAAY,EAAA,QAAA;AAAA,MACZ,GAAA,EAAK,KAAM,CAAA,OAAA,CAAQ,CAAC;AAAA,KACtB;AAAA,IACA,WAAa,EAAA;AAAA,MACX,QAAU,EAAA,UAAA;AAAA,MACV,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,MACtB,GAAA,EAAK,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,MACpB,KAAO,EAAA,KAAA,CAAM,OAAQ,CAAA,IAAA,CAAK,GAAG;AAAA;AAC/B,GACD;AACH,CAAA;AAQA,MAAM,0BAA0B,CAAC;AAAA,EAC/B,IAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA;AACF,CAAoC,KAAA;AAClC,EAAA,MAAM,UAAU,SAAU,EAAA;AAE1B,EACE,uBAAAA,cAAA,CAAA,aAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,aAAY,EAAA,2BAAA;AAAA,MACZ,QAAS,EAAA,IAAA;AAAA,MACT,SAAS,EAAA,IAAA;AAAA,MACT,IAAA;AAAA,MACA,OAAS,EAAA;AAAA,KAAA;AAAA,oBAETA,cAAA,CAAA,aAAA,CAAC,WAAY,EAAA,EAAA,EAAA,EAAG,oBAAqB,EAAA,KAAA,EAAM,wCACxCA,cAAA,CAAA,aAAA,CAAA,GAAA,EAAA,EAAI,SAAW,EAAA,OAAA,CAAQ,cACtB,EAAA,kBAAAA,cAAA,CAAA,aAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,KAAO,EAAA,gBAAA;AAAA,QACP,IAAK,EAAA,KAAA;AAAA,QACL,IAAA,EAAM,WAAa,EAAA,QAAA,EAAU,IAAQ,IAAA;AAAA;AAAA,OACpC,GACH,kBAAAA,cAAA,CAAA,aAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,YAAW,EAAA,OAAA;AAAA,QACX,WAAW,OAAQ,CAAA,WAAA;AAAA,QACnB,OAAS,EAAA;AAAA,OAAA;AAAA,mDAER,SAAU,EAAA,IAAA;AAAA,KAEf,CACF,CAAA;AAAA,oBACAA,cAAA,CAAA,aAAA,CAAC,qCACEA,cAAA,CAAA,aAAA,CAAA,aAAA,EAAA,IAAA,+CACE,iBAAkB,EAAA,EAAA,WAAA,EAA0B,QAAoB,EAAA,CACnE,CACF;AAAA,GACF;AAEJ,CAAA;AAEA,gCAAeA,cAAA,CAAM,KAAK,uBAAuB,CAAA;;;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { Routes, Route } from 'react-router-dom';
|
|
3
|
+
import { useEntity } from '@backstage/plugin-catalog-react';
|
|
4
|
+
import { TektonCIComponent } from './Tekton/TektonCIComponent.esm.js';
|
|
5
|
+
import { isTektonCIAvailable } from '../utils/isTektonCIAvailable.esm.js';
|
|
6
|
+
|
|
7
|
+
const Router = () => {
|
|
8
|
+
const { entity } = useEntity();
|
|
9
|
+
if (isTektonCIAvailable(entity)) {
|
|
10
|
+
return /* @__PURE__ */ React__default.createElement(Routes, null, /* @__PURE__ */ React__default.createElement(Route, { path: "/", element: /* @__PURE__ */ React__default.createElement(TektonCIComponent, null) }));
|
|
11
|
+
}
|
|
12
|
+
return null;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export { Router };
|
|
16
|
+
//# sourceMappingURL=Router.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Router.esm.js","sources":["../../src/components/Router.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 from 'react';\nimport { Route, Routes } from 'react-router-dom';\n\nimport { useEntity } from '@backstage/plugin-catalog-react';\n\nimport { TektonCIComponent } from './Tekton/TektonCIComponent';\nimport { isTektonCIAvailable } from '../utils/isTektonCIAvailable';\n\n/** @public */\nexport const Router = () => {\n const { entity } = useEntity();\n if (isTektonCIAvailable(entity)) {\n return (\n <Routes>\n <Route path=\"/\" element={<TektonCIComponent />} />\n </Routes>\n );\n }\n return null;\n};\n"],"names":["React"],"mappings":";;;;;;AAwBO,MAAM,SAAS,MAAM;AAC1B,EAAM,MAAA,EAAE,MAAO,EAAA,GAAI,SAAU,EAAA;AAC7B,EAAI,IAAA,mBAAA,CAAoB,MAAM,CAAG,EAAA;AAC/B,IACE,uBAAAA,cAAA,CAAA,aAAA,CAAC,MACC,EAAA,IAAA,kBAAAA,cAAA,CAAA,aAAA,CAAC,KAAM,EAAA,EAAA,IAAA,EAAK,KAAI,OAAS,kBAAAA,cAAA,CAAA,aAAA,CAAC,iBAAkB,EAAA,IAAA,CAAA,EAAI,CAClD,CAAA;AAAA;AAGJ,EAAO,OAAA,IAAA;AACT;;;;"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { TektonResourcesContext } from '../../hooks/TektonResourcesContext.esm.js';
|
|
3
|
+
import { useDarkTheme } from '../../hooks/useDarkTheme.esm.js';
|
|
4
|
+
import { useTektonObjectsResponse } from '../../hooks/useTektonObjectsResponse.esm.js';
|
|
5
|
+
import { useTektonViewPermission } from '../../hooks/useTektonViewPermission.esm.js';
|
|
6
|
+
import { ModelsPlural } from '../../models.esm.js';
|
|
7
|
+
import PermissionAlert from '../common/PermissionAlert.esm.js';
|
|
8
|
+
import PipelineRunList from '../PipelineRunList/PipelineRunList.esm.js';
|
|
9
|
+
import '@patternfly/react-core/dist/styles/base.css';
|
|
10
|
+
import '@patternfly/patternfly/patternfly-theme-dark.css';
|
|
11
|
+
import '@patternfly/patternfly/patternfly-charts-theme-dark.css';
|
|
12
|
+
import '@patternfly/patternfly/utilities/Accessibility/accessibility.css';
|
|
13
|
+
|
|
14
|
+
const savedStylesheets = /* @__PURE__ */ new Set();
|
|
15
|
+
const TektonCIComponent = () => {
|
|
16
|
+
useDarkTheme();
|
|
17
|
+
React__default.useLayoutEffect(() => {
|
|
18
|
+
const scalprumStyles = Array.from(
|
|
19
|
+
document.querySelectorAll('link[rel="stylesheet"]')
|
|
20
|
+
).filter(
|
|
21
|
+
(link) => link.attributes.getNamedItem("href")?.value?.includes("backstage-plugin-tekton")
|
|
22
|
+
);
|
|
23
|
+
scalprumStyles.forEach(
|
|
24
|
+
(link) => savedStylesheets.add(link)
|
|
25
|
+
);
|
|
26
|
+
savedStylesheets.forEach((link) => {
|
|
27
|
+
if (!document.head.contains(link)) {
|
|
28
|
+
document.head.appendChild(link);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
return () => {
|
|
32
|
+
savedStylesheets.forEach((link) => {
|
|
33
|
+
if (document.head.contains(link)) {
|
|
34
|
+
document.head.removeChild(link);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
}, []);
|
|
39
|
+
const watchedResources = [
|
|
40
|
+
ModelsPlural.pipelineruns,
|
|
41
|
+
ModelsPlural.taskruns,
|
|
42
|
+
ModelsPlural.pods
|
|
43
|
+
];
|
|
44
|
+
const tektonResourcesContextData = useTektonObjectsResponse(watchedResources);
|
|
45
|
+
const hasViewPermission = useTektonViewPermission();
|
|
46
|
+
if (!hasViewPermission) {
|
|
47
|
+
return /* @__PURE__ */ React__default.createElement(PermissionAlert, null);
|
|
48
|
+
}
|
|
49
|
+
return /* @__PURE__ */ React__default.createElement(TektonResourcesContext.Provider, { value: tektonResourcesContextData }, /* @__PURE__ */ React__default.createElement(PipelineRunList, null));
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export { TektonCIComponent };
|
|
53
|
+
//# sourceMappingURL=TektonCIComponent.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TektonCIComponent.esm.js","sources":["../../../src/components/Tekton/TektonCIComponent.tsx"],"sourcesContent":["/*\n * Copyright 2024 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 from 'react';\n\nimport { TektonResourcesContext } from '../../hooks/TektonResourcesContext';\nimport { useDarkTheme } from '../../hooks/useDarkTheme';\nimport { useTektonObjectsResponse } from '../../hooks/useTektonObjectsResponse';\nimport { useTektonViewPermission } from '../../hooks/useTektonViewPermission';\nimport { ModelsPlural } from '../../models';\nimport PermissionAlert from '../common/PermissionAlert';\nimport PipelineRunList from '../PipelineRunList/PipelineRunList';\n\nimport '@patternfly/react-core/dist/styles/base.css';\nimport '@patternfly/patternfly/patternfly-theme-dark.css';\nimport '@patternfly/patternfly/patternfly-charts-theme-dark.css';\nimport '@patternfly/patternfly/utilities/Accessibility/accessibility.css';\n\nconst savedStylesheets = new Set<HTMLLinkElement>();\n\nexport const TektonCIComponent = () => {\n useDarkTheme();\n\n React.useLayoutEffect(() => {\n const scalprumStyles = Array.from(\n document.querySelectorAll('link[rel=\"stylesheet\"]'),\n ).filter(link =>\n link.attributes\n .getNamedItem('href')\n ?.value?.includes('backstage-plugin-tekton'),\n );\n\n scalprumStyles.forEach(link =>\n savedStylesheets.add(link as HTMLLinkElement),\n );\n\n savedStylesheets.forEach(link => {\n if (!document.head.contains(link)) {\n document.head.appendChild(link);\n }\n });\n return () => {\n savedStylesheets.forEach(link => {\n if (document.head.contains(link)) {\n document.head.removeChild(link);\n }\n });\n };\n }, []);\n\n const watchedResources = [\n ModelsPlural.pipelineruns,\n ModelsPlural.taskruns,\n ModelsPlural.pods,\n ];\n const tektonResourcesContextData = useTektonObjectsResponse(watchedResources);\n const hasViewPermission = useTektonViewPermission();\n\n if (!hasViewPermission) {\n return <PermissionAlert />;\n }\n return (\n <TektonResourcesContext.Provider value={tektonResourcesContextData}>\n <PipelineRunList />\n </TektonResourcesContext.Provider>\n );\n};\n"],"names":["React"],"mappings":";;;;;;;;;;;;;AA8BA,MAAM,gBAAA,uBAAuB,GAAqB,EAAA;AAE3C,MAAM,oBAAoB,MAAM;AACrC,EAAa,YAAA,EAAA;AAEb,EAAAA,cAAA,CAAM,gBAAgB,MAAM;AAC1B,IAAA,MAAM,iBAAiB,KAAM,CAAA,IAAA;AAAA,MAC3B,QAAA,CAAS,iBAAiB,wBAAwB;AAAA,KAClD,CAAA,MAAA;AAAA,MAAO,CAAA,IAAA,KACP,KAAK,UACF,CAAA,YAAA,CAAa,MAAM,CAClB,EAAA,KAAA,EAAO,SAAS,yBAAyB;AAAA,KAC/C;AAEA,IAAe,cAAA,CAAA,OAAA;AAAA,MAAQ,CAAA,IAAA,KACrB,gBAAiB,CAAA,GAAA,CAAI,IAAuB;AAAA,KAC9C;AAEA,IAAA,gBAAA,CAAiB,QAAQ,CAAQ,IAAA,KAAA;AAC/B,MAAA,IAAI,CAAC,QAAA,CAAS,IAAK,CAAA,QAAA,CAAS,IAAI,CAAG,EAAA;AACjC,QAAS,QAAA,CAAA,IAAA,CAAK,YAAY,IAAI,CAAA;AAAA;AAChC,KACD,CAAA;AACD,IAAA,OAAO,MAAM;AACX,MAAA,gBAAA,CAAiB,QAAQ,CAAQ,IAAA,KAAA;AAC/B,QAAA,IAAI,QAAS,CAAA,IAAA,CAAK,QAAS,CAAA,IAAI,CAAG,EAAA;AAChC,UAAS,QAAA,CAAA,IAAA,CAAK,YAAY,IAAI,CAAA;AAAA;AAChC,OACD,CAAA;AAAA,KACH;AAAA,GACF,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,gBAAmB,GAAA;AAAA,IACvB,YAAa,CAAA,YAAA;AAAA,IACb,YAAa,CAAA,QAAA;AAAA,IACb,YAAa,CAAA;AAAA,GACf;AACA,EAAM,MAAA,0BAAA,GAA6B,yBAAyB,gBAAgB,CAAA;AAC5E,EAAA,MAAM,oBAAoB,uBAAwB,EAAA;AAElD,EAAA,IAAI,CAAC,iBAAmB,EAAA;AACtB,IAAA,oDAAQ,eAAgB,EAAA,IAAA,CAAA;AAAA;AAE1B,EACE,uBAAAA,cAAA,CAAA,aAAA,CAAC,uBAAuB,QAAvB,EAAA,EAAgC,OAAO,0BACtC,EAAA,kBAAAA,cAAA,CAAA,aAAA,CAAC,qBAAgB,CACnB,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import styleInject from '../../node_modules/style-inject/dist/style-inject.es.esm.js';
|
|
2
|
+
|
|
3
|
+
var css_248z = ".bs-tkn-cluster-selector {\n display: flex;\n align-items: center;\n}\n\n.bs-tkn-cluster-selector > div > div > div {\n margin-top: 0;\n}\n";
|
|
4
|
+
styleInject(css_248z);
|
|
5
|
+
|
|
6
|
+
export { css_248z as default };
|
|
7
|
+
//# sourceMappingURL=ClusterSelector.css.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClusterSelector.css.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
|