Revert "feat(ui): add bulk edit notifications modal and checkmark selection for uptime monitors"
This reverts commit 27dd565bc6.
This commit is contained in:
1 parent
2a1645baf2
commit
5578fdf17f
5 files changed
-243
No files matched your search
Generated
-31
@@ -18,7 +18,6 @@
|
||||
"@mui/x-date-pickers": "7.29.4",
|
||||
"@reduxjs/toolkit": "2.7.0",
|
||||
"@types/maplibre-gl": "^1.13.2",
|
||||
"@types/react-map-gl": "^6.1.8",
|
||||
"axios": "^1.7.4",
|
||||
"dayjs": "1.11.13",
|
||||
"flag-icons": "7.3.2",
|
||||
@@ -2291,15 +2290,6 @@
|
||||
"integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/mapbox-gl": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-3.4.1.tgz",
|
||||
"integrity": "sha512-NsGKKtgW93B+UaLPti6B7NwlxYlES5DpV5Gzj9F75rK5ALKsqSk15CiEHbOnTr09RGbr6ZYiCdI+59NNNcAImg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/geojson": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/maplibre-gl": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/maplibre-gl/-/maplibre-gl-1.13.2.tgz",
|
||||
@@ -2341,18 +2331,6 @@
|
||||
"@types/react": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-map-gl": {
|
||||
"version": "6.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-map-gl/-/react-map-gl-6.1.8.tgz",
|
||||
"integrity": "sha512-M0WLRx7Q7m47aFoNRu7NxwaboY/K12J+zgSesJnwisIq5EgqkGUdl9AUb/yRd0cJtx6oOTeOMVPb7emEdlXpQg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/geojson": "*",
|
||||
"@types/mapbox-gl": "<3.5",
|
||||
"@types/react": "*",
|
||||
"@types/viewport-mercator-project": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-transition-group": {
|
||||
"version": "4.4.12",
|
||||
"license": "MIT",
|
||||
@@ -2373,15 +2351,6 @@
|
||||
"version": "0.0.6",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/viewport-mercator-project": {
|
||||
"version": "6.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/viewport-mercator-project/-/viewport-mercator-project-6.1.6.tgz",
|
||||
"integrity": "sha512-uWrbqhRXFeiT6CAvRjf0BkQKRkKED+ofrPhglKpUktQML3463dEPiA4iwe7cZQs6m49Zo/g03rL7ChMLiE5Z8w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"gl-matrix": "^3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ungap/structured-clone": {
|
||||
"version": "1.3.0",
|
||||
"dev": true,
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
"@mui/x-date-pickers": "7.29.4",
|
||||
"@reduxjs/toolkit": "2.7.0",
|
||||
"@types/maplibre-gl": "^1.13.2",
|
||||
"@types/react-map-gl": "^6.1.8",
|
||||
"axios": "^1.7.4",
|
||||
"dayjs": "1.11.13",
|
||||
"flag-icons": "7.3.2",
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
import { Dialog, Select, Autocomplete } from "@/Components/inputs";
|
||||
import { useState, useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useGet, usePatch } from "@/Hooks/UseApi";
|
||||
import type { Notification } from "@/Types/Notification";
|
||||
import Stack from "@mui/material/Stack";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Divider from "@mui/material/Divider";
|
||||
import IconButton from "@mui/material/IconButton";
|
||||
import { Trash2 } from "lucide-react";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import { LAYOUT } from "@/Utils/Theme/constants";
|
||||
|
||||
type ActionType = "add" | "remove" | "set";
|
||||
|
||||
export const BulkEditNotificationsModal = ({
|
||||
open,
|
||||
monitorIds,
|
||||
onClose,
|
||||
onSuccess,
|
||||
}: {
|
||||
open: boolean;
|
||||
monitorIds: string[];
|
||||
onClose: () => void;
|
||||
onSuccess: () => void;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
const [action, setAction] = useState<ActionType>("add");
|
||||
const [selectedNotificationIds, setSelectedNotificationIds] = useState<string[]>([]);
|
||||
|
||||
const { data: notifications } = useGet<Notification[]>("/notifications/team");
|
||||
const { patch, loading } = usePatch();
|
||||
|
||||
const handleConfirm = async () => {
|
||||
if (selectedNotificationIds.length === 0 && action !== "set") return;
|
||||
|
||||
const result = await patch("/notifications", {
|
||||
monitorIds,
|
||||
notificationIds: selectedNotificationIds,
|
||||
action,
|
||||
});
|
||||
|
||||
if (result?.success) {
|
||||
onSuccess();
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
|
||||
const notificationOptions = useMemo(() => {
|
||||
return (notifications ?? []).map((n) => ({
|
||||
...n,
|
||||
name: n.notificationName,
|
||||
}));
|
||||
}, [notifications]);
|
||||
|
||||
const selectedItems = useMemo(() => {
|
||||
return notificationOptions.filter((n) => selectedNotificationIds.includes(n.id));
|
||||
}, [notificationOptions, selectedNotificationIds]);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
title={t("pages.uptime.bulkEdit.title", { defaultValue: "Bulk Edit Notifications" })}
|
||||
content={t("pages.uptime.bulkEdit.description", {
|
||||
defaultValue: `Apply notification changes to ${monitorIds.length} selected monitors.`,
|
||||
})}
|
||||
onConfirm={handleConfirm}
|
||||
onCancel={onClose}
|
||||
loading={loading}
|
||||
confirmText={t("common.buttons.save")}
|
||||
>
|
||||
<Stack spacing={theme.spacing(LAYOUT.MD)} sx={{ mt: 2 }}>
|
||||
<Select
|
||||
value={action}
|
||||
onChange={(e) => setAction(e.target.value as ActionType)}
|
||||
fieldLabel={t("pages.uptime.bulkEdit.actionLabel", { defaultValue: "Action" })}
|
||||
>
|
||||
<MenuItem value="add">
|
||||
{t("pages.uptime.bulkEdit.actionAdd", { defaultValue: "Add Notifications" })}
|
||||
</MenuItem>
|
||||
<MenuItem value="remove">
|
||||
{t("pages.uptime.bulkEdit.actionRemove", { defaultValue: "Remove Notifications" })}
|
||||
</MenuItem>
|
||||
<MenuItem value="set">
|
||||
{t("pages.uptime.bulkEdit.actionSet", { defaultValue: "Set Notifications (Replace All)" })}
|
||||
</MenuItem>
|
||||
</Select>
|
||||
|
||||
<Autocomplete
|
||||
multiple
|
||||
options={notificationOptions}
|
||||
value={selectedItems}
|
||||
getOptionLabel={(option) => option.name}
|
||||
onChange={(_: unknown, newValue: typeof notificationOptions) => {
|
||||
setSelectedNotificationIds(newValue.map((n) => n.id));
|
||||
}}
|
||||
isOptionEqualToValue={(option, value) => option.id === value.id}
|
||||
fieldLabel={t("pages.uptime.bulkEdit.notificationsLabel", {
|
||||
defaultValue: "Notifications",
|
||||
})}
|
||||
/>
|
||||
|
||||
{selectedItems.length > 0 && (
|
||||
<Stack flex={1} width="100%">
|
||||
{selectedItems.map((notification, index) => (
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
key={notification.id}
|
||||
width="100%"
|
||||
>
|
||||
<Typography flexGrow={1}>{notification.notificationName}</Typography>
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => {
|
||||
setSelectedNotificationIds((prev) =>
|
||||
prev.filter((id) => id !== notification.id)
|
||||
);
|
||||
}}
|
||||
aria-label="Remove notification"
|
||||
>
|
||||
<Trash2 size={16} />
|
||||
</IconButton>
|
||||
{index < selectedItems.length - 1 && <Divider />}
|
||||
</Stack>
|
||||
))}
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
@@ -16,7 +16,6 @@ import { useTheme } from "@mui/material/styles";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { usePost } from "@/Hooks/UseApi";
|
||||
import { useSelector } from "react-redux";
|
||||
import { Checkbox } from "@/Components/inputs";
|
||||
|
||||
import type { Monitor } from "@/Types/Monitor";
|
||||
import type { ActionMenuItem } from "@/Components/actions-menu";
|
||||
@@ -35,8 +34,6 @@ export const MonitorTable = ({
|
||||
setPage,
|
||||
rowsPerPage,
|
||||
setRowsPerPage,
|
||||
selectedMonitors,
|
||||
setSelectedMonitors,
|
||||
}: {
|
||||
monitors: Monitor[];
|
||||
refetch: Function;
|
||||
@@ -50,8 +47,6 @@ export const MonitorTable = ({
|
||||
setPage: (page: number) => void;
|
||||
rowsPerPage: number;
|
||||
setRowsPerPage: (rowsPerPage: number) => void;
|
||||
selectedMonitors: string[];
|
||||
setSelectedMonitors: React.Dispatch<React.SetStateAction<string[]>>;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
@@ -156,37 +151,6 @@ export const MonitorTable = ({
|
||||
</Box>
|
||||
);
|
||||
const headers: Header<Monitor>[] = [
|
||||
{
|
||||
id: "select",
|
||||
content: (
|
||||
<Checkbox
|
||||
checked={monitors.length > 0 && selectedMonitors.length === monitors.length}
|
||||
indeterminate={selectedMonitors.length > 0 && selectedMonitors.length < monitors.length}
|
||||
onChange={(e) => {
|
||||
e.stopPropagation();
|
||||
if (e.target.checked) {
|
||||
setSelectedMonitors(monitors.map((m) => m.id));
|
||||
} else {
|
||||
setSelectedMonitors([]);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
),
|
||||
onClick: (e) => e.stopPropagation(),
|
||||
render: (row) => (
|
||||
<Checkbox
|
||||
checked={selectedMonitors.includes(row.id)}
|
||||
onChange={(e) => {
|
||||
e.stopPropagation();
|
||||
if (e.target.checked) {
|
||||
setSelectedMonitors((prev) => [...prev, row.id]);
|
||||
} else {
|
||||
setSelectedMonitors((prev) => prev.filter((id) => id !== row.id));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "name",
|
||||
content: (
|
||||
|
||||
@@ -2,11 +2,8 @@ import { ControlsFilter, HeaderMonitorsSummary } from "@/Components/monitors";
|
||||
import { MonitorBasePageWithStates } from "@/Components/design-elements";
|
||||
import { TextField, Dialog } from "@/Components/inputs";
|
||||
import Stack from "@mui/material/Stack";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { MonitorTable } from "@/Pages/Uptime/Monitors/Components/UptimeMonitorsTable";
|
||||
import { HeaderCreate } from "@/Components/common";
|
||||
import { Button } from "@/Components/inputs";
|
||||
import { BulkEditNotificationsModal } from "./Components/BulkEditNotificationsModal";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
import useMediaQuery from "@mui/material/useMediaQuery";
|
||||
@@ -42,9 +39,6 @@ const UptimeMonitorsPage = () => {
|
||||
const [selectedMonitor, setSelectedMonitor] = useState<Monitor | null>(null);
|
||||
const isDialogOpen = Boolean(selectedMonitor);
|
||||
|
||||
const [selectedMonitors, setSelectedMonitors] = useState<string[]>([]);
|
||||
const [isBulkEditOpen, setIsBulkEditOpen] = useState(false);
|
||||
|
||||
const debouncedSearch = useDebounce<string>(search, 300);
|
||||
|
||||
// Convert filter selections to API filter values
|
||||
@@ -165,28 +159,6 @@ const UptimeMonitorsPage = () => {
|
||||
justifyContent={isSmall ? "flex-start" : "space-between"}
|
||||
gap={theme.spacing(4)}
|
||||
>
|
||||
{selectedMonitors.length > 0 ? (
|
||||
<Stack direction="row" alignItems="center" spacing={2} width="100%">
|
||||
<Typography variant="body1" fontWeight="medium">
|
||||
{selectedMonitors.length} monitor(s) selected
|
||||
</Typography>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => setIsBulkEditOpen(true)}
|
||||
>
|
||||
Bulk Edit Notifications
|
||||
</Button>
|
||||
<Button
|
||||
variant="text"
|
||||
color="inherit"
|
||||
onClick={() => setSelectedMonitors([])}
|
||||
>
|
||||
Cancel Selection
|
||||
</Button>
|
||||
</Stack>
|
||||
) : (
|
||||
<>
|
||||
<ControlsFilter
|
||||
selectedTypes={selectedTypes}
|
||||
setSelectedTypes={setSelectedTypes}
|
||||
@@ -203,8 +175,6 @@ const UptimeMonitorsPage = () => {
|
||||
setSearch(event.target.value);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
<MonitorTable
|
||||
monitors={monitorsWithChecks || []}
|
||||
@@ -218,8 +188,6 @@ const UptimeMonitorsPage = () => {
|
||||
setSortField={setSortField}
|
||||
sortOrder={sortOrder}
|
||||
setSortOrder={setSortOrder}
|
||||
selectedMonitors={selectedMonitors}
|
||||
setSelectedMonitors={setSelectedMonitors}
|
||||
setRowsPerPage={(rowsPerPage: number) => {
|
||||
dispatch(
|
||||
setRowsPerPage({
|
||||
@@ -238,15 +206,6 @@ const UptimeMonitorsPage = () => {
|
||||
onCancel={handleCancel}
|
||||
loading={isDeleting}
|
||||
/>
|
||||
<BulkEditNotificationsModal
|
||||
open={isBulkEditOpen}
|
||||
monitorIds={selectedMonitors}
|
||||
onClose={() => setIsBulkEditOpen(false)}
|
||||
onSuccess={() => {
|
||||
setSelectedMonitors([]);
|
||||
refetch();
|
||||
}}
|
||||
/>
|
||||
</MonitorBasePageWithStates>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user