Can display information about the movement attached to an inbox entry
This commit is contained in:
		@@ -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>
 | 
				
			||||||
 | 
					      )}
 | 
				
			||||||
 | 
					    />
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user