END-712 - import report styling

END-714 - import error rename
END-716 - update map after import
END-717 - updated favicon
END-718 - enlarge legend icons
END-719 - legend points border
END-720 - points count loader
dev
RekHoto 2 years ago
parent aeaf90f136
commit 39a7ca811c

BIN
dist/favicon.ico vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

1
dist/index.html vendored

@ -2,7 +2,6 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
<link href="/vite.svg" rel="icon" type="image/svg+xml"/>
<link href="/favicon.ico" rel="icon"/> <link href="/favicon.ico" rel="icon"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/> <meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<title>PostNet by Spatial</title> <title>PostNet by Spatial</title>

@ -2,7 +2,6 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link href="/favicon.ico" rel="icon"/> <link href="/favicon.ico" rel="icon"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PostNet by Spatial</title> <title>PostNet by Spatial</title>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

@ -79,7 +79,14 @@ export const unmatchInitialPointLayer = getPointConfig(
UNMATCHED_COLOR, UNMATCHED_COLOR,
UNMATCH_POINT_SIZE UNMATCH_POINT_SIZE
); );
export const approvePointLayer = getPointConfig(APPROVE_COLOR); export const approvePointLayer = {
...getPointConfig(APPROVE_COLOR),
paint: {
...getPointConfig(APPROVE_COLOR).paint,
"circle-stroke-width": 1,
"circle-stroke-color": "#252525",
},
};
export const workingPointSymbolLayer = { export const workingPointSymbolLayer = {
type: "symbol", type: "symbol",

@ -13,7 +13,7 @@ import React from "react";
const LegendPointItem = ({color, imageSrc, name, hideImage, border}) => { const LegendPointItem = ({color, imageSrc, name, hideImage, border}) => {
return ( return (
<div className="flex gap-2 items-center"> <div className="flex gap-2 items-center">
{imageSrc && <Image src={imageSrc} width={12} height={12} className='flex items-center' preview={false}/>} {imageSrc && <Image src={imageSrc} width={18} height={18} className='flex items-center' preview={false}/>}
{color && !imageSrc && ( {color && !imageSrc && (
<span <span
className={`rounded-xl w-3 h-3 inline-block ${border && "border-black border-[1px] border-solid"}`} className={`rounded-xl w-3 h-3 inline-block ${border && "border-black border-[1px] border-solid"}`}
@ -21,7 +21,7 @@ const LegendPointItem = ({color, imageSrc, name, hideImage, border}) => {
/> />
)} )}
{!imageSrc && !color && !hideImage && ( {!imageSrc && !color && !hideImage && (
<Logo width={12} height={12} /> <Logo width={18} height={18} />
)} )}
<span className='text-xs text-grey'>{name}</span> <span className='text-xs text-grey'>{name}</span>
@ -109,6 +109,7 @@ export function Legend({ postGroups, otherGroups }) {
<LegendPointItem <LegendPointItem
name="Согласование-установка" name="Согласование-установка"
color={APPROVE_COLOR} color={APPROVE_COLOR}
border
/> />
<LegendPointItem name="Работающие постаматы"/> <LegendPointItem name="Работающие постаматы"/>
<LegendPointItem <LegendPointItem

@ -5,6 +5,7 @@ import { usePointSelection } from "./stores/usePointSelection";
import { RANGE_FILTERS_KEYS, usePendingPointsFilters } from "./stores/usePendingPointsFilters"; import { RANGE_FILTERS_KEYS, usePendingPointsFilters } from "./stores/usePendingPointsFilters";
import { appendFiltersInUse } from "./utils.js"; import { appendFiltersInUse } from "./utils.js";
import { useMode } from "./stores/useMode.js"; import { useMode } from "./stores/useMode.js";
import { useMemo } from "react";
export const BASE_URL = import.meta.env.VITE_API_URL; export const BASE_URL = import.meta.env.VITE_API_URL;
@ -204,10 +205,18 @@ export const useGetPermissions = () => {
}); });
}; };
const TASK_STATUSES = {
finished: "Завершено"
}
export const useCanEdit = () => { export const useCanEdit = () => {
const { data } = useGetPermissions(); const { data } = useGetPermissions();
const { data: statusData } = useLastMLRun();
const hasFinishedUpdate = useMemo(() => {
return statusData?.task_status === TASK_STATUSES.finished
}, [statusData])
return data === "editor"; return data === "editor" && hasFinishedUpdate;
}; };
export const useUpdatePostamatId = () => { export const useUpdatePostamatId = () => {

@ -8,6 +8,7 @@ import {
CloseCircleOutlined, CloseCircleOutlined,
LoadingOutlined LoadingOutlined
} from "@ant-design/icons"; } from "@ant-design/icons";
import { useUpdateLayerCounter } from "../../stores/useUpdateLayerCounter.js";
export const PointsFileUploadModal = ({onClose, isOpened}) => { export const PointsFileUploadModal = ({onClose, isOpened}) => {
const [fileId, setFileId] = useState(); const [fileId, setFileId] = useState();
@ -15,12 +16,14 @@ export const PointsFileUploadModal = ({onClose, isOpened}) => {
const [isImporting, setIsImporting] = useState(false); const [isImporting, setIsImporting] = useState(false);
const [isReportStage, setIsReportStage] = useState(false); const [isReportStage, setIsReportStage] = useState(false);
const [isError, setIsError] = useState(false); const [isError, setIsError] = useState(false);
const { toggleUpdateCounter } = useUpdateLayerCounter();
const onImportPoints = async () => { const onImportPoints = async () => {
setIsImporting(true); setIsImporting(true);
try { try {
const { message } = await importPoints(fileId); const { message } = await importPoints(fileId);
setReport(message); setReport(message);
toggleUpdateCounter();
} catch (e) { } catch (e) {
setIsError(true); setIsError(true);
} finally { } finally {

@ -5,28 +5,28 @@ export const ReportStage = ({ report }) => {
return ( return (
<> <>
<Row className={twMerge("p-1")}> <Row className={twMerge("p-1")}>
<Col className={"text-gray-600"} span={12}> <Col className="text-gray-600" span={12}>
Всего точек: Всего точек:
</Col> </Col>
<Col span={12}>{report.total}</Col> <Col className="font-semibold" span={12}>{report.total}</Col>
</Row> </Row>
<Row className={twMerge("p-1")}> <Row className={twMerge("p-1")}>
<Col className={"text-gray-600"} span={12}> <Col className={"text-gray-600"} span={12}>
Совпадений: Совпадений:
</Col> </Col>
<Col span={12}>{report.matched}</Col> <Col className="font-semibold text-[#2f54eb]" span={12}>{report.matched}</Col>
</Row> </Row>
<Row className={twMerge("p-1")}> <Row className={twMerge("p-1")}>
<Col className={"text-gray-600"} span={12}> <Col className={"text-gray-600"} span={12}>
Проблемные: Проблемные:
</Col> </Col>
<Col span={12}>{report.error}</Col> <Col className="font-semibold text-[#f5222d]" span={12}>{report.error}</Col>
</Row> </Row>
<Row className={twMerge("p-1")}> <Row className={twMerge("p-1")}>
<Col className={"text-gray-600"} span={12}> <Col className={"text-gray-600"} span={12}>
Новые: Новые:
</Col> </Col>
<Col span={12}>{report.unmatched}</Col> <Col className="font-semibold text-[#52c41a]" span={12}>{report.unmatched}</Col>
</Row> </Row>
</> </>

@ -9,7 +9,7 @@ import { useEffect } from "react";
export const SelectedLocations = ({ onSelectedChange }) => { export const SelectedLocations = ({ onSelectedChange }) => {
const { data: totalCount, isInitialLoading: isTotalLoading } = const { data: totalCount, isInitialLoading: isTotalLoading } =
useGetTotalInitialPointsCount(); useGetTotalInitialPointsCount();
const { data: filteredCount, isInitialLoading: isFilteredLoading } = const { data: filteredCount, isInitialLoading: isFilteredLoading, isFetching: isFilteredFetching } =
useGetFilteredPendingPointsCount(); useGetFilteredPendingPointsCount();
const { const {
@ -21,7 +21,7 @@ export const SelectedLocations = ({ onSelectedChange }) => {
[filteredCount, excluded] [filteredCount, excluded]
); );
const showSpinner = isTotalLoading || isFilteredLoading; const showSpinner = isTotalLoading || isFilteredLoading || isFilteredFetching;
return ( return (
<div className={"flex items-center justify-between"}> <div className={"flex items-center justify-between"}>

@ -2,16 +2,11 @@ import { Alert, Button, Modal, Spin } from "antd";
import { useQueryClient } from "@tanstack/react-query"; import { useQueryClient } from "@tanstack/react-query";
import { usePointSelection } from "../../../stores/usePointSelection"; import { usePointSelection } from "../../../stores/usePointSelection";
import { STATUSES } from "../../../config"; import { STATUSES } from "../../../config";
import { useMemo, useState } from "react"; import { useState } from "react";
import { useUpdateStatus } from "../../../hooks/useUpdateStatus"; import { useUpdateStatus } from "../../../hooks/useUpdateStatus";
import { ArrowRightOutlined } from "@ant-design/icons"; import { ArrowRightOutlined } from "@ant-design/icons";
import { Title } from "../../../components/Title"; import { Title } from "../../../components/Title";
import { usePendingPointsFilters } from "../../../stores/usePendingPointsFilters"; import { usePendingPointsFilters } from "../../../stores/usePendingPointsFilters";
import { useLastMLRun } from "../../../api.js";
const TASK_STATUSES = {
finished: "Завершено"
}
export const TakeToWorkButton = ({ disabled }) => { export const TakeToWorkButton = ({ disabled }) => {
const { filters } = usePendingPointsFilters(); const { filters } = usePendingPointsFilters();
@ -19,11 +14,6 @@ export const TakeToWorkButton = ({ disabled }) => {
const { selection } = usePointSelection(); const { selection } = usePointSelection();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const [isModalOpened, setIsModalOpened] = useState(false); const [isModalOpened, setIsModalOpened] = useState(false);
const { data: statusData } = useLastMLRun();
const disableButton = useMemo(() => {
return statusData?.task_status !== TASK_STATUSES.finished
}, [statusData])
const { const {
mutate: updateStatus, mutate: updateStatus,
@ -89,7 +79,7 @@ export const TakeToWorkButton = ({ disabled }) => {
block block
className={"mt-2"} className={"mt-2"}
onClick={() => setIsModalOpened(true)} onClick={() => setIsModalOpened(true)}
disabled={disabled || disableButton} disabled={disabled}
> >
<span className="mr-1">Взять в работу</span> <span className="mr-1">Взять в работу</span>
<ArrowRightOutlined /> <ArrowRightOutlined />

@ -11,7 +11,7 @@ const MATCHING_STATUS = {
color: 'import_status_new' color: 'import_status_new'
}, },
Error: { Error: {
name: 'Ошибка', name: 'Ошибка геокодирования',
color: 'import_status_error' color: 'import_status_error'
}, },
Matched: { Matched: {

Loading…
Cancel
Save