Can delete multiple inbox entries
This commit is contained in:
parent
9fe90c3527
commit
34ccb78ab7
@ -10,6 +10,7 @@ import {
|
|||||||
ListItemText,
|
ListItemText,
|
||||||
Menu,
|
Menu,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
|
TextField,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { DataGrid, GridColDef, GridRowSelectionModel } from "@mui/x-data-grid";
|
import { DataGrid, GridColDef, GridRowSelectionModel } from "@mui/x-data-grid";
|
||||||
@ -117,6 +118,14 @@ function InboxTable(p: {
|
|||||||
const snackbar = useSnackbar();
|
const snackbar = useSnackbar();
|
||||||
const loadingMessage = useLoadingMessage();
|
const loadingMessage = useLoadingMessage();
|
||||||
|
|
||||||
|
const [labelFilter, setLabelFilter] = React.useState("");
|
||||||
|
|
||||||
|
const filteredList = React.useMemo(() => {
|
||||||
|
return p.entries.filter((m) =>
|
||||||
|
(m.label ?? "").toLowerCase().includes(labelFilter.toLowerCase())
|
||||||
|
);
|
||||||
|
}, [p.entries, labelFilter]);
|
||||||
|
|
||||||
const [rowSelectionModel, setRowSelectionModel] =
|
const [rowSelectionModel, setRowSelectionModel] =
|
||||||
React.useState<GridRowSelectionModel>([]);
|
React.useState<GridRowSelectionModel>([]);
|
||||||
|
|
||||||
@ -168,6 +177,50 @@ function InboxTable(p: {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Delete multiple inbox entries
|
||||||
|
const deleteMultiple = async () => {
|
||||||
|
try {
|
||||||
|
const deletedEntries = p.entries.filter((m) =>
|
||||||
|
rowSelectionModel.includes(m.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!(await confirm(
|
||||||
|
<>
|
||||||
|
Do you really want to delete the following inbox entries:
|
||||||
|
<ul>
|
||||||
|
{deletedEntries.map((m) => (
|
||||||
|
<li key={m.id}>
|
||||||
|
{m.label ?? "Label unspecified"} ({m.amount ?? 0} €)
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
))
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (const [num, e] of deletedEntries.entries()) {
|
||||||
|
loadingMessage.show(
|
||||||
|
`Deleting inbox entry ${num}/${deletedEntries.length}`
|
||||||
|
);
|
||||||
|
|
||||||
|
await InboxApi.Delete(e);
|
||||||
|
|
||||||
|
p.onDeleteEntry(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
snackbar("The inbox entries have been successfully deleted!");
|
||||||
|
|
||||||
|
p.onReload(false);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Failed to delete multiple inbox entries!", e);
|
||||||
|
alert(`Failed to delete multiple inbox entries! ${e}`);
|
||||||
|
} finally {
|
||||||
|
loadingMessage.hide();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const columns: GridColDef<(typeof p.entries)[number]>[] = [
|
const columns: GridColDef<(typeof p.entries)[number]>[] = [
|
||||||
{
|
{
|
||||||
field: "time",
|
field: "time",
|
||||||
@ -247,39 +300,65 @@ function InboxTable(p: {
|
|||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ flex: 1 }}>
|
<>
|
||||||
<DataGrid<InboxEntry>
|
<div style={{ display: "flex" }}>
|
||||||
columns={columns}
|
<TextField
|
||||||
rows={p.entries}
|
placeholder="Filter by label"
|
||||||
autoPageSize
|
variant="standard"
|
||||||
checkboxSelection
|
size="small"
|
||||||
initialState={{
|
value={labelFilter}
|
||||||
sorting: {
|
onChange={(e) => {
|
||||||
sortModel: [{ field: "time", sort: "desc" }],
|
setLabelFilter(e.target.value);
|
||||||
},
|
}}
|
||||||
columns: {
|
style={{ padding: "0px", flex: 1 }}
|
||||||
columnVisibilityModel: {
|
/>
|
||||||
movement_id: p.showMovements!!,
|
<span style={{ flex: 1 }}></span>
|
||||||
|
<Tooltip title="Delete all the selected inbox entries">
|
||||||
|
<IconButton
|
||||||
|
disabled={
|
||||||
|
rowSelectionModel.length === 0 ||
|
||||||
|
rowSelectionModel.length === p.entries.length
|
||||||
|
}
|
||||||
|
onClick={deleteMultiple}
|
||||||
|
>
|
||||||
|
<DeleteIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
<div style={{ flex: 1 }}>
|
||||||
|
<DataGrid<InboxEntry>
|
||||||
|
columns={columns}
|
||||||
|
rows={filteredList}
|
||||||
|
autoPageSize
|
||||||
|
checkboxSelection
|
||||||
|
initialState={{
|
||||||
|
sorting: {
|
||||||
|
sortModel: [{ field: "time", sort: "desc" }],
|
||||||
},
|
},
|
||||||
},
|
columns: {
|
||||||
}}
|
columnVisibilityModel: {
|
||||||
onRowSelectionModelChange={(newRowSelectionModel) => {
|
movement_id: p.showMovements!!,
|
||||||
setRowSelectionModel(newRowSelectionModel);
|
},
|
||||||
}}
|
},
|
||||||
rowSelectionModel={rowSelectionModel}
|
}}
|
||||||
processRowUpdate={async (n) => {
|
onRowSelectionModelChange={(newRowSelectionModel) => {
|
||||||
try {
|
setRowSelectionModel(newRowSelectionModel);
|
||||||
return await InboxApi.Update(n);
|
}}
|
||||||
} catch (e) {
|
rowSelectionModel={rowSelectionModel}
|
||||||
console.error("Failed to update movement information!", e);
|
processRowUpdate={async (n) => {
|
||||||
alert(`Failed to update row! ${e}`);
|
try {
|
||||||
throw e;
|
return await InboxApi.Update(n);
|
||||||
} finally {
|
} catch (e) {
|
||||||
p.onReload(true);
|
console.error("Failed to update inbox entry information!", e);
|
||||||
}
|
alert(`Failed to update row! ${e}`);
|
||||||
}}
|
throw e;
|
||||||
/>
|
} finally {
|
||||||
</div>
|
p.onReload(true);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user