Can delete a movement

This commit is contained in:
2025-04-22 12:14:50 +02:00
parent 68dfbfff2b
commit bff1c2d171
4 changed files with 83 additions and 22 deletions

View File

@ -1,17 +1,19 @@
import DeleteIcon from "@mui/icons-material/DeleteOutlined";
import { Tooltip, Typography } from "@mui/material";
import { DataGrid, GridActionsCellItem, GridColDef } from "@mui/x-data-grid";
import React from "react";
import { useParams } from "react-router-dom";
import { MoneyMgrWebRouteContainer } from "../widgets/MoneyMgrWebRouteContainer";
import { Movement, MovementApi } from "../api/MovementsApi";
import { useAccounts } from "../hooks/AccountsListProvider";
import { NotFoundRoute } from "./NotFound";
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
import { AccountWidget } from "../widgets/AccountWidget";
import { AmountWidget } from "../widgets/AmountWidget";
import { Typography } from "@mui/material";
import { NewMovementWidget } from "../widgets/NewMovementWidget";
import { Movement, MovementApi } from "../api/MovementsApi";
import React from "react";
import { AsyncWidget } from "../widgets/AsyncWidget";
import { DataGrid, GridColDef } from "@mui/x-data-grid";
import { DateWidget } from "../widgets/DateWidget";
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
import { MoneyMgrWebRouteContainer } from "../widgets/MoneyMgrWebRouteContainer";
import { NewMovementWidget } from "../widgets/NewMovementWidget";
import { NotFoundRoute } from "./NotFound";
import { useConfirm } from "../hooks/context_providers/ConfirmDialogProvider";
export function AccountRoute(): React.ReactElement {
const { accountId } = useParams();
@ -28,10 +30,12 @@ export function AccountRoute(): React.ReactElement {
setMovements(await MovementApi.GetAccountMovements(account!.id));
};
const reload = async () => {
const reload = (skipMovements = false) => {
accounts.reloadBalances();
setMovements(undefined);
loadKey.current += 1;
if (!skipMovements) {
setMovements(undefined);
loadKey.current += 1;
}
};
if (account === null) return <NotFoundRoute />;
@ -58,7 +62,9 @@ export function AccountRoute(): React.ReactElement {
load={load}
ready={movements !== null}
errMsg="Failed to load the list of movements!"
build={() => <MovementsTable movements={movements!} />}
build={() => (
<MovementsTable needReload={reload} movements={movements!} />
)}
/>
</div>
<NewMovementWidget account={account} onCreated={reload} />
@ -69,9 +75,31 @@ export function AccountRoute(): React.ReactElement {
function MovementsTable(p: {
movements: Movement[];
needReload: () => {};
needReload: (skipMovements: boolean) => void;
}): React.ReactElement {
const alert = useAlert();
const confirm = useConfirm();
const handleDeleteClick = async (movement: Movement) => {
try {
if (
!(await confirm(
`Do you really want to delete the movement ${movement.label} (${movement.amount}€)?`
))
)
return;
await MovementApi.Delete(movement);
const id = p.movements.findIndex((m) => movement.id === m.id);
p.movements.slice(id, id);
p.needReload(false);
} catch (e) {
console.error("Failed to delete movement!", e);
alert(`Failed to delete movement! ${e}`);
}
};
const columns: GridColDef<(typeof p.movements)[number]>[] = [
{
@ -122,6 +150,26 @@ function MovementsTable(p: {
headerName: "File",
// TODO
},
{
field: "actions",
type: "actions",
headerName: "Actions",
width: 80,
cellClassName: "actions",
editable: false,
getActions: (params) => {
return [
<Tooltip title="Delete the movement">
<GridActionsCellItem
icon={<DeleteIcon color="error" />}
label="Delete"
onClick={() => handleDeleteClick(params.row)}
color="inherit"
/>
</Tooltip>,
];
},
},
];
return (
<DataGrid<Movement>
@ -146,6 +194,8 @@ function MovementsTable(p: {
console.error("Failed to update movement information!", e);
alert(`Failed to update row! ${e}`);
throw e;
} finally {
p.needReload(true);
}
}}
/>