UNPKG

@roadiehq/backstage-plugin-jira

Version:
284 lines (281 loc) 11.4 kB
import { jsxs, jsx, Fragment } from 'react/jsx-runtime'; import { useState, useEffect } from 'react'; import { makeStyles, createStyles, Box, IconButton, Menu, MenuItem, Checkbox, Button, Grid, Typography, Divider, TableContainer, Table, TableHead, TableRow, TableCell, TableBody, TablePagination, Avatar } from '@material-ui/core'; import Alert from '@material-ui/lab/Alert'; import { InfoCard, Progress } from '@backstage/core-components'; import { useEntity } from '@backstage/plugin-catalog-react'; import 'xml-js'; import 'luxon'; import 'uuid'; import { useAnalytics } from '@backstage/core-plugin-api'; import 'react-use'; import '../../api/index.esm.js'; import { useProjectInfo } from '../../hooks/useProjectInfo.esm.js'; import { useProjectEntity } from '../../hooks/useProjectEntity.esm.js'; import { Status } from './components/Status.esm.js'; import { ActivityStream } from '../EntityJiraActivityStreamCard/ActivityStream.esm.js'; import { Selectors } from './components/Selectors.esm.js'; import { useEmptyIssueTypeFilter } from '../../hooks/useEmptyIssueTypeFilter.esm.js'; import MoreVertIcon from '@material-ui/icons/MoreVert'; import ArrowForwardIcon from '@material-ui/icons/ArrowForward'; const useStyles = makeStyles( (theme) => createStyles({ infoCard: { marginBottom: theme.spacing(3), "& + .MuiAlert-root": { marginTop: theme.spacing(3) } }, root: { flexGrow: 1, fontSize: "0.75rem", "& > * + *": { marginTop: theme.spacing(1) } }, ticketLink: { color: theme.palette.link, textDecoration: "none", transition: "color 0.3s", "&:hover": { color: theme.palette.linkHover } } }) ); const CardProjectDetails = ({ project, component }) => /* @__PURE__ */ jsxs(Box, { display: "inline-flex", alignItems: "center", children: [ /* @__PURE__ */ jsx(Avatar, { alt: "", src: project.iconUrl }), /* @__PURE__ */ jsxs(Box, { ml: 1, children: [ project.name, " | ", project.type, component ? /* @__PURE__ */ jsxs(Box, { children: [ "component: ", component ] }) : null ] }) ] }); const JiraOverviewCard = (props) => { const { hideIssueFilter } = props; const { entity } = useEntity(); const classes = useStyles(); const analytics = useAnalytics(); const { projectKey, component, tokenType, label } = useProjectEntity(entity); const [statusesNames, setStatusesNames] = useState([]); const { project, issues, tickets, ticketIds, projectLoading, projectError, fetchProjectInfo } = useProjectInfo(projectKey, component, label, statusesNames); const { issueTypes: displayIssues, type, changeType } = useEmptyIssueTypeFilter(issues); const [anchorEl, setAnchorEl] = useState(null); const [page, setPage] = useState(0); const [rowsPerPage, setRowsPerPage] = useState(5); useEffect(() => { setPage(0); }, [tickets]); const handleClick = (event) => { setAnchorEl(event.currentTarget); }; const handleClose = () => { setAnchorEl(null); }; return /* @__PURE__ */ jsxs( InfoCard, { className: classes.infoCard, title: "Jira", subheader: project && /* @__PURE__ */ jsxs( Box, { display: "flex", justifyContent: "space-between", width: "100%", alignItems: "center", children: [ /* @__PURE__ */ jsxs(Box, { children: [ /* @__PURE__ */ jsx(CardProjectDetails, { project, component }), /* @__PURE__ */ jsxs(Box, { display: "inline-flex", pl: 1, children: [ /* @__PURE__ */ jsx( IconButton, { "aria-label": "more", "aria-controls": "long-menu", "aria-haspopup": "true", onClick: handleClick, children: /* @__PURE__ */ jsx(MoreVertIcon, {}) } ), /* @__PURE__ */ jsx( Menu, { id: "simple-menu", anchorEl, keepMounted: true, open: Boolean(anchorEl), onClose: handleClose, children: /* @__PURE__ */ jsxs(MenuItem, { onClick: changeType, children: [ /* @__PURE__ */ jsx(Checkbox, { checked: type === "all" }), /* @__PURE__ */ jsx(Fragment, { children: "Show empty issue types" }) ] }) } ) ] }) ] }), /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx( Button, { variant: "outlined", color: "primary", size: "medium", endIcon: /* @__PURE__ */ jsx(ArrowForwardIcon, {}), href: `${project?.url}/browse/${projectKey}`, target: "_blank", children: "Open in JIRA" } ) }) ] } ), children: [ projectLoading && !(project && issues) ? /* @__PURE__ */ jsx(Progress, {}) : null, projectError ? /* @__PURE__ */ jsx(Alert, { severity: "error", className: classes.infoCard, children: projectError.message }) : null, project && issues ? /* @__PURE__ */ jsxs("div", { className: classes.root, children: [ !hideIssueFilter && /* @__PURE__ */ jsx( Selectors, { projectKey, statusesNames, setStatusesNames, fetchProjectInfo } ), /* @__PURE__ */ jsx(Grid, { container: true, spacing: 3, children: displayIssues?.map((issueType) => /* @__PURE__ */ jsx(Grid, { item: true, xs: true, children: /* @__PURE__ */ jsxs( Box, { width: 100, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", children: [ /* @__PURE__ */ jsx(Status, { name: issueType.name, iconUrl: issueType.iconUrl }), /* @__PURE__ */ jsx(Typography, { variant: "h4", children: issueType.total }) ] } ) }, issueType.name)) }), /* @__PURE__ */ jsx(Divider, {}), /* @__PURE__ */ jsxs(TableContainer, { children: [ /* @__PURE__ */ jsxs(Table, { className: classes.infoCard, "aria-label": "tickets-table", children: [ /* @__PURE__ */ jsx(TableHead, { children: /* @__PURE__ */ jsxs(TableRow, { children: [ /* @__PURE__ */ jsx(TableCell, { children: "Key" }), /* @__PURE__ */ jsx(TableCell, { align: "left", children: "Summary" }), /* @__PURE__ */ jsx(TableCell, { align: "left", children: "Priority" }), /* @__PURE__ */ jsx(TableCell, { align: "left", children: "Status" }), /* @__PURE__ */ jsx(TableCell, { align: "left", children: "Created" }), /* @__PURE__ */ jsx(TableCell, { align: "left", children: "Updated" }), /* @__PURE__ */ jsx(TableCell, { align: "left", children: "Assignee" }) ] }) }), /* @__PURE__ */ jsx(TableBody, { children: tickets && tickets.length > 0 ? tickets.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((ticket) => /* @__PURE__ */ jsxs(TableRow, { children: [ /* @__PURE__ */ jsx(TableCell, { component: "th", children: /* @__PURE__ */ jsx( "a", { href: `${project?.url}/browse/${ticket?.key}`, target: "_blank", rel: "noopener noreferrer", className: classes.ticketLink, children: ticket?.key } ) }), /* @__PURE__ */ jsx(TableCell, { align: "left", children: ticket?.summary }), /* @__PURE__ */ jsx(TableCell, { align: "left", children: /* @__PURE__ */ jsx( "img", { src: ticket?.priority?.iconUrl, alt: ticket?.priority?.name, title: ticket?.priority?.name, width: "20px" } ) }), /* @__PURE__ */ jsx(TableCell, { align: "left", children: ticket?.status }), /* @__PURE__ */ jsx(TableCell, { align: "left", children: new Date(ticket?.created).toLocaleDateString() }), /* @__PURE__ */ jsx(TableCell, { align: "left", children: new Date(ticket?.updated).toLocaleDateString() }), /* @__PURE__ */ jsx( TableCell, { align: "left", style: { display: "flex", alignItems: "center" }, children: ticket?.assignee?.displayName ? /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx( "img", { src: ticket?.assignee?.avatarUrl, alt: ticket?.assignee?.displayName, title: ticket?.assignee?.displayName, style: { marginRight: "10px" }, width: "30px" } ), ticket?.assignee?.displayName ] }) : /* @__PURE__ */ jsx("span", { children: "Not Assigned" }) } ) ] }, ticket?.key)) : /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: 7, align: "center", children: "No Jira tickets available." }) }) }) ] }), /* @__PURE__ */ jsx( TablePagination, { rowsPerPageOptions: [5, 10, 20], component: "div", count: tickets?.length ?? 0, rowsPerPage, page, onPageChange: (_event, newPage) => { setPage(newPage); analytics.captureEvent( "paginate", `page: ${newPage}, size: ${rowsPerPage}` ); }, onRowsPerPageChange: (event) => { setRowsPerPage(parseInt(event.target.value, 10)); setPage(0); analytics.captureEvent( "paginate", `page: 0, size: ${parseInt(event.target.value, 10)}` ); } } ) ] }), /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx(Typography, { variant: "subtitle1", children: "Activity Stream" }), /* @__PURE__ */ jsx( ActivityStream, { projectKey, tokenType, componentName: component, label, ticketIds } ) ] }) ] }) : null ] } ); }; export { JiraOverviewCard }; //# sourceMappingURL=JiraOverviewCard.esm.js.map