From 83d56f1ff6f53b3054c636901cef9ac4c8abbfb9 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Sat, 21 Feb 2026 16:03:45 +0000 Subject: [PATCH] fe->be --- client/src/Pages/Settings/index.tsx | 22 +++++++++++-------- server/src/service/business/monitorService.ts | 4 +--- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/client/src/Pages/Settings/index.tsx b/client/src/Pages/Settings/index.tsx index 55e08234d..484ab3690 100644 --- a/client/src/Pages/Settings/index.tsx +++ b/client/src/Pages/Settings/index.tsx @@ -8,6 +8,7 @@ import { useTranslation } from "react-i18next"; import { useSelector, useDispatch } from "react-redux"; import DummyChart from "@/Pages/Settings/DummyChart"; import { useGet, usePatch, usePost, useLazyGet } from "@/Hooks/UseApi"; +import { useToast } from "@/Hooks/UseToast"; import { useSettingsForm } from "@/Hooks/useSettingsForm"; import { useIsAdmin } from "@/Hooks/useIsAdmin.js"; import type { SettingsFormData } from "@/Validation/settings"; @@ -44,10 +45,13 @@ export const SettingsPage = () => { const { t, i18n } = useTranslation(); const dispatch = useDispatch(); const isAdmin = useIsAdmin(); + const { toastError } = useToast(); // Local state for demo monitors dialog const [isDemoMonitorsDialogOpen, setIsDemoMonitorsDialogOpen] = useState(false); const { post: postDemoMonitors, loading: isPostingDemoMonitors } = usePost(); const { deleteFn: deleteAllMonitors, loading: isDeletingAllMonitors } = useDelete(); + // Import monitors functionality + const { post: importMonitors, loading: isImportingMonitors } = usePost(); // Fetch settings data from API const { data: fetchedSettings } = useGet("/settings"); @@ -209,26 +213,25 @@ export const SettingsPage = () => { } if (file.type !== "application/json") { - alert("Please select a valid JSON file"); - event.target.value = ""; // Reset input - return; + toastError("Please select a valid JSON file"); + event.target.value = ""; } - // Log the file contents try { const text = await file.text(); const monitors = JSON.parse(text); if (!Array.isArray(monitors)) { - alert("Invalid file format: expected an array of monitors"); + toastError("Invalid file format: expected an array of monitors"); event.target.value = ""; return; } - console.log(monitors); - event.target.value = ""; // Reset input + + await importMonitors("/monitors/import/json", { monitors }); + + event.target.value = ""; } catch (error) { - console.error("Import error:", error); - alert("Error importing monitors. Please check the file format."); + toastError("Error parsing JSON file. Please check the file format."); event.target.value = ""; } }; @@ -914,6 +917,7 @@ export const SettingsPage = () => { diff --git a/server/src/service/business/monitorService.ts b/server/src/service/business/monitorService.ts index 2d633ab46..87bb7eeda 100644 --- a/server/src/service/business/monitorService.ts +++ b/server/src/service/business/monitorService.ts @@ -499,7 +499,6 @@ export class MonitorService implements IMonitorService { }): Promise<{ imported: number; errors: string[] }> => { const errors: string[] = []; - // Clean the data: remove id, _id, createdAt, updatedAt, recentChecks fields const cleanedMonitors = monitors.map((monitor) => { const cleanData = { ...monitor }; delete cleanData.id; @@ -507,12 +506,11 @@ export class MonitorService implements IMonitorService { delete cleanData.createdAt; delete cleanData.updatedAt; delete cleanData.recentChecks; - // Force the monitor to belong to the current team + // Monitors must belong to current team cleanData.teamId = teamId; return cleanData; }); - // Use createBulkMonitors for efficient bulk insert const createdMonitors = await this.createBulkMonitors(cleanedMonitors, userId, teamId); if (!createdMonitors || createdMonitors.length === 0) {