feat: pagination for tables with deleted station directions

This commit is contained in:
2025-12-24 15:43:25 +03:00
parent 39e11ad5ca
commit a3d574a79c
20 changed files with 448 additions and 302 deletions

View File

@@ -30,6 +30,10 @@ export const StationListPage = observer(() => {
);
const [ids, setIds] = useState<number[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [paginationModel, setPaginationModel] = useState({
page: 0,
pageSize: 50,
});
const { language } = languageStore;
useEffect(() => {
@@ -75,25 +79,6 @@ export const StationListPage = observer(() => {
);
},
},
{
field: "direction",
headerName: "Направление",
width: 200,
align: "center",
headerAlign: "center",
renderCell: (params: GridRenderCellParams) => {
return (
<p
className={
params.row.direction === true ? "text-green-500" : "text-red-500"
}
>
{params.row.direction ? "Прямой" : "Обратный"}
</p>
);
},
},
{
field: "actions",
headerName: "Действия",
@@ -134,7 +119,6 @@ export const StationListPage = observer(() => {
},
];
// Фильтрация станций по выбранному городу
const filteredStations = () => {
const { selectedCityId } = selectedCityStore;
if (!selectedCityId) {
@@ -149,7 +133,6 @@ export const StationListPage = observer(() => {
id: station.id,
name: station.name,
description: station.description,
direction: station.direction,
}));
return (
@@ -162,29 +145,75 @@ export const StationListPage = observer(() => {
<CreateButton label="Создать остановки" path="/station/create" />
</div>
<div
className="flex justify-end mb-5 duration-300"
style={{ opacity: ids.length > 0 ? 1 : 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"
onClick={() => setIsBulkDeleteModalOpen(true)}
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}
>
<Trash2 size={20} className="text-white" /> Удалить выбранные (
{ids.length})
<Trash2
size={20}
className={ids.length > 0 ? "text-white" : "text-gray-500"}
/>
Удалить выбранные ({ids.length})
</button>
</div>
<DataGrid
rows={rows}
columns={columns}
hideFooterPagination
checkboxSelection
disableRowSelectionExcludeModel
loading={isLoading}
onRowSelectionModelChange={(newSelection) => {
setIds(Array.from(newSelection.ids) as number[]);
paginationModel={paginationModel}
onPaginationModelChange={setPaginationModel}
pageSizeOptions={[50]}
onRowSelectionModelChange={(newSelection: any) => {
if (Array.isArray(newSelection)) {
const selectedIds = newSelection
.map((id: string | number) => {
const numId =
typeof id === "string"
? Number.parseInt(id, 10)
: Number(id);
return numId;
})
.filter(
(id: number) =>
!Number.isNaN(id) && id !== null && id !== undefined
);
setIds(selectedIds);
} 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) => {
const numId =
typeof id === "string"
? Number.parseInt(id, 10)
: Number(id);
return numId;
})
.filter(
(id: number) =>
!Number.isNaN(id) && id !== null && id !== undefined
);
setIds(selectedIds);
} else {
setIds([]);
}
}}
hideFooter
localeText={ruRU.components.MuiDataGrid.defaultProps.localeText}
slots={{
noRowsOverlay: () => (