stage two See merge request spatial/postamates_frontend!35dev
commit
3134a672c7
@ -0,0 +1,45 @@
|
|||||||
|
import { useLayoutEffect, useRef, useState } from "react";
|
||||||
|
import { uploadPointsFile } from "../../api.js";
|
||||||
|
import { Button, Upload } from "antd";
|
||||||
|
import { UploadOutlined } from "@ant-design/icons";
|
||||||
|
|
||||||
|
export const LoadingStage = ({setFileId}) => {
|
||||||
|
const ref = useRef(null);
|
||||||
|
const [isClicked, setIsClicked] = useState(true);
|
||||||
|
|
||||||
|
const onFileChange = async (options) => {
|
||||||
|
const { onSuccess, onError, file, onProgress } = options;
|
||||||
|
const config = {
|
||||||
|
onUploadProgress: event => {
|
||||||
|
const percent = Math.floor((event.loaded / event.total) * 100);
|
||||||
|
onProgress({ percent });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const {id} = await uploadPointsFile(file, config);
|
||||||
|
onSuccess("Ok");
|
||||||
|
setFileId(id);
|
||||||
|
} catch (e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
if (ref && ref.current && !isClicked) {
|
||||||
|
ref.current.click();
|
||||||
|
setIsClicked(true);
|
||||||
|
}
|
||||||
|
}, [isClicked]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Upload
|
||||||
|
name='file'
|
||||||
|
accept='application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml'
|
||||||
|
customRequest={onFileChange}
|
||||||
|
>
|
||||||
|
<Button icon={<UploadOutlined />}>Выбрать файл .xlsx</Button>
|
||||||
|
</Upload>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,91 @@
|
|||||||
|
import { Button, Modal, Spin } from "antd";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { importPoints } from "../../api.js";
|
||||||
|
import { LoadingStage } from "./LoadingStage.jsx";
|
||||||
|
import { ReportStage } from "./ReportStage.jsx";
|
||||||
|
import { CheckCircleOutlined, LoadingOutlined } from "@ant-design/icons";
|
||||||
|
|
||||||
|
export const OnLoadModal = ({onClose, isOpened}) => {
|
||||||
|
const [fileId, setFileId] = useState();
|
||||||
|
const [report, setReport] = useState();
|
||||||
|
const [isImporting, setIsImporting] = useState(false);
|
||||||
|
const [isReportStage, setIsReportStage] = useState(false);
|
||||||
|
|
||||||
|
const onImportPoints = async () => {
|
||||||
|
setIsImporting(true);
|
||||||
|
try {
|
||||||
|
const { message } = await importPoints(fileId);
|
||||||
|
setReport(message);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
} finally {
|
||||||
|
setIsImporting(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getFooter = () => {
|
||||||
|
if (isReportStage) return [
|
||||||
|
<Button
|
||||||
|
key="finish-button"
|
||||||
|
type="primary"
|
||||||
|
onClick={onClose}
|
||||||
|
>
|
||||||
|
Перейти к выбору
|
||||||
|
</Button>
|
||||||
|
]
|
||||||
|
if (report) return [
|
||||||
|
<Button
|
||||||
|
key="report-button"
|
||||||
|
type="primary"
|
||||||
|
onClick={() => setIsReportStage(true)}
|
||||||
|
>
|
||||||
|
Просмотреть отчет
|
||||||
|
</Button>
|
||||||
|
]
|
||||||
|
return [
|
||||||
|
<Button
|
||||||
|
key="close-button"
|
||||||
|
type="default"
|
||||||
|
onClick={onClose}
|
||||||
|
>
|
||||||
|
Отмена
|
||||||
|
</Button>,
|
||||||
|
<Button
|
||||||
|
key="ok-button"
|
||||||
|
type="primary"
|
||||||
|
onClick={() => onImportPoints()}
|
||||||
|
disabled={!fileId || isImporting}
|
||||||
|
>
|
||||||
|
Импортировать
|
||||||
|
</Button>,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
const getContent = () => {
|
||||||
|
if (isImporting) return (
|
||||||
|
<div className="flex flex-col justify-center gap-2 items-center">
|
||||||
|
<Spin indicator={<LoadingOutlined style={{ fontSize: 64}} spin />} />
|
||||||
|
Импортируем точки...
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
if (isReportStage) return <ReportStage report={report} />;
|
||||||
|
if (report) return (
|
||||||
|
<div className="flex items-center justify-center font-bold gap-2">
|
||||||
|
<CheckCircleOutlined style={{ fontSize: 24, color: "#52C41A" }} />
|
||||||
|
Точки успешно импортированы
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
return <LoadingStage setFileId={setFileId} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
open={isOpened}
|
||||||
|
title="Импорт точек"
|
||||||
|
onCancel={onClose}
|
||||||
|
width={400}
|
||||||
|
footer={getFooter()}
|
||||||
|
>
|
||||||
|
{getContent()}
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
import { useMode } from "../../stores/useMode.js";
|
||||||
|
import { Button } from "antd";
|
||||||
|
import { ImportOutlined } from "@ant-design/icons";
|
||||||
|
import { OnLoadModal } from "./OnLoadModal.jsx";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { AddPointsModal } from "./AddPointsModal.jsx";
|
||||||
|
import { MODES } from "../../config.js";
|
||||||
|
|
||||||
|
export const ImportModeSidebarButtons = () => {
|
||||||
|
const { mode, isImportMode, setImportMode } = useMode();
|
||||||
|
const [loadModalOpen, setLoadModalOpen] = useState(false);
|
||||||
|
const [addPointsModalOpen, setAddPointsModalOpen] = useState(false);
|
||||||
|
|
||||||
|
const onCancel = () => {
|
||||||
|
setImportMode(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onImport = () => {
|
||||||
|
setImportMode(true);
|
||||||
|
setLoadModalOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isImportMode) {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-row flex-0 gap-2 border-t-[1px] border-b-[1px]">
|
||||||
|
<Button type="default" onClick={onCancel}>
|
||||||
|
Отмена
|
||||||
|
</Button>
|
||||||
|
<Button type="primary" className="flex-1" onClick={() => setAddPointsModalOpen(true)}>
|
||||||
|
Добавить в базу
|
||||||
|
</Button>
|
||||||
|
{loadModalOpen &&
|
||||||
|
<OnLoadModal
|
||||||
|
isOpened={loadModalOpen}
|
||||||
|
onClose={() => setLoadModalOpen(false)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
{addPointsModalOpen &&
|
||||||
|
<AddPointsModal
|
||||||
|
isOpened={addPointsModalOpen}
|
||||||
|
onClose={() => setAddPointsModalOpen(false)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mode === MODES.PENDING && (
|
||||||
|
<div className="flex flex-col flex-0 border-t-[1px] border-b-[1px]">
|
||||||
|
<Button type="default" onClick={onImport}>
|
||||||
|
<ImportOutlined />
|
||||||
|
Импортировать
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Reference in new issue