Add permissions; validate making working form

dev
Platon Yasev 3 years ago
parent 558dbb3940
commit 455ecc4122

@ -4,8 +4,8 @@ import { MODES } from "../../config";
import { useMode } from "../../stores/useMode";
import { LAYER_IDS } from "../Layers/constants";
import { PopupWrapper } from "./PopupWrapper";
import { InitialPointPopup } from "./mode-popup/InitialPointPopup";
import { ApproveWorkingPointPopup } from "./mode-popup/ApproveWorkingPointPopup";
import { PendingPointPopup } from "./mode-popup/PendingPointPopup";
import { OnApprovalPointPopup } from "./mode-popup/OnApprovalPointPopup";
import { WorkingPointPopup } from "./mode-popup/WorkingPointPopup";
import { FeatureProperties } from "./mode-popup/FeatureProperties";
@ -22,7 +22,7 @@ const SingleFeaturePopup = ({ feature }) => {
}
if (mode === MODES.ON_APPROVAL) {
return <ApproveWorkingPointPopup feature={feature} />;
return <OnApprovalPointPopup feature={feature} />;
}
if (mode === MODES.WORKING) {
@ -30,7 +30,7 @@ const SingleFeaturePopup = ({ feature }) => {
}
if (mode === MODES.PENDING && isInitialLayer)
return <InitialPointPopup feature={feature} />;
return <PendingPointPopup feature={feature} />;
return <FeatureProperties feature={feature} />;
};

@ -5,8 +5,9 @@ import { Title } from "../../../components/Title";
import { useQueryClient } from "@tanstack/react-query";
import { useUpdateStatus } from "../../../hooks/useUpdateStatus";
import { StatusSelect } from "../../../components/StatusSelect";
import { useCanEdit } from "../../../api";
export const ApproveWorkingPointPopup = ({ feature }) => {
export const OnApprovalPointPopup = ({ feature }) => {
const featureId = feature.properties.id;
const { setClickedPointConfig } = useClickedPointConfig();
const [status, setStatus] = useState(feature.properties.status);
@ -33,15 +34,19 @@ export const ApproveWorkingPointPopup = ({ feature }) => {
updateStatus(params);
};
const canEdit = useCanEdit();
return (
<>
<FeatureProperties feature={feature} dynamicStatus={status} />
<div className="flex justify-center mt-4">
<div className={"flex flex-col items-center"}>
<Title text="Изменить статус" />
<StatusSelect value={status} onChange={handleStatusChange} />
{canEdit && (
<div className="flex justify-center mt-4">
<div className={"flex flex-col items-center"}>
<Title text="Изменить статус" />
<StatusSelect value={status} onChange={handleStatusChange} />
</div>
</div>
</div>
)}
</>
);
};

@ -4,8 +4,9 @@ import { LAYER_IDS } from "../../Layers/constants";
import { useEffect } from "react";
import { FeatureProperties } from "./FeatureProperties";
import { Button } from "antd";
import { useCanEdit } from "../../../api";
export const InitialPointPopup = ({ feature }) => {
export const PendingPointPopup = ({ feature }) => {
const { include, selection, exclude } = usePointSelection();
const { setClickedPointConfig } = useClickedPointConfig();
const doesMatchFilter = feature.layer.id === LAYER_IDS["initial-match"];
@ -25,17 +26,21 @@ export const InitialPointPopup = ({ feature }) => {
}
};
const canEdit = useCanEdit();
return (
<>
<FeatureProperties feature={feature} />
<Button
type="primary"
className="mt-2 mx-auto"
block
onClick={handleSelect}
>
{isSelected ? "Исключить из выборки" : "Добавить в выборку"}
</Button>
{canEdit && (
<Button
type="primary"
className="mt-2 mx-auto"
block
onClick={handleSelect}
>
{isSelected ? "Исключить из выборки" : "Добавить в выборку"}
</Button>
)}
</>
);
};

@ -95,3 +95,21 @@ export const useGetFilteredPendingPointsCount = () => {
{ select: (data) => data.count, keepPreviousData: true }
);
};
export const useGetPermissions = () => {
return useQuery(["permissions"], async () => {
const { data } = await api.get("/api/me");
if (data?.groups?.includes("Редактор")) {
return "editor";
}
return "viewer";
});
};
export const useCanEdit = () => {
const { data } = useGetPermissions();
return data === "editor";
};

@ -9,7 +9,7 @@
.mapboxgl-popup-content,
.maplibregl-popup-content {
@apply bg-grey-light shadow-lg rounded-md max-h-[300px] overflow-y-auto;
@apply bg-grey-light shadow-lg rounded-md max-h-[500px] overflow-y-auto;
}
.mapboxgl-popup-anchor-bottom .mapboxgl-popup-tip,

@ -13,6 +13,7 @@ import {
import { usePendingPointsFilters } from "../../../stores/usePendingPointsFilters";
import { ClearFiltersButton } from "../../../components/ClearFiltersButton";
import { getDynamicActiveFilters } from "../utils";
import { useCanEdit } from "../../../api";
export const PendingPointsFilters = ({ fullRange }) => {
const hasManualEdits = useHasManualEdits();
@ -46,6 +47,8 @@ export const PendingPointsFilters = ({ fullRange }) => {
activeDynamicFilters.prediction ||
filters.categories.length !== 0;
const canEdit = useCanEdit();
return (
<div className="flex flex-col flex-1 justify-between">
<div>
@ -83,7 +86,7 @@ export const PendingPointsFilters = ({ fullRange }) => {
<div>
<SelectedLocations />
<TakeToWorkButton />
{canEdit && <TakeToWorkButton />}
</div>
</div>
);

@ -28,8 +28,12 @@ export const MakeWorkingModal = ({ selectedIds, onClose, onSuccess }) => {
return await getPoints(params);
});
const [hasError, setHasError] = useState(false);
const [dataSource, setDataSource] = useState([]);
const [updateError, setUpdateError] = useState(null);
useEffect(() => {
setDataSource(data?.results);
}, [data]);
@ -58,12 +62,19 @@ export const MakeWorkingModal = ({ selectedIds, onClose, onSuccess }) => {
const updateStatusPromise = updateStatus(updateStatusParams);
Promise.all([...updatePostamatPromises, updateStatusPromise]).then(() => {
queryClient.invalidateQueries(["on-approval-points"]);
setPopup(null);
onSuccess();
onClose();
});
Promise.all([...updatePostamatPromises, updateStatusPromise])
.then(() => {
queryClient.invalidateQueries(["on-approval-points"]);
setUpdateError(null);
setPopup(null);
onSuccess();
onClose();
})
.catch(() =>
setUpdateError(
"Введенные идентификаторы уже существуют, попробуйте другие"
)
);
};
return (
@ -73,13 +84,27 @@ export const MakeWorkingModal = ({ selectedIds, onClose, onSuccess }) => {
onCancel={onClose}
width={800}
footer={[
<Button key="ok-button" type="primary" onClick={handleUpdate}>
updateError && (
<span key="error" className="mr-2 text-primary">
{updateError}
</span>
),
<Button
key="ok-button"
type="primary"
onClick={handleUpdate}
disabled={hasError}
>
Обновить статус
</Button>,
]}
>
{dataSource && (
<MakeWorkingTable data={dataSource} onChange={setDataSource} />
<MakeWorkingTable
data={dataSource}
onChange={setDataSource}
setHasError={setHasError}
/>
)}
</Modal>
);

@ -24,6 +24,7 @@ const EditableCell = ({
dataIndex,
record,
handleSave,
setHasError,
...restProps
}) => {
const [editing, setEditing] = useState(false);
@ -47,6 +48,8 @@ const EditableCell = ({
try {
const values = await form.validateFields();
setHasError(false);
toggleEdit();
handleSave({
...record,
@ -54,6 +57,7 @@ const EditableCell = ({
});
} catch (errInfo) {
console.log("Save failed:", errInfo);
setHasError(true);
}
};
@ -98,7 +102,7 @@ const EditableCell = ({
return <td {...restProps}>{childNode}</td>;
};
export const MakeWorkingTable = ({ data, onChange }) => {
export const MakeWorkingTable = ({ data, onChange, setHasError }) => {
const handleSave = (row) => {
const newData = [...data];
const index = newData.findIndex((item) => row.id === item.id);
@ -130,6 +134,7 @@ export const MakeWorkingTable = ({ data, onChange }) => {
dataIndex: col.dataIndex,
title: col.title,
handleSave,
setHasError,
}),
};
});

@ -7,7 +7,7 @@
cursor: pointer;
border: 1px solid #d9d9d9;
border-radius: 4px;
min-height: 24px;
min-height: 30px;
}
.editable-row:hover .editable-cell-value-wrap {

@ -1,7 +1,7 @@
import { Table } from "../Table";
import { columns } from "../columns";
import { useQuery } from "@tanstack/react-query";
import { getPoints } from "../../../api";
import { getPoints, useCanEdit } from "../../../api";
import { useCallback, useState } from "react";
import { PAGE_SIZE } from "../constants";
import { STATUSES } from "../../../config";
@ -60,6 +60,8 @@ export const OnApprovalTable = ({ fullWidth }) => {
hideSelectAll: true,
};
const canEdit = useCanEdit();
return (
<>
<Table
@ -70,7 +72,7 @@ export const OnApprovalTable = ({ fullWidth }) => {
onOpenMakeWorkingModal={() => setIsMakeWorkingModalOpened(true)}
/>
}
rowSelection={rowSelection}
rowSelection={canEdit ? rowSelection : undefined}
data={mergedData}
onPageChange={handlePageChange}
page={page}

@ -6,6 +6,7 @@ import { usePendingTableData } from "./usePendingTableData";
import { columns } from "../columns";
import { HeaderWrapper } from "../HeaderWrapper";
import { useExportPendingData } from "./useExportPendingData";
import { useCanEdit } from "../../../api";
export const PendingTable = ({ fullWidth }) => {
const { selection, include, exclude } = usePointSelection();
@ -48,9 +49,11 @@ export const PendingTable = ({ fullWidth }) => {
const handlePageChange = useCallback((page) => setPage(page), []);
const canEdit = useCanEdit();
return (
<Table
rowSelection={rowSelection}
rowSelection={canEdit ? rowSelection : undefined}
data={data}
onPageChange={handlePageChange}
page={page}

@ -3,7 +3,7 @@ import { immer } from "zustand/middleware/immer";
import { MODES } from "../config";
const store = (set) => ({
mode: MODES.ON_APPROVAL,
mode: MODES.PENDING,
setMode: (mode) => {
set((state) => {

Loading…
Cancel
Save