From 5a10687778366e008cae9566395303e06e07b20f Mon Sep 17 00:00:00 2001 From: RekHoto Date: Tue, 22 Aug 2023 01:32:24 +0400 Subject: [PATCH 1/2] refactoring --- src/Map/Layers/Layers.jsx | 2 +- src/Map/Layers/PendingPoints.jsx | 16 ++---- src/Map/LayersControl/LayersVisibility.jsx | 2 +- src/Map/Legend.jsx | 4 +- src/Map/MapComponent.jsx | 39 +++------------ src/Map/Popup/Popup.jsx | 15 ++---- src/api.js | 17 ++++--- .../AdvancedFilters/AdvancedFilters.jsx | 49 +++++-------------- .../AdvancedFiltersWrapper.jsx | 8 +-- .../AdvancedFilters/Slider.jsx | 10 ++-- .../Table/PendingTable/usePendingTableData.js | 8 +-- src/stores/usePendingPointsFilters.js | 16 ++++++ src/utils.js | 29 +++++++++++ 13 files changed, 99 insertions(+), 116 deletions(-) diff --git a/src/Map/Layers/Layers.jsx b/src/Map/Layers/Layers.jsx index ed3396d..ffefac9 100644 --- a/src/Map/Layers/Layers.jsx +++ b/src/Map/Layers/Layers.jsx @@ -43,7 +43,7 @@ export const Layers = ({ postGroups, otherGroups }) => { type="vector" tiles={[`${BASE_URL}/martin/public.service_post_and_pvz/{z}/{x}/{y}.pbf`]} > - {postGroups && postGroups.map((item) => { + {postGroups?.map((item) => { return item.groups.map((itemGroup) => { const dynamicKeyExpressions = dynamicKeyFiltersExpressions.filter((expression) => { const filterKey = expression[0][1][1]; - const range = ranges[filterKey]; - const gtValue = expression[0][2] || 0; - const gtInitial = range ? range[0] : 0; - const ltValue = expression[1][2] || 0; - const ltInitial = range ? range[1] : 0; - - return !(gtValue === gtInitial && ltValue === ltInitial); + return fieldHasChanged(filters, ranges, filterKey).result; }).flat(); const staticKeyExpressions = staticKeyFiltersExpressions.filter((expression) => { const filterKey = expression[0][1][1]; - const gtValue = expression[0][2]; - const gtInitial = ranges[filterKey][0]; - const ltValue = expression[1][2]; - const ltInitial = ranges[filterKey][1]; - - return !(gtValue === gtInitial && ltValue === ltInitial); + return fieldHasChanged(filters, ranges, filterKey).result; }).flat(); const categoryExpression = diff --git a/src/Map/LayersControl/LayersVisibility.jsx b/src/Map/LayersControl/LayersVisibility.jsx index 59eb37a..dbf8ff9 100644 --- a/src/Map/LayersControl/LayersVisibility.jsx +++ b/src/Map/LayersControl/LayersVisibility.jsx @@ -28,7 +28,7 @@ export const LayersVisibility = ({ postGroups, otherGroups }) => { )} - {postGroups && postGroups.map((item) => { + {postGroups?.map((item) => { return (
- {postGroups && postGroups?.map((item) => { + {postGroups?.map((item) => { return })}
- {otherGroups && otherGroups?.map((item) => { + {otherGroups?.map((item) => { return })}
diff --git a/src/Map/MapComponent.jsx b/src/Map/MapComponent.jsx index 064b003..576cf89 100644 --- a/src/Map/MapComponent.jsx +++ b/src/Map/MapComponent.jsx @@ -23,7 +23,7 @@ import { Header } from "./Header"; import { icons } from "../icons/icons-config"; import { LastMLRun } from "./LastMLRun"; import { useGetPendingPointsRange, useOtherGroups, usePostamatesAndPvzGroups } from "../api.js"; -import {transliterate} from "../utils.js"; +import { getFilteredGroups, transliterate } from "../utils.js"; import { usePendingPointsFilters } from "../stores/usePendingPointsFilters.js"; export const MapComponent = () => { @@ -35,10 +35,9 @@ export const MapComponent = () => { const { setLayersVisibility } = useLayersVisibility(); const { mode } = useMode(); const { tableState, openTable } = useTable(); - const { toggleVisibility } = useLayersVisibility(); const { ranges, setRanges } = usePendingPointsFilters(); - const { data: fullRange, isInitialLoading } = useGetPendingPointsRange(); + const { data: fullRange } = useGetPendingPointsRange(); useEffect(() => { if (fullRange) setRanges({...ranges, ...fullRange}); @@ -48,45 +47,21 @@ export const MapComponent = () => { const { data: otherGroups } = useOtherGroups(); const filteredPostamatesGroups = useMemo(() => { - if (!postamatesAndPvzGroups) return []; - return postamatesAndPvzGroups - .filter((category) => category.visible) - .map((category) => { - toggleVisibility(LAYER_IDS.pvz_category + category.id) - return { - ...category, - groups: [...category.groups.filter((group) => group.visible)], - } - }) + return getFilteredGroups(postamatesAndPvzGroups); }, [postamatesAndPvzGroups]); const filteredOtherGroups = useMemo(() => { - if (!otherGroups) return []; - return otherGroups - .filter((category) => !category.visible) - .map((category) => { - return { - ...category, - groups: [...category.groups.filter((group) => group.visible)], - } - }) + return getFilteredGroups(otherGroups); }, [otherGroups]); const mapIcons = useMemo(() => { const res = []; - filteredPostamatesGroups.map((category) => { + [...filteredOtherGroups, ...filteredPostamatesGroups].map((category) => { category.groups.map((group) => { - res.push({name: transliterate(group.name + group.id), url: group.image}) + res.push({name: transliterate(group.name + group.id), url: group.image}); }) }); - - filteredOtherGroups.map((category) => { - category.groups.map((group) => { - res.push({name: transliterate(group.name + group.id), url: group.image}) - }) - }); - return [...res, ...icons]; }, [icons, filteredPostamatesGroups, filteredOtherGroups]); @@ -220,7 +195,7 @@ export const MapComponent = () => { ); img.onload = () => mapRef.current.addImage(icon.name, img); - img.src = icon.url; + img.src = 'https://docs.mapbox.com/mapbox-gl-js/assets/cat.png'; img.crossOrigin = "Anonymous"; }); }} diff --git a/src/Map/Popup/Popup.jsx b/src/Map/Popup/Popup.jsx index 10d6879..8027c3c 100644 --- a/src/Map/Popup/Popup.jsx +++ b/src/Map/Popup/Popup.jsx @@ -11,6 +11,7 @@ import { usePopup } from "../../stores/usePopup.js"; import { PanoramaIcon } from "../../icons/PanoramaIcon"; import {usePostamatesAndPvzGroups} from "../../api.js"; import {useMemo} from "react"; +import {getFilteredGroups} from "../../utils.js"; const SingleFeaturePopup = ({ feature, groups, categories }) => { const { mode } = useMode(); @@ -94,24 +95,16 @@ export const MapPopup = ({ features, lat, lng, onClose }) => { const { data: postamatesAndPvzGroups } = usePostamatesAndPvzGroups(); const filteredPostamatesCategories = useMemo(() => { - if (!postamatesAndPvzGroups) return []; - return postamatesAndPvzGroups - .filter((category) => category.visible) - .map((category) => { - return { - ...category, - groups: [...category.groups.filter((group) => group.visible)], - } - }) + return getFilteredGroups(postamatesAndPvzGroups); }, [postamatesAndPvzGroups]); const postamatesGroups = useMemo(() => { if (!filteredPostamatesCategories) return []; return filteredPostamatesCategories .map((category) => { - return [...category.groups.filter((group) => group.visible)] + return [...category.groups] }).flat(); - }, [postamatesAndPvzGroups]); + }, [filteredPostamatesCategories]); const getContent = () => { if (features.length === 1) { diff --git a/src/api.js b/src/api.js index 2b99223..7e5a5e6 100644 --- a/src/api.js +++ b/src/api.js @@ -2,7 +2,7 @@ import axios from "axios"; import { useMutation, useQuery } from "@tanstack/react-query"; import { STATUSES } from "./config"; import { usePointSelection } from "./stores/usePointSelection"; -import { usePendingPointsFilters } from "./stores/usePendingPointsFilters"; +import { RANGE_FILTERS_KEYS, usePendingPointsFilters } from "./stores/usePendingPointsFilters"; export const BASE_URL = import.meta.env.VITE_API_URL; @@ -189,16 +189,19 @@ export const useGetPendingPointsRange = () => { select: (data) => { const distToGroupsArr = data.dist_to_groups.map((groupRange) => { return { - [`d${groupRange.group_id}`]: groupRange.dist, + [`d${groupRange.group_id}`]: [Math.floor(groupRange.dist[0]), Math.ceil(groupRange.dist[1])], } - }) + }); const distToGroups = Object.assign({}, ...distToGroupsArr); + const rangesArr = RANGE_FILTERS_KEYS.map((key) => { + return { + [key]: [Math.floor(data[key][0]), Math.ceil(data[key][1])] + } + }); + const ranges = Object.assign({}, ...rangesArr); return { prediction: data.prediction_current, - doors: data.doors, - flat_cnt: data.flat_cnt, - flats_cnt: data.flats_cnt, - target_post_cnt: data.target_post_cnt, + ...ranges, ...distToGroups }; }, diff --git a/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/AdvancedFilters.jsx b/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/AdvancedFilters.jsx index 30fbd70..13ca18d 100644 --- a/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/AdvancedFilters.jsx +++ b/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/AdvancedFilters.jsx @@ -4,26 +4,15 @@ import { Collapse } from "antd"; import React, { useMemo } from "react"; import { Title } from "../../../../components/Title.jsx"; import { usePostamatesAndPvzGroups } from "../../../../api.js"; +import { getFilteredGroups } from "../../../../utils.js"; export const AdvancedFilters = () => { - const { - filters, - setFilterWithKey, - ranges - } = usePendingPointsFilters(); + const { filters, ranges } = usePendingPointsFilters(); const { data: postamatesAndPvzGroups } = usePostamatesAndPvzGroups(); const filteredPostamatesGroups = useMemo(() => { - if (!postamatesAndPvzGroups) return []; - return postamatesAndPvzGroups - .filter((category) => category.visible) - .map((category) => { - return { - ...category, - groups: [...category.groups.filter((group) => group.visible)], - } - }) + return getFilteredGroups(postamatesAndPvzGroups); }, [postamatesAndPvzGroups]); return ( @@ -45,7 +34,6 @@ export const AdvancedFilters = () => {
{
{
{
{
{
{
{
{
{ {filteredPostamatesGroups.map((category) => { return ( {
{category.groups.map((group) => { return ( -
+
{ ) })}
- ) diff --git a/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/AdvancedFiltersWrapper.jsx b/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/AdvancedFiltersWrapper.jsx index 3c7df0b..1a73438 100644 --- a/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/AdvancedFiltersWrapper.jsx +++ b/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/AdvancedFiltersWrapper.jsx @@ -1,5 +1,6 @@ -import {Button, Dropdown} from "antd"; -import {AdvancedFilters} from "./AdvancedFilters.jsx"; +import { Button, Dropdown } from "antd"; +import { AdvancedFilters } from "./AdvancedFilters.jsx"; +import { RightOutlined } from "@ant-design/icons"; export const AdvancedFiltersWrapper = () => { const filtersRender = () => { @@ -17,9 +18,10 @@ export const AdvancedFiltersWrapper = () => { > ); diff --git a/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/Slider.jsx b/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/Slider.jsx index 00ddfda..0b4e947 100644 --- a/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/Slider.jsx +++ b/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/Slider.jsx @@ -1,11 +1,13 @@ import { SliderComponent as Slider } from "../../../../components/SliderComponent"; import { useEffect } from "react"; import { - INITIAL, + INITIAL, usePendingPointsFilters, } from "../../../../stores/usePendingPointsFilters"; -export const FilterSlider = ({ filterRange, setFilterRange, disabled, fullRange, title, filterKey, dynamicKey }) => { - const handleAfterChange = (range) => setFilterRange(range, filterKey); +export const FilterSlider = ({ filterRange, disabled, fullRange, title, filterKey, dynamicKey }) => { + + const { setFilterWithKey } = usePendingPointsFilters(); + const handleAfterChange = (range) => setFilterWithKey(range, filterKey); useEffect(() => { if (!fullRange) return; @@ -24,7 +26,7 @@ export const FilterSlider = ({ filterRange, setFilterRange, disabled, fullRange, filterRange[1] === 0); if (shouldSetFullRange || (shouldSetDynamicKeyRange && dynamicKey)) { - setFilterRange([min, max], filterKey); + setFilterWithKey([min, max], filterKey); } }, [fullRange]); diff --git a/src/modules/Table/PendingTable/usePendingTableData.js b/src/modules/Table/PendingTable/usePendingTableData.js index 2bbd685..c8612a5 100644 --- a/src/modules/Table/PendingTable/usePendingTableData.js +++ b/src/modules/Table/PendingTable/usePendingTableData.js @@ -3,6 +3,7 @@ import { getPoints } from "../../../api"; import { useMergeTableData } from "../useMergeTableData"; import { STATUSES } from "../../../config"; import { RANGE_FILTERS_KEYS, usePendingPointsFilters } from "../../../stores/usePendingPointsFilters"; +import {fieldHasChanged} from "../../../utils.js"; export const usePendingTableData = (page, resetPage, pageSize, setPageSize, sort) => { const { filters, ranges } = usePendingPointsFilters(); @@ -23,12 +24,7 @@ export const usePendingTableData = (page, resetPage, pageSize, setPageSize, sort }; RANGE_FILTERS_KEYS.map((filterKey) => { - const gtValue = filters[`${filterKey}__gt`]; - const gtInitial = ranges[filterKey][0]; - const ltValue = filters[`${filterKey}__lt`]; - const ltInitial = ranges[filterKey][1]; - - if (gtValue === gtInitial && ltValue === ltInitial) return; + if (!fieldHasChanged(filters, ranges, filterKey).result) return; tempParams = { ...tempParams, [`${filterKey}__gt`]: filters[`${filterKey}__gt`] - 1, diff --git a/src/stores/usePendingPointsFilters.js b/src/stores/usePendingPointsFilters.js index 6fe386d..bc5eb80 100644 --- a/src/stores/usePendingPointsFilters.js +++ b/src/stores/usePendingPointsFilters.js @@ -18,6 +18,22 @@ export const RANGE_FILTERS_KEYS = [ 'metro_dist', ] +export const RANGE_FILTERS_MAP = { + doors: "Кол-во подъездов в жилом доме", + flat_cnt: "Кол-во квартир в подъезде жилого дома", + rival_post_cnt: "Кол-во постаматов других сетей", + rival_pvz_cnt: "Кол-во ПВЗ", + target_post_cnt: "Кол-во постаматов Мой постамат", + flats_cnt: "Кол-во квартир в окрестности", + tc_cnt: "Кол-во торговых центров", + culture_cnt: "Кол-во объектов культуры (театры, музей и тд)", + mfc_cnt: "Кол-во МФЦ", + public_stop_cnt: "Кол-во остановок ОТ", + supermarket_cnt: "Кол-во супермаркетов", + target_dist: "Расстояние до постамата Мой постамат", + metro_dist: "Расстояние до метро", +} + export const INITIAL = { prediction: [0, 0], categories: [], diff --git a/src/utils.js b/src/utils.js index b589d75..332e4bf 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,3 +1,5 @@ +import {usePendingPointsFilters} from "./stores/usePendingPointsFilters.js"; + export function download(filename, data) { const downloadLink = window.document.createElement("a"); downloadLink.href = window.URL.createObjectURL( @@ -19,5 +21,32 @@ export function transliterate(word){ }).join(""); } +export function getFilteredGroups(categories) { + if (!categories) return []; + return categories + .filter((category) => category.visible) + .map((category) => { + return { + ...category, + groups: [...category.groups.filter((group) => group.visible)], + } + }) +} + +export function fieldHasChanged(filters, ranges, filterKey) { + const gtValue = filters[`${filterKey}__gt`]; + const gtInitial = ranges[filterKey][0]; + const ltValue = filters[`${filterKey}__lt`]; + const ltInitial = ranges[filterKey][1]; + + const result = !(gtValue === gtInitial && ltValue === ltInitial) + + return { + result, + gtValue, + ltValue, + } +} + export const isNil = (value) => value === undefined || value === null || value === ""; From cdbcc2dafe33d438f7dabe6083dd50ea086d8b74 Mon Sep 17 00:00:00 2001 From: RekHoto Date: Tue, 22 Aug 2023 06:26:39 +0400 Subject: [PATCH 2/2] filters styling --- src/App.jsx | 2 +- src/Map/LastMLRun.jsx | 2 +- src/Map/Layers/PendingPoints.jsx | 41 +- src/Map/MapComponent.jsx | 6 +- src/api.js | 3 +- .../AdvancedFilters/AdvancedFilters.jsx | 380 ++++++++++-------- .../AdvancedFiltersWrapper.jsx | 54 ++- .../AdvancedFilters/Slider.jsx | 5 +- src/stores/usePendingPointsFilters.js | 7 + src/utils.js | 9 +- 10 files changed, 284 insertions(+), 225 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index e93a74d..2c505b4 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -23,7 +23,7 @@ if (import.meta.env.MODE === "development") { mountStoreDevtool("PointSelection", usePointSelection); } -const version = '0.0.4'; +const version = '0.0.5'; function App() { diff --git a/src/Map/LastMLRun.jsx b/src/Map/LastMLRun.jsx index 7a83c7a..1ba9416 100644 --- a/src/Map/LastMLRun.jsx +++ b/src/Map/LastMLRun.jsx @@ -19,7 +19,7 @@ export function LastMLRun() { trigger="click" placement={"leftBottom"} > - + diff --git a/src/Map/Layers/PendingPoints.jsx b/src/Map/Layers/PendingPoints.jsx index dafdc74..dae2938 100644 --- a/src/Map/Layers/PendingPoints.jsx +++ b/src/Map/Layers/PendingPoints.jsx @@ -9,35 +9,11 @@ import { STATUSES } from "../../config"; import { useRegionFilterExpression } from "./useRegionFilterExpression"; import { LAYER_IDS } from "./constants"; import { RANGE_FILTERS_KEYS, usePendingPointsFilters } from "../../stores/usePendingPointsFilters"; -import { usePostamatesAndPvzGroups } from "../../api.js"; -import { useMemo } from "react"; import {fieldHasChanged} from "../../utils.js"; const statusExpression = ["==", ["get", "status"], STATUSES.pending]; const useFilterExpression = () => { - const { data: postamatesAndPvzGroups } = usePostamatesAndPvzGroups(); - - const filteredPostamatesCategories = useMemo(() => { - if (!postamatesAndPvzGroups) return []; - return postamatesAndPvzGroups - .filter((category) => category.visible) - .map((category) => { - return { - ...category, - groups: [...category.groups.filter((group) => group.visible)], - } - }) - }, [postamatesAndPvzGroups]); - - const postamatesGroups = useMemo(() => { - if (!filteredPostamatesCategories) return []; - return filteredPostamatesCategories - .map((category) => { - return [...category.groups.filter((group) => group.visible)] - }).flat(); - }, [postamatesAndPvzGroups]); - const { filters, ranges } = usePendingPointsFilters(); const { prediction, categories, region } = filters; const { selection } = usePointSelection(); @@ -54,14 +30,6 @@ const useFilterExpression = () => { ["<=", ["get", "prediction_current"], prediction[1]], ]; - const dynamicKeyFiltersExpressions = postamatesGroups.map((group) => { - const key = `d${group.id}` - return [ - [">=", ["get", key], filters[`${key}__gt`]], - ["<=", ["get", key], filters[`${key}__lt`]], - ]; - }); - const staticKeyFiltersExpressions = RANGE_FILTERS_KEYS.map((key) => { return [ [">=", ["get", key], filters[`${key}__gt`]], @@ -69,11 +37,6 @@ const useFilterExpression = () => { ]; }); - const dynamicKeyExpressions = dynamicKeyFiltersExpressions.filter((expression) => { - const filterKey = expression[0][1][1]; - return fieldHasChanged(filters, ranges, filterKey).result; - }).flat(); - const staticKeyExpressions = staticKeyFiltersExpressions.filter((expression) => { const filterKey = expression[0][1][1]; return fieldHasChanged(filters, ranges, filterKey).result; @@ -91,8 +54,8 @@ const useFilterExpression = () => { [ "any", regionExpression - ? ["all", ...predictionExpression, ...staticKeyExpressions, ...dynamicKeyExpressions, categoryExpression, regionExpression] - : ["all", ...predictionExpression, ...staticKeyExpressions, ...dynamicKeyExpressions, categoryExpression], + ? ["all", ...predictionExpression, ...staticKeyExpressions, categoryExpression, regionExpression] + : ["all", ...predictionExpression, ...staticKeyExpressions, categoryExpression], includedExpression, ], ]; diff --git a/src/Map/MapComponent.jsx b/src/Map/MapComponent.jsx index 576cf89..25d82c7 100644 --- a/src/Map/MapComponent.jsx +++ b/src/Map/MapComponent.jsx @@ -24,7 +24,7 @@ import { icons } from "../icons/icons-config"; import { LastMLRun } from "./LastMLRun"; import { useGetPendingPointsRange, useOtherGroups, usePostamatesAndPvzGroups } from "../api.js"; import { getFilteredGroups, transliterate } from "../utils.js"; -import { usePendingPointsFilters } from "../stores/usePendingPointsFilters.js"; +import { RANGE_FILTERS_KEYS, RANGE_FILTERS_MAP, usePendingPointsFilters } from "../stores/usePendingPointsFilters.js"; export const MapComponent = () => { const mapRef = useRef(null); @@ -70,6 +70,8 @@ export const MapComponent = () => { filteredPostamatesGroups.map((item) => { item.groups.map((groupItem) => { + RANGE_FILTERS_KEYS.push(`d${groupItem.id}`); + RANGE_FILTERS_MAP[`d${groupItem.id}`] = groupItem.name; res.push(LAYER_IDS.pvz + groupItem.id); }) }); @@ -195,7 +197,7 @@ export const MapComponent = () => { ); img.onload = () => mapRef.current.addImage(icon.name, img); - img.src = 'https://docs.mapbox.com/mapbox-gl-js/assets/cat.png'; + img.src = icon.url; img.crossOrigin = "Anonymous"; }); }} diff --git a/src/api.js b/src/api.js index 7e5a5e6..105dad2 100644 --- a/src/api.js +++ b/src/api.js @@ -194,10 +194,11 @@ export const useGetPendingPointsRange = () => { }); const distToGroups = Object.assign({}, ...distToGroupsArr); const rangesArr = RANGE_FILTERS_KEYS.map((key) => { + if ((/d[0-9]/.test(key))) return; return { [key]: [Math.floor(data[key][0]), Math.ceil(data[key][1])] } - }); + }).filter(item => !!item); const ranges = Object.assign({}, ...rangesArr); return { prediction: data.prediction_current, diff --git a/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/AdvancedFilters.jsx b/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/AdvancedFilters.jsx index 13ca18d..5d07964 100644 --- a/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/AdvancedFilters.jsx +++ b/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/AdvancedFilters.jsx @@ -1,13 +1,13 @@ -import { usePendingPointsFilters } from "../../../../stores/usePendingPointsFilters"; +import { RANGE_FILTERS_KEYS, usePendingPointsFilters } from "../../../../stores/usePendingPointsFilters"; import { FilterSlider } from "./Slider.jsx"; -import { Collapse } from "antd"; +import { Button, Collapse } from "antd"; import React, { useMemo } from "react"; import { Title } from "../../../../components/Title.jsx"; import { usePostamatesAndPvzGroups } from "../../../../api.js"; -import { getFilteredGroups } from "../../../../utils.js"; +import {fieldHasChanged, getFilteredGroups} from "../../../../utils.js"; export const AdvancedFilters = () => { - const { filters, ranges } = usePendingPointsFilters(); + const { filters, ranges, tempFilters, setFilterWithKey, setTempFilterWithKey } = usePendingPointsFilters(); const { data: postamatesAndPvzGroups } = usePostamatesAndPvzGroups(); @@ -15,184 +15,220 @@ export const AdvancedFilters = () => { return getFilteredGroups(postamatesAndPvzGroups); }, [postamatesAndPvzGroups]); + const selectedCnt = useMemo(() => { + let counter = 0; + RANGE_FILTERS_KEYS.map((key) => { + if (fieldHasChanged(tempFilters, ranges, key).result) counter += 1; + }) + return counter; + }, [tempFilters]); + + const onApply = () => { + RANGE_FILTERS_KEYS.map((key) => { + setFilterWithKey([tempFilters[`${key}__gt`], tempFilters[`${key}__lt`]], key); + }) + }; + + const onCancel = () => { + RANGE_FILTERS_KEYS.map((key) => { + setTempFilterWithKey([filters[`${key}__gt`], filters[`${key}__lt`]], key); + }) + } + return ( -
- - } - forceRender +
+
+ Расширенные фильтры +
+
+ -
-
- -
-
- + } + forceRender + > +
+
+ +
+
+ +
-
- - + + - - } - forceRender + -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- + } + forceRender + > +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
-
- - + + - {filteredPostamatesGroups.map((category) => { - return ( - - { + return ( + } - forceRender + bordered={false} + expandIconPosition={"end"} + style={{ + background: 'none', + }} + className="filter_group my-4" > -
- {category.groups.map((group) => { - return ( -
- -
- ) - })} -
-
-
- ) - })} + } + forceRender + > +
+ {category.groups.map((group) => { + return ( +
+ +
+ ) + })} +
+
+ + ) + })} +
+
+ Выбрано: {selectedCnt} +
+ + +
+
); }; diff --git a/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/AdvancedFiltersWrapper.jsx b/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/AdvancedFiltersWrapper.jsx index 1a73438..db7de75 100644 --- a/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/AdvancedFiltersWrapper.jsx +++ b/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/AdvancedFiltersWrapper.jsx @@ -1,8 +1,46 @@ -import { Button, Dropdown } from "antd"; +import { Button, Dropdown, Popover } from "antd"; import { AdvancedFilters } from "./AdvancedFilters.jsx"; import { RightOutlined } from "@ant-design/icons"; +import { useMemo } from "react"; + +import { + RANGE_FILTERS_KEYS, + RANGE_FILTERS_MAP, + usePendingPointsFilters +} from "../../../../stores/usePendingPointsFilters.js"; +import {fieldHasChanged} from "../../../../utils.js"; export const AdvancedFiltersWrapper = () => { + const { filters, ranges } = usePendingPointsFilters(); + + const selectedCnt = useMemo(() => { + let counter = 0; + RANGE_FILTERS_KEYS.map((key) => { + if (fieldHasChanged(filters, ranges, key).result) counter += 1; + }) + return counter; + }, [filters]); + + const getPopoverContent = () => { + const keys = RANGE_FILTERS_KEYS.map((key) => { + if (fieldHasChanged(filters, ranges, key).result) return key; + }).filter(k => !!k); + + if (keys.length === 0) { + return

Не выбрано ни одного фильтра

+ } + + return ( +
+ {keys.map((key) => { + if (RANGE_FILTERS_MAP[key]) return ( +

{RANGE_FILTERS_MAP[key]}

+ ); + })} +
+ ); + } + const filtersRender = () => { return ( @@ -20,7 +58,19 @@ export const AdvancedFiltersWrapper = () => { onClick={(e) => e.stopPropagation()} className="w-full text-left flex justify-between items-center border-0 p-0 mt-16" > - Расширенные фильтры +
+ Расширенные фильтры + + {selectedCnt} + +
diff --git a/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/Slider.jsx b/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/Slider.jsx index 0b4e947..ec816d7 100644 --- a/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/Slider.jsx +++ b/src/modules/Sidebar/PendingPointsFilters/AdvancedFilters/Slider.jsx @@ -6,8 +6,8 @@ import { export const FilterSlider = ({ filterRange, disabled, fullRange, title, filterKey, dynamicKey }) => { - const { setFilterWithKey } = usePendingPointsFilters(); - const handleAfterChange = (range) => setFilterWithKey(range, filterKey); + const { setFilterWithKey, setTempFilterWithKey } = usePendingPointsFilters(); + const handleAfterChange = (range) => setTempFilterWithKey(range, filterKey); useEffect(() => { if (!fullRange) return; @@ -26,6 +26,7 @@ export const FilterSlider = ({ filterRange, disabled, fullRange, title, filterKe filterRange[1] === 0); if (shouldSetFullRange || (shouldSetDynamicKeyRange && dynamicKey)) { + setTempFilterWithKey([min, max], filterKey); setFilterWithKey([min, max], filterKey); } }, [fullRange]); diff --git a/src/stores/usePendingPointsFilters.js b/src/stores/usePendingPointsFilters.js index bc5eb80..4a417a4 100644 --- a/src/stores/usePendingPointsFilters.js +++ b/src/stores/usePendingPointsFilters.js @@ -86,6 +86,7 @@ const INITIAL_RANGES = { const store = (set) => ({ filters: INITIAL, ranges: INITIAL_RANGES, + tempFilters: INITIAL, setPrediction: (value) => { set((state) => { @@ -109,6 +110,12 @@ const store = (set) => ({ state.filters[`${key}__lt`] = value[1]; }), + setTempFilterWithKey: (value, key) => + set((state) => { + state.tempFilters[`${key}__gt`] = value[0]; + state.tempFilters[`${key}__lt`] = value[1]; + }), + setRanges: (value) => set((state) => { state.ranges = value; diff --git a/src/utils.js b/src/utils.js index 332e4bf..c2c14f7 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,5 +1,3 @@ -import {usePendingPointsFilters} from "./stores/usePendingPointsFilters.js"; - export function download(filename, data) { const downloadLink = window.document.createElement("a"); downloadLink.href = window.URL.createObjectURL( @@ -33,11 +31,12 @@ export function getFilteredGroups(categories) { }) } -export function fieldHasChanged(filters, ranges, filterKey) { +export function fieldHasChanged(filters, ranges, filterKey) { + const r = ranges[filterKey] const gtValue = filters[`${filterKey}__gt`]; - const gtInitial = ranges[filterKey][0]; + const gtInitial = r ? r[0] : 0 ; const ltValue = filters[`${filterKey}__lt`]; - const ltInitial = ranges[filterKey][1]; + const ltInitial =r ? r[1] : 0; const result = !(gtValue === gtInitial && ltValue === ltInitial)