UNPKG

@spacelift-io/backstage-integration-frontend

Version:

Backstage plugin for integrating Spacelift.io with Backstage

145 lines (142 loc) 5.14 kB
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