Fix take to work action; add export action

dev
Platon Yasev 3 years ago
parent 0b673f34e2
commit c230e6382e

@ -39,10 +39,11 @@ export const Points = () => {
const unmatchFilterExpression = [
"all",
statusExpression,
["!", includedExpression],
[
"any",
excludedExpression,
["!", ["all", ...predictionExpression, categoryExpression]],
excludedExpression,
],
];

@ -157,6 +157,7 @@ const SingleFeaturePopup = ({ feature }) => {
};
const MultipleFeaturesPopup = ({ features, onSelect }) => {
console.log(features);
return (
<div className="space-y-2 p-1">
{features.map((feature) => {

@ -32,6 +32,8 @@ export const SliderComponent = ({
range = false,
step = 1,
disabled = false,
onMouseEnter,
onMouseLeave,
}) => {
const fullRangeMarks = {
[min]: <Mark value={min} />,
@ -71,7 +73,7 @@ export const SliderComponent = ({
};
return (
<div>
<div onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>
<Title text={title} />
<Slider
range={range}

@ -1,5 +1,5 @@
export const STATUSES = {
toWork: "К рассмотрению",
initial: "К рассмотрению",
approve: "Согласование-установка",
working: "Работает",
};
@ -13,3 +13,6 @@ export const CATEGORIES = {
residential: "Подъезд жилого дома",
dk: "Дом культуры/Клуб",
};
export const DISABLED_FILTER_TEXT =
"Фильтр заблокирован - было ручное редактирование";

@ -2,7 +2,6 @@ import { Button } from "antd";
import { twMerge } from "tailwind-merge";
import { Title } from "../../components/Title";
import { useFilters } from "../../stores/useFilters";
import { useHasManualEdits } from "../../stores/usePointSelection";
import { CATEGORIES } from "../../config";
const SelectItem = ({ name, isActive, onClick, disabled }) => {
@ -22,9 +21,8 @@ const SelectItem = ({ name, isActive, onClick, disabled }) => {
);
};
export const ObjectTypesSelect = () => {
export const CategoriesSelect = ({ disabled }) => {
const { filters, setCategories } = useFilters();
const hasManualEdits = useHasManualEdits();
const handleClick = (category) => setCategories(category);
@ -39,7 +37,7 @@ export const ObjectTypesSelect = () => {
type="text"
className="text-grey text-xs p-0 hover:bg-transparent active:bg-transparent focus:bg-transparent h-fit"
onClick={clear}
disabled={hasManualEdits}
disabled={disabled}
>
сбросить
</Button>
@ -53,7 +51,7 @@ export const ObjectTypesSelect = () => {
name={value}
isActive={filters.categories.includes(value)}
onClick={() => handleClick(value)}
disabled={hasManualEdits}
disabled={disabled}
/>
))}
</div>

@ -0,0 +1,74 @@
import { useFilters } from "../../stores/useFilters";
import { usePointSelection } from "../../stores/usePointSelection";
import { useQuery } from "@tanstack/react-query";
import { api } from "../../api";
import { Button } from "antd";
import { useState } from "react";
function download(filename, data) {
const downloadLink = window.document.createElement("a");
downloadLink.href = window.URL.createObjectURL(
new Blob([data], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
})
);
downloadLink.download = filename;
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
}
const useExportData = (enabled, onSuccess, onSettled) => {
const { filters } = useFilters();
const { prediction, status, categories } = filters;
const { selection } = usePointSelection();
return useQuery(
["export", filters, selection],
async () => {
const params = new URLSearchParams({
"prediction_current[]": prediction,
"status[]": status,
"categories[]": categories,
"included[]": [...selection.included],
"excluded[]": [...selection.excluded],
});
const { data } = await api.get(
`/api/placement_points/to_excel?${params.toString()}`,
{ responseType: "arraybuffer" }
);
return data;
},
{ enabled, onSuccess, onSettled }
);
};
export const ExportButton = () => {
const [startExport, setStartExport] = useState(false);
useExportData(
startExport,
(data) => {
download("postamates.xlsx", data);
},
() => setStartExport(false)
);
const handleExport = () => {
setStartExport(true);
};
return (
<Button
type="primary"
block
className={"mt-2"}
onClick={handleExport}
loading={startExport}
disabled={startExport}
>
Экспорт данных
</Button>
);
};

@ -0,0 +1,39 @@
import { RegionSelect } from "./RegionSelect";
import { CategoriesSelect } from "./CategoriesSelect";
import { PredictionSlider } from "./PredictionSlider";
import { useEffect, useState } from "react";
import { Tooltip } from "antd";
import { DISABLED_FILTER_TEXT } from "../../config";
export const Filters = ({ disabled }) => {
const [hover, setHover] = useState(false);
useEffect(() => {
const timer = setTimeout(() => setHover(false), 1500);
return () => clearTimeout(timer);
}, [hover]);
const handleMouseEnter = () => setHover(true);
const handleMouseLeave = () => {
setHover(false);
};
return (
<Tooltip
title={DISABLED_FILTER_TEXT}
placement="right"
open={disabled && hover}
>
<div
className="space-y-5"
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
<RegionSelect disabled={disabled} />
<CategoriesSelect disabled={disabled} />
<PredictionSlider disabled={disabled} />
</div>
</Tooltip>
);
};

@ -3,15 +3,14 @@ import { useFilters } from "../../stores/useFilters";
import { useQuery } from "@tanstack/react-query";
import { api } from "../../api";
import { useEffect } from "react";
import { useHasManualEdits } from "../../stores/usePointSelection";
export const PredictionSlider = () => {
export const PredictionSlider = ({ disabled }) => {
const { filters, setPrediction } = useFilters();
const hasManualEdits = useHasManualEdits();
const { data } = useQuery(
["max-min"],
async () => {
const { data } = await api.get(`/api/placement_points/filters`);
const { data } = await api.get(`/api/placement_points/filters/`);
return data;
},
@ -39,7 +38,7 @@ export const PredictionSlider = () => {
min={200}
max={299}
range
disabled={hasManualEdits}
disabled={disabled}
/>
);
};

@ -23,7 +23,7 @@ const normalizeRegions = (rawRegions) => {
}, {});
};
export const RegionSelect = () => {
export const RegionSelect = ({ disabled }) => {
const { current: map } = useMap();
const {
filters: { region },
@ -38,6 +38,7 @@ export const RegionSelect = () => {
setLoading(true);
try {
const response = await api.get("/api/ao_and_rayons");
console.log(response.data);
setData(response.data);
} catch (err) {
console.error(err);
@ -93,6 +94,7 @@ export const RegionSelect = () => {
description={"Не найдено"}
/>
}
disabled={disabled}
>
{data?.map((parent) => {
return (

@ -1,106 +1,24 @@
import { RegionSelect } from "./RegionSelect";
import { Button } from "antd";
import { ObjectTypesSelect } from "./ObjectTypesSelect";
import { PredictionSlider } from "./PredictionSlider";
import { LayersVisibility } from "./LayersVisibility";
import { useState } from "react";
import { api } from "../../api";
import { useFilters } from "../../stores/useFilters";
import {
useHasManualEdits,
usePointSelection,
} from "../../stores/usePointSelection";
import { TakeToWorkButton } from "./TakeToWorkButton";
function download(filename, data) {
const downloadLink = window.document.createElement("a");
downloadLink.href = window.URL.createObjectURL(
new Blob([data], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
})
);
downloadLink.download = filename;
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
}
const getRegionParam = (regionId) => {
if (!regionId) return null;
const [type, id] = regionId.split("-");
if (type === "ao") {
return { msk_ao: Number(id) };
}
return { msk_rayon: Number(id) - 1 };
};
import { Filters } from "./Filters";
import { ExportButton } from "./ExportButton";
export const Sidebar = () => {
const {
filters: { prediction, region, categories },
} = useFilters();
const [isExporting, setIsExporting] = useState(false);
const hasManualEdits = useHasManualEdits();
const { reset: resetSelection } = usePointSelection();
const handleExport = async () => {
setIsExporting(true);
try {
const params = {
filters: {
rate_from: prediction[0],
rate_to: prediction[1],
},
};
if (region) {
params.filters = {
...params.filters,
...getRegionParam(region),
};
}
if (categories.length) {
params.filters = {
...params.filters,
category: categories,
};
}
const resp = await api.post("/api/raschet/", params, {
responseType: "arraybuffer",
});
const blob = resp.data;
download("postamates.xlsx", blob);
} catch (err) {
console.log("Произошла ошибка");
} finally {
setIsExporting(false);
}
};
return (
<div className="absolute top-[20px] left-[20px] bg-white-background w-[320px] rounded-xl p-3 max-h-[calc(100%-40px)] overflow-y-auto z-10">
<div className="space-y-5">
<LayersVisibility />
<RegionSelect />
<ObjectTypesSelect />
<PredictionSlider />
<Filters disabled={hasManualEdits} />
<div>
<Button
type="primary"
block
className={"mt-2"}
onClick={handleExport}
loading={isExporting}
disabled={true}
>
Экспорт данных
</Button>
<ExportButton />
<TakeToWorkButton />
{hasManualEdits ? (
<Button

@ -14,7 +14,7 @@ export const TakeToWorkButton = () => {
const { mutate } = useMutation({
mutationFn: () => {
const params = new URLSearchParams({
status: STATUSES.toWork,
status: STATUSES.approve,
"prediction_current[]": prediction,
"categories[]": categories,
"included[]": [...selection.included],

Loading…
Cancel
Save