@roadiehq/backstage-plugin-jira
Version:
204 lines (201 loc) • 6.83 kB
JavaScript
import React, { useState, useEffect, useCallback } from 'react';
import { Typography, Card, Grid, Link, Avatar } from '@material-ui/core';
import 'xml-js';
import 'luxon';
import 'uuid';
import '@backstage/core-plugin-api';
import 'react-use';
import '../../../api/index.esm.js';
import { useUserInfo } from '../../../hooks/useUserInfo.esm.js';
import Skeleton from '@material-ui/lab/Skeleton';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import DraggableCard from '../../DraggableCard.esm.js';
import { makeStyles } from '@material-ui/core/styles';
const useStyles = makeStyles((theme) => ({
container: {
overflowY: "auto",
maxHeight: "100%"
},
title: {
fontWeight: Number(theme.typography.fontWeightBold),
color: "darkgray"
},
link: {
color: theme.palette.text.primary,
"&:hover": {
color: "#539bf5",
fill: "#539bf5"
},
"&:first-child": {
paddingRight: "4px"
}
},
secondaryText: {
color: theme.palette.text.secondary
}
}));
const JiraTicketSkeleton = () => {
return /* @__PURE__ */ React.createElement(
Skeleton,
{
variant: "rect",
style: { fontSize: "5rem", borderRadius: "8px", margin: 3 }
}
);
};
const JiraTicketsSkeletonView = () => {
return /* @__PURE__ */ React.createElement("div", null, Array.from({ length: 5 }).map(() => /* @__PURE__ */ React.createElement(JiraTicketSkeleton, null)));
};
const JiraTicketCard = ({
user,
ticket,
index,
moveCard
}) => {
const classes = useStyles();
return /* @__PURE__ */ React.createElement(
DraggableCard,
{
key: ticket.key,
id: ticket.key,
index,
moveCard
},
/* @__PURE__ */ React.createElement(Card, { style: { marginBottom: "1em", padding: "1em" } }, /* @__PURE__ */ React.createElement(Grid, { container: true, spacing: 2 }, /* @__PURE__ */ React.createElement(
Grid,
{
container: true,
direction: "row",
alignItems: "center",
justifyContent: "space-between"
},
/* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2", className: classes.title }, /* @__PURE__ */ React.createElement(
"img",
{
src: ticket?.issuetype?.iconUrl,
alt: ticket?.issuetype?.name,
title: ticket?.issuetype?.name,
width: "15px",
style: { marginRight: "5px", marginBottom: "-3px" }
}
), ticket.parent ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
Link,
{
href: `${user?.url}/browse/${ticket?.parent}`,
target: "_blank",
rel: "noopener noreferrer",
underline: "none",
className: `${classes.secondaryText} ${classes.link}`
},
ticket.parent
), " / ", /* @__PURE__ */ React.createElement(
Link,
{
href: `${user?.url}/browse/${ticket?.key}`,
target: "_blank",
rel: "noopener noreferrer",
underline: "none",
className: `${classes.secondaryText} ${classes.link}`
},
ticket.key
)) : /* @__PURE__ */ React.createElement(
Link,
{
href: `${user?.url}/browse/${ticket?.key}`,
target: "_blank",
rel: "noopener noreferrer",
underline: "none",
className: `${classes.secondaryText} ${classes.link}`
},
ticket.key
), /* @__PURE__ */ React.createElement(
"span",
{
style: {
display: "inline-flex",
alignItems: "center",
marginLeft: "5px"
}
},
/* @__PURE__ */ React.createElement(
"img",
{
src: ticket?.priority?.iconUrl,
alt: ticket?.priority?.name,
title: ticket?.priority?.name,
width: "15px",
style: { marginRight: "5px" }
}
),
/* @__PURE__ */ React.createElement(Typography, { style: { fontSize: "1rem" } }, ticket?.priority?.name)
))),
/* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2", color: "textSecondary" }, /* @__PURE__ */ React.createElement(
"img",
{
src: ticket?.status?.iconUrl,
alt: ticket?.status?.name,
title: ticket?.status?.name,
width: "15px",
style: { marginRight: "5px" }
}
), ticket?.status?.name))
), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(Typography, { variant: "body2" }, ticket.summary)), /* @__PURE__ */ React.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React.createElement(Grid, { container: true, direction: "row", alignItems: "center" }, ticket.assignee && /* @__PURE__ */ React.createElement(
Avatar,
{
src: ticket.assignee.avatarUrl,
style: { width: "30px", height: "30px" }
}
), /* @__PURE__ */ React.createElement(
Typography,
{
variant: "body2",
style: { marginLeft: "8px" },
className: classes.secondaryText
},
ticket.assignee ? ticket.assignee.displayName : "Unassigned"
)))))
);
};
const JiraTicketsListView = ({ user, tickets }) => {
const [cards, setCards] = useState(tickets || []);
useEffect(() => {
setCards(tickets || []);
}, [tickets]);
const moveCard = useCallback(
(dragIndex, hoverIndex) => {
const dragCard = cards[dragIndex];
const updatedCards = [...cards];
updatedCards.splice(dragIndex, 1);
updatedCards.splice(hoverIndex, 0, dragCard);
setCards(updatedCards);
},
[cards]
);
return /* @__PURE__ */ React.createElement(DndProvider, { backend: HTML5Backend }, cards.map((ticket, index) => /* @__PURE__ */ React.createElement(
JiraTicketCard,
{
user,
ticket,
index,
moveCard
}
)));
};
const Content = (props) => {
const { userId } = props;
const { user, loading, error, tickets } = useUserInfo(userId);
if (loading) return /* @__PURE__ */ React.createElement(JiraTicketsSkeletonView, null);
if (error) {
return /* @__PURE__ */ React.createElement(Typography, null, "Error loading tickets: ", error.message);
}
if (!user) {
return /* @__PURE__ */ React.createElement(Typography, null, "User not found");
}
if (!tickets || tickets.length === 0) {
return /* @__PURE__ */ React.createElement(Typography, null, "No tickets to show");
}
return /* @__PURE__ */ React.createElement(JiraTicketsListView, { user, tickets });
};
export { Content };
//# sourceMappingURL=Content.esm.js.map