Add accounts list as a provider
This commit is contained in:
68
moneymgr_web/src/hooks/AccountsListProvider.tsx
Normal file
68
moneymgr_web/src/hooks/AccountsListProvider.tsx
Normal file
@ -0,0 +1,68 @@
|
||||
import React from "react";
|
||||
import { Account, AccountApi, AccountsList } from "../api/AccountApi";
|
||||
import { AsyncWidget } from "../widgets/AsyncWidget";
|
||||
|
||||
interface AccountContext {
|
||||
list: AccountsList;
|
||||
reload: () => void;
|
||||
get(id: number): Account | null;
|
||||
}
|
||||
|
||||
const AccountContextK = React.createContext<AccountContext | null>(null);
|
||||
|
||||
export function AccountsListProvider(
|
||||
p: React.PropsWithChildren
|
||||
): React.ReactElement {
|
||||
const [list, setList] = React.useState<AccountsList | null>(null);
|
||||
|
||||
const loadKey = React.useRef(1);
|
||||
|
||||
const loadPromise = React.useRef<(() => void) | null>(null);
|
||||
|
||||
const load = async () => {
|
||||
setList(await AccountApi.GetList());
|
||||
};
|
||||
|
||||
const onReload = async () => {
|
||||
loadKey.current += 1;
|
||||
setList(null);
|
||||
|
||||
return new Promise<void>((res) => {
|
||||
loadPromise.current = () => {
|
||||
res();
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<AsyncWidget
|
||||
loadKey={loadKey.current}
|
||||
load={load}
|
||||
errMsg="Failed to load the list of accounts!"
|
||||
build={() => {
|
||||
if (loadPromise.current != null) {
|
||||
loadPromise.current();
|
||||
loadPromise.current = null;
|
||||
}
|
||||
|
||||
return (
|
||||
<AccountContextK
|
||||
value={{
|
||||
list: list!,
|
||||
get(id) {
|
||||
return list!.get(id);
|
||||
},
|
||||
reload: onReload,
|
||||
}}
|
||||
>
|
||||
{p.children}
|
||||
</AccountContextK>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function useAccounts(): AccountContext {
|
||||
return React.use(AccountContextK)!;
|
||||
}
|
Reference in New Issue
Block a user