@backstage-community/plugin-xcmetrics 0.2.53 → 0.2.55
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 +12 -0
- package/dist/{esm/index-DfJWmS4I.esm.js → api/XcmetricsClient.esm.js} +7 -50
- package/dist/api/XcmetricsClient.esm.js.map +1 -0
- package/dist/api/types.esm.js +8 -0
- package/dist/api/types.esm.js.map +1 -0
- package/dist/components/Accordion/Accordion.esm.js +43 -0
- package/dist/components/Accordion/Accordion.esm.js.map +1 -0
- package/dist/components/BuildDetails/BuildDetails.esm.js +139 -0
- package/dist/components/BuildDetails/BuildDetails.esm.js.map +1 -0
- package/dist/components/BuildList/BuildList.esm.js +73 -0
- package/dist/components/BuildList/BuildList.esm.js.map +1 -0
- package/dist/components/BuildListFilter/BuildListFilter.esm.js +124 -0
- package/dist/components/BuildListFilter/BuildListFilter.esm.js.map +1 -0
- package/dist/components/BuildTableColumns.esm.js +61 -0
- package/dist/components/BuildTableColumns.esm.js.map +1 -0
- package/dist/components/BuildTimeline/BuildTimeline.esm.js +67 -0
- package/dist/components/BuildTimeline/BuildTimeline.esm.js.map +1 -0
- package/dist/components/DataValue/DataValue.esm.js +11 -0
- package/dist/components/DataValue/DataValue.esm.js.map +1 -0
- package/dist/components/DatePicker/DatePicker.esm.js +59 -0
- package/dist/components/DatePicker/DatePicker.esm.js.map +1 -0
- package/dist/components/Overview/Overview.esm.js +53 -0
- package/dist/components/Overview/Overview.esm.js.map +1 -0
- package/dist/components/OverviewTrends/OverviewTrends.esm.js +132 -0
- package/dist/components/OverviewTrends/OverviewTrends.esm.js.map +1 -0
- package/dist/components/PreformattedText/PreformattedText.esm.js +81 -0
- package/dist/components/PreformattedText/PreformattedText.esm.js.map +1 -0
- package/dist/components/StatusCell/StatusCell.esm.js +79 -0
- package/dist/components/StatusCell/StatusCell.esm.js.map +1 -0
- package/dist/components/StatusIcon/StatusIcon.esm.js +12 -0
- package/dist/components/StatusIcon/StatusIcon.esm.js.map +1 -0
- package/dist/components/StatusMatrix/StatusMatrix.esm.js +68 -0
- package/dist/components/StatusMatrix/StatusMatrix.esm.js.map +1 -0
- package/dist/components/Trend/Trend.esm.js +20 -0
- package/dist/components/Trend/Trend.esm.js.map +1 -0
- package/dist/components/XcmetricsLayout/XcmetricsLayout.esm.js +22 -0
- package/dist/components/XcmetricsLayout/XcmetricsLayout.esm.js.map +1 -0
- package/dist/components/XcmetricsLayout/index.esm.js +2 -0
- package/dist/components/XcmetricsLayout/index.esm.js.map +1 -0
- package/dist/index.esm.js +1 -4
- package/dist/index.esm.js.map +1 -1
- package/dist/plugin.esm.js +33 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/routes.esm.js +13 -0
- package/dist/routes.esm.js.map +1 -0
- package/dist/utils/array.esm.js +12 -0
- package/dist/utils/array.esm.js.map +1 -0
- package/dist/utils/buildData.esm.js +21 -0
- package/dist/utils/buildData.esm.js.map +1 -0
- package/dist/utils/classnames.esm.js +5 -0
- package/dist/utils/classnames.esm.js.map +1 -0
- package/dist/utils/format.esm.js +30 -0
- package/dist/utils/format.esm.js.map +1 -0
- package/package.json +11 -7
- package/dist/esm/index-Dehp5p72.esm.js +0 -966
- package/dist/esm/index-Dehp5p72.esm.js.map +0 -1
- package/dist/esm/index-DfJWmS4I.esm.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusCell.esm.js","sources":["../../../src/components/StatusCell/StatusCell.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 Tooltip from '@material-ui/core/Tooltip';\nimport { makeStyles, Theme } from '@material-ui/core/styles';\nimport React from 'react';\nimport { BuildStatus, BuildStatusResult, xcmetricsApiRef } from '../../api';\nimport { cn, formatDuration, formatStatus } from '../../utils';\nimport useAsync from 'react-use/esm/useAsync';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { Progress } from '@backstage/core-components';\n\ninterface TooltipContentProps {\n buildId: string;\n}\n\nconst TooltipContent = ({ buildId }: TooltipContentProps) => {\n const client = useApi(xcmetricsApiRef);\n const { value, loading, error } = useAsync(\n async () => client.getBuild(buildId),\n [],\n );\n\n if (error) {\n return <div>{error.message}</div>;\n }\n\n if (loading || !value?.build) {\n return <Progress style={{ width: 100 }} />;\n }\n\n return (\n <table>\n <tbody>\n <tr>\n <td>Started</td>\n <td>{new Date(value.build.startTimestamp).toLocaleString()}</td>\n </tr>\n <tr>\n <td>Duration</td>\n <td>{formatDuration(value.build.duration)}</td>\n </tr>\n <tr>\n <td>Status</td>\n <td>{formatStatus(value.build.buildStatus)}</td>\n </tr>\n </tbody>\n </table>\n );\n};\n\ninterface StatusCellProps {\n buildStatus?: BuildStatusResult;\n size: number;\n spacing: number;\n}\n\ntype StatusStyle = {\n [key in BuildStatus]: any;\n};\n\nconst useStyles = makeStyles<Theme, StatusCellProps>(theme => ({\n root: {\n width: ({ size }) => size,\n height: ({ size }) => size,\n marginRight: ({ spacing }) => spacing,\n marginBottom: ({ spacing }) => spacing,\n backgroundColor: theme.palette.grey[600],\n '&:hover': {\n transform: 'scale(1.2)',\n },\n },\n ...({\n succeeded: {\n backgroundColor:\n theme.palette.type === 'light'\n ? theme.palette.success.light\n : theme.palette.success.main,\n },\n } as StatusStyle), // Make sure that key matches a status\n ...({\n failed: {\n backgroundColor: theme.palette.error[theme.palette.type],\n },\n } as StatusStyle),\n ...({\n stopped: {\n backgroundColor: theme.palette.warning[theme.palette.type],\n },\n } as StatusStyle),\n}));\n\nexport const StatusCell = (props: StatusCellProps) => {\n const classes = useStyles(props);\n const { buildStatus } = props;\n\n if (!buildStatus) {\n return <div className={classes.root} />;\n }\n\n return (\n <Tooltip\n title={<TooltipContent buildId={buildStatus.id} />}\n enterNextDelay={500}\n arrow\n >\n <div\n data-testid={buildStatus.id}\n className={cn(classes.root, classes[buildStatus.buildStatus])}\n />\n </Tooltip>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StatusAborted, StatusOK, StatusError, StatusWarning } from '@backstage/core-components';
|
|
3
|
+
|
|
4
|
+
const STATUS_ICONS = {
|
|
5
|
+
succeeded: /* @__PURE__ */ React.createElement(StatusOK, null),
|
|
6
|
+
failed: /* @__PURE__ */ React.createElement(StatusError, null),
|
|
7
|
+
stopped: /* @__PURE__ */ React.createElement(StatusWarning, null)
|
|
8
|
+
};
|
|
9
|
+
const StatusIcon = ({ buildStatus }) => STATUS_ICONS[buildStatus] ?? /* @__PURE__ */ React.createElement(StatusAborted, null);
|
|
10
|
+
|
|
11
|
+
export { StatusIcon };
|
|
12
|
+
//# sourceMappingURL=StatusIcon.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusIcon.esm.js","sources":["../../../src/components/StatusIcon/StatusIcon.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 React from 'react';\nimport {\n StatusAborted,\n StatusError,\n StatusOK,\n StatusWarning,\n} from '@backstage/core-components';\nimport { BuildStatus } from '../../api';\n\nconst STATUS_ICONS: { [key in BuildStatus]: JSX.Element } = {\n succeeded: <StatusOK />,\n failed: <StatusError />,\n stopped: <StatusWarning />,\n};\n\ninterface StatusIconProps {\n buildStatus: BuildStatus;\n}\n\nexport const StatusIcon = ({ buildStatus }: StatusIconProps) =>\n STATUS_ICONS[buildStatus] ?? <StatusAborted />;\n"],"names":[],"mappings":";;;AAwBA,MAAM,YAAsD,GAAA;AAAA,EAC1D,SAAA,sCAAY,QAAS,EAAA,IAAA,CAAA;AAAA,EACrB,MAAA,sCAAS,WAAY,EAAA,IAAA,CAAA;AAAA,EACrB,OAAA,sCAAU,aAAc,EAAA,IAAA,CAAA;AAC1B,CAAA,CAAA;AAMa,MAAA,UAAA,GAAa,CAAC,EAAE,WAAA,OAC3B,YAAa,CAAA,WAAW,CAAK,oBAAA,KAAA,CAAA,aAAA,CAAC,aAAc,EAAA,IAAA;;;;"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { makeStyles } from '@material-ui/core/styles';
|
|
3
|
+
import { xcmetricsApiRef } from '../../api/types.esm.js';
|
|
4
|
+
import '@backstage/errors';
|
|
5
|
+
import 'luxon';
|
|
6
|
+
import useAsync from 'react-use/esm/useAsync';
|
|
7
|
+
import useMeasure from 'react-use/esm/useMeasure';
|
|
8
|
+
import 'lodash/upperFirst';
|
|
9
|
+
import { cn } from '../../utils/classnames.esm.js';
|
|
10
|
+
import { useApi } from '@backstage/core-plugin-api';
|
|
11
|
+
import Alert from '@material-ui/lab/Alert';
|
|
12
|
+
import { StatusCell } from '../StatusCell/StatusCell.esm.js';
|
|
13
|
+
|
|
14
|
+
const CELL_SIZE = 12;
|
|
15
|
+
const CELL_MARGIN = 4;
|
|
16
|
+
const MAX_ROWS = 4;
|
|
17
|
+
const useStyles = makeStyles((theme) => ({
|
|
18
|
+
root: {
|
|
19
|
+
marginTop: 8,
|
|
20
|
+
display: "flex",
|
|
21
|
+
flexWrap: "wrap",
|
|
22
|
+
width: "100%"
|
|
23
|
+
},
|
|
24
|
+
loading: {
|
|
25
|
+
animation: `$loadingOpacity 900ms ${theme.transitions.easing.easeInOut}`,
|
|
26
|
+
animationIterationCount: "infinite"
|
|
27
|
+
},
|
|
28
|
+
"@keyframes loadingOpacity": {
|
|
29
|
+
"0%": { opacity: 0.3 },
|
|
30
|
+
"100%": { opacity: 0.8 }
|
|
31
|
+
}
|
|
32
|
+
}));
|
|
33
|
+
const StatusMatrix = () => {
|
|
34
|
+
const classes = useStyles();
|
|
35
|
+
const [measureRef, { width: rootWidth }] = useMeasure();
|
|
36
|
+
const client = useApi(xcmetricsApiRef);
|
|
37
|
+
const {
|
|
38
|
+
value: builds,
|
|
39
|
+
loading,
|
|
40
|
+
error
|
|
41
|
+
} = useAsync(async () => client.getBuildStatuses(300), []);
|
|
42
|
+
if (error) {
|
|
43
|
+
return /* @__PURE__ */ React.createElement(Alert, { severity: "error" }, error.message);
|
|
44
|
+
}
|
|
45
|
+
const cols = Math.trunc(rootWidth / (CELL_SIZE + CELL_MARGIN)) || 1;
|
|
46
|
+
return /* @__PURE__ */ React.createElement(
|
|
47
|
+
"div",
|
|
48
|
+
{
|
|
49
|
+
className: cn(classes.root, loading && classes.loading),
|
|
50
|
+
ref: measureRef
|
|
51
|
+
},
|
|
52
|
+
loading && [...new Array(cols * MAX_ROWS)].map((_, index) => {
|
|
53
|
+
return /* @__PURE__ */ React.createElement(StatusCell, { key: index, size: CELL_SIZE, spacing: CELL_MARGIN });
|
|
54
|
+
}),
|
|
55
|
+
builds && builds.slice(0, cols * MAX_ROWS).map((buildStatus, index) => /* @__PURE__ */ React.createElement(
|
|
56
|
+
StatusCell,
|
|
57
|
+
{
|
|
58
|
+
key: index,
|
|
59
|
+
buildStatus,
|
|
60
|
+
size: CELL_SIZE,
|
|
61
|
+
spacing: CELL_MARGIN
|
|
62
|
+
}
|
|
63
|
+
))
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export { StatusMatrix };
|
|
68
|
+
//# sourceMappingURL=StatusMatrix.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusMatrix.esm.js","sources":["../../../src/components/StatusMatrix/StatusMatrix.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 React from 'react';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { xcmetricsApiRef } from '../../api';\nimport useAsync from 'react-use/esm/useAsync';\nimport useMeasure from 'react-use/esm/useMeasure';\nimport { cn } from '../../utils';\nimport { useApi } from '@backstage/core-plugin-api';\nimport Alert from '@material-ui/lab/Alert';\nimport { StatusCell } from '../StatusCell';\n\nconst CELL_SIZE = 12;\nconst CELL_MARGIN = 4;\nconst MAX_ROWS = 4;\n\nconst useStyles = makeStyles(theme => ({\n root: {\n marginTop: 8,\n display: 'flex',\n flexWrap: 'wrap',\n width: '100%',\n },\n loading: {\n animation: `$loadingOpacity 900ms ${theme.transitions.easing.easeInOut}`,\n animationIterationCount: 'infinite',\n },\n '@keyframes loadingOpacity': {\n '0%': { opacity: 0.3 },\n '100%': { opacity: 0.8 },\n },\n}));\n\nexport const StatusMatrix = () => {\n const classes = useStyles();\n const [measureRef, { width: rootWidth }] = useMeasure<HTMLDivElement>();\n const client = useApi(xcmetricsApiRef);\n const {\n value: builds,\n loading,\n error,\n } = useAsync(async () => client.getBuildStatuses(300), []);\n\n if (error) {\n return <Alert severity=\"error\">{error.message}</Alert>;\n }\n\n const cols = Math.trunc(rootWidth / (CELL_SIZE + CELL_MARGIN)) || 1;\n\n return (\n <div\n className={cn(classes.root, loading && classes.loading)}\n ref={measureRef}\n >\n {loading &&\n [...new Array(cols * MAX_ROWS)].map((_, index) => {\n return (\n <StatusCell key={index} size={CELL_SIZE} spacing={CELL_MARGIN} />\n );\n })}\n\n {builds &&\n builds\n .slice(0, cols * MAX_ROWS)\n .map((buildStatus, index) => (\n <StatusCell\n key={index}\n buildStatus={buildStatus}\n size={CELL_SIZE}\n spacing={CELL_MARGIN}\n />\n ))}\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;AA0BA,MAAM,SAAY,GAAA,EAAA,CAAA;AAClB,MAAM,WAAc,GAAA,CAAA,CAAA;AACpB,MAAM,QAAW,GAAA,CAAA,CAAA;AAEjB,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,IAAM,EAAA;AAAA,IACJ,SAAW,EAAA,CAAA;AAAA,IACX,OAAS,EAAA,MAAA;AAAA,IACT,QAAU,EAAA,MAAA;AAAA,IACV,KAAO,EAAA,MAAA;AAAA,GACT;AAAA,EACA,OAAS,EAAA;AAAA,IACP,SAAW,EAAA,CAAA,sBAAA,EAAyB,KAAM,CAAA,WAAA,CAAY,OAAO,SAAS,CAAA,CAAA;AAAA,IACtE,uBAAyB,EAAA,UAAA;AAAA,GAC3B;AAAA,EACA,2BAA6B,EAAA;AAAA,IAC3B,IAAA,EAAM,EAAE,OAAA,EAAS,GAAI,EAAA;AAAA,IACrB,MAAA,EAAQ,EAAE,OAAA,EAAS,GAAI,EAAA;AAAA,GACzB;AACF,CAAE,CAAA,CAAA,CAAA;AAEK,MAAM,eAAe,MAAM;AAChC,EAAA,MAAM,UAAU,SAAU,EAAA,CAAA;AAC1B,EAAA,MAAM,CAAC,UAAY,EAAA,EAAE,OAAO,SAAU,EAAC,IAAI,UAA2B,EAAA,CAAA;AACtE,EAAM,MAAA,MAAA,GAAS,OAAO,eAAe,CAAA,CAAA;AACrC,EAAM,MAAA;AAAA,IACJ,KAAO,EAAA,MAAA;AAAA,IACP,OAAA;AAAA,IACA,KAAA;AAAA,GACF,GAAI,SAAS,YAAY,MAAA,CAAO,iBAAiB,GAAG,CAAA,EAAG,EAAE,CAAA,CAAA;AAEzD,EAAA,IAAI,KAAO,EAAA;AACT,IAAA,uBAAQ,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAM,QAAS,EAAA,OAAA,EAAA,EAAS,MAAM,OAAQ,CAAA,CAAA;AAAA,GAChD;AAEA,EAAA,MAAM,OAAO,IAAK,CAAA,KAAA,CAAM,SAAa,IAAA,SAAA,GAAY,YAAY,CAAK,IAAA,CAAA,CAAA;AAElE,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAW,EAAG,CAAA,OAAA,CAAQ,IAAM,EAAA,OAAA,IAAW,QAAQ,OAAO,CAAA;AAAA,MACtD,GAAK,EAAA,UAAA;AAAA,KAAA;AAAA,IAEJ,OACC,IAAA,CAAC,GAAG,IAAI,KAAM,CAAA,IAAA,GAAO,QAAQ,CAAC,CAAE,CAAA,GAAA,CAAI,CAAC,CAAA,EAAG,KAAU,KAAA;AAChD,MAAA,2CACG,UAAW,EAAA,EAAA,GAAA,EAAK,OAAO,IAAM,EAAA,SAAA,EAAW,SAAS,WAAa,EAAA,CAAA,CAAA;AAAA,KAElE,CAAA;AAAA,IAEF,MAAA,IACC,MACG,CAAA,KAAA,CAAM,CAAG,EAAA,IAAA,GAAO,QAAQ,CACxB,CAAA,GAAA,CAAI,CAAC,WAAA,EAAa,KACjB,qBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,GAAK,EAAA,KAAA;AAAA,QACL,WAAA;AAAA,QACA,IAAM,EAAA,SAAA;AAAA,QACN,OAAS,EAAA,WAAA;AAAA,OAAA;AAAA,KAEZ,CAAA;AAAA,GACP,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { TrendLine } from '@backstage/core-components';
|
|
3
|
+
import Typography from '@material-ui/core/Typography';
|
|
4
|
+
|
|
5
|
+
const Trend = ({ data, title, color }) => {
|
|
6
|
+
const emptyData = [0, 0];
|
|
7
|
+
const max = Math.max(...data ?? emptyData);
|
|
8
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Typography, { variant: "overline" }, title), /* @__PURE__ */ React.createElement(
|
|
9
|
+
TrendLine,
|
|
10
|
+
{
|
|
11
|
+
data: data ?? emptyData,
|
|
12
|
+
title,
|
|
13
|
+
max,
|
|
14
|
+
color: data && color
|
|
15
|
+
}
|
|
16
|
+
));
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export { Trend };
|
|
20
|
+
//# sourceMappingURL=Trend.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Trend.esm.js","sources":["../../../src/components/Trend/Trend.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 React from 'react';\nimport { TrendLine } from '@backstage/core-components';\nimport Typography from '@material-ui/core/Typography';\n\ninterface TrendProps {\n data?: number[];\n title: string;\n color: string;\n}\n\nexport const Trend = ({ data, title, color }: TrendProps) => {\n const emptyData = [0, 0];\n const max = Math.max(...(data ?? emptyData));\n\n return (\n <>\n <Typography variant=\"overline\">{title}</Typography>\n <TrendLine\n data={data ?? emptyData}\n title={title}\n max={max}\n color={data && color}\n />\n </>\n );\n};\n"],"names":[],"mappings":";;;;AAyBO,MAAM,QAAQ,CAAC,EAAE,IAAM,EAAA,KAAA,EAAO,OAAwB,KAAA;AAC3D,EAAM,MAAA,SAAA,GAAY,CAAC,CAAA,EAAG,CAAC,CAAA,CAAA;AACvB,EAAA,MAAM,GAAM,GAAA,IAAA,CAAK,GAAI,CAAA,GAAI,QAAQ,SAAU,CAAA,CAAA;AAE3C,EAAA,iFAEK,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,OAAQ,EAAA,UAAA,EAAA,EAAY,KAAM,CACtC,kBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,MAAM,IAAQ,IAAA,SAAA;AAAA,MACd,KAAA;AAAA,MACA,GAAA;AAAA,MACA,OAAO,IAAQ,IAAA,KAAA;AAAA,KAAA;AAAA,GAEnB,CAAA,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Page, Header, HeaderLabel, TabbedLayout, Content } from '@backstage/core-components';
|
|
3
|
+
import { Overview } from '../Overview/Overview.esm.js';
|
|
4
|
+
import { buildsRouteRef } from '../../routes.esm.js';
|
|
5
|
+
import { BuildList } from '../BuildList/BuildList.esm.js';
|
|
6
|
+
|
|
7
|
+
const TABS = [
|
|
8
|
+
{
|
|
9
|
+
path: "/",
|
|
10
|
+
title: "Overview",
|
|
11
|
+
component: /* @__PURE__ */ React.createElement(Overview, null)
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
path: buildsRouteRef.path,
|
|
15
|
+
title: "Builds",
|
|
16
|
+
component: /* @__PURE__ */ React.createElement(BuildList, null)
|
|
17
|
+
}
|
|
18
|
+
];
|
|
19
|
+
const XcmetricsLayout = () => /* @__PURE__ */ React.createElement(Page, { themeId: "tool" }, /* @__PURE__ */ React.createElement(Header, { title: "XCMetrics", subtitle: "Dashboard" }, /* @__PURE__ */ React.createElement(HeaderLabel, { label: "Owner", value: "Spotify" }), /* @__PURE__ */ React.createElement(HeaderLabel, { label: "Lifecycle", value: "Alpha" })), /* @__PURE__ */ React.createElement(TabbedLayout, null, TABS.map((tab) => /* @__PURE__ */ React.createElement(TabbedLayout.Route, { key: tab.path, path: tab.path, title: tab.title }, /* @__PURE__ */ React.createElement(Content, null, tab.component)))));
|
|
20
|
+
|
|
21
|
+
export { XcmetricsLayout };
|
|
22
|
+
//# sourceMappingURL=XcmetricsLayout.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"XcmetricsLayout.esm.js","sources":["../../../src/components/XcmetricsLayout/XcmetricsLayout.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 React, { ReactChild } from 'react';\nimport {\n Content,\n Header,\n HeaderLabel,\n Page,\n TabbedLayout,\n} from '@backstage/core-components';\nimport { Overview } from '../Overview';\nimport { buildsRouteRef } from '../../routes';\nimport { BuildList } from '../BuildList';\n\nexport interface TabConfig {\n path: string;\n title: string;\n component: ReactChild;\n}\n\nconst TABS: TabConfig[] = [\n {\n path: '/',\n title: 'Overview',\n component: <Overview />,\n },\n {\n path: buildsRouteRef.path,\n title: 'Builds',\n component: <BuildList />,\n },\n];\n\nexport const XcmetricsLayout = () => (\n <Page themeId=\"tool\">\n <Header title=\"XCMetrics\" subtitle=\"Dashboard\">\n <HeaderLabel label=\"Owner\" value=\"Spotify\" />\n <HeaderLabel label=\"Lifecycle\" value=\"Alpha\" />\n </Header>\n <TabbedLayout>\n {TABS.map(tab => (\n <TabbedLayout.Route key={tab.path} path={tab.path} title={tab.title}>\n <Content>{tab.component}</Content>\n </TabbedLayout.Route>\n ))}\n </TabbedLayout>\n </Page>\n);\n"],"names":[],"mappings":";;;;;;AAiCA,MAAM,IAAoB,GAAA;AAAA,EACxB;AAAA,IACE,IAAM,EAAA,GAAA;AAAA,IACN,KAAO,EAAA,UAAA;AAAA,IACP,SAAA,sCAAY,QAAS,EAAA,IAAA,CAAA;AAAA,GACvB;AAAA,EACA;AAAA,IACE,MAAM,cAAe,CAAA,IAAA;AAAA,IACrB,KAAO,EAAA,QAAA;AAAA,IACP,SAAA,sCAAY,SAAU,EAAA,IAAA,CAAA;AAAA,GACxB;AACF,CAAA,CAAA;AAEa,MAAA,eAAA,GAAkB,sBAC7B,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,OAAA,EAAQ,0BACX,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,EAAO,KAAM,EAAA,WAAA,EAAY,QAAS,EAAA,WAAA,EAAA,sCAChC,WAAY,EAAA,EAAA,KAAA,EAAM,OAAQ,EAAA,KAAA,EAAM,SAAU,EAAA,CAAA,sCAC1C,WAAY,EAAA,EAAA,KAAA,EAAM,WAAY,EAAA,KAAA,EAAM,OAAQ,EAAA,CAC/C,mBACC,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA,IAAA,EACE,IAAK,CAAA,GAAA,CAAI,CACR,GAAA,qBAAA,KAAA,CAAA,aAAA,CAAC,aAAa,KAAb,EAAA,EAAmB,GAAK,EAAA,GAAA,CAAI,IAAM,EAAA,IAAA,EAAM,IAAI,IAAM,EAAA,KAAA,EAAO,GAAI,CAAA,KAAA,EAAA,kBAC3D,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA,IAAA,EAAS,IAAI,SAAU,CAC1B,CACD,CACH,CACF;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
export {
|
|
2
|
-
import '@backstage/core-plugin-api';
|
|
3
|
-
import '@backstage/errors';
|
|
4
|
-
import 'luxon';
|
|
1
|
+
export { XcmetricsPage, xcmetricsPlugin } from './plugin.esm.js';
|
|
5
2
|
//# sourceMappingURL=index.esm.js.map
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createPlugin, createApiFactory, discoveryApiRef, fetchApiRef, createRoutableExtension } from '@backstage/core-plugin-api';
|
|
2
|
+
import { xcmetricsApiRef } from './api/types.esm.js';
|
|
3
|
+
import { XcmetricsClient } from './api/XcmetricsClient.esm.js';
|
|
4
|
+
import { rootRouteRef } from './routes.esm.js';
|
|
5
|
+
|
|
6
|
+
const xcmetricsPlugin = createPlugin({
|
|
7
|
+
id: "xcmetrics",
|
|
8
|
+
routes: {
|
|
9
|
+
root: rootRouteRef
|
|
10
|
+
},
|
|
11
|
+
apis: [
|
|
12
|
+
createApiFactory({
|
|
13
|
+
api: xcmetricsApiRef,
|
|
14
|
+
deps: {
|
|
15
|
+
discoveryApi: discoveryApiRef,
|
|
16
|
+
fetchApi: fetchApiRef
|
|
17
|
+
},
|
|
18
|
+
factory({ discoveryApi, fetchApi }) {
|
|
19
|
+
return new XcmetricsClient({ discoveryApi, fetchApi });
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
]
|
|
23
|
+
});
|
|
24
|
+
const XcmetricsPage = xcmetricsPlugin.provide(
|
|
25
|
+
createRoutableExtension({
|
|
26
|
+
name: "XcmetricsPage",
|
|
27
|
+
component: () => import('./components/XcmetricsLayout/index.esm.js').then((m) => m.XcmetricsLayout),
|
|
28
|
+
mountPoint: rootRouteRef
|
|
29
|
+
})
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
export { XcmetricsPage, xcmetricsPlugin };
|
|
33
|
+
//# sourceMappingURL=plugin.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.esm.js","sources":["../src/plugin.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 createApiFactory,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n fetchApiRef,\n} from '@backstage/core-plugin-api';\nimport { xcmetricsApiRef, XcmetricsClient } from './api';\nimport { rootRouteRef } from './routes';\n\n/** @public */\nexport const xcmetricsPlugin = createPlugin({\n id: 'xcmetrics',\n routes: {\n root: rootRouteRef,\n },\n apis: [\n createApiFactory({\n api: xcmetricsApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n },\n factory({ discoveryApi, fetchApi }) {\n return new XcmetricsClient({ discoveryApi, fetchApi });\n },\n }),\n ],\n});\n\n/** @public */\nexport const XcmetricsPage = xcmetricsPlugin.provide(\n createRoutableExtension({\n name: 'XcmetricsPage',\n component: () =>\n import('./components/XcmetricsLayout').then(m => m.XcmetricsLayout),\n mountPoint: rootRouteRef,\n }),\n);\n"],"names":[],"mappings":";;;;;AA2BO,MAAM,kBAAkB,YAAa,CAAA;AAAA,EAC1C,EAAI,EAAA,WAAA;AAAA,EACJ,MAAQ,EAAA;AAAA,IACN,IAAM,EAAA,YAAA;AAAA,GACR;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,gBAAiB,CAAA;AAAA,MACf,GAAK,EAAA,eAAA;AAAA,MACL,IAAM,EAAA;AAAA,QACJ,YAAc,EAAA,eAAA;AAAA,QACd,QAAU,EAAA,WAAA;AAAA,OACZ;AAAA,MACA,OAAQ,CAAA,EAAE,YAAc,EAAA,QAAA,EAAY,EAAA;AAClC,QAAA,OAAO,IAAI,eAAA,CAAgB,EAAE,YAAA,EAAc,UAAU,CAAA,CAAA;AAAA,OACvD;AAAA,KACD,CAAA;AAAA,GACH;AACF,CAAC,EAAA;AAGM,MAAM,gBAAgB,eAAgB,CAAA,OAAA;AAAA,EAC3C,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,eAAA;AAAA,IACN,SAAA,EAAW,MACT,OAAO,2CAA8B,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,eAAe,CAAA;AAAA,IACpE,UAAY,EAAA,YAAA;AAAA,GACb,CAAA;AACH;;;;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createRouteRef, createSubRouteRef } from '@backstage/core-plugin-api';
|
|
2
|
+
|
|
3
|
+
const rootRouteRef = createRouteRef({
|
|
4
|
+
id: "xcmetrics"
|
|
5
|
+
});
|
|
6
|
+
const buildsRouteRef = createSubRouteRef({
|
|
7
|
+
id: "xcmetrics-builds",
|
|
8
|
+
parent: rootRouteRef,
|
|
9
|
+
path: "/builds"
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export { buildsRouteRef, rootRouteRef };
|
|
13
|
+
//# sourceMappingURL=routes.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.esm.js","sources":["../src/routes.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 */\nimport { createRouteRef, createSubRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'xcmetrics',\n});\n\nexport const buildsRouteRef = createSubRouteRef({\n id: 'xcmetrics-builds',\n parent: rootRouteRef,\n path: '/builds',\n});\n"],"names":[],"mappings":";;AAiBO,MAAM,eAAe,cAAe,CAAA;AAAA,EACzC,EAAI,EAAA,WAAA;AACN,CAAC,EAAA;AAEM,MAAM,iBAAiB,iBAAkB,CAAA;AAAA,EAC9C,EAAI,EAAA,kBAAA;AAAA,EACJ,MAAQ,EAAA,YAAA;AAAA,EACR,IAAM,EAAA,SAAA;AACR,CAAC;;;;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const sumField = (field, arr) => {
|
|
2
|
+
return arr?.reduce((sum, current) => sum + field(current), 0);
|
|
3
|
+
};
|
|
4
|
+
const getValues = (field, arr) => {
|
|
5
|
+
if (!arr?.length) {
|
|
6
|
+
return void 0;
|
|
7
|
+
}
|
|
8
|
+
return arr.map((element) => field(element));
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export { getValues, sumField };
|
|
12
|
+
//# sourceMappingURL=array.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"array.esm.js","sources":["../../src/utils/array.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\nexport const sumField = <T extends {}>(\n field: (element: T) => number,\n arr?: T[],\n) => {\n return arr?.reduce((sum, current) => sum + field(current), 0);\n};\n\nexport const getValues = <T extends {}>(\n field: (element: T) => number,\n arr?: T[],\n) => {\n if (!arr?.length) {\n return undefined;\n }\n\n return arr.map(element => field(element));\n};\n"],"names":[],"mappings":"AAgBa,MAAA,QAAA,GAAW,CACtB,KAAA,EACA,GACG,KAAA;AACH,EAAO,OAAA,GAAA,EAAK,OAAO,CAAC,GAAA,EAAK,YAAY,GAAM,GAAA,KAAA,CAAM,OAAO,CAAA,EAAG,CAAC,CAAA,CAAA;AAC9D,EAAA;AAEa,MAAA,SAAA,GAAY,CACvB,KAAA,EACA,GACG,KAAA;AACH,EAAI,IAAA,CAAC,KAAK,MAAQ,EAAA;AAChB,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACT;AAEA,EAAA,OAAO,GAAI,CAAA,GAAA,CAAI,CAAW,OAAA,KAAA,KAAA,CAAM,OAAO,CAAC,CAAA,CAAA;AAC1C;;;;"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { formatDuration } from './format.esm.js';
|
|
2
|
+
|
|
3
|
+
const getErrorRatios = (buildCounts) => {
|
|
4
|
+
if (!buildCounts?.length) {
|
|
5
|
+
return void 0;
|
|
6
|
+
}
|
|
7
|
+
return buildCounts.map(
|
|
8
|
+
(counts) => counts.builds === 0 ? 0 : counts.errors / counts.builds
|
|
9
|
+
);
|
|
10
|
+
};
|
|
11
|
+
const getAverageDuration = (buildTimes, field) => {
|
|
12
|
+
if (!buildTimes?.length) {
|
|
13
|
+
return void 0;
|
|
14
|
+
}
|
|
15
|
+
return formatDuration(
|
|
16
|
+
buildTimes.reduce((sum, current) => sum + field(current), 0) / buildTimes.length
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export { getAverageDuration, getErrorRatios };
|
|
21
|
+
//# sourceMappingURL=buildData.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildData.esm.js","sources":["../../src/utils/buildData.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 { formatDuration } from './format';\nimport { BuildCount, BuildTime } from '../api';\n\nexport const getErrorRatios = (buildCounts?: BuildCount[]) => {\n if (!buildCounts?.length) {\n return undefined;\n }\n\n return buildCounts.map(counts =>\n counts.builds === 0 ? 0 : counts.errors / counts.builds,\n );\n};\n\nexport const getAverageDuration = (\n buildTimes: BuildTime[] | undefined,\n field: (b: BuildTime) => number,\n) => {\n if (!buildTimes?.length) {\n return undefined;\n }\n\n return formatDuration(\n buildTimes.reduce((sum, current) => sum + field(current), 0) /\n buildTimes.length,\n );\n};\n"],"names":[],"mappings":";;AAmBa,MAAA,cAAA,GAAiB,CAAC,WAA+B,KAAA;AAC5D,EAAI,IAAA,CAAC,aAAa,MAAQ,EAAA;AACxB,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACT;AAEA,EAAA,OAAO,WAAY,CAAA,GAAA;AAAA,IAAI,YACrB,MAAO,CAAA,MAAA,KAAW,IAAI,CAAI,GAAA,MAAA,CAAO,SAAS,MAAO,CAAA,MAAA;AAAA,GACnD,CAAA;AACF,EAAA;AAEa,MAAA,kBAAA,GAAqB,CAChC,UAAA,EACA,KACG,KAAA;AACH,EAAI,IAAA,CAAC,YAAY,MAAQ,EAAA;AACvB,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACT;AAEA,EAAO,OAAA,cAAA;AAAA,IACL,UAAA,CAAW,MAAO,CAAA,CAAC,GAAK,EAAA,OAAA,KAAY,GAAM,GAAA,KAAA,CAAM,OAAO,CAAA,EAAG,CAAC,CAAA,GACzD,UAAW,CAAA,MAAA;AAAA,GACf,CAAA;AACF;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classnames.esm.js","sources":["../../src/utils/classnames.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\ntype ClassName = string | false | undefined | null;\n\nexport const classNames = (...args: ClassName[]) =>\n args.filter(c => !!c).join(' ');\n\nexport const cn = classNames;\n"],"names":[],"mappings":"AAkBa,MAAA,UAAA,GAAa,CAAI,GAAA,IAAA,KAC5B,IAAK,CAAA,MAAA,CAAO,CAAK,CAAA,KAAA,CAAC,CAAC,CAAC,CAAE,CAAA,IAAA,CAAK,GAAG,EAAA;AAEzB,MAAM,EAAK,GAAA;;;;"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Duration, DateTime } from 'luxon';
|
|
2
|
+
import upperFirst from 'lodash/upperFirst';
|
|
3
|
+
|
|
4
|
+
const formatDuration = (seconds) => {
|
|
5
|
+
const duration = Duration.fromObject({
|
|
6
|
+
seconds
|
|
7
|
+
}).shiftTo("hours", "minutes", "seconds", "milliseconds");
|
|
8
|
+
if (duration.hours + duration.minutes + duration.seconds === 0) {
|
|
9
|
+
return `${Math.round(duration.milliseconds)} ms`;
|
|
10
|
+
}
|
|
11
|
+
const h = duration.hours ? `${duration.hours} h` : "";
|
|
12
|
+
const m = duration.minutes ? `${duration.minutes} m` : "";
|
|
13
|
+
const s = duration.hours < 12 ? `${duration.seconds ?? 0} s` : "";
|
|
14
|
+
return `${h} ${m} ${s}`;
|
|
15
|
+
};
|
|
16
|
+
const formatSecondsInterval = ([start, end]) => {
|
|
17
|
+
return `${Math.round(start * 100) / 100} s - ${Math.round(end * 100) / 100} s`;
|
|
18
|
+
};
|
|
19
|
+
const formatTime = (timestamp) => {
|
|
20
|
+
return DateTime.fromISO(timestamp).toLocaleString(
|
|
21
|
+
DateTime.DATETIME_SHORT_WITH_SECONDS
|
|
22
|
+
);
|
|
23
|
+
};
|
|
24
|
+
const formatPercentage = (number) => {
|
|
25
|
+
return `${Math.round(number * 100)} %`;
|
|
26
|
+
};
|
|
27
|
+
const formatStatus = (status) => upperFirst(status);
|
|
28
|
+
|
|
29
|
+
export { formatDuration, formatPercentage, formatSecondsInterval, formatStatus, formatTime };
|
|
30
|
+
//# sourceMappingURL=format.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.esm.js","sources":["../../src/utils/format.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 */\nimport { DateTime, Duration } from 'luxon';\nimport { BuildStatus } from '../api';\nimport upperFirst from 'lodash/upperFirst';\n\nexport const formatDuration = (seconds: number) => {\n const duration = Duration.fromObject({\n seconds: seconds,\n }).shiftTo('hours', 'minutes', 'seconds', 'milliseconds');\n\n if (duration.hours + duration.minutes + duration.seconds === 0) {\n return `${Math.round(duration.milliseconds)} ms`;\n }\n\n const h = duration.hours ? `${duration.hours} h` : '';\n const m = duration.minutes ? `${duration.minutes} m` : '';\n const s = duration.hours < 12 ? `${duration.seconds ?? 0} s` : '';\n\n return `${h} ${m} ${s}`;\n};\n\nexport const formatSecondsInterval = ([start, end]: [number, number]) => {\n return `${Math.round(start * 100) / 100} s - ${\n Math.round(end * 100) / 100\n } s`;\n};\n\nexport const formatTime = (timestamp: string) => {\n return DateTime.fromISO(timestamp).toLocaleString(\n DateTime.DATETIME_SHORT_WITH_SECONDS,\n );\n};\n\nexport const formatPercentage = (number: number) => {\n return `${Math.round(number * 100)} %`;\n};\n\nexport const formatStatus = (status: BuildStatus) => upperFirst(status);\n"],"names":[],"mappings":";;;AAmBa,MAAA,cAAA,GAAiB,CAAC,OAAoB,KAAA;AACjD,EAAM,MAAA,QAAA,GAAW,SAAS,UAAW,CAAA;AAAA,IACnC,OAAA;AAAA,GACD,CAAE,CAAA,OAAA,CAAQ,OAAS,EAAA,SAAA,EAAW,WAAW,cAAc,CAAA,CAAA;AAExD,EAAA,IAAI,SAAS,KAAQ,GAAA,QAAA,CAAS,OAAU,GAAA,QAAA,CAAS,YAAY,CAAG,EAAA;AAC9D,IAAA,OAAO,CAAG,EAAA,IAAA,CAAK,KAAM,CAAA,QAAA,CAAS,YAAY,CAAC,CAAA,GAAA,CAAA,CAAA;AAAA,GAC7C;AAEA,EAAA,MAAM,IAAI,QAAS,CAAA,KAAA,GAAQ,CAAG,EAAA,QAAA,CAAS,KAAK,CAAO,EAAA,CAAA,GAAA,EAAA,CAAA;AACnD,EAAA,MAAM,IAAI,QAAS,CAAA,OAAA,GAAU,CAAG,EAAA,QAAA,CAAS,OAAO,CAAO,EAAA,CAAA,GAAA,EAAA,CAAA;AACvD,EAAM,MAAA,CAAA,GAAI,SAAS,KAAQ,GAAA,EAAA,GAAK,GAAG,QAAS,CAAA,OAAA,IAAW,CAAC,CAAO,EAAA,CAAA,GAAA,EAAA,CAAA;AAE/D,EAAA,OAAO,CAAG,EAAA,CAAC,CAAI,CAAA,EAAA,CAAC,IAAI,CAAC,CAAA,CAAA,CAAA;AACvB,EAAA;AAEO,MAAM,qBAAwB,GAAA,CAAC,CAAC,KAAA,EAAO,GAAG,CAAwB,KAAA;AACvE,EAAA,OAAO,CAAG,EAAA,IAAA,CAAK,KAAM,CAAA,KAAA,GAAQ,GAAG,CAAA,GAAI,GAAG,CAAA,KAAA,EACrC,IAAK,CAAA,KAAA,CAAM,GAAM,GAAA,GAAG,IAAI,GAC1B,CAAA,EAAA,CAAA,CAAA;AACF,EAAA;AAEa,MAAA,UAAA,GAAa,CAAC,SAAsB,KAAA;AAC/C,EAAO,OAAA,QAAA,CAAS,OAAQ,CAAA,SAAS,CAAE,CAAA,cAAA;AAAA,IACjC,QAAS,CAAA,2BAAA;AAAA,GACX,CAAA;AACF,EAAA;AAEa,MAAA,gBAAA,GAAmB,CAAC,MAAmB,KAAA;AAClD,EAAA,OAAO,CAAG,EAAA,IAAA,CAAK,KAAM,CAAA,MAAA,GAAS,GAAG,CAAC,CAAA,EAAA,CAAA,CAAA;AACpC,EAAA;AAEO,MAAM,YAAe,GAAA,CAAC,MAAwB,KAAA,UAAA,CAAW,MAAM;;;;"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage-community/plugin-xcmetrics",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.55",
|
|
4
4
|
"description": "A Backstage plugin that shows XCode build metrics for your components",
|
|
5
5
|
"backstage": {
|
|
6
|
-
"role": "frontend-plugin"
|
|
6
|
+
"role": "frontend-plugin",
|
|
7
|
+
"pluginId": "xcmetrics",
|
|
8
|
+
"pluginPackages": [
|
|
9
|
+
"@backstage-community/plugin-xcmetrics"
|
|
10
|
+
]
|
|
7
11
|
},
|
|
8
12
|
"publishConfig": {
|
|
9
13
|
"access": "public",
|
|
@@ -33,8 +37,8 @@
|
|
|
33
37
|
"test": "backstage-cli package test"
|
|
34
38
|
},
|
|
35
39
|
"dependencies": {
|
|
36
|
-
"@backstage/core-components": "^0.14.
|
|
37
|
-
"@backstage/core-plugin-api": "^1.9.
|
|
40
|
+
"@backstage/core-components": "^0.14.9",
|
|
41
|
+
"@backstage/core-plugin-api": "^1.9.3",
|
|
38
42
|
"@backstage/errors": "^1.2.4",
|
|
39
43
|
"@material-ui/core": "^4.12.2",
|
|
40
44
|
"@material-ui/icons": "^4.9.1",
|
|
@@ -46,9 +50,9 @@
|
|
|
46
50
|
"recharts": "^2.5.0"
|
|
47
51
|
},
|
|
48
52
|
"devDependencies": {
|
|
49
|
-
"@backstage/cli": "^0.26.
|
|
50
|
-
"@backstage/dev-utils": "^1.0.
|
|
51
|
-
"@backstage/test-utils": "^1.5.
|
|
53
|
+
"@backstage/cli": "^0.26.11",
|
|
54
|
+
"@backstage/dev-utils": "^1.0.36",
|
|
55
|
+
"@backstage/test-utils": "^1.5.9",
|
|
52
56
|
"@testing-library/dom": "^10.0.0",
|
|
53
57
|
"@testing-library/jest-dom": "^6.0.0",
|
|
54
58
|
"@testing-library/react": "^15.0.0",
|