0a1631dbc0
RestClient.listInboxItems/patchInboxItem + InboxItem type; iios-inbox-web InboxProvider + useInbox (poll + snooze/done/reopen). Boundary allowlist extended. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
64 lines
1.9 KiB
TypeScript
64 lines
1.9 KiB
TypeScript
import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
|
import { RestClient, type InboxItem, type InboxState } from '@insignia/iios-kernel-client';
|
|
|
|
const InboxContext = createContext<RestClient | null>(null);
|
|
|
|
/** Provides an inbox REST client to the inbox hooks. */
|
|
export function InboxProvider({
|
|
serviceUrl,
|
|
token,
|
|
children,
|
|
}: {
|
|
serviceUrl: string;
|
|
token: string;
|
|
children: React.ReactNode;
|
|
}): React.ReactElement {
|
|
const client = useMemo(() => new RestClient({ serviceUrl, token }), [serviceUrl, token]);
|
|
return <InboxContext.Provider value={client}>{children}</InboxContext.Provider>;
|
|
}
|
|
|
|
function useClient(): RestClient {
|
|
const c = useContext(InboxContext);
|
|
if (!c) throw new Error('useInbox must be used within <InboxProvider>');
|
|
return c;
|
|
}
|
|
|
|
/** The caller's inbox items + actions. Polls on an interval (default 3s). */
|
|
export function useInbox(opts?: { state?: InboxState; pollMs?: number }): {
|
|
items: InboxItem[];
|
|
refresh: () => Promise<void>;
|
|
snooze: (id: string) => Promise<void>;
|
|
done: (id: string) => Promise<void>;
|
|
reopen: (id: string) => Promise<void>;
|
|
} {
|
|
const client = useClient();
|
|
const [items, setItems] = useState<InboxItem[]>([]);
|
|
|
|
const refresh = useCallback(async () => {
|
|
try {
|
|
setItems(await client.listInboxItems(opts?.state));
|
|
} catch {
|
|
/* transient — keep last items */
|
|
}
|
|
}, [client, opts?.state]);
|
|
|
|
useEffect(() => {
|
|
void refresh();
|
|
const t = setInterval(() => void refresh(), opts?.pollMs ?? 3000);
|
|
return () => clearInterval(t);
|
|
}, [refresh, opts?.pollMs]);
|
|
|
|
const patch = async (id: string, state: InboxState): Promise<void> => {
|
|
await client.patchInboxItem(id, { state });
|
|
await refresh();
|
|
};
|
|
|
|
return {
|
|
items,
|
|
refresh,
|
|
snooze: (id) => patch(id, 'SNOOZED'),
|
|
done: (id) => patch(id, 'DONE'),
|
|
reopen: (id) => patch(id, 'OPEN'),
|
|
};
|
|
}
|