empty view updated

This commit is contained in:
Alex Holliday committed 2025-12-16 18:15:47 +00:00
1 parent 422d13ef25
commit 465e673f4b
5 files changed
+77 -28

No files matched your search

@@ -17,6 +17,8 @@ import {
ChevronsRight,
ChevronLeft,
ChevronRight,
Coffee,
PartyPopper,
} from "lucide-react";
import TablePagination from "@mui/material/TablePagination";
@@ -45,6 +47,8 @@ type DataTableProps<T extends { id?: string | number; _id?: string | number }> =
cardsOnSmallScreens?: boolean;
expandableRows?: boolean;
renderExpandedContent?: (row: T) => React.ReactNode;
emptyViewText?: string;
emptyViewPositive?: boolean;
};
export function DataTable<
@@ -60,6 +64,8 @@ export function DataTable<
cardsOnSmallScreens = true,
expandableRows = false,
renderExpandedContent,
emptyViewText,
emptyViewPositive,
}: DataTableProps<T>) {
const theme = useTheme();
const [expanded, setExpanded] = useState<(string | number) | null>(null);
@@ -69,7 +75,10 @@ export function DataTable<
};
const isSmall = useMediaQuery(theme.breakpoints.down("md"));
if (data.length === 0 || headers.length === 0) return <EmptyView />;
if (data.length === 0 || headers.length === 0) {
return <EmptyView text={emptyViewText} positive={emptyViewPositive} />;
}
const keys = [];
// Return stack of cards for small screens
@@ -369,21 +378,51 @@ export const Pagination = ({ ...props }: TablePaginationProps) => {
);
};
const EmptyView = () => {
const EmptyView = ({
text,
positive,
}: {
text?: string;
positive?: boolean;
}) => {
const theme = useTheme();
const { t } = useTranslation();
const Icon = positive ? PartyPopper : Coffee;
return (
<Stack
alignItems={"center"}
justifyContent={"center"}
sx={{
p: theme.spacing(4),
py: theme.spacing(12),
px: theme.spacing(4),
borderWidth: 1,
borderStyle: "solid",
borderColor: theme.palette.divider,
borderRadius: theme.shape.borderRadius,
textAlign: "center",
}}
>
<Typography>{t("common.table.empty")}</Typography>
<Box
sx={{
width: 64,
height: 64,
borderRadius: "50%",
backgroundColor: theme.palette.action.hover,
display: "flex",
alignItems: "center",
justifyContent: "center",
mb: theme.spacing(2),
}}
>
<Icon size={28} strokeWidth={1} color={theme.palette.text.secondary} />
</Box>
<Typography
variant="subtitle1"
color={theme.palette.text.primary}
sx={{ fontWeight: 500 }}
>
{text ?? t("common.table.empty")}
</Typography>
</Stack>
);
};
+25 -23
View File
@@ -110,6 +110,7 @@
},
"checks": {
"table": {
"empty": "No checks",
"headers": {
"dateTime": "Date & Time",
"message": "Message",
@@ -120,21 +121,21 @@
"common": {
"appName": "Checkmate",
"breadcrumbs": {
"uptime": "Uptime Monitors",
"pagespeed": "PageSpeed Monitors",
"infrastructure": "Infrastructure Monitors",
"checks": "Checks",
"configure": "Configure",
"create": "Create",
"diagnostics": "Diagnostics",
"incidents": "Incidents",
"infrastructure": "Infrastructure Monitors",
"invite": "Invite",
"maintenance": "Maintenance",
"notification-channels": "Notification Channels",
"status-pages": "Status Pages",
"teams": "Teams",
"pagespeed": "PageSpeed Monitors",
"settings": "Settings",
"create": "Create",
"configure": "Configure",
"invite": "Invite",
"status-pages": "Status Pages",
"team-members": "Team Members",
"checks": "Checks"
"teams": "Teams",
"uptime": "Uptime Monitors"
},
"buttons": {
"acceptInvitation": "Accept invitation",
@@ -273,6 +274,7 @@
}
},
"table": {
"empty": "No incidents",
"headers": {
"end": "Incident end",
"monitorStatus": "Current monitor status",
@@ -709,20 +711,6 @@
}
},
"teams": {
"form": {
"basic": {
"title": "Basic information",
"description": "Set team name and description",
"optionName": "Team name",
"optionDescription": "Team description"
},
"role": {
"title": "Role",
"description": "Choose your role for this new team. You will be the first member",
"optionRole": "Role",
"optionIncludedPermissions": "Included permissions"
}
},
"details": {
"infoHeader": {
"description": "Description",
@@ -736,6 +724,20 @@
"title": "Team members"
}
},
"form": {
"basic": {
"description": "Set team name and description",
"optionDescription": "Team description",
"optionName": "Team name",
"title": "Basic information"
},
"role": {
"description": "Choose your role for this new team. You will be the first member",
"optionIncludedPermissions": "Included permissions",
"optionRole": "Role",
"title": "Role"
}
},
"infoBox": {
"description": "Organize your monitoring workspace by creating teams. Control who can view and manage monitors, set up role-based permissions, and collaborate effectively.",
"title": "Team Collaboration"
+5 -1
View File
@@ -102,7 +102,11 @@ export const ChecksTable = ({
return (
<Box>
<Table headers={headers} data={checks} />
<Table
headers={headers}
data={checks}
emptyViewText={t("checks.table.empty")}
/>
<Pagination
component="div"
count={count}
@@ -160,6 +160,8 @@ export const IncidentTable = ({
onRowClick={(row) => {
navigate(`/incidents/${row._id}`);
}}
emptyViewPositive
emptyViewText={t("incidents.table.empty")}
/>
<Pagination
component="div"
+2
View File
@@ -8,6 +8,7 @@ import type { ApiResponse } from "@/hooks/UseApi";
import type { IUser } from "@/types/user";
import { useAppDispatch } from "@/hooks/AppHooks";
import { setUser } from "@/features/authSlice";
import { mutate } from "swr";
const TeamsConfigPage = () => {
type FormValues = Omit<z.infer<typeof teamSchema>, "roleId">;
@@ -28,6 +29,7 @@ const TeamsConfigPage = () => {
description: data.description,
};
await patch(`/teams/${id}`, toSubmit);
mutate("/teams/joined");
const me = await getOnDemand("/me");
if (me?.data) {
dispatch(setUser(me.data));