dev
RekHoto 3 years ago
parent dc054c81f3
commit b819cbaa52

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

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

@ -22,8 +22,9 @@ import { LAYER_IDS } from "./Layers/constants";
import { Header } from "./Header";
import { icons } from "../icons/icons-config";
import { LastMLRun } from "./LastMLRun";
import {useOtherGroups, usePostamatesAndPvzGroups} from "../api.js";
import { useGetPendingPointsRange, useOtherGroups, usePostamatesAndPvzGroups } from "../api.js";
import {transliterate} from "../utils.js";
import { usePendingPointsFilters } from "../stores/usePendingPointsFilters.js";
export const MapComponent = () => {
const mapRef = useRef(null);
@ -35,6 +36,13 @@ export const MapComponent = () => {
const { mode } = useMode();
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: 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,
};
},
}
);
};

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

@ -4,7 +4,7 @@ import {
INITIAL,
} 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);
useEffect(() => {
@ -14,8 +14,8 @@ export const FilterSlider = ({ filterRange, setFilterRange, disabled, fullRange,
const max = fullRange[1];
const shouldSetFullRange =
filterRange[0] === INITIAL.prediction[0] &&
filterRange[1] === INITIAL.prediction[1];
filterRange[0] === INITIAL[`${filterKey}__gt`] &&
filterRange[1] === INITIAL[`${filterKey}__lt`];
if (shouldSetFullRange) {
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 { SelectedLocations } from "./SelectedLocations";
import { TakeToWorkButton } from "./TakeToWorkButton";
@ -13,35 +13,13 @@ import {
import { usePendingPointsFilters } from "../../../stores/usePendingPointsFilters";
import { ClearFiltersButton } from "../../../components/ClearFiltersButton";
import { getDynamicActiveFilters } from "../utils";
import { api, useCanEdit } from "../../../api";
import { useQuery } from "@tanstack/react-query";
import { useCanEdit } from "../../../api";
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 = () => {
const hasManualEdits = useHasManualEdits();
const { reset: resetPointSelection } = usePointSelection();
const { filters, setRegion, clear } = usePendingPointsFilters();
const { data: fullRange, isInitialLoading } = useGetPendingPointsRange();
const { ranges, filters, setRegion, clear } = usePendingPointsFilters();
const [isSelectionEmpty, setIsSelectionEmpty] = useState(false);
@ -69,11 +47,11 @@ export const PendingPointsFilters = () => {
setHover(false);
};
const activeDynamicFilters = getDynamicActiveFilters(filters, fullRange, [
const activeDynamicFilters = getDynamicActiveFilters(filters, ranges, [
"prediction",
]);
const clearFilters = () => clear(fullRange);
const clearFilters = () => clear(ranges);
const hasActiveFilters =
filters.region ||
@ -101,8 +79,8 @@ export const PendingPointsFilters = () => {
<CategoriesSelect disabled={hasManualEdits} />
<PredictionSlider
disabled={hasManualEdits}
fullRange={fullRange}
isLoading={isInitialLoading}
fullRange={ranges}
isLoading={false}
/>
<AdvancedFiltersWrapper />
</div>

@ -2,79 +2,47 @@ import { useQuery } from "@tanstack/react-query";
import { getPoints } from "../../../api";
import { useMergeTableData } from "../useMergeTableData";
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) => {
const { filters } = usePendingPointsFilters();
const { filters, ranges } = usePendingPointsFilters();
const {
prediction,
categories,
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;
const getParams = () => {
let tempParams = {
page,
page_size: pageSize,
"prediction_current[]": prediction,
"status[]": [STATUSES.pending],
"categories[]": categories,
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({
page,
page_size: pageSize,
"prediction_current[]": prediction,
"status[]": [STATUSES.pending],
"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,
});
const params = new URLSearchParams(getParams());
return await getPoints(params, region);
},

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

Loading…
Cancel
Save