@spacelift-io/backstage-integration-frontend
Version:
Backstage plugin for integrating Spacelift.io with Backstage
145 lines (142 loc) • 5.14 kB
JavaScript
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
import { Table, MarkdownContent } from '@backstage/core-components';
import { useApi, configApiRef } from '@backstage/core-plugin-api';
import { makeStyles, Drawer, Box, DialogTitle, IconButton, Link, Chip, Tooltip, Typography } from '@material-ui/core';
import CloseIcon from '@material-ui/icons/Close';
import RepeatIcon from '@material-ui/icons/RepeatRounded';
import { useState } from 'react';
import { DESCRIPTION_DRAWER_WIDTH, ALLOW_RETRY_STATES, DESCRIPTION_TRUNCATE_LENGTH } from '../../constants.esm.js';
const useStyles = makeStyles((theme) => ({
neutral: {
backgroundColor: theme.palette.grey[500]
},
info: {
backgroundColor: theme.palette.info.main
},
success: {
backgroundColor: theme.palette.success.main
},
danger: {
backgroundColor: theme.palette.error.main
},
warning: {
backgroundColor: theme.palette.warning.main
}
}));
const renderState = (classes, state) => {
const stateToClass = {
APPLYING: classes.info,
CONFIRMED: classes.warning,
DESTROYING: classes.info,
DISCARDED: classes.danger,
FAILED: classes.danger,
FINISHED: classes.success,
INITIALIZING: classes.info,
NONE: classes.neutral,
PLANNING: classes.info,
PREPARING_APPLY: classes.info,
PREPARING_REPLAN: classes.info,
PREPARING: classes.info,
REPLAN_REQUESTED: classes.neutral,
STOPPED: classes.danger,
UNCONFIRMED: classes.warning
};
const className = stateToClass[state] || classes.neutral;
return /* @__PURE__ */ jsx(Chip, { size: "small", label: state, className });
};
const renderDescription = (description, onExpand) => {
if (!description) return /* @__PURE__ */ jsx("span", { children: "-" });
return description.length > DESCRIPTION_TRUNCATE_LENGTH ? /* @__PURE__ */ jsxs(Typography, { variant: "inherit", onClick: () => onExpand(description), children: [
description.slice(0, DESCRIPTION_TRUNCATE_LENGTH),
" ..."
] }) : description;
};
const SpaceliftStacksTable = ({
stacks,
loading,
triggerRun
}) => {
const [description, setDescription] = useState(null);
const classes = useStyles();
const config = useApi(configApiRef);
const hostUrl = config.getString("spacelift.hostUrl");
const columns = [
{
title: "Name",
field: "name",
highlight: true,
render: (row) => /* @__PURE__ */ jsx(Link, { href: `https://${hostUrl}/stack/${row.id}`, target: "_blank", children: row.name })
},
{
title: "Description",
field: "description",
render: (row) => renderDescription(row.description, setDescription)
},
{
title: "Labels",
field: "labels",
render: (row) => {
if (!row.labels.length) return /* @__PURE__ */ jsx("span", { children: "-" });
return /* @__PURE__ */ jsx(Box, { display: "flex", flexWrap: "wrap", children: row.labels.map((label) => /* @__PURE__ */ jsx(Chip, { label, style: { margin: "0.25rem" }, size: "small" }, label)) });
}
},
{
title: "Current State",
render: (row) => renderState(classes, row.state)
},
{
title: "Branch",
field: "branch"
},
{
title: "Space",
render: (row) => /* @__PURE__ */ jsx(Link, { href: `https://${hostUrl}/spaces/${row.spaceDetails.name}`, target: "_blank", children: row.spaceDetails.name })
},
{
width: "30px",
render: (row) => {
const showAction = ALLOW_RETRY_STATES.includes(row.state);
if (!showAction) return null;
return /* @__PURE__ */ jsx(Tooltip, { title: "Trigger run", children: /* @__PURE__ */ jsx(IconButton, { onClick: () => triggerRun(row.id), children: /* @__PURE__ */ jsx(RepeatIcon, {}) }) });
}
}
];
return /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(
Table,
{
title: "Spacelift Stacks",
options: {
search: true,
paging: true,
pageSize: 20,
padding: "dense"
},
columns,
data: stacks,
isLoading: loading,
emptyContent: "No stacks found"
}
),
/* @__PURE__ */ jsxs(Drawer, { anchor: "right", open: !!description, onClose: () => setDescription(null), children: [
/* @__PURE__ */ jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", children: [
/* @__PURE__ */ jsx(
DialogTitle,
{
id: "dialog-title",
style: {
padding: "0 1rem",
display: "flex",
justifyContent: "space-between"
},
children: "Stack description"
}
),
/* @__PURE__ */ jsx(IconButton, { "aria-label": "close", onClick: () => setDescription(null), children: /* @__PURE__ */ jsx(CloseIcon, {}) })
] }),
/* @__PURE__ */ jsx(Box, { width: DESCRIPTION_DRAWER_WIDTH, padding: 2, style: { paddingTop: 0 }, children: /* @__PURE__ */ jsx(MarkdownContent, { content: description ?? "" }) })
] })
] });
};
export { SpaceliftStacksTable };
//# sourceMappingURL=SpaceliftStacksTable.esm.js.map