Загрузка данных
import { type AuditRouteSearch } from '@/app/router/routes/audit';
import { EquipmentModel } from '@/features/Settings/selects/lib';
import { useGetLocationChildrenQuery } from '@/shared/api/location/client';
import { useAutocompleteDebounce } from '@/shared/hooks';
import { Helpers } from '@/shared/lib';
import { ChangeEvent, useCallback, useEffect, useMemo, useRef } from 'react';
type ModelSelectValue = string | number | boolean | null;
type ModelSelectChangeValue = ModelSelectValue | ModelSelectValue[];
type Params = {
searchParams: AuditRouteSearch;
updateParamAndResetPage: (paramName: string, value: unknown) => void;
updateParamsAndResetPage: (queryObject: Record<string, unknown>) => void;
};
const EQUIPMENT_FILTER_TYPES = [
'controller_delete',
'device_delete',
'network_device_delete',
'offline_device_delete',
'padlet_delete',
];
const getEquipmentModelType = (messageType?: string) => {
switch (messageType) {
case 'controller_delete':
return EquipmentModel.controller;
case 'padlet_delete':
return EquipmentModel.padlet;
default:
return EquipmentModel.device;
}
};
const normalizeModelSelectValue = (
value: ModelSelectChangeValue,
): ModelSelectValue[] => {
if (Array.isArray(value)) {
return value;
}
return value === null ? [] : [value];
};
export const useAdditionalFilters = ({
searchParams,
updateParamAndResetPage,
updateParamsAndResetPage,
}: Params) => {
const isMacResetting = useRef(false);
const isIpResetting = useRef(false);
const isMacDebounceReady = useRef(false);
const isIpDebounceReady = useRef(false);
const {
inputValue: macValue,
debouncedValue: debouncedMac,
onInputChange: onMacInputChange,
resetDebounce: resetMacDebounce,
} = useAutocompleteDebounce(searchParams.mac || '');
const {
inputValue: ipValue,
debouncedValue: debouncedIp,
onInputChange: onIpInputChange,
resetDebounce: resetIpDebounce,
} = useAutocompleteDebounce(searchParams.ip || '');
const isEquipmentFiltersAvailable = EQUIPMENT_FILTER_TYPES.includes(
searchParams.type || '',
);
const equipmentModelType = getEquipmentModelType(searchParams.type);
const { data: roomsData } = useGetLocationChildrenQuery(
{
parentId: Helpers.convertStringsToNumbers(searchParams.floorId),
},
{
skip: !searchParams.floorId.length,
refetchOnMountOrArgChange: true,
},
);
const roomIdByTreeId = useMemo(() => {
const map = new Map<string, string>();
roomsData?.forEach((room) => {
if (room.treeId !== undefined && room.id !== undefined) {
map.set(String(room.treeId), String(room.id));
}
});
return map;
}, [roomsData]);
useEffect(() => {
if (!isMacDebounceReady.current) {
isMacDebounceReady.current = true;
return;
}
if (isMacResetting.current) {
isMacResetting.current = false;
return;
}
updateParamAndResetPage('mac', debouncedMac || undefined);
}, [debouncedMac, updateParamAndResetPage]);
useEffect(() => {
if (!isIpDebounceReady.current) {
isIpDebounceReady.current = true;
return;
}
if (isIpResetting.current) {
isIpResetting.current = false;
return;
}
updateParamAndResetPage('ip', debouncedIp || undefined);
}, [debouncedIp, updateParamAndResetPage]);
const setRegionId = useCallback(
(value: string[]) => {
updateParamsAndResetPage({
regionId: value,
cityId: [],
placeId: [],
floorId: [],
roomId: [],
locationIds: [],
});
},
[updateParamsAndResetPage],
);
const setCityId = useCallback(
(value: string[]) => {
updateParamsAndResetPage({
cityId: value,
placeId: [],
floorId: [],
roomId: [],
locationIds: [],
});
},
[updateParamsAndResetPage],
);
const setPlaceId = useCallback(
(value: string[]) => {
updateParamsAndResetPage({
placeId: value,
floorId: [],
roomId: [],
locationIds: [],
});
},
[updateParamsAndResetPage],
);
const setFloorId = useCallback(
(value: string[]) => {
updateParamsAndResetPage({
floorId: value,
roomId: [],
locationIds: [],
});
},
[updateParamsAndResetPage],
);
const setRoomId = useCallback(
(roomTreeIds: string[]) => {
const locationIds = roomTreeIds
.map((treeId) => roomIdByTreeId.get(String(treeId)))
.filter((id): id is string => Boolean(id));
updateParamsAndResetPage({
roomId: roomTreeIds,
locationIds,
});
},
[roomIdByTreeId, updateParamsAndResetPage],
);
const handleChangeModels = useCallback(
(value: ModelSelectChangeValue) => {
updateParamAndResetPage(
'modelIds',
normalizeModelSelectValue(value).map(String),
);
},
[updateParamAndResetPage],
);
const handleMacChange = useCallback(
(event: ChangeEvent<HTMLInputElement>) => {
onMacInputChange(event.target.value);
},
[onMacInputChange],
);
const handleIpChange = useCallback(
(event: ChangeEvent<HTMLInputElement>) => {
onIpInputChange(event.target.value);
},
[onIpInputChange],
);
const resetAdditionalFilterInputs = useCallback(() => {
isMacResetting.current = true;
isIpResetting.current = true;
resetMacDebounce();
resetIpDebounce();
}, [resetIpDebounce, resetMacDebounce]);
const clearAdditionalFilters = useCallback(() => {
resetAdditionalFilterInputs();
updateParamsAndResetPage({
modelIds: [],
locationIds: [],
mac: undefined,
ip: undefined,
regionId: [],
cityId: [],
placeId: [],
floorId: [],
roomId: [],
});
}, [resetAdditionalFilterInputs, updateParamsAndResetPage]);
return {
isEquipmentFiltersAvailable,
equipmentModelType,
modelIds: searchParams.modelIds,
macValue,
ipValue,
locationIds: searchParams.locationIds,
cityId: searchParams.cityId,
floorId: searchParams.floorId,
placeId: searchParams.placeId,
regionId: searchParams.regionId,
roomId: searchParams.roomId,
setRegionId,
setCityId,
setPlaceId,
setFloorId,
setRoomId,
handleChangeModels,
handleMacChange,
handleIpChange,
clearAdditionalFilters,
resetAdditionalFilterInputs,
};
};