Can display information about the movement attached to an inbox entry
This commit is contained in:
parent
76f9e37ded
commit
07ee499742
@ -59,6 +59,17 @@ export class MovementApi {
|
|||||||
).data;
|
).data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a single movement information
|
||||||
|
*/ static async GetSingleMovement(movement_id: number): Promise<Movement> {
|
||||||
|
return (
|
||||||
|
await APIClient.exec({
|
||||||
|
uri: `/movement/${movement_id}`,
|
||||||
|
method: "GET",
|
||||||
|
})
|
||||||
|
).data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a movement information
|
* Update a movement information
|
||||||
*/
|
*/
|
||||||
|
@ -10,6 +10,7 @@ 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 { MoneyMgrWebRouteContainer } from "../widgets/MoneyMgrWebRouteContainer";
|
import { MoneyMgrWebRouteContainer } from "../widgets/MoneyMgrWebRouteContainer";
|
||||||
|
import { MovementWidget } from "../widgets/MovementWidget";
|
||||||
import { NewMovementWidget } from "../widgets/NewMovementWidget";
|
import { NewMovementWidget } from "../widgets/NewMovementWidget";
|
||||||
import { UploadedFileWidget } from "../widgets/UploadedFileWidget";
|
import { UploadedFileWidget } from "../widgets/UploadedFileWidget";
|
||||||
|
|
||||||
@ -71,7 +72,13 @@ export function InboxRoute(): React.ReactElement {
|
|||||||
loadKey={loadKey.current + String(includeAttached)}
|
loadKey={loadKey.current + String(includeAttached)}
|
||||||
load={load}
|
load={load}
|
||||||
errMsg="Failed to load the content of inbox!"
|
errMsg="Failed to load the content of inbox!"
|
||||||
build={() => <InboxTable entries={entries!} onReload={reload} />}
|
build={() => (
|
||||||
|
<InboxTable
|
||||||
|
entries={entries!}
|
||||||
|
onReload={reload}
|
||||||
|
showMovements={includeAttached}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
<NewMovementWidget isInbox onCreated={() => reload(false)} />
|
<NewMovementWidget isInbox onCreated={() => reload(false)} />
|
||||||
</div>
|
</div>
|
||||||
@ -83,6 +90,7 @@ export function InboxRoute(): React.ReactElement {
|
|||||||
function InboxTable(p: {
|
function InboxTable(p: {
|
||||||
entries: InboxEntry[];
|
entries: InboxEntry[];
|
||||||
onReload: (skipEntries: boolean) => void;
|
onReload: (skipEntries: boolean) => void;
|
||||||
|
showMovements?: boolean;
|
||||||
}): React.ReactElement {
|
}): React.ReactElement {
|
||||||
const [rowSelectionModel, setRowSelectionModel] =
|
const [rowSelectionModel, setRowSelectionModel] =
|
||||||
React.useState<GridRowSelectionModel>([]);
|
React.useState<GridRowSelectionModel>([]);
|
||||||
@ -135,6 +143,16 @@ function InboxTable(p: {
|
|||||||
return <UploadedFileWidget file_id={params.row.file_id} />;
|
return <UploadedFileWidget file_id={params.row.file_id} />;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: "movement_id",
|
||||||
|
headerName: "Movement",
|
||||||
|
editable: false,
|
||||||
|
flex: 3,
|
||||||
|
renderCell: (params) => {
|
||||||
|
if (params.row.movement_id)
|
||||||
|
return <MovementWidget id={params.row.movement_id} />;
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -150,7 +168,7 @@ function InboxTable(p: {
|
|||||||
},
|
},
|
||||||
columns: {
|
columns: {
|
||||||
columnVisibilityModel: {
|
columnVisibilityModel: {
|
||||||
checked: false,
|
movement_id: p.showMovements!!,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
|
63
moneymgr_web/src/widgets/MovementWidget.tsx
Normal file
63
moneymgr_web/src/widgets/MovementWidget.tsx
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import CallMadeIcon from "@mui/icons-material/CallMade";
|
||||||
|
import CallReceivedIcon from "@mui/icons-material/CallReceived";
|
||||||
|
import React from "react";
|
||||||
|
import { Movement, MovementApi } from "../api/MovementsApi";
|
||||||
|
import { useAccounts } from "../hooks/AccountsListProvider";
|
||||||
|
import { AccountWidget } from "./AccountWidget";
|
||||||
|
import { AmountWidget } from "./AmountWidget";
|
||||||
|
import { AsyncWidget } from "./AsyncWidget";
|
||||||
|
|
||||||
|
export function MovementWidget(p: { id: number }): React.ReactElement {
|
||||||
|
const accounts = useAccounts();
|
||||||
|
|
||||||
|
const [movement, setMovement] = React.useState<Movement | undefined>();
|
||||||
|
|
||||||
|
const load = async () => {
|
||||||
|
setMovement(await MovementApi.GetSingleMovement(p.id));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AsyncWidget
|
||||||
|
loadKey={p.id}
|
||||||
|
load={load}
|
||||||
|
errMsg="Failed to load movement!"
|
||||||
|
build={() => (
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
display: "inline-flex",
|
||||||
|
alignItems: "center",
|
||||||
|
height: "100%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{movement!.amount > 0 ? (
|
||||||
|
<CallReceivedIcon color="success" />
|
||||||
|
) : (
|
||||||
|
<CallMadeIcon color="error" />
|
||||||
|
)}
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
display: "inline-flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "center",
|
||||||
|
height: "100%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span style={{ height: "1em", lineHeight: 1 }}>
|
||||||
|
{movement?.label}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
style={{ display: "flex", alignItems: "center", lineHeight: 1 }}
|
||||||
|
>
|
||||||
|
<AmountWidget amount={movement!.amount} />
|
||||||
|
<span style={{ width: "0.5em" }} />
|
||||||
|
•
|
||||||
|
<span style={{ width: "0.5em" }} />
|
||||||
|
<AccountWidget account={accounts.get(movement!.account_id)!} />
|
||||||
|
{accounts.get(movement!.account_id)?.name}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user