Can detach file from movement
This commit is contained in:
parent
a5609d2ebd
commit
bce17bc9b4
@ -1,14 +1,20 @@
|
|||||||
import DeleteIcon from "@mui/icons-material/DeleteOutlined";
|
import DeleteIcon from "@mui/icons-material/DeleteOutlined";
|
||||||
import DriveFileMoveOutlineIcon from "@mui/icons-material/DriveFileMoveOutline";
|
import DriveFileMoveOutlineIcon from "@mui/icons-material/DriveFileMoveOutline";
|
||||||
import { IconButton, Tooltip, Typography } from "@mui/material";
|
import LinkOffIcon from "@mui/icons-material/LinkOff";
|
||||||
|
import MoreVertIcon from "@mui/icons-material/MoreVert";
|
||||||
import {
|
import {
|
||||||
DataGrid,
|
IconButton,
|
||||||
GridActionsCellItem,
|
ListItemIcon,
|
||||||
GridColDef,
|
ListItemText,
|
||||||
GridRowSelectionModel,
|
Tooltip,
|
||||||
} from "@mui/x-data-grid";
|
Typography,
|
||||||
|
} from "@mui/material";
|
||||||
|
import Menu from "@mui/material/Menu";
|
||||||
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
|
import { DataGrid, GridColDef, GridRowSelectionModel } from "@mui/x-data-grid";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
|
import { UploadedFile } from "../api/FileApi";
|
||||||
import { Movement, MovementApi } from "../api/MovementsApi";
|
import { Movement, MovementApi } from "../api/MovementsApi";
|
||||||
import { useAccounts } from "../hooks/AccountsListProvider";
|
import { useAccounts } from "../hooks/AccountsListProvider";
|
||||||
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
|
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
|
||||||
@ -20,12 +26,11 @@ import { AccountWidget } from "../widgets/AccountWidget";
|
|||||||
import { AmountWidget } from "../widgets/AmountWidget";
|
import { AmountWidget } from "../widgets/AmountWidget";
|
||||||
import { AsyncWidget } from "../widgets/AsyncWidget";
|
import { AsyncWidget } from "../widgets/AsyncWidget";
|
||||||
import { DateWidget } from "../widgets/DateWidget";
|
import { DateWidget } from "../widgets/DateWidget";
|
||||||
|
import { UploadFileButton } from "../widgets/forms/UploadFileButton";
|
||||||
import { MoneyMgrWebRouteContainer } from "../widgets/MoneyMgrWebRouteContainer";
|
import { MoneyMgrWebRouteContainer } from "../widgets/MoneyMgrWebRouteContainer";
|
||||||
import { NewMovementWidget } from "../widgets/NewMovementWidget";
|
import { NewMovementWidget } from "../widgets/NewMovementWidget";
|
||||||
import { NotFoundRoute } from "./NotFound";
|
|
||||||
import { UploadFileButton } from "../widgets/forms/UploadFileButton";
|
|
||||||
import { UploadedFile } from "../api/FileApi";
|
|
||||||
import { UploadedFileWidget } from "../widgets/UploadedFileWidget";
|
import { UploadedFileWidget } from "../widgets/UploadedFileWidget";
|
||||||
|
import { NotFoundRoute } from "./NotFound";
|
||||||
|
|
||||||
export function AccountRoute(): React.ReactElement {
|
export function AccountRoute(): React.ReactElement {
|
||||||
const loadingMessage = useLoadingMessage();
|
const loadingMessage = useLoadingMessage();
|
||||||
@ -80,7 +85,7 @@ export function AccountRoute(): React.ReactElement {
|
|||||||
<AsyncWidget
|
<AsyncWidget
|
||||||
loadKey={`${account.id}-${loadKey.current}`}
|
loadKey={`${account.id}-${loadKey.current}`}
|
||||||
load={load}
|
load={load}
|
||||||
ready={movements}
|
ready={movements !== undefined}
|
||||||
errMsg="Failed to load the list of movements!"
|
errMsg="Failed to load the list of movements!"
|
||||||
build={() => (
|
build={() => (
|
||||||
<MovementsTable needReload={reload} movements={movements!} />
|
<MovementsTable needReload={reload} movements={movements!} />
|
||||||
@ -148,6 +153,25 @@ function MovementsTable(p: {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Detach movement from account
|
||||||
|
const handleDetachFile = async (movement: Movement) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
!(await confirm(
|
||||||
|
`Do you really want to detach the file attached to the movement ${movement.label} (${movement.amount}€)? The associated file will be automatically deleted within the day if it is not referenced anywhere else!`,
|
||||||
|
`Detach file from movement`,
|
||||||
|
`Detach file`
|
||||||
|
))
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await setUploadedFile(movement, undefined);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Failed to detach file from movement!", e);
|
||||||
|
alert(`Failed to detach file from movement! ${e}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Delete movement
|
// Delete movement
|
||||||
const handleDeleteClick = async (movement: Movement) => {
|
const handleDeleteClick = async (movement: Movement) => {
|
||||||
try {
|
try {
|
||||||
@ -318,28 +342,19 @@ function MovementsTable(p: {
|
|||||||
{
|
{
|
||||||
field: "actions",
|
field: "actions",
|
||||||
type: "actions",
|
type: "actions",
|
||||||
headerName: "Actions",
|
headerName: "",
|
||||||
width: 80,
|
width: 55,
|
||||||
cellClassName: "actions",
|
cellClassName: "actions",
|
||||||
editable: false,
|
editable: false,
|
||||||
getActions: (params) => {
|
getActions: (params) => {
|
||||||
return [
|
return [
|
||||||
<Tooltip title="Move to another account" key="move">
|
<MovementActionMenu
|
||||||
<GridActionsCellItem
|
key="menu"
|
||||||
icon={<DriveFileMoveOutlineIcon />}
|
movement={params.row}
|
||||||
label="Move to another account"
|
onDelete={handleDeleteClick}
|
||||||
onClick={() => handleMoveClick(params.row)}
|
onMove={handleMoveClick}
|
||||||
color="inherit"
|
onDetachFile={handleDetachFile}
|
||||||
/>
|
/>,
|
||||||
</Tooltip>,
|
|
||||||
<Tooltip title="Delete the movement" key="delete">
|
|
||||||
<GridActionsCellItem
|
|
||||||
icon={<DeleteIcon color="error" />}
|
|
||||||
label="Delete"
|
|
||||||
onClick={() => handleDeleteClick(params.row)}
|
|
||||||
color="inherit"
|
|
||||||
/>
|
|
||||||
</Tooltip>,
|
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -407,3 +422,74 @@ function MovementsTable(p: {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function MovementActionMenu(p: {
|
||||||
|
movement: Movement;
|
||||||
|
onDetachFile: (m: Movement) => void;
|
||||||
|
onMove: (m: Movement) => void;
|
||||||
|
onDelete: (m: Movement) => void;
|
||||||
|
}): React.ReactElement {
|
||||||
|
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
||||||
|
const open = Boolean(anchorEl);
|
||||||
|
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
|
||||||
|
setAnchorEl(event.currentTarget);
|
||||||
|
};
|
||||||
|
const handleClose = () => {
|
||||||
|
setAnchorEl(null);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<IconButton
|
||||||
|
aria-label="Actions"
|
||||||
|
aria-haspopup="true"
|
||||||
|
onClick={handleClick}
|
||||||
|
>
|
||||||
|
<MoreVertIcon />
|
||||||
|
</IconButton>
|
||||||
|
<Menu anchorEl={anchorEl} open={open} onClose={handleClose}>
|
||||||
|
{/* Detach file */}
|
||||||
|
{p.movement.file_id && (
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
handleClose();
|
||||||
|
p.onDetachFile(p.movement);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ListItemIcon>
|
||||||
|
<LinkOffIcon />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText secondary={"Detach linked file"}>
|
||||||
|
Detach file
|
||||||
|
</ListItemText>
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
|
{/* Move to another account */}
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
handleClose();
|
||||||
|
p.onMove(p.movement);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ListItemIcon>
|
||||||
|
<DriveFileMoveOutlineIcon />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText secondary={"Move to another account"}>
|
||||||
|
Move
|
||||||
|
</ListItemText>
|
||||||
|
</MenuItem>
|
||||||
|
{/* Delete */}
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
handleClose();
|
||||||
|
p.onDelete(p.movement);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ListItemIcon>
|
||||||
|
<DeleteIcon color="error" />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText secondary={"Delete the movement"}>Delete</ListItemText>
|
||||||
|
</MenuItem>
|
||||||
|
</Menu>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user