90 lines
2.3 KiB
TypeScript
90 lines
2.3 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
|
|
import { api } from "../api";
|
|
import { AUTH_USER_CHANGED_EVENT, getAuthUserKey } from "../auth";
|
|
import { Company } from "../types";
|
|
import { useViewResource, ViewResourceError } from "./useViewResource";
|
|
|
|
let cachedCompanies: Company[] | null = null;
|
|
let inflight: Promise<Company[]> | null = null;
|
|
let cacheOwner = "";
|
|
|
|
function resetForOwner(owner: string) {
|
|
if (cacheOwner === owner) return;
|
|
cacheOwner = owner;
|
|
cachedCompanies = null;
|
|
inflight = null;
|
|
}
|
|
|
|
function cachedForCurrentOwner() {
|
|
const owner = getAuthUserKey();
|
|
resetForOwner(owner);
|
|
return cachedCompanies;
|
|
}
|
|
|
|
async function fetchCompanies(): Promise<Company[]> {
|
|
const owner = getAuthUserKey();
|
|
resetForOwner(owner);
|
|
if (cachedCompanies) return cachedCompanies;
|
|
if (inflight) return inflight;
|
|
|
|
const request = api
|
|
.get<Company[]>('/companies')
|
|
.then((r) => {
|
|
if (cacheOwner === owner && getAuthUserKey() === owner) cachedCompanies = r.data;
|
|
return r.data;
|
|
})
|
|
.finally(() => {
|
|
if (inflight === request) inflight = null;
|
|
});
|
|
inflight = request;
|
|
|
|
return inflight;
|
|
}
|
|
|
|
export function invalidateCompaniesCache() {
|
|
cachedCompanies = null;
|
|
inflight = null;
|
|
}
|
|
|
|
export function useCompanies(): {
|
|
companies: Company[];
|
|
loading: boolean;
|
|
refreshing: boolean;
|
|
error: ViewResourceError | null;
|
|
reload: () => Promise<void>;
|
|
} {
|
|
const [cacheBust, setCacheBust] = useState(0);
|
|
const resource = useViewResource(fetchCompanies, {
|
|
initialData: cachedForCurrentOwner() ?? [],
|
|
errorMessage: 'Unable to load companies right now.',
|
|
deps: [cacheBust],
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (!resource.error) {
|
|
cachedCompanies = resource.data;
|
|
}
|
|
}, [resource.data, resource.error]);
|
|
|
|
useEffect(() => {
|
|
const reloadForAccount = () => {
|
|
resetForOwner(getAuthUserKey());
|
|
setCacheBust((value) => value + 1);
|
|
};
|
|
window.addEventListener(AUTH_USER_CHANGED_EVENT, reloadForAccount);
|
|
return () => window.removeEventListener(AUTH_USER_CHANGED_EVENT, reloadForAccount);
|
|
}, []);
|
|
|
|
return {
|
|
companies: resource.data,
|
|
loading: resource.loading,
|
|
refreshing: resource.refreshing,
|
|
error: resource.error,
|
|
reload: async () => {
|
|
invalidateCompaniesCache();
|
|
setCacheBust((value) => value + 1);
|
|
},
|
|
};
|
|
}
|