import React, { useEffect, useState } from "react"; import { ApiClient, ApiLoadFailedError } from "../api"; import ErrorScreen from "../containers/ErrorScreen"; import { ContribComponentList, ContribComponentMap } from "../types"; import { getCookie } from "../util/get_cookie"; export interface ApiContextProviderProps { api: | ApiClient | string | URL | { schema: string | URL; server?: string | URL; prefix?: string; }; contrib?: ContribComponentMap | ContribComponentList; } const ApiContext = React.createContext(undefined as unknown as ApiClient); export const useApi = () => React.useContext(ApiContext); export const ApiContextProvider: React.FC> = ({ children, api: init, contrib, }) => { const [api, setApi] = useState(); const [error, setError] = useState(null); useEffect(() => { if (api == null) { (init instanceof ApiClient ? Promise.resolve(init) : typeof init === "string" || init instanceof URL ? ApiClient.load(init) : ApiClient.load(init.schema, init.server) ) .then(async (api) => { if (contrib) { const contribArray = Array.isArray(contrib) ? contrib : Object.entries(contrib).map(([tag, contrib]) => ({ tag, contrib })); for (const [i, { tag, contrib: hit }] of contribArray.entries()) { const operations = api.contrib[tag]; if (operations) { for (const operation of Object.values(operations)) { operation.component = { ...hit, component: hit.component?.() ?? ((() => null) as React.FC), }; operation.order = i; } } } } setApi(api); if (getCookie("csrftoken") == null) { await api.operations["bananas.csrf:list"].call(); } }) .catch((error) => setError(error)); } }, [api]); if (error != null) { return ; } return {children}; }; export default ApiContext;