feat: role system fix
This commit is contained in:
@@ -21,6 +21,7 @@ export const ArticleListPage = observer(() => {
|
||||
page: 0,
|
||||
pageSize: 50,
|
||||
});
|
||||
const canWriteArticles = authStore.canWrite("sights");
|
||||
|
||||
useEffect(() => {
|
||||
const fetchArticles = async () => {
|
||||
@@ -56,7 +57,7 @@ export const ArticleListPage = observer(() => {
|
||||
<button onClick={() => navigate(`/article/${params.row.id}`)}>
|
||||
<Eye size={20} className="text-green-500" />
|
||||
</button>
|
||||
{authStore.canWrite("sights") && (
|
||||
{canWriteArticles && (
|
||||
<button
|
||||
onClick={() => {
|
||||
setIsDeleteModalOpen(true);
|
||||
@@ -86,7 +87,7 @@ export const ArticleListPage = observer(() => {
|
||||
<h1 className="text-2xl">Статьи</h1>
|
||||
</div>
|
||||
|
||||
{ids.length > 0 && (
|
||||
{canWriteArticles && ids.length > 0 && (
|
||||
<div className="flex justify-end mb-5 duration-300">
|
||||
<button
|
||||
className="px-4 py-2 bg-red-500 text-white rounded flex gap-2 items-center"
|
||||
@@ -102,25 +103,37 @@ export const ArticleListPage = observer(() => {
|
||||
<DataGrid
|
||||
rows={rows}
|
||||
columns={columns}
|
||||
checkboxSelection
|
||||
checkboxSelection={canWriteArticles}
|
||||
disableRowSelectionExcludeModel
|
||||
loading={isLoading}
|
||||
paginationModel={paginationModel}
|
||||
onPaginationModelChange={setPaginationModel}
|
||||
pageSizeOptions={[50]}
|
||||
localeText={ruRU.components.MuiDataGrid.defaultProps.localeText}
|
||||
onRowSelectionModelChange={(newSelection: any) => {
|
||||
onRowSelectionModelChange={
|
||||
canWriteArticles
|
||||
? (newSelection: any) => {
|
||||
if (Array.isArray(newSelection)) {
|
||||
const selectedIds = newSelection.map((id: string | number) => Number(id));
|
||||
const selectedIds = newSelection.map(
|
||||
(id: string | number) => Number(id)
|
||||
);
|
||||
setIds(selectedIds);
|
||||
} else if (newSelection && typeof newSelection === 'object' && 'ids' in newSelection) {
|
||||
} else if (
|
||||
newSelection &&
|
||||
typeof newSelection === "object" &&
|
||||
"ids" in newSelection
|
||||
) {
|
||||
const idsSet = newSelection.ids as Set<string | number>;
|
||||
const selectedIds = Array.from(idsSet).map((id: string | number) => Number(id));
|
||||
const selectedIds = Array.from(idsSet).map(
|
||||
(id: string | number) => Number(id)
|
||||
);
|
||||
setIds(selectedIds);
|
||||
} else {
|
||||
setIds([]);
|
||||
}
|
||||
}}
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
slots={{
|
||||
noRowsOverlay: () => (
|
||||
<Box
|
||||
|
||||
@@ -130,7 +130,7 @@ export const CityListPage = observer(() => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{ids.length > 0 && (
|
||||
{canWriteCities && ids.length > 0 && (
|
||||
<div className="flex justify-end mb-5 duration-300">
|
||||
<button
|
||||
className="px-4 py-2 bg-red-500 text-white rounded flex gap-2 items-center"
|
||||
@@ -145,25 +145,37 @@ export const CityListPage = observer(() => {
|
||||
<DataGrid
|
||||
rows={rows}
|
||||
columns={columns}
|
||||
checkboxSelection={authStore.canWrite("cities")}
|
||||
checkboxSelection={canWriteCities}
|
||||
disableRowSelectionExcludeModel
|
||||
loading={isLoading}
|
||||
paginationModel={paginationModel}
|
||||
onPaginationModelChange={setPaginationModel}
|
||||
pageSizeOptions={[50]}
|
||||
localeText={ruRU.components.MuiDataGrid.defaultProps.localeText}
|
||||
onRowSelectionModelChange={(newSelection: any) => {
|
||||
onRowSelectionModelChange={
|
||||
canWriteCities
|
||||
? (newSelection: any) => {
|
||||
if (Array.isArray(newSelection)) {
|
||||
const selectedIds = newSelection.map((id: string | number) => Number(id));
|
||||
const selectedIds = newSelection.map(
|
||||
(id: string | number) => Number(id)
|
||||
);
|
||||
setIds(selectedIds);
|
||||
} else if (newSelection && typeof newSelection === 'object' && 'ids' in newSelection) {
|
||||
} else if (
|
||||
newSelection &&
|
||||
typeof newSelection === "object" &&
|
||||
"ids" in newSelection
|
||||
) {
|
||||
const idsSet = newSelection.ids as Set<string | number>;
|
||||
const selectedIds = Array.from(idsSet).map((id: string | number) => Number(id));
|
||||
const selectedIds = Array.from(idsSet).map(
|
||||
(id: string | number) => Number(id)
|
||||
);
|
||||
setIds(selectedIds);
|
||||
} else {
|
||||
setIds([]);
|
||||
}
|
||||
}}
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
slots={{
|
||||
noRowsOverlay: () => (
|
||||
<Box sx={{ mt: 5, textAlign: "center", color: "text.secondary" }}>
|
||||
|
||||
@@ -90,7 +90,7 @@ export const CountryListPage = observer(() => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{ids.length > 0 && (
|
||||
{canWriteCountries && ids.length > 0 && (
|
||||
<div className="flex justify-end mb-5 duration-300">
|
||||
<button
|
||||
className="px-4 py-2 bg-red-500 text-white rounded flex gap-2 items-center"
|
||||
@@ -105,25 +105,37 @@ export const CountryListPage = observer(() => {
|
||||
<DataGrid
|
||||
rows={rows || []}
|
||||
columns={columns}
|
||||
checkboxSelection={authStore.canWrite("countries")}
|
||||
checkboxSelection={canWriteCountries}
|
||||
disableRowSelectionExcludeModel
|
||||
loading={isLoading}
|
||||
paginationModel={paginationModel}
|
||||
onPaginationModelChange={setPaginationModel}
|
||||
pageSizeOptions={[50]}
|
||||
localeText={ruRU.components.MuiDataGrid.defaultProps.localeText}
|
||||
onRowSelectionModelChange={(newSelection: any) => {
|
||||
onRowSelectionModelChange={
|
||||
canWriteCountries
|
||||
? (newSelection: any) => {
|
||||
if (Array.isArray(newSelection)) {
|
||||
const selectedIds = newSelection.map((id: string | number) => Number(id));
|
||||
const selectedIds = newSelection.map(
|
||||
(id: string | number) => Number(id)
|
||||
);
|
||||
setIds(selectedIds);
|
||||
} else if (newSelection && typeof newSelection === 'object' && 'ids' in newSelection) {
|
||||
} else if (
|
||||
newSelection &&
|
||||
typeof newSelection === "object" &&
|
||||
"ids" in newSelection
|
||||
) {
|
||||
const idsSet = newSelection.ids as Set<string | number>;
|
||||
const selectedIds = Array.from(idsSet).map((id: string | number) => Number(id));
|
||||
const selectedIds = Array.from(idsSet).map(
|
||||
(id: string | number) => Number(id)
|
||||
);
|
||||
setIds(selectedIds);
|
||||
} else {
|
||||
setIds([]);
|
||||
}
|
||||
}}
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
slots={{
|
||||
noRowsOverlay: () => (
|
||||
<Box sx={{ mt: 5, textAlign: "center", color: "text.secondary" }}>
|
||||
|
||||
@@ -21,6 +21,7 @@ export const MediaListPage = observer(() => {
|
||||
pageSize: 50,
|
||||
});
|
||||
const { language } = languageStore;
|
||||
const canWriteMedia = authStore.canWrite("sights");
|
||||
|
||||
useEffect(() => {
|
||||
const fetchMedia = async () => {
|
||||
@@ -79,7 +80,7 @@ export const MediaListPage = observer(() => {
|
||||
<button onClick={() => navigate(`/media/${params.row.id}`)}>
|
||||
<Eye size={20} className="text-green-500" />
|
||||
</button>
|
||||
{authStore.canWrite("sights") && (
|
||||
{canWriteMedia && (
|
||||
<button
|
||||
onClick={() => {
|
||||
setIsDeleteModalOpen(true);
|
||||
@@ -103,7 +104,7 @@ export const MediaListPage = observer(() => {
|
||||
return (
|
||||
<>
|
||||
<div className="w-full">
|
||||
{ids.length > 0 && (
|
||||
{canWriteMedia && ids.length > 0 && (
|
||||
<div className="flex justify-end mb-5 duration-300">
|
||||
<button
|
||||
className="px-4 py-2 bg-red-500 text-white rounded flex gap-2 items-center"
|
||||
@@ -118,24 +119,36 @@ export const MediaListPage = observer(() => {
|
||||
<DataGrid
|
||||
rows={rows}
|
||||
columns={columns}
|
||||
checkboxSelection={authStore.canWrite("sights")}
|
||||
checkboxSelection={canWriteMedia}
|
||||
disableRowSelectionExcludeModel
|
||||
loading={isLoading}
|
||||
paginationModel={paginationModel}
|
||||
onPaginationModelChange={setPaginationModel}
|
||||
pageSizeOptions={[50]}
|
||||
onRowSelectionModelChange={(newSelection: any) => {
|
||||
onRowSelectionModelChange={
|
||||
canWriteMedia
|
||||
? (newSelection: any) => {
|
||||
if (Array.isArray(newSelection)) {
|
||||
const selectedIds = newSelection.map((id: string | number) => String(id));
|
||||
const selectedIds = newSelection.map(
|
||||
(id: string | number) => String(id)
|
||||
);
|
||||
setIds(selectedIds);
|
||||
} else if (newSelection && typeof newSelection === 'object' && 'ids' in newSelection) {
|
||||
} else if (
|
||||
newSelection &&
|
||||
typeof newSelection === "object" &&
|
||||
"ids" in newSelection
|
||||
) {
|
||||
const idsSet = newSelection.ids as Set<string | number>;
|
||||
const selectedIds = Array.from(idsSet).map((id: string | number) => String(id));
|
||||
const selectedIds = Array.from(idsSet).map(
|
||||
(id: string | number) => String(id)
|
||||
);
|
||||
setIds(selectedIds);
|
||||
} else {
|
||||
setIds([]);
|
||||
}
|
||||
}}
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
localeText={ruRU.components.MuiDataGrid.defaultProps.localeText}
|
||||
slots={{
|
||||
noRowsOverlay: () => (
|
||||
|
||||
@@ -252,7 +252,7 @@ const LinkedItemsContentsInner = <
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error fetching all items:", error);
|
||||
setError("Failed to load available stations");
|
||||
setError(null);
|
||||
setAllItems([]);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,6 +22,12 @@ export const RouteListPage = observer(() => {
|
||||
pageSize: 50,
|
||||
});
|
||||
const { language } = languageStore;
|
||||
const canWriteRoutes = authStore.canWrite("routes");
|
||||
const canShowRoutePreview =
|
||||
authStore.canWrite("stations") &&
|
||||
authStore.canWrite("sights") &&
|
||||
authStore.canWrite("routes");
|
||||
const canShowActionsColumn = canWriteRoutes || canShowRoutePreview;
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
@@ -104,7 +110,7 @@ export const RouteListPage = observer(() => {
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
...(canShowActionsColumn ? [{
|
||||
field: "actions",
|
||||
headerName: "Действия",
|
||||
width: 250,
|
||||
@@ -112,14 +118,9 @@ export const RouteListPage = observer(() => {
|
||||
headerAlign: "center" as const,
|
||||
sortable: false,
|
||||
renderCell: (params: GridRenderCellParams) => {
|
||||
const canWrite = authStore.canWrite("routes");
|
||||
const canShowRoutePreview =
|
||||
authStore.canRead("stations") &&
|
||||
authStore.canRead("sights") &&
|
||||
authStore.canRead("routes");
|
||||
return (
|
||||
<div className="flex h-full gap-7 justify-center items-center">
|
||||
{canWrite && (
|
||||
{canWriteRoutes && (
|
||||
<button onClick={() => navigate(`/route/${params.row.id}/edit`)}>
|
||||
<Pencil size={20} className="text-blue-500" />
|
||||
</button>
|
||||
@@ -129,7 +130,7 @@ export const RouteListPage = observer(() => {
|
||||
<Map size={20} className="text-purple-500" />
|
||||
</button>
|
||||
)}
|
||||
{canWrite && (
|
||||
{canWriteRoutes && (
|
||||
<button
|
||||
onClick={() => {
|
||||
setIsDeleteModalOpen(true);
|
||||
@@ -142,7 +143,7 @@ export const RouteListPage = observer(() => {
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
}] : []),
|
||||
];
|
||||
|
||||
const rows = routes.data.map((route) => ({
|
||||
@@ -160,10 +161,12 @@ export const RouteListPage = observer(() => {
|
||||
<div style={{ width: "100%" }}>
|
||||
<div className="flex justify-between items-center mb-10">
|
||||
<h1 className="text-2xl">Маршруты</h1>
|
||||
{canWriteRoutes && (
|
||||
<CreateButton label="Создать маршрут" path="/route/create" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
{ids.length > 0 && (
|
||||
{canWriteRoutes && ids.length > 0 && (
|
||||
<div className="flex justify-end mb-5 duration-300">
|
||||
<button
|
||||
className="px-4 py-2 bg-red-500 text-white rounded flex gap-2 items-center"
|
||||
@@ -178,25 +181,37 @@ export const RouteListPage = observer(() => {
|
||||
<DataGrid
|
||||
rows={rows}
|
||||
columns={columns}
|
||||
checkboxSelection={authStore.canWrite("routes")}
|
||||
checkboxSelection={canWriteRoutes}
|
||||
disableRowSelectionExcludeModel
|
||||
loading={isLoading}
|
||||
paginationModel={paginationModel}
|
||||
onPaginationModelChange={setPaginationModel}
|
||||
pageSizeOptions={[50]}
|
||||
localeText={ruRU.components.MuiDataGrid.defaultProps.localeText}
|
||||
onRowSelectionModelChange={(newSelection: any) => {
|
||||
onRowSelectionModelChange={
|
||||
canWriteRoutes
|
||||
? (newSelection: any) => {
|
||||
if (Array.isArray(newSelection)) {
|
||||
const selectedIds = newSelection.map((id: string | number) => Number(id));
|
||||
const selectedIds = newSelection.map((id: string | number) =>
|
||||
Number(id)
|
||||
);
|
||||
setIds(selectedIds);
|
||||
} else if (newSelection && typeof newSelection === 'object' && 'ids' in newSelection) {
|
||||
} else if (
|
||||
newSelection &&
|
||||
typeof newSelection === "object" &&
|
||||
"ids" in newSelection
|
||||
) {
|
||||
const idsSet = newSelection.ids as Set<string | number>;
|
||||
const selectedIds = Array.from(idsSet).map((id: string | number) => Number(id));
|
||||
const selectedIds = Array.from(idsSet).map(
|
||||
(id: string | number) => Number(id)
|
||||
);
|
||||
setIds(selectedIds);
|
||||
} else {
|
||||
setIds([]);
|
||||
}
|
||||
}}
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
slots={{
|
||||
noRowsOverlay: () => (
|
||||
<Box sx={{ mt: 5, textAlign: "center", color: "text.secondary" }}>
|
||||
|
||||
@@ -356,7 +356,7 @@ const LinkedStationsContentsInner = <
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error fetching all stations:", error);
|
||||
setError("Failed to load available stations");
|
||||
setError(null);
|
||||
setAllItems([]);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ const LinkedSightsContentsInner = <
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error fetching all sights:", error);
|
||||
setError("Failed to load available sights");
|
||||
setError(null);
|
||||
setAllItems([]);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -149,38 +149,30 @@ export const StationListPage = observer(() => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{canWriteStations && ids.length > 0 && (
|
||||
<div className="flex justify-end mb-5 duration-300">
|
||||
<button
|
||||
className={`px-4 py-2 rounded flex gap-2 items-center transition-all ${
|
||||
ids.length > 0
|
||||
? "bg-red-500 text-white cursor-pointer opacity-100"
|
||||
: "bg-gray-300 text-gray-500 cursor-not-allowed opacity-0 pointer-events-none"
|
||||
}`}
|
||||
onClick={() => {
|
||||
if (ids.length > 0) {
|
||||
setIsBulkDeleteModalOpen(true);
|
||||
}
|
||||
}}
|
||||
disabled={ids.length === 0}
|
||||
className="px-4 py-2 bg-red-500 text-white rounded flex gap-2 items-center"
|
||||
onClick={() => setIsBulkDeleteModalOpen(true)}
|
||||
>
|
||||
<Trash2
|
||||
size={20}
|
||||
className={ids.length > 0 ? "text-white" : "text-gray-500"}
|
||||
/>
|
||||
Удалить выбранные ({ids.length})
|
||||
<Trash2 size={20} className="text-white" /> Удалить выбранные (
|
||||
{ids.length})
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<DataGrid
|
||||
rows={rows}
|
||||
columns={columns}
|
||||
checkboxSelection
|
||||
checkboxSelection={canWriteStations}
|
||||
disableRowSelectionExcludeModel
|
||||
loading={isLoading}
|
||||
paginationModel={paginationModel}
|
||||
onPaginationModelChange={setPaginationModel}
|
||||
pageSizeOptions={[50]}
|
||||
onRowSelectionModelChange={(newSelection: any) => {
|
||||
onRowSelectionModelChange={
|
||||
canWriteStations
|
||||
? (newSelection: any) => {
|
||||
if (Array.isArray(newSelection)) {
|
||||
const selectedIds = newSelection
|
||||
.map((id: string | number) => {
|
||||
@@ -217,7 +209,9 @@ export const StationListPage = observer(() => {
|
||||
} else {
|
||||
setIds([]);
|
||||
}
|
||||
}}
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
localeText={ruRU.components.MuiDataGrid.defaultProps.localeText}
|
||||
slots={{
|
||||
noRowsOverlay: () => (
|
||||
|
||||
@@ -124,7 +124,7 @@ export const UserListPage = observer(() => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{ids.length > 0 && (
|
||||
{canWriteUsers && ids.length > 0 && (
|
||||
<div className="flex justify-end mb-5 duration-300">
|
||||
<button
|
||||
className="px-4 py-2 bg-red-500 text-white rounded flex gap-2 items-center"
|
||||
@@ -145,18 +145,30 @@ export const UserListPage = observer(() => {
|
||||
paginationModel={paginationModel}
|
||||
onPaginationModelChange={setPaginationModel}
|
||||
pageSizeOptions={[50]}
|
||||
onRowSelectionModelChange={(newSelection: any) => {
|
||||
onRowSelectionModelChange={
|
||||
canWriteUsers
|
||||
? (newSelection: any) => {
|
||||
if (Array.isArray(newSelection)) {
|
||||
const selectedIds = newSelection.map((id: string | number) => Number(id));
|
||||
const selectedIds = newSelection.map(
|
||||
(id: string | number) => Number(id)
|
||||
);
|
||||
setIds(selectedIds);
|
||||
} else if (newSelection && typeof newSelection === 'object' && 'ids' in newSelection) {
|
||||
} else if (
|
||||
newSelection &&
|
||||
typeof newSelection === "object" &&
|
||||
"ids" in newSelection
|
||||
) {
|
||||
const idsSet = newSelection.ids as Set<string | number>;
|
||||
const selectedIds = Array.from(idsSet).map((id: string | number) => Number(id));
|
||||
const selectedIds = Array.from(idsSet).map(
|
||||
(id: string | number) => Number(id)
|
||||
);
|
||||
setIds(selectedIds);
|
||||
} else {
|
||||
setIds([]);
|
||||
}
|
||||
}}
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
localeText={ruRU.components.MuiDataGrid.defaultProps.localeText}
|
||||
slots={{
|
||||
noRowsOverlay: () => (
|
||||
|
||||
@@ -23,6 +23,7 @@ export const VehicleListPage = observer(() => {
|
||||
pageSize: 50,
|
||||
});
|
||||
const { language } = languageStore;
|
||||
const canWriteVehicles = authStore.canWrite("devices");
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
@@ -156,7 +157,7 @@ export const VehicleListPage = observer(() => {
|
||||
/>
|
||||
</div>
|
||||
|
||||
{ids.length > 0 && (
|
||||
{canWriteVehicles && ids.length > 0 && (
|
||||
<div className="flex justify-end mb-5 duration-300">
|
||||
<button
|
||||
className="px-4 py-2 bg-red-500 text-white rounded flex gap-2 items-center"
|
||||
@@ -171,24 +172,36 @@ export const VehicleListPage = observer(() => {
|
||||
<DataGrid
|
||||
rows={rows}
|
||||
columns={columns}
|
||||
checkboxSelection={authStore.canWrite("devices")}
|
||||
checkboxSelection={canWriteVehicles}
|
||||
disableRowSelectionExcludeModel
|
||||
loading={isLoading}
|
||||
paginationModel={paginationModel}
|
||||
onPaginationModelChange={setPaginationModel}
|
||||
pageSizeOptions={[50]}
|
||||
onRowSelectionModelChange={(newSelection: any) => {
|
||||
onRowSelectionModelChange={
|
||||
canWriteVehicles
|
||||
? (newSelection: any) => {
|
||||
if (Array.isArray(newSelection)) {
|
||||
const selectedIds = newSelection.map((id: string | number) => Number(id));
|
||||
const selectedIds = newSelection.map(
|
||||
(id: string | number) => Number(id)
|
||||
);
|
||||
setIds(selectedIds);
|
||||
} else if (newSelection && typeof newSelection === 'object' && 'ids' in newSelection) {
|
||||
} else if (
|
||||
newSelection &&
|
||||
typeof newSelection === "object" &&
|
||||
"ids" in newSelection
|
||||
) {
|
||||
const idsSet = newSelection.ids as Set<string | number>;
|
||||
const selectedIds = Array.from(idsSet).map((id: string | number) => Number(id));
|
||||
const selectedIds = Array.from(idsSet).map(
|
||||
(id: string | number) => Number(id)
|
||||
);
|
||||
setIds(selectedIds);
|
||||
} else {
|
||||
setIds([]);
|
||||
}
|
||||
}}
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
localeText={ruRU.components.MuiDataGrid.defaultProps.localeText}
|
||||
slots={{
|
||||
noRowsOverlay: () => (
|
||||
|
||||
@@ -152,8 +152,6 @@ class AuthStore {
|
||||
};
|
||||
|
||||
canAccess = (permission: string): boolean => {
|
||||
// If permission looks like a concrete role (e.g. snapshot_create/snapshot_rw),
|
||||
// check it as-is; otherwise treat it as a resource name.
|
||||
if (permission.includes("_")) {
|
||||
return this.hasRole(permission);
|
||||
}
|
||||
|
||||
@@ -13,17 +13,17 @@ import { MapPin } from "lucide-react";
|
||||
|
||||
export const CitySelector: React.FC = observer(() => {
|
||||
const { selectedCity, setSelectedCity } = selectedCityStore;
|
||||
const canReadCities = authStore.canRead("cities");
|
||||
const canLoadAllCities = authStore.isAdmin && authStore.canRead("cities");
|
||||
|
||||
useEffect(() => {
|
||||
if (canReadCities) {
|
||||
if (canLoadAllCities) {
|
||||
cityStore.getCities("ru");
|
||||
return;
|
||||
}
|
||||
authStore.fetchMeCities().catch(() => undefined);
|
||||
}, [canReadCities]);
|
||||
}, [canLoadAllCities]);
|
||||
|
||||
const baseCities: City[] = canReadCities
|
||||
const baseCities: City[] = canLoadAllCities
|
||||
? cityStore.cities["ru"].data
|
||||
: authStore.meCities["ru"].map((uc) => ({
|
||||
id: uc.city_id,
|
||||
|
||||
@@ -781,7 +781,7 @@ export const DevicesTable = observer(() => {
|
||||
Добавить устройство
|
||||
</Button>
|
||||
)}
|
||||
{selectedIds.length > 0 && (
|
||||
{canWriteDevices && selectedIds.length > 0 && (
|
||||
<Button
|
||||
variant="contained"
|
||||
color="error"
|
||||
@@ -862,16 +862,18 @@ export const DevicesTable = observer(() => {
|
||||
<DataGrid
|
||||
rows={groupRows}
|
||||
columns={columns}
|
||||
checkboxSelection
|
||||
checkboxSelection={canWriteDevices}
|
||||
disableRowSelectionExcludeModel
|
||||
loading={isLoading}
|
||||
paginationModel={paginationModel}
|
||||
onPaginationModelChange={setPaginationModel}
|
||||
pageSizeOptions={[50]}
|
||||
onRowSelectionModelChange={
|
||||
createSelectionHandler(groupRowIds) as (
|
||||
canWriteDevices
|
||||
? (createSelectionHandler(groupRowIds) as (
|
||||
ids: unknown,
|
||||
) => void
|
||||
) => void)
|
||||
: undefined
|
||||
}
|
||||
rowSelectionModel={{
|
||||
type: "include",
|
||||
|
||||
Reference in New Issue
Block a user