From 940247b7bf86d12a7776bcac0b98f3f989a4eb38 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Wed, 14 Jan 2026 21:47:37 +0000 Subject: [PATCH] teamid --- .../src/Components/v1/Inputs/Search/index.jsx | 8 +-- .../src/Components/v1/Inputs/Select/index.jsx | 37 +++++++---- client/src/Hooks/monitorHooks.js | 38 ++--------- client/src/Pages/Incidents2/index.jsx | 2 +- .../Components/MonitorList/index.jsx | 8 +-- .../hooks/useMaintenanceActions.jsx | 8 ++- .../hooks/useMaintenanceData.jsx | 4 +- .../Maintenance/CreateMaintenance/index.jsx | 1 + .../Create/Components/MonitorList/index.jsx | 6 +- .../Create/Components/Tabs/Content.jsx | 2 +- .../Create/Hooks/useMonitorsFetch.jsx | 2 +- client/src/Pages/StatusPage/Create/index.jsx | 5 +- .../Status/Components/MonitorsList/index.jsx | 4 +- client/src/Utils/NetworkService.js | 9 +-- server/src/controllers/monitorController.ts | 7 +- server/src/db/modules/monitorModule.js | 66 ++++++++----------- server/src/service/business/monitorService.ts | 28 +------- server/src/validation/joi.js | 25 +++++-- 18 files changed, 109 insertions(+), 151 deletions(-) diff --git a/client/src/Components/v1/Inputs/Search/index.jsx b/client/src/Components/v1/Inputs/Search/index.jsx index 7a3771d47..347223bf3 100644 --- a/client/src/Components/v1/Inputs/Search/index.jsx +++ b/client/src/Components/v1/Inputs/Search/index.jsx @@ -85,7 +85,7 @@ const Search = ({ const enhancedOptions = React.useMemo(() => { return multiple && isAdorned ? [ - { [filteredBy]: t("selectAll"), isSelectAll: true, _id: "select_all" }, + { [filteredBy]: t("selectAll"), isSelectAll: true, _id: "select_all", id: "select_all" }, ...options, ] : options; @@ -93,7 +93,7 @@ const Search = ({ const isOptionSelected = (option) => { if (!multiple && !isAdorned) return false; if (Array.isArray(value)) { - return value.some((item) => item._id === option._id); + return value.some((item) => (item._id ?? item.id) === (option._id ?? option.id)); } return false; }; @@ -145,7 +145,7 @@ const Search = ({ disableClearable options={enhancedOptions} getOptionLabel={(option) => option[filteredBy]} - isOptionEqualToValue={(option, value) => option._id === value._id} // Compare by unique identifier + isOptionEqualToValue={(option, value) => (option._id ?? option.id) === (value?._id ?? value?.id)} // Compare by unique identifier renderInput={(params) => ( { - return option._id; + return option._id ?? option.id; }} renderOption={(props, option) => { const { key, ...optionProps } = props; diff --git a/client/src/Components/v1/Inputs/Select/index.jsx b/client/src/Components/v1/Inputs/Select/index.jsx index 37ce30dc1..f952b6818 100644 --- a/client/src/Components/v1/Inputs/Select/index.jsx +++ b/client/src/Components/v1/Inputs/Select/index.jsx @@ -62,6 +62,7 @@ const Select = ({ fieldWrapperSx = {}, }) => { const theme = useTheme(); + const getItemValue = (item) => item?._id ?? item?.id; const itemStyles = { fontSize: "var(--env-var-font-size-medium)", color: theme.palette.primary.contrastTextTertiary, @@ -123,7 +124,7 @@ const Select = ({ ...sx, }} renderValue={(selected) => { - const selectedItem = items.find((item) => item._id === selected); + const selectedItem = items.find((item) => getItemValue(item) === selected); const displayName = selectedItem ? selectedItem.name : placeholder; return ( )} - {items.map((item) => ( - - {item.name} - - ))} + {items + .map((item) => { + const itemValue = getItemValue(item); + if (itemValue === undefined || itemValue === null) { + return null; + } + return ( + + {item.name} + + ); + }) + .filter(Boolean)} ); @@ -179,8 +188,8 @@ Select.propTypes = { .isRequired, items: PropTypes.arrayOf( PropTypes.shape({ - _id: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool]) - .isRequired, + _id: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool]), + id: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool]), name: PropTypes.string.isRequired, }) diff --git a/client/src/Hooks/monitorHooks.js b/client/src/Hooks/monitorHooks.js index ffc356320..197779b53 100644 --- a/client/src/Hooks/monitorHooks.js +++ b/client/src/Hooks/monitorHooks.js @@ -100,22 +100,9 @@ const useFetchMonitorsWithChecks = ({ return [monitors, count, isLoading, networkError]; }; -const useFetchMonitorsByTeamId = ({ - types, - limit, - page, - rowsPerPage, - filter, - field, - order, - checkOrder, - normalize, - status, - updateTrigger, -}) => { +const useFetchMonitorsByTeamId = ({ types, filter, updateTrigger }) => { const [isLoading, setIsLoading] = useState(false); const [monitors, setMonitors] = useState(undefined); - const [summary, setSummary] = useState(undefined); const [networkError, setNetworkError] = useState(false); useEffect(() => { @@ -123,20 +110,11 @@ const useFetchMonitorsByTeamId = ({ try { setIsLoading(true); const res = await networkService.getMonitorsByTeamId({ - limit, types, - page, - rowsPerPage, filter, - field, - order, - checkOrder, - status, - normalize, }); - if (res?.data?.data?.filteredMonitors) { - setMonitors(res.data.data.filteredMonitors); - setSummary(res.data.data.summary); + if (res?.data?.data) { + setMonitors(res.data.data); } } catch (error) { setNetworkError(true); @@ -150,18 +128,10 @@ const useFetchMonitorsByTeamId = ({ fetchMonitors(); }, [ types, - limit, - page, - rowsPerPage, filter, - field, - order, updateTrigger, - checkOrder, - normalize, - status, ]); - return [monitors, summary, isLoading, networkError]; + return [monitors, isLoading, networkError]; }; const useFetchStatsByMonitorId = ({ diff --git a/client/src/Pages/Incidents2/index.jsx b/client/src/Pages/Incidents2/index.jsx index eda68d976..966388b51 100644 --- a/client/src/Pages/Incidents2/index.jsx +++ b/client/src/Pages/Incidents2/index.jsx @@ -34,7 +34,7 @@ const Incidents2 = () => { setUpdateTrigger((prev) => !prev); }; - const [monitors, , isLoadingMonitors, monitorsNetworkError] = useFetchMonitorsByTeamId( + const [monitors, isLoadingMonitors, monitorsNetworkError] = useFetchMonitorsByTeamId( {} ); diff --git a/client/src/Pages/Maintenance/CreateMaintenance/Components/MonitorList/index.jsx b/client/src/Pages/Maintenance/CreateMaintenance/Components/MonitorList/index.jsx index c3a4681a1..c70912582 100644 --- a/client/src/Pages/Maintenance/CreateMaintenance/Components/MonitorList/index.jsx +++ b/client/src/Pages/Maintenance/CreateMaintenance/Components/MonitorList/index.jsx @@ -24,7 +24,7 @@ const MonitorListItem = ({ monitor, onDelete }) => { MonitorListItem.propTypes = { monitor: PropTypes.shape({ - _id: PropTypes.string.isRequired, + id: PropTypes.string.isRequired, name: PropTypes.string.isRequired, }).isRequired, onDelete: PropTypes.func.isRequired, @@ -33,7 +33,7 @@ MonitorListItem.propTypes = { const MonitorList = ({ selectedMonitors, setSelectedMonitors }) => { const onDelete = (monitorToDelete) => { const newMonitors = selectedMonitors.filter( - (monitor) => monitor._id !== monitorToDelete._id + (monitor) => monitor.id !== monitorToDelete.id ); setSelectedMonitors(newMonitors); }; @@ -47,7 +47,7 @@ const MonitorList = ({ selectedMonitors, setSelectedMonitors }) => { > {selectedMonitors?.map((monitor) => ( @@ -59,7 +59,7 @@ const MonitorList = ({ selectedMonitors, setSelectedMonitors }) => { MonitorList.propTypes = { selectedMonitors: PropTypes.arrayOf( PropTypes.shape({ - _id: PropTypes.string.isRequired, + id: PropTypes.string.isRequired, name: PropTypes.string.isRequired, }) ).isRequired, diff --git a/client/src/Pages/Maintenance/CreateMaintenance/hooks/useMaintenanceActions.jsx b/client/src/Pages/Maintenance/CreateMaintenance/hooks/useMaintenanceActions.jsx index 6f180c880..22a61084d 100644 --- a/client/src/Pages/Maintenance/CreateMaintenance/hooks/useMaintenanceActions.jsx +++ b/client/src/Pages/Maintenance/CreateMaintenance/hooks/useMaintenanceActions.jsx @@ -22,6 +22,12 @@ const useMaintenanceActions = () => { weekly: MS_PER_DAY * 7, }; const handleSubmitForm = async (maintenanceWindowId, form) => { + const toStringId = (monitor) => { + if (!monitor) { + return ""; + } + return monitor._id ?? monitor.id ?? ""; + }; const start = dayjs(form.startDate) .set("hour", form.startTime.hour()) .set("minute", form.startTime.minute()); @@ -33,7 +39,7 @@ const useMaintenanceActions = () => { const repeat = REPEAT_LOOKUP[form.repeat]; const submit = { - monitors: form.monitors.map((monitor) => monitor._id), + monitors: form.monitors.map((monitor) => toStringId(monitor)).filter(Boolean), name: form.name, start: start.toISOString(), end: end.toISOString(), diff --git a/client/src/Pages/Maintenance/CreateMaintenance/hooks/useMaintenanceData.jsx b/client/src/Pages/Maintenance/CreateMaintenance/hooks/useMaintenanceData.jsx index c3be0091a..96f37fd61 100644 --- a/client/src/Pages/Maintenance/CreateMaintenance/hooks/useMaintenanceData.jsx +++ b/client/src/Pages/Maintenance/CreateMaintenance/hooks/useMaintenanceData.jsx @@ -41,7 +41,7 @@ const useMaintenanceData = () => { limit: null, types: ["http", "ping", "pagespeed", "port"], }); - const fetchedMonitors = response.data.data.monitors; + const fetchedMonitors = response.data.data; return fetchedMonitors; }; @@ -55,7 +55,7 @@ const useMaintenanceData = () => { const endTime = dayjs(end); const durationInMs = endTime.diff(startTime, "milliseconds").toString(); const { duration, durationUnit } = getDurationAndUnit(durationInMs); - const monitor = monitorList.find((monitor) => monitor._id === monitorId); + const monitor = monitorList.find((monitor) => (monitor._id ?? monitor.id) === monitorId); const maintenanceWindowInformation = { name, repeat: REVERSE_REPEAT_LOOKUP[repeat], diff --git a/client/src/Pages/Maintenance/CreateMaintenance/index.jsx b/client/src/Pages/Maintenance/CreateMaintenance/index.jsx index 384805f3a..759679a2d 100644 --- a/client/src/Pages/Maintenance/CreateMaintenance/index.jsx +++ b/client/src/Pages/Maintenance/CreateMaintenance/index.jsx @@ -108,6 +108,7 @@ const CreateMaintenance = () => { const handleSubmit = async () => { if (hasValidationErrors(form, maintenanceWindowValidation, setErrors)) return; + const request = handleSubmitForm(maintenanceWindowId, form); try { setIsLoading(true); diff --git a/client/src/Pages/StatusPage/Create/Components/MonitorList/index.jsx b/client/src/Pages/StatusPage/Create/Components/MonitorList/index.jsx index 5484202d5..d2a13b2eb 100644 --- a/client/src/Pages/StatusPage/Create/Components/MonitorList/index.jsx +++ b/client/src/Pages/StatusPage/Create/Components/MonitorList/index.jsx @@ -43,7 +43,7 @@ const MonitorListItem = ({ const MonitorList = ({ selectedMonitors, setSelectedMonitors }) => { const onDelete = (monitorToDelete) => { const newMonitors = selectedMonitors.filter( - (monitor) => monitor._id !== monitorToDelete._id + (monitor) => monitor.id !== monitorToDelete.id ); setSelectedMonitors(newMonitors); }; @@ -80,8 +80,8 @@ const MonitorList = ({ selectedMonitors, setSelectedMonitors }) => { > {selectedMonitors?.map((monitor, index) => ( {(provided, snapshot) => ( diff --git a/client/src/Pages/StatusPage/Create/Components/Tabs/Content.jsx b/client/src/Pages/StatusPage/Create/Components/Tabs/Content.jsx index d11825e69..e84de16dc 100644 --- a/client/src/Pages/StatusPage/Create/Components/Tabs/Content.jsx +++ b/client/src/Pages/StatusPage/Create/Components/Tabs/Content.jsx @@ -24,7 +24,7 @@ const Content = ({ // Handlers const handleMonitorsChange = (selectedMonitors) => { handleFormChange({ - target: { name: "monitors", value: selectedMonitors.map((monitor) => monitor._id) }, + target: { name: "monitors", value: selectedMonitors.map((monitor) => monitor.id) }, }); setSelectedMonitors(selectedMonitors); }; diff --git a/client/src/Pages/StatusPage/Create/Hooks/useMonitorsFetch.jsx b/client/src/Pages/StatusPage/Create/Hooks/useMonitorsFetch.jsx index 95ce2b8c0..03ebb07bf 100644 --- a/client/src/Pages/StatusPage/Create/Hooks/useMonitorsFetch.jsx +++ b/client/src/Pages/StatusPage/Create/Hooks/useMonitorsFetch.jsx @@ -16,7 +16,7 @@ const useMonitorsFetch = () => { limit: null, // donot return any checks for the monitors types: ["http", "ping", "port", "game"], // include game servers in status page monitor selection }); - setMonitors(response.data.data.monitors); + setMonitors(response.data.data); } catch (error) { setNetworkError(true); createToast({ body: error.message }); diff --git a/client/src/Pages/StatusPage/Create/index.jsx b/client/src/Pages/StatusPage/Create/index.jsx index 7fbe6a8dc..f8fcf0e91 100644 --- a/client/src/Pages/StatusPage/Create/index.jsx +++ b/client/src/Pages/StatusPage/Create/index.jsx @@ -62,7 +62,6 @@ const CreateStatusPage = () => { useStatusPageFetch(isCreate, url); const [deleteStatusPage, isDeleting] = useStatusPageDelete(fetchStatusPage, url); - console.log(JSON.stringify(form, null, 2)); // Handlers const handleFormChange = (e) => { let { type, name, value, checked } = e.target; @@ -144,6 +143,8 @@ const CreateStatusPage = () => { ...form, logo: { type: form.logo?.type ?? null, size: form.logo?.size ?? null }, }; + + console.log(toSubmit); const { error } = statusPageValidation.validate(toSubmit, { abortEarly: false, }); @@ -205,7 +206,7 @@ const CreateStatusPage = () => { companyName: statusPage?.companyName, isPublished: statusPage?.isPublished, timezone: statusPage?.timezone, - monitors: statusPageMonitors.map((monitor) => monitor._id), + monitors: statusPageMonitors.map((monitor) => monitor.id), color: statusPage?.color, logo: newLogo, showCharts: statusPage?.showCharts ?? true, diff --git a/client/src/Pages/StatusPage/Status/Components/MonitorsList/index.jsx b/client/src/Pages/StatusPage/Status/Components/MonitorsList/index.jsx index 89e32e5d5..33f771233 100644 --- a/client/src/Pages/StatusPage/Status/Components/MonitorsList/index.jsx +++ b/client/src/Pages/StatusPage/Status/Components/MonitorsList/index.jsx @@ -28,14 +28,14 @@ const MonitorsList = ({ const status = determineState(monitor); return ( { params.append("type", type); }); } - if (page) params.append("page", page); - if (rowsPerPage) params.append("rowsPerPage", rowsPerPage); - if (filter) params.append("filter", filter); - if (field) params.append("field", field); - if (order) params.append("order", order); + if (filter !== undefined && filter !== null && filter !== "") params.append("filter", filter); return this.axiosInstance.get(`/monitors/team?${params.toString()}`, { headers: { diff --git a/server/src/controllers/monitorController.ts b/server/src/controllers/monitorController.ts index ce0347512..9124abd06 100644 --- a/server/src/controllers/monitorController.ts +++ b/server/src/controllers/monitorController.ts @@ -5,6 +5,7 @@ import { getMonitorByIdQueryValidation, getMonitorsByTeamIdParamValidation, getMonitorsByTeamIdQueryValidation, + getMonitorsWithChecksQueryValidation, createMonitorBodyValidation, editMonitorBodyValidation, pauseMonitorParamValidation, @@ -317,10 +318,10 @@ class MonitorController { await getMonitorsByTeamIdParamValidation.validateAsync(req.params); await getMonitorsByTeamIdQueryValidation.validateAsync(req.query); - let { limit, type, page, rowsPerPage, filter, field, order } = req.query; + const { type, filter } = req.query; const teamId = req?.user?.teamId; - const monitors = await this.monitorService.getMonitorsByTeamId({ teamId, limit, type, page, rowsPerPage, filter, field, order }); + const monitors = await this.monitorService.getMonitorsByTeamId({ teamId, type, filter }); return res.status(200).json({ success: true, @@ -358,7 +359,7 @@ class MonitorController { getMonitorsWithChecksByTeamId = async (req: Request, res: Response, next: NextFunction) => { try { await getMonitorsByTeamIdParamValidation.validateAsync(req.params); - await getMonitorsByTeamIdQueryValidation.validateAsync(req.query); + await getMonitorsWithChecksQueryValidation.validateAsync(req.query); const explain = req?.query?.explain; let { limit, type, page, rowsPerPage, filter, field, order } = req.query; diff --git a/server/src/db/modules/monitorModule.js b/server/src/db/modules/monitorModule.js index 87237632a..84ff86996 100755 --- a/server/src/db/modules/monitorModule.js +++ b/server/src/db/modules/monitorModule.js @@ -289,47 +289,33 @@ class MonitorModule { } }; - getMonitorsByTeamId = async ({ limit, type, page, rowsPerPage, filter, field, order, teamId }) => { - limit = parseInt(limit); - page = parseInt(page); - rowsPerPage = parseInt(rowsPerPage); - if (field === undefined) { - field = "name"; - order = "asc"; - } - // Build match stage - const matchStage = { teamId: new this.ObjectId(teamId) }; - if (type !== undefined) { - matchStage.type = Array.isArray(type) ? { $in: type } : type; - } - - const summaryResult = await this.Monitor.aggregate(buildMonitorSummaryByTeamIdPipeline({ matchStage })); - const summary = summaryResult[0]; - - const monitors = await this.Monitor.aggregate(buildMonitorsByTeamIdPipeline({ matchStage, field, order })); - - const filteredMonitors = await this.Monitor.aggregate( - buildFilteredMonitorsByTeamIdPipeline({ - matchStage, - filter, - page, - rowsPerPage, - field, - order, - limit, - type, - }) - ); - - const normalizedFilteredMonitors = filteredMonitors.map((monitor) => { - if (!monitor.checks) { - return monitor; + getMonitorsByTeamId = async ({ teamId, type, filter }) => { + try { + const matchStage = { teamId: new this.ObjectId(teamId) }; + if (type !== undefined) { + matchStage.type = Array.isArray(type) ? { $in: type } : type; } - monitor.checks = this.NormalizeData(monitor.checks, 10, 100); - return monitor; - }); - - return { summary, monitors, filteredMonitors: normalizedFilteredMonitors }; + if (filter !== undefined && filter !== null && filter !== "") { + matchStage.$or = [{ name: { $regex: filter, $options: "i" } }, { url: { $regex: filter, $options: "i" } }]; + } + const monitors = await this.Monitor.find(matchStage) + .sort({ name: 1 }) + .select({ + _id: 1, + name: 1, + type: 1, + url: 1, + status: 1, + isActive: 1, + teamId: 1, + }) + .lean(); + return monitors; + } catch (error) { + error.service = SERVICE_NAME; + error.method = "getMonitorsByTeamId"; + throw error; + } }; getMonitorsAndSummaryByTeamId = async ({ type, explain, teamId }) => { diff --git a/server/src/service/business/monitorService.ts b/server/src/service/business/monitorService.ts index 0296ce9ca..46731446f 100644 --- a/server/src/service/business/monitorService.ts +++ b/server/src/service/business/monitorService.ts @@ -323,34 +323,10 @@ export class MonitorService implements IMonitorService { return monitor; }; - getMonitorsByTeamId = async ({ - teamId, - limit, - type, - page, - rowsPerPage, - filter, - field, - order, - }: { - teamId: string; - limit?: number; - type?: string | string[]; - page?: number; - rowsPerPage?: number; - filter?: string; - field?: string; - order?: "asc" | "desc"; - }): Promise => { - const monitors = await this.db.monitorModule.getMonitorsByTeamId({ - limit, + getMonitorsByTeamId = async ({ teamId, type, filter }: { teamId: string; type?: MonitorType | MonitorType[]; filter?: string }): Promise => { + const monitors = await this.monitorsRepository.findByTeamId(teamId, { type, - page, - rowsPerPage, filter, - field, - order, - teamId, }); return monitors; }; diff --git a/server/src/validation/joi.js b/server/src/validation/joi.js index e1d04047d..c09ac88b9 100755 --- a/server/src/validation/joi.js +++ b/server/src/validation/joi.js @@ -120,18 +120,30 @@ const getMonitorByIdQueryValidation = joi.object({ const getMonitorsByTeamIdParamValidation = joi.object({}); const getMonitorsByTeamIdQueryValidation = joi.object({ - limit: joi.number(), type: joi .alternatives() .try( joi.string().valid("http", "ping", "pagespeed", "docker", "hardware", "port", "game"), joi.array().items(joi.string().valid("http", "ping", "pagespeed", "docker", "hardware", "port", "game")) ), - page: joi.number(), - rowsPerPage: joi.number(), - filter: joi.string(), - field: joi.string(), - order: joi.string().valid("asc", "desc"), + filter: joi.string().allow("", null), +}); + +const getMonitorsWithChecksQueryValidation = joi.object({ + limit: joi.number().integer().min(1).max(100).optional(), + page: joi.number().integer().min(0).optional(), + rowsPerPage: joi.number().integer().min(1).max(100).optional(), + filter: joi.string().allow("", null).optional(), + field: joi.string().optional(), + order: joi.string().valid("asc", "desc").optional(), + type: joi + .alternatives() + .try( + joi.string().valid("http", "ping", "pagespeed", "docker", "hardware", "port", "game"), + joi.array().items(joi.string().valid("http", "ping", "pagespeed", "docker", "hardware", "port", "game")) + ) + .optional(), + explain: joi.boolean().optional(), }); const getCertificateParamValidation = joi.object({ @@ -713,6 +725,7 @@ export { getMonitorByIdQueryValidation, getMonitorsByTeamIdParamValidation, getMonitorsByTeamIdQueryValidation, + getMonitorsWithChecksQueryValidation, getHardwareDetailsByIdParamValidation, getHardwareDetailsByIdQueryValidation, getCertificateParamValidation,