152 lines
3.8 KiB
TypeScript
152 lines
3.8 KiB
TypeScript
import Box from "@mui/material/Box";
|
|
import Stack from "@mui/material/Stack";
|
|
import Typography from "@mui/material/Typography";
|
|
import { Table, type Header, ValueLabel } from "@/Components/design-elements";
|
|
import { Pagination } from "@/Components/design-elements/Table";
|
|
import { ActionsMenu, type ActionMenuItem } from "@/Components/actions-menu";
|
|
import { useClientPagination } from "@/Hooks/useClientPagination";
|
|
import { ExternalLink } from "lucide-react";
|
|
|
|
import { useTranslation } from "react-i18next";
|
|
import { useTheme } from "@mui/material/styles";
|
|
import { useNavigate } from "react-router-dom";
|
|
|
|
import { getStatusPagePublicPath, getStatusPagePublicUrl } from "@/Utils/statusPageUrl";
|
|
|
|
import { type StatusPage } from "@/Types/StatusPage";
|
|
|
|
interface StatusPagesTableProps {
|
|
data: StatusPage[];
|
|
setSelectedStatusPage: (statusPage: StatusPage | null) => void;
|
|
}
|
|
|
|
export const StatusPagesTable = ({
|
|
data,
|
|
setSelectedStatusPage,
|
|
}: StatusPagesTableProps) => {
|
|
const { t } = useTranslation();
|
|
const theme = useTheme();
|
|
const navigate = useNavigate();
|
|
const { pagedRows, paginationProps } = useClientPagination(data);
|
|
|
|
const getActions = (row: StatusPage): ActionMenuItem[] => {
|
|
return [
|
|
{
|
|
id: 1,
|
|
label: t("common.buttons.configure"),
|
|
action: () => {
|
|
navigate(`/status/configure/${row.url}`);
|
|
},
|
|
closeMenu: true,
|
|
},
|
|
{
|
|
id: 2,
|
|
label: (
|
|
<Typography color={theme.palette.error.main}>
|
|
{t("common.buttons.delete")}
|
|
</Typography>
|
|
),
|
|
action: () => setSelectedStatusPage(row),
|
|
closeMenu: true,
|
|
},
|
|
];
|
|
};
|
|
|
|
const handleUrlClick = (e: React.MouseEvent, row: StatusPage) => {
|
|
if (row.isPublished) {
|
|
e.stopPropagation();
|
|
window.open(getStatusPagePublicUrl(row), "_blank", "noopener,noreferrer");
|
|
}
|
|
};
|
|
|
|
const getHeaders = (): Header<StatusPage>[] => {
|
|
return [
|
|
{
|
|
id: "name",
|
|
content: t("pages.statusPages.table.headers.name"),
|
|
render: (row) => row.companyName,
|
|
},
|
|
{
|
|
id: "url",
|
|
content: t("pages.statusPages.table.headers.url"),
|
|
render: (row) => {
|
|
const content = row.isPublished
|
|
? row.customDomain
|
|
? getStatusPagePublicPath(row)
|
|
: `/${row.url}`
|
|
: t("pages.statusPages.table.unpublished");
|
|
return (
|
|
<Stack
|
|
direction="row"
|
|
alignItems="center"
|
|
justifyContent="center"
|
|
gap={theme.spacing(2)}
|
|
paddingLeft={theme.spacing(2)}
|
|
paddingRight={theme.spacing(2)}
|
|
onClick={(e) => handleUrlClick(e, row)}
|
|
sx={{
|
|
...(row.isPublished && {
|
|
display: "inline-flex",
|
|
":hover": {
|
|
cursor: "pointer",
|
|
borderBottom: 1,
|
|
},
|
|
}),
|
|
}}
|
|
>
|
|
<Typography>{content}</Typography>
|
|
{row.isPublished && <ExternalLink size={18} />}
|
|
</Stack>
|
|
);
|
|
},
|
|
},
|
|
{
|
|
id: "type",
|
|
content: t("common.table.headers.type"),
|
|
render: (row) => row.type.join(", "),
|
|
},
|
|
{
|
|
id: "status",
|
|
content: t("common.table.headers.status"),
|
|
render: (row) => {
|
|
return (
|
|
<ValueLabel
|
|
value={row.isPublished ? "positive" : "neutral"}
|
|
text={
|
|
row.isPublished
|
|
? t("pages.statusPages.table.published")
|
|
: t("pages.statusPages.table.unpublished")
|
|
}
|
|
/>
|
|
);
|
|
},
|
|
},
|
|
{
|
|
id: "actions",
|
|
content: t("common.table.headers.actions"),
|
|
render: (row) => {
|
|
return <ActionsMenu items={getActions(row)} />;
|
|
},
|
|
},
|
|
];
|
|
};
|
|
|
|
const handleRowClick = (statusPage: StatusPage) => {
|
|
navigate(`/status/${statusPage.url}`);
|
|
};
|
|
|
|
return (
|
|
<Box>
|
|
<Table
|
|
headers={getHeaders()}
|
|
data={pagedRows}
|
|
onRowClick={handleRowClick}
|
|
emptyViewText={t("common.table.empty")}
|
|
/>
|
|
{data.length > 0 && <Pagination {...paginationProps} />}
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
export default StatusPagesTable;
|