@kwiz/fluentui
Version:
KWIZ common controls for FluentUI
68 lines (67 loc) • 2.98 kB
TypeScript
import { iLoadingProps } from "../controls/loading";
import { iPleaseWaitProps } from "../controls/please-wait";
type queueType = "required" | "optional" | "idle";
type isLoadingType = {
type: queueType;
label?: string;
};
export interface iUseReloadTracker<Scope extends string = "global"> {
/** marker to set as dependency when you want to re-run the effect when reload was called */
reloadKey: {
[key in withGlobal<Scope>]?: number;
};
/** call to reload scope+global, or send global to reload all scopes */
reload: (scope?: Scope) => void;
/** state: is there pending promises in the queue */
isLoading: isLoadingType;
/** add a loading promise to the queue */
queue: <Result>(promise: () => Promise<Result>, info: {
label: string;
type?: queueType;
/** will use promiseOnce if provided, along with the reload key */
cacheKey?: string;
/** switch reloadKey scope for cacheKey. Global will update on any reload. You want to set this if you have a dependency on reloadKey.[scope] that is not global */
cacheScope?: Scope;
}) => Promise<Result>;
/** render loading animation, or track isLoading to add animation yourself */
reloadElement?: JSX.Element;
}
type withGlobal<t extends string> = t | "global";
/** a simple reload marker, can be used as a dependency, and called as a function */
export declare function useReloadTracker<Scope extends string = "global">(props?: {
requiredElement?: Partial<iLoadingProps> | JSX.Element;
optionalElement?: Partial<iPleaseWaitProps> | JSX.Element;
}): iUseReloadTracker<Scope>;
export {};
/** examples
* =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
* in your main/top control or in your context provider, call:
* const rt = useReloadTracker();
* render its content:
* {rt.reloadElement}
*
* load content that never changes, and cached (type:'required' will cover the page content while this is pending):
* useEffect(() => {
* queue(() => ASYNC_ACTION(), { label:'Loading XXX', cacheKey: 'ASYNC_ACTION', type: "required" })
* .then(result => setResult(result));
* }, [queue]);
*
* load content that changes based on other state, and cached:
* useEffect(() => {
* queue(() => ASYNC_ACTION(STATE1), { label:'Loading XXX', cacheKey: `ASYNC_ACTION|${STATE1}` })
* .then(result => setResult(result));
* }, [queue, STATE1]);
*
* load content that changes when you call reload anywhere:
* useEffect(() => {
* queue(() => ASYNC_ACTION(), { label:'Loading XXX', cacheKey: 'ASYNC_ACTION' })
* .then(result => setResult(result));
* }, [queue, reloadKey.global]);
*
* load content that changes when you call reload('scope1') anywhere:
* useEffect(() => {
* queue(() => ASYNC_ACTION(), { label:'Loading XXX', cacheKey: 'ASYNC_ACTION', cacheScope: 'scope1' })
* .then(result => setResult(result));
* }, [queue, reloadKey.scope1]);
*
*/