Can detach movement from inbox entry
This commit is contained in:
parent
2f807b4c73
commit
11d140826d
@ -24,8 +24,6 @@ export function UnmatchedInboxEntriesCountProvider(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onReload = async () => {
|
const onReload = async () => {
|
||||||
loadKey.current += 1;
|
|
||||||
|
|
||||||
load();
|
load();
|
||||||
|
|
||||||
return new Promise<void>((res) => {
|
return new Promise<void>((res) => {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import DeleteIcon from "@mui/icons-material/DeleteOutlined";
|
import DeleteIcon from "@mui/icons-material/DeleteOutlined";
|
||||||
|
import LinkOffIcon from "@mui/icons-material/LinkOff";
|
||||||
import MoreVertIcon from "@mui/icons-material/MoreVert";
|
import MoreVertIcon from "@mui/icons-material/MoreVert";
|
||||||
import RefreshIcon from "@mui/icons-material/Refresh";
|
import RefreshIcon from "@mui/icons-material/Refresh";
|
||||||
import {
|
import {
|
||||||
@ -88,6 +89,11 @@ export function InboxRoute(): React.ReactElement {
|
|||||||
build={() => (
|
build={() => (
|
||||||
<InboxTable
|
<InboxTable
|
||||||
entries={entries!}
|
entries={entries!}
|
||||||
|
onDeleteEntry={(del) => {
|
||||||
|
setEntries((entries) => {
|
||||||
|
return entries?.filter((m) => m.id !== del.id);
|
||||||
|
});
|
||||||
|
}}
|
||||||
onReload={reload}
|
onReload={reload}
|
||||||
showMovements={includeAttached}
|
showMovements={includeAttached}
|
||||||
/>
|
/>
|
||||||
@ -102,6 +108,7 @@ export function InboxRoute(): React.ReactElement {
|
|||||||
|
|
||||||
function InboxTable(p: {
|
function InboxTable(p: {
|
||||||
entries: InboxEntry[];
|
entries: InboxEntry[];
|
||||||
|
onDeleteEntry: (entry: InboxEntry) => void;
|
||||||
onReload: (skipEntries: boolean) => void;
|
onReload: (skipEntries: boolean) => void;
|
||||||
showMovements?: boolean;
|
showMovements?: boolean;
|
||||||
}): React.ReactElement {
|
}): React.ReactElement {
|
||||||
@ -127,13 +134,37 @@ function InboxTable(p: {
|
|||||||
|
|
||||||
await InboxApi.Delete(entry);
|
await InboxApi.Delete(entry);
|
||||||
|
|
||||||
const id = p.entries.findIndex((m) => entry.id === m.id);
|
p.onDeleteEntry(entry);
|
||||||
p.entries.slice(id, id);
|
|
||||||
|
|
||||||
p.onReload(false);
|
p.onReload(true);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Failed to delete movement!", e);
|
console.error("Failed to delete entry!", e);
|
||||||
alert(`Failed to delete movement! ${e}`);
|
alert(`Failed to delete entry! ${e}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Detach inbox entry from movement
|
||||||
|
const handleDetachClick = async (entry: InboxEntry) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
!(await confirm(
|
||||||
|
`Do you really want to detach this inbox entry ${
|
||||||
|
entry.label ?? ""
|
||||||
|
} (${entry.amount ?? 0} €) from its movement?`,
|
||||||
|
"Detach inbox entry from movement",
|
||||||
|
"Detach"
|
||||||
|
))
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
entry.movement_id = undefined;
|
||||||
|
|
||||||
|
await InboxApi.Update(entry);
|
||||||
|
|
||||||
|
p.onReload(true);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Failed to detach movement from entry!", e);
|
||||||
|
alert(`Failed to detach movement from entry! ${e}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -206,8 +237,9 @@ function InboxTable(p: {
|
|||||||
return [
|
return [
|
||||||
<InboxEntryActionMenu
|
<InboxEntryActionMenu
|
||||||
key="menu"
|
key="menu"
|
||||||
movement={params.row}
|
entry={params.row}
|
||||||
onDelete={handleDeleteClick}
|
onDelete={handleDeleteClick}
|
||||||
|
onDetach={handleDetachClick}
|
||||||
/>,
|
/>,
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
@ -252,8 +284,9 @@ function InboxTable(p: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function InboxEntryActionMenu(p: {
|
function InboxEntryActionMenu(p: {
|
||||||
movement: InboxEntry;
|
entry: InboxEntry;
|
||||||
onDelete: (entry: InboxEntry) => void;
|
onDelete: (entry: InboxEntry) => void;
|
||||||
|
onDetach: (entry: InboxEntry) => void;
|
||||||
}): React.ReactElement {
|
}): React.ReactElement {
|
||||||
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
||||||
const open = Boolean(anchorEl);
|
const open = Boolean(anchorEl);
|
||||||
@ -273,11 +306,28 @@ function InboxEntryActionMenu(p: {
|
|||||||
<MoreVertIcon />
|
<MoreVertIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<Menu anchorEl={anchorEl} open={open} onClose={handleClose}>
|
<Menu anchorEl={anchorEl} open={open} onClose={handleClose}>
|
||||||
|
{/* Unlink entry */}
|
||||||
|
{p.entry.movement_id && (
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
handleClose();
|
||||||
|
p.onDetach(p.entry);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ListItemIcon>
|
||||||
|
<LinkOffIcon />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText secondary={"Detach the entry from its movement"}>
|
||||||
|
Detach from movement
|
||||||
|
</ListItemText>
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Delete */}
|
{/* Delete */}
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleClose();
|
handleClose();
|
||||||
p.onDelete(p.movement);
|
p.onDelete(p.entry);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user