Add createKey to quick-add manifests and client create dialog host. FAB and command palette open in-place create UIs instead of navigating away.
100 lines
2.4 KiB
TypeScript
100 lines
2.4 KiB
TypeScript
import type { ReactNode } from "react";
|
|
import type { ZodType } from "zod";
|
|
|
|
export type ActivityLogEntry = {
|
|
id: string;
|
|
householdId: string;
|
|
entityType: string;
|
|
entityId: string;
|
|
actorId: string | null;
|
|
action: string;
|
|
payload: Record<string, unknown> | null;
|
|
createdAt: Date;
|
|
};
|
|
|
|
export type ShareCapabilities = {
|
|
canShare: boolean;
|
|
defaultCapabilities?: string[];
|
|
};
|
|
|
|
export type ShareContext = {
|
|
householdId: string;
|
|
userId: string;
|
|
};
|
|
|
|
export type PublicShareContext = {
|
|
householdId: string;
|
|
};
|
|
|
|
export type ReminderCapabilities = {
|
|
canRemind: boolean;
|
|
};
|
|
|
|
export type SearchResult = {
|
|
id: string;
|
|
title: string;
|
|
url: string;
|
|
excerpt?: string;
|
|
};
|
|
|
|
export type SearchAdapter = {
|
|
search: (query: string, householdId: string) => Promise<SearchResult[]>;
|
|
};
|
|
|
|
export type WidgetContext = {
|
|
userId: string;
|
|
householdId: string;
|
|
};
|
|
|
|
export type DashboardWidget = {
|
|
id: string;
|
|
title: string;
|
|
description: string;
|
|
category?: string;
|
|
defaultSize: { w: number; h: number };
|
|
minSize?: { w: number; h: number };
|
|
maxSize?: { w: number; h: number };
|
|
defaultPriority: number;
|
|
configSchema: ZodType;
|
|
defaultConfig: unknown;
|
|
resolveConfigOptions?: (ctx: WidgetContext) => Promise<unknown>;
|
|
render: (props: { config: unknown; ctx: WidgetContext }) => ReactNode;
|
|
};
|
|
|
|
export type QuickAddAction = {
|
|
id: string;
|
|
label: string;
|
|
icon?: string;
|
|
/** Navigation target used by the FAB sheet and command palette. */
|
|
url: string;
|
|
/** Client-side create dialog key (see quick-add create registry). */
|
|
createKey?: string;
|
|
action?: (ctx: WidgetContext) => void | Promise<void>;
|
|
};
|
|
|
|
export type EntityTypeRegistration = {
|
|
type: string;
|
|
label: { singular: string; plural: string };
|
|
share?: ShareCapabilities;
|
|
reminder?: ReminderCapabilities;
|
|
search?: SearchAdapter;
|
|
resolveUrl: (id: string) => string;
|
|
canShareEntity?: (id: string, ctx: ShareContext) => Promise<boolean>;
|
|
loadForShare?: (id: string, ctx: PublicShareContext) => Promise<unknown>;
|
|
renderSharedView?: (props: {
|
|
data: unknown;
|
|
capabilities: { read: boolean; write: boolean };
|
|
token: string;
|
|
}) => ReactNode;
|
|
renderActivity?: (entry: ActivityLogEntry) => string;
|
|
};
|
|
|
|
export type ModuleManifest = {
|
|
id: string;
|
|
name: string;
|
|
nav?: { href: string; label: string; icon?: string };
|
|
entities: EntityTypeRegistration[];
|
|
dashboardWidgets?: DashboardWidget[];
|
|
quickAdds?: QuickAddAction[];
|
|
};
|