Merge branch 'fixes' into 'dev'

map fixes

See merge request spatial/postamates_frontend!19
dev
Timofey Malinin 3 years ago
commit 0ffd2546a8

@ -10,6 +10,7 @@ import { usePointSelection } from "./stores/usePointSelection";
import { usePendingPointsFilters } from "./stores/usePendingPointsFilters"; import { usePendingPointsFilters } from "./stores/usePendingPointsFilters";
import { useOnApprovalPointsFilters } from "./stores/useOnApprovalPointsFilters"; import { useOnApprovalPointsFilters } from "./stores/useOnApprovalPointsFilters";
import { useWorkingPointsFilters } from "./stores/useWorkingPointsFilters"; import { useWorkingPointsFilters } from "./stores/useWorkingPointsFilters";
import useLocalStorage from "./hooks/useLocalStorage.js";
const queryClient = new QueryClient(); const queryClient = new QueryClient();
@ -22,7 +23,17 @@ if (import.meta.env.MODE === "development") {
mountStoreDevtool("PointSelection", usePointSelection); mountStoreDevtool("PointSelection", usePointSelection);
} }
const version = '0.0.2';
function App() { function App() {
const [versionControl, setVersionControl] = useLocalStorage('version_control', version);
if (versionControl !== version) {
localStorage.clear();
setVersionControl(version);
}
return ( return (
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
<BrowserRouter basename={import.meta.env.BASE_URL}> <BrowserRouter basename={import.meta.env.BASE_URL}>

@ -13,7 +13,7 @@ import { usePendingPointsFilters } from "../../stores/usePendingPointsFilters";
const statusExpression = ["==", ["get", "status"], STATUSES.pending]; const statusExpression = ["==", ["get", "status"], STATUSES.pending];
const useFilterExpression = () => { const useFilterExpression = () => {
const { filters } = usePendingPointsFilters(); const { filters, ranges } = usePendingPointsFilters();
const { const {
prediction, prediction,
categories, categories,
@ -113,21 +113,30 @@ const useFilterExpression = () => {
]; ];
const filterExpressions = [ const filterExpressions = [
...doorsExpression, doorsExpression,
...flatExpression, flatExpression,
...rivalPostExpression, rivalPostExpression,
...rivalPvzExpression, rivalPvzExpression,
...targetPostExpression, targetPostExpression,
// ...flatsExpression, // flatsExpression,
...tcExpression, tcExpression,
...cultureExpression, cultureExpression,
...mfcExpression, mfcExpression,
...publicStopExpression, publicStopExpression,
...supermarketExpression, supermarketExpression,
...targetDistExpression, targetDistExpression,
// ...metroDistExpression // metroDistExpression
] ]
const activeExpressions = filterExpressions.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);
}).flat();
const categoryExpression = const categoryExpression =
categories.length > 0 categories.length > 0
@ -141,8 +150,8 @@ const useFilterExpression = () => {
[ [
"any", "any",
regionExpression regionExpression
? ["all", ...predictionExpression, ...filterExpressions, categoryExpression, regionExpression] ? ["all", ...predictionExpression, ...activeExpressions, categoryExpression, regionExpression]
: ["all", ...predictionExpression, ...filterExpressions, categoryExpression], : ["all", ...predictionExpression, ...activeExpressions, categoryExpression],
includedExpression, includedExpression,
], ],
]; ];

@ -22,8 +22,9 @@ import { LAYER_IDS } from "./Layers/constants";
import { Header } from "./Header"; import { Header } from "./Header";
import { icons } from "../icons/icons-config"; import { icons } from "../icons/icons-config";
import { LastMLRun } from "./LastMLRun"; import { LastMLRun } from "./LastMLRun";
import {useOtherGroups, usePostamatesAndPvzGroups} from "../api.js"; import { useGetPendingPointsRange, useOtherGroups, usePostamatesAndPvzGroups } from "../api.js";
import {transliterate} from "../utils.js"; import {transliterate} from "../utils.js";
import { usePendingPointsFilters } from "../stores/usePendingPointsFilters.js";
export const MapComponent = () => { export const MapComponent = () => {
const mapRef = useRef(null); const mapRef = useRef(null);
@ -35,6 +36,13 @@ export const MapComponent = () => {
const { mode } = useMode(); const { mode } = useMode();
const { tableState, openTable } = useTable(); const { tableState, openTable } = useTable();
const { ranges, setRanges } = usePendingPointsFilters();
const { data: fullRange, isInitialLoading } = useGetPendingPointsRange();
useEffect(() => {
if (fullRange) setRanges({...ranges, ...fullRange});
}, [fullRange]);
const { data: postamatesAndPvzGroups } = usePostamatesAndPvzGroups(); const { data: postamatesAndPvzGroups } = usePostamatesAndPvzGroups();
const { data: otherGroups } = useOtherGroups(); const { data: otherGroups } = useOtherGroups();

@ -174,3 +174,24 @@ export const useLastMLRun = () => {
}, },
); );
} }
export const useGetPendingPointsRange = () => {
return useQuery(
["prediction-max-min"],
async () => {
const { data } = await api.get(
`/api/placement_points/filters?status[]=${STATUSES.pending}`
);
return data;
},
{
select: (data) => {
return {
prediction: data.prediction_current,
doors: data.doors,
};
},
}
);
};

@ -16,7 +16,8 @@ export const AdvancedFilters = () => {
setPublicStopCnt, setPublicStopCnt,
setSupermarketCnt, setSupermarketCnt,
setTargetDist, setTargetDist,
setMetroDist setMetroDist,
ranges
} = usePendingPointsFilters(); } = usePendingPointsFilters();
return ( return (
@ -26,7 +27,8 @@ export const AdvancedFilters = () => {
filterRange={[filters.doors__gt, filters.doors__lt]} filterRange={[filters.doors__gt, filters.doors__lt]}
setFilterRange={setDoors} setFilterRange={setDoors}
title={"Кол-во подъездов в жилом доме"} title={"Кол-во подъездов в жилом доме"}
fullRange={[-1, 50]} fullRange={ranges.doors || [0, 0]}
filterKey={"doors"}
/> />
</div> </div>
<div> <div>
@ -74,7 +76,7 @@ export const AdvancedFilters = () => {
filterRange={[filters.tc_cnt__gt, filters.tc_cnt__lt]} filterRange={[filters.tc_cnt__gt, filters.tc_cnt__lt]}
setFilterRange={setTcCnt} setFilterRange={setTcCnt}
title={"Кол-во торговых центров"} title={"Кол-во торговых центров"}
fullRange={[-1, 500]} fullRange={[-1, 5000]}
/> />
</div> </div>
<div> <div>
@ -82,7 +84,7 @@ export const AdvancedFilters = () => {
filterRange={[filters.culture_cnt__gt, filters.culture_cnt__lt]} filterRange={[filters.culture_cnt__gt, filters.culture_cnt__lt]}
setFilterRange={setCultureCnt} setFilterRange={setCultureCnt}
title={"Кол-во объектов культуры (театры, музей и тд)"} title={"Кол-во объектов культуры (театры, музей и тд)"}
fullRange={[-1, 500]} fullRange={[-1, 5000]}
/> />
</div> </div>
<div> <div>
@ -90,7 +92,7 @@ export const AdvancedFilters = () => {
filterRange={[filters.mfc_cnt__gt, filters.mfc_cnt__lt]} filterRange={[filters.mfc_cnt__gt, filters.mfc_cnt__lt]}
setFilterRange={setMfcCnt} setFilterRange={setMfcCnt}
title={"Кол-во МФЦ"} title={"Кол-во МФЦ"}
fullRange={[-1, 500]} fullRange={[-1, 5000]}
/> />
</div> </div>
<div> <div>
@ -98,7 +100,7 @@ export const AdvancedFilters = () => {
filterRange={[filters.public_stop_cnt__gt, filters.public_stop_cnt__lt]} filterRange={[filters.public_stop_cnt__gt, filters.public_stop_cnt__lt]}
setFilterRange={setPublicStopCnt} setFilterRange={setPublicStopCnt}
title={"Кол-во остановок ОТ"} title={"Кол-во остановок ОТ"}
fullRange={[-1, 500]} fullRange={[-1, 5000]}
/> />
</div> </div>
<div> <div>
@ -106,7 +108,7 @@ export const AdvancedFilters = () => {
filterRange={[filters.supermarket_cnt__gt, filters.supermarket_cnt__lt]} filterRange={[filters.supermarket_cnt__gt, filters.supermarket_cnt__lt]}
setFilterRange={setSupermarketCnt} setFilterRange={setSupermarketCnt}
title={"Кол-во супермаркетов"} title={"Кол-во супермаркетов"}
fullRange={[-1, 500]} fullRange={[-1, 5000]}
/> />
</div> </div>
<div> <div>

@ -4,7 +4,7 @@ import {
INITIAL, INITIAL,
} from "../../../../stores/usePendingPointsFilters"; } from "../../../../stores/usePendingPointsFilters";
export const FilterSlider = ({ filterRange, setFilterRange, disabled, fullRange, title }) => { export const FilterSlider = ({ filterRange, setFilterRange, disabled, fullRange, title, filterKey }) => {
const handleAfterChange = (range) => setFilterRange(range); const handleAfterChange = (range) => setFilterRange(range);
useEffect(() => { useEffect(() => {
@ -14,8 +14,8 @@ export const FilterSlider = ({ filterRange, setFilterRange, disabled, fullRange,
const max = fullRange[1]; const max = fullRange[1];
const shouldSetFullRange = const shouldSetFullRange =
filterRange[0] === INITIAL.prediction[0] && filterRange[0] === INITIAL[`${filterKey}__gt`] &&
filterRange[1] === INITIAL.prediction[1]; filterRange[1] === INITIAL[`${filterKey}__lt`];
if (shouldSetFullRange) { if (shouldSetFullRange) {
setFilterRange([min, max]); setFilterRange([min, max]);

@ -1,4 +1,4 @@
import { DISABLED_FILTER_TEXT, STATUSES } from "../../../config"; import { DISABLED_FILTER_TEXT } from "../../../config";
import { Button, Tooltip } from "antd"; import { Button, Tooltip } from "antd";
import { SelectedLocations } from "./SelectedLocations"; import { SelectedLocations } from "./SelectedLocations";
import { TakeToWorkButton } from "./TakeToWorkButton"; import { TakeToWorkButton } from "./TakeToWorkButton";
@ -13,35 +13,13 @@ import {
import { usePendingPointsFilters } from "../../../stores/usePendingPointsFilters"; import { usePendingPointsFilters } from "../../../stores/usePendingPointsFilters";
import { ClearFiltersButton } from "../../../components/ClearFiltersButton"; import { ClearFiltersButton } from "../../../components/ClearFiltersButton";
import { getDynamicActiveFilters } from "../utils"; import { getDynamicActiveFilters } from "../utils";
import { api, useCanEdit } from "../../../api"; import { useCanEdit } from "../../../api";
import { useQuery } from "@tanstack/react-query";
import { AdvancedFiltersWrapper } from "./AdvancedFilters/AdvancedFiltersWrapper.jsx"; import { AdvancedFiltersWrapper } from "./AdvancedFilters/AdvancedFiltersWrapper.jsx";
const useGetPendingPointsRange = () => {
return useQuery(
["prediction-max-min"],
async () => {
const { data } = await api.get(
`/api/placement_points/filters?status[]=${STATUSES.pending}`
);
return data;
},
{
select: (data) => {
return {
prediction: [data.prediction_current[0], data.prediction_current[1]],
};
},
}
);
};
export const PendingPointsFilters = () => { export const PendingPointsFilters = () => {
const hasManualEdits = useHasManualEdits(); const hasManualEdits = useHasManualEdits();
const { reset: resetPointSelection } = usePointSelection(); const { reset: resetPointSelection } = usePointSelection();
const { filters, setRegion, clear } = usePendingPointsFilters(); const { ranges, filters, setRegion, clear } = usePendingPointsFilters();
const { data: fullRange, isInitialLoading } = useGetPendingPointsRange();
const [isSelectionEmpty, setIsSelectionEmpty] = useState(false); const [isSelectionEmpty, setIsSelectionEmpty] = useState(false);
@ -69,11 +47,11 @@ export const PendingPointsFilters = () => {
setHover(false); setHover(false);
}; };
const activeDynamicFilters = getDynamicActiveFilters(filters, fullRange, [ const activeDynamicFilters = getDynamicActiveFilters(filters, ranges, [
"prediction", "prediction",
]); ]);
const clearFilters = () => clear(fullRange); const clearFilters = () => clear(ranges);
const hasActiveFilters = const hasActiveFilters =
filters.region || filters.region ||
@ -101,8 +79,8 @@ export const PendingPointsFilters = () => {
<CategoriesSelect disabled={hasManualEdits} /> <CategoriesSelect disabled={hasManualEdits} />
<PredictionSlider <PredictionSlider
disabled={hasManualEdits} disabled={hasManualEdits}
fullRange={fullRange} fullRange={ranges}
isLoading={isInitialLoading} isLoading={false}
/> />
<AdvancedFiltersWrapper /> <AdvancedFiltersWrapper />
</div> </div>

@ -2,80 +2,48 @@ import { useQuery } from "@tanstack/react-query";
import { getPoints } from "../../../api"; import { getPoints } from "../../../api";
import { useMergeTableData } from "../useMergeTableData"; import { useMergeTableData } from "../useMergeTableData";
import { STATUSES } from "../../../config"; import { STATUSES } from "../../../config";
import { usePendingPointsFilters } from "../../../stores/usePendingPointsFilters"; import { RANGE_FILTERS_KEYS, usePendingPointsFilters } from "../../../stores/usePendingPointsFilters";
export const usePendingTableData = (page, resetPage, pageSize, setPageSize, sort) => { export const usePendingTableData = (page, resetPage, pageSize, setPageSize, sort) => {
const { filters } = usePendingPointsFilters(); const { filters, ranges } = usePendingPointsFilters();
const { const {
prediction, prediction,
categories, categories,
region, region,
doors__gt,
doors__lt,
flat_cnt__gt,
flat_cnt__lt,
rival_post_cnt__gt,
rival_post_cnt__lt,
rival_pvz_cnt__gt,
rival_pvz_cnt__lt,
target_post_cnt__gt,
target_post_cnt__lt,
flats_cnt__gt,
flats_cnt__lt,
tc_cnt__gt,
tc_cnt__lt,
culture_cnt__gt,
culture_cnt__lt,
mfc_cnt__gt,
mfc_cnt__lt,
public_stop_cnt__gt,
public_stop_cnt__lt,
supermarket_cnt__gt,
supermarket_cnt__lt,
target_dist__gt,
target_dist__lt,
metro_dist__gt,
metro_dist__lt
} = filters; } = filters;
const {data, isInitialLoading, isFetching} = useQuery( const getParams = () => {
["table", page, filters, sort], let tempParams = {
async () => {
const params = new URLSearchParams({
page, page,
page_size: pageSize, page_size: pageSize,
"prediction_current[]": prediction, "prediction_current[]": prediction,
"status[]": [STATUSES.pending], "status[]": [STATUSES.pending],
"categories[]": categories, "categories[]": categories,
doors__gt,
doors__lt,
flat_cnt__gt,
flat_cnt__lt,
rival_post_cnt__gt,
rival_post_cnt__lt,
rival_pvz_cnt__gt,
rival_pvz_cnt__lt,
target_post_cnt__gt,
target_post_cnt__lt,
// flats_cnt__gt,
// flats_cnt__lt,
tc_cnt__gt,
tc_cnt__lt,
culture_cnt__gt,
culture_cnt__lt,
mfc_cnt__gt,
mfc_cnt__lt,
public_stop_cnt__gt,
public_stop_cnt__lt,
supermarket_cnt__gt,
supermarket_cnt__lt,
target_dist__gt,
target_dist__lt,
metro_dist__gt,
metro_dist__lt,
ordering: sort, ordering: 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;
tempParams = {
...tempParams,
[`${filterKey}__gt`]: filters[`${filterKey}__gt`],
[`${filterKey}__lt`]: filters[`${filterKey}__lt`],
}
}); });
return tempParams;
}
const {data, isInitialLoading, isFetching} = useQuery(
["table", page, filters, sort],
async () => {
const params = new URLSearchParams(getParams());
return await getPoints(params, region); return await getPoints(params, region);
}, },
{ {

@ -2,40 +2,75 @@ import { create } from "zustand";
import { immer } from "zustand/middleware/immer"; import { immer } from "zustand/middleware/immer";
import { persist } from "zustand/middleware"; import { persist } from "zustand/middleware";
export const RANGE_FILTERS_KEYS = [
'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 = { export const INITIAL = {
prediction: [0, 0], prediction: [0, 0],
categories: [], categories: [],
region: null, region: null,
doors__gt: -1, doors__gt: 0,
doors__lt: 500, doors__lt: 0,
flat_cnt__gt: -1, flat_cnt__gt: 0,
flat_cnt__lt: 5000, flat_cnt__lt: 5000,
rival_post_cnt__gt: -1, rival_post_cnt__gt: 0,
rival_post_cnt__lt: 5000, rival_post_cnt__lt: 5000,
rival_pvz_cnt__gt: -1, rival_pvz_cnt__gt: 0,
rival_pvz_cnt__lt: 5000, rival_pvz_cnt__lt: 5000,
target_post_cnt__gt: -1, target_post_cnt__gt: 0,
target_post_cnt__lt: 5000, target_post_cnt__lt: 5000,
flats_cnt__gt: -1, flats_cnt__gt: 0,
flats_cnt__lt: 5000, flats_cnt__lt: 5000,
tc_cnt__gt: -1, tc_cnt__gt: 0,
tc_cnt__lt: 500, tc_cnt__lt: 5000,
culture_cnt__gt: -1, culture_cnt__gt: 0,
culture_cnt__lt: 500, culture_cnt__lt: 5000,
mfc_cnt__gt: -1, mfc_cnt__gt: 0,
mfc_cnt__lt: 500, mfc_cnt__lt: 5000,
public_stop_cnt__gt: -1, public_stop_cnt__gt: 0,
public_stop_cnt__lt: 50, public_stop_cnt__lt: 5000,
supermarket_cnt__gt: -1, supermarket_cnt__gt: 0,
supermarket_cnt__lt: 50, supermarket_cnt__lt: 5000,
target_dist__gt: -1, target_dist__gt: 0,
target_dist__lt: 5000, target_dist__lt: 5000,
metro_dist__gt: -1, metro_dist__gt: 0,
metro_dist__lt: 50000, metro_dist__lt: 5000,
}; };
const INITIAL_RANGES = {
prediction: [0, 0],
doors: [0, 0],
flat_cnt: [0, 5000],
rival_post_cnt: [0, 5000],
rival_pvz_cnt: [0, 5000],
target_post_cnt: [0, 5000],
flats_cnt: [0, 5000],
tc_cnt: [0, 5000],
culture_cnt: [0, 5000],
mfc_cnt: [0, 5000],
public_stop_cnt: [0, 5000],
supermarket_cnt: [0, 5000],
target_dist: [0, 5000],
metro_dist: [0, 5000],
}
const store = (set) => ({ const store = (set) => ({
filters: INITIAL, filters: INITIAL,
ranges: INITIAL_RANGES,
setPrediction: (value) => { setPrediction: (value) => {
set((state) => { set((state) => {
state.filters.prediction = value; state.filters.prediction = value;
@ -130,6 +165,11 @@ const store = (set) => ({
state.filters.metro_dist__lt = value[1]; state.filters.metro_dist__lt = value[1];
}), }),
setRanges: (value) =>
set((state) => {
state.ranges = value;
}),
clear: (fullRange) => clear: (fullRange) =>
set((state) => { set((state) => {
if (!fullRange) { if (!fullRange) {

Loading…
Cancel
Save