@genispace/geniapp 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ai.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ai.js","sources":["../src/ai/managed-data/createTableClient.ts","../src/ai/managed-data/queryManagedDatasource.ts","../src/ai/managed-data/executeManagedDatasource.ts","../src/ai/managed-data/emitManagedEvent.ts","../src/ai/managed-data/DatasourceReadonlyTable.tsx","../src/ai/components/ServerDataTable.tsx","../src/ai/components/AsyncCombobox.tsx","../src/ai/components/useInfiniteRows.ts","../src/ai/components/Timeline.tsx","../src/ai/components/EntityRef.tsx","../src/ai/components/BulkActionBar.tsx","../src/ai/components/AgentJobProgress.tsx","../src/ai/components/JobProgress.tsx","../src/ai/providers/AppUiProviders.tsx","../src/ai/layout/layoutConstants.ts","../src/ai/layout/ModalWithAiLayout.tsx","../src/ai/layout/modalSizeForAi.ts","../src/ai/adopt/DetailPageAiLayout.tsx","../src/ai/layout/aiUi.tsx","../src/ai/locales/sharedAiCopy.ts","../src/ai/adopt/parseAiSummary.ts","../src/ai/adopt/guidanceContent.ts","../src/ai/adopt/AiSuggestionPanel.tsx","../src/ai/adopt/BusinessGuidancePanel.tsx","../src/ai/adopt/adoptPresets.ts","../src/ai/integrations/partner/partnerRecordPicker.ts","../src/ai/integrations/partner/createPartnerRecordPickerHook.ts"],"sourcesContent":["import type { AppTableClient } from '../types';\n\n/** Adapter for apps using apiList / apiUpdate style helpers. */\nexport function createTableClient(handlers: {\n list: <T>(table: string, params?: Record<string, string | number | boolean | null>) => Promise<T[]>;\n update: (table: string, id: string, payload: Record<string, unknown>) => Promise<unknown>;\n}): AppTableClient {\n return {\n async list<T>(\n table: string,\n options?: { filters?: Record<string, string | number | boolean | null>; limit?: number; offset?: number }\n ) {\n const params: Record<string, string | number | boolean | null> = {\n ...(options?.filters ?? {}),\n };\n if (options?.limit != null) params.limit = options.limit;\n if (options?.offset != null) params.offset = options.offset;\n const items = await handlers.list<T>(table, params);\n return { items };\n },\n update: handlers.update,\n };\n}\n","import { GeniSpace } from 'genispace';\n\nfunction metaBool(v: unknown): boolean {\n return v === true || v === 'true';\n}\n\n/**\n * Max datasources per list page. `GET /datasources` on older/deployed API\n * versions validates `limit` as 1-100 (a single `limit: 500` call 400s there —\n * the message even reads \"between 1-100\"), so we page in bounded 100-row\n * windows rather than one oversized request. This mirrors the agent-resolution\n * pattern (precheck/aiDraft/scheduleAdvisor) and keeps cross-app datasource\n * resolution working in spaces that publish 500+ datasources (e.g. retail-crm\n * alone ships 240+), where the target row falls past the first page.\n */\nconst DS_LIST_PAGE = 100;\n/** Hard ceiling on pages scanned so a mis-provisioned space can't loop forever. */\nconst DS_LIST_MAX_PAGES = 50;\n\nfunction matchesManaged(\n x: { identifier?: string | null; metadata?: unknown },\n seedIdentifier: string,\n geniappIdentifier: string\n): boolean {\n const meta = x.metadata as Record<string, unknown> | null | undefined;\n return (\n String(x.identifier || '') === seedIdentifier &&\n metaBool(meta?.managedByGeniapp) &&\n String(meta?.geniappIdentifier || '') === geniappIdentifier\n );\n}\n\nexport async function findManagedAppDataSourceId(\n client: GeniSpace,\n seedIdentifier: string,\n geniappIdentifier: string\n): Promise<string | null> {\n // Fast path: server-side name search narrows to the handful of datasources\n // whose name/description contain the identifier (managed datasource names are\n // seeded from the identifier), so the match is almost always on page 1.\n try {\n const { items } = await client.dataSources.listDataSources({ search: seedIdentifier, limit: DS_LIST_PAGE });\n const hit = items.find((x) => matchesManaged(x, seedIdentifier, geniappIdentifier));\n if (hit?.id != null) return String(hit.id);\n } catch {\n // Search unsupported on this API version — fall through to full paging.\n }\n\n // Fallback: page through the space's datasources in bounded windows. Stop as\n // soon as a page is short (last page) so we never over-fetch.\n for (let page = 1; page <= DS_LIST_MAX_PAGES; page += 1) {\n const { items } = await client.dataSources.listDataSources({ page, limit: DS_LIST_PAGE });\n const hit = items.find((x) => matchesManaged(x, seedIdentifier, geniappIdentifier));\n if (hit?.id != null) return String(hit.id);\n if (items.length < DS_LIST_PAGE) break;\n }\n return null;\n}\n\nexport function createGeniSpaceClient(apiRoot: string, accessToken: string | null): GeniSpace {\n const baseURL = apiRoot.replace(/\\/$/, '');\n const client = new GeniSpace({ baseURL, apiKey: accessToken || '' });\n if (accessToken) client.updateAccessToken(accessToken);\n return client;\n}\n\ntype DsQueryParams = Record<string, string | number | boolean | undefined>;\n\nfunction asNonNegativeInt(v: string | number | boolean | undefined): number | null {\n if (typeof v === 'boolean' || v === undefined) return null;\n const n = typeof v === 'number' ? v : Number(String(v).trim());\n return Number.isInteger(n) && n >= 0 ? n : null;\n}\n\nfunction rowsOf(payload: { data?: unknown[] | null }): Record<string, unknown>[] {\n return (payload.data || []).filter((r): r is Record<string, unknown> => r != null && typeof r === 'object');\n}\n\n/** Mirrors the API's default page size when the request carries no `limit`. */\nconst API_DEFAULT_LIMIT = 20;\n\n/**\n * Run one READ query with pagination expressed in a way EVERY API version\n * honors.\n *\n * Why this exists: `GET /datasources/:id/data` derives the `{{offset}}` SQL\n * binding from `(page - 1) * limit` and OVERWRITES any `offset` sent as a plain\n * query param (see api datasource.service `getDataSourceData`). So a bare\n * `{ limit, offset }` GET silently pins `{{offset}}` to 0 — page turns fetch\n * the same first page. Newer API branches may honor the `offset` param\n * directly, so every request here keeps `page`, `limit` and `offset` mutually\n * consistent (`offset === (page - 1) * limit`); both interpretations then\n * yield the same window.\n *\n * - `offset` aligned to `limit` → one request with the matching `page`.\n * - misaligned `offset` (e.g. ServerDataTable's `limit = pageSize + 1`,\n * `offset = pageIndex * pageSize`) → stitch the two aligned windows that\n * cover the requested range.\n */\nexport async function queryReadRowsPaged(\n gs: GeniSpace,\n datasourceId: string,\n params: DsQueryParams\n): Promise<Record<string, unknown>[]> {\n const { offset: rawOffset, ...rest } = params;\n const offset = asNonNegativeInt(rawOffset);\n\n // No usable offset (absent/0/non-numeric): page 1 on every API version.\n if (!offset) {\n return rowsOf(await gs.dataSources.queryDataSourceRead(datasourceId, params));\n }\n\n const limit = asNonNegativeInt(params.limit);\n const windowSize = limit && limit > 0 ? limit : API_DEFAULT_LIMIT;\n\n const fetchWindow = async (windowIndex: number): Promise<Record<string, unknown>[]> => {\n const windowOffset = windowIndex * windowSize;\n const payload = await gs.dataSources.queryDataSourceRead(datasourceId, {\n ...rest,\n page: windowIndex + 1,\n limit: windowSize,\n offset: windowOffset,\n });\n return rowsOf(payload);\n };\n\n // Aligned: the requested range IS one window.\n if (offset % windowSize === 0) {\n return fetchWindow(offset / windowSize);\n }\n\n // Misaligned: stitch the two adjacent aligned windows covering\n // [offset, offset + windowSize).\n const firstWindow = Math.floor(offset / windowSize);\n const skip = offset - firstWindow * windowSize;\n const head = (await fetchWindow(firstWindow)).slice(skip);\n // Only fetch the next window when the first was full (i.e. more rows may exist).\n if (head.length + skip < windowSize) return head;\n const tail = await fetchWindow(firstWindow + 1);\n return head.concat(tail.slice(0, windowSize - head.length));\n}\n\nexport async function queryManagedDatasourceRows(\n apiRoot: string,\n accessToken: string | null,\n geniappIdentifier: string,\n seedIdentifier: string,\n params: DsQueryParams = { limit: 50 }\n): Promise<Record<string, unknown>[]> {\n if (!apiRoot || !accessToken) return [];\n const gs = createGeniSpaceClient(apiRoot, accessToken);\n const id = await findManagedAppDataSourceId(gs, seedIdentifier, geniappIdentifier);\n if (!id) return [];\n return queryReadRowsPaged(gs, id, params);\n}\n\nconst DATASOURCE_PAGE_SIZE = 1000;\n\n/** Fetch all rows from a managed datasource, paginating at the API max limit (1000). */\nexport async function queryManagedDatasourceRowsAll(\n apiRoot: string,\n accessToken: string | null,\n geniappIdentifier: string,\n seedIdentifier: string,\n params: Record<string, string | number | boolean | undefined> = {}\n): Promise<Record<string, unknown>[]> {\n const all: Record<string, unknown>[] = [];\n let offset = 0;\n while (true) {\n const rows = await queryManagedDatasourceRows(apiRoot, accessToken, geniappIdentifier, seedIdentifier, {\n ...params,\n limit: DATASOURCE_PAGE_SIZE,\n offset,\n });\n all.push(...rows);\n if (rows.length < DATASOURCE_PAGE_SIZE) break;\n offset += DATASOURCE_PAGE_SIZE;\n }\n return all;\n}\n","import {\n createGeniSpaceClient,\n findManagedAppDataSourceId,\n} from './queryManagedDatasource';\n\n/** Result from POST /datasources/:id/data for TRANSACTION / CREATE / UPDATE operations. */\nexport type ManagedDatasourceOperationResult = {\n operationType?: string;\n affectedRows?: number;\n insertId?: number | string;\n executionTime?: number;\n statementCount?: number;\n [key: string]: unknown;\n};\n\nexport type ExecuteManagedDatasourceParams = Record<string, string | number | boolean | null | undefined>;\n\n/**\n * Execute a managed GeniApp datasource write operation (TRANSACTION, CREATE, UPDATE, etc.)\n * via POST /datasources/:id/data. For TRANSACTION datasources with JSON payloads, pass\n * `payload` as a JSON string (SQL uses `{{payload}}::jsonb`).\n */\nexport async function executeManagedDatasourceOperation(\n apiRoot: string,\n accessToken: string | null,\n geniappIdentifier: string,\n seedIdentifier: string,\n params: ExecuteManagedDatasourceParams\n): Promise<ManagedDatasourceOperationResult> {\n if (!apiRoot?.trim()) {\n throw new Error('API root is not configured.');\n }\n if (!accessToken?.trim()) {\n throw new Error('Authentication required to execute datasource operation.');\n }\n\n const gs = createGeniSpaceClient(apiRoot, accessToken);\n const id = await findManagedAppDataSourceId(gs, seedIdentifier, geniappIdentifier);\n if (!id) {\n throw new Error(`Managed datasource \"${seedIdentifier}\" is not installed for app \"${geniappIdentifier}\". Upgrade the application.`);\n }\n\n const body: Record<string, string | number | boolean> = {};\n for (const [k, v] of Object.entries(params)) {\n if (v === undefined || v === null) continue;\n body[k] = v;\n }\n\n const baseURL = apiRoot.replace(/\\/$/, '');\n const res = await fetch(`${baseURL}/datasources/${encodeURIComponent(id)}/data`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify(body),\n });\n\n const text = await res.text();\n let parsed: { success?: boolean; data?: ManagedDatasourceOperationResult; message?: string } = {};\n if (text) {\n try {\n parsed = JSON.parse(text) as typeof parsed;\n } catch {\n throw new Error(text || `Datasource operation failed (${res.status})`);\n }\n }\n\n if (!res.ok) {\n const msg = parsed.message || text || `Datasource operation failed (${res.status})`;\n throw new Error(msg);\n }\n\n return parsed.data ?? {};\n}\n\n/** Convenience wrapper for TRANSACTION datasources that accept a single JSON payload parameter. */\nexport async function executeManagedDatasourceTransaction(\n apiRoot: string,\n accessToken: string | null,\n geniappIdentifier: string,\n seedIdentifier: string,\n payload: unknown,\n payloadParamName = 'payload'\n): Promise<ManagedDatasourceOperationResult> {\n return executeManagedDatasourceOperation(apiRoot, accessToken, geniappIdentifier, seedIdentifier, {\n [payloadParamName]: JSON.stringify(payload),\n });\n}\n\nexport type TransactionDatasourceClient = (\n seedIdentifier: string,\n payload: unknown\n) => Promise<ManagedDatasourceOperationResult>;\n\n/** Factory for per-app transaction executors. */\nexport function createTransactionDatasourceClient(\n geniappIdentifier: string,\n resolveApiRoot: () => string,\n resolveAccessToken: () => string | null = () => {\n try {\n return localStorage.getItem('token');\n } catch {\n return null;\n }\n }\n): TransactionDatasourceClient {\n return (seedIdentifier, payload) =>\n executeManagedDatasourceTransaction(\n resolveApiRoot(),\n resolveAccessToken(),\n geniappIdentifier,\n seedIdentifier,\n payload\n );\n}\n","export type EmittedEventEnvelope = {\n id: string;\n status: string;\n eventName: string;\n [k: string]: unknown;\n};\n\n/**\n * Emit a Space-level event from a GeniApp. The app's installed events.json must\n * declare the event; the payload is validated server-side against its schema.\n */\nexport async function emitManagedEvent(\n apiRoot: string,\n accessToken: string | null,\n geniappIdentifier: string,\n eventName: string,\n payload: Record<string, unknown>,\n opts?: { idempotencyKey?: string }\n): Promise<EmittedEventEnvelope> {\n if (!apiRoot?.trim()) {\n throw new Error('API root is not configured.');\n }\n if (!accessToken?.trim()) {\n throw new Error('Authentication required to emit event.');\n }\n\n const body: Record<string, unknown> = {\n appIdentifier: geniappIdentifier,\n event: eventName,\n payload,\n };\n if (opts?.idempotencyKey) {\n body.idempotencyKey = opts.idempotencyKey;\n }\n\n const baseURL = apiRoot.replace(/\\/$/, '');\n const res = await fetch(`${baseURL}/events/emit`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify(body),\n });\n\n const text = await res.text();\n let parsed: { success?: boolean; data?: EmittedEventEnvelope; message?: string } = {};\n if (text) {\n try {\n parsed = JSON.parse(text) as typeof parsed;\n } catch {\n throw new Error(text || `Event emit failed (${res.status})`);\n }\n }\n\n if (!res.ok) {\n const msg = parsed.message || text || `Event emit failed (${res.status})`;\n throw new Error(msg);\n }\n\n return parsed.data ?? ({} as EmittedEventEnvelope);\n}\n\nexport type ManagedEventClient = (\n eventName: string,\n payload: Record<string, unknown>,\n opts?: { idempotencyKey?: string }\n) => Promise<EmittedEventEnvelope>;\n\n/** Factory for per-app event emitters. */\nexport function createManagedEventClient(\n geniappIdentifier: string,\n resolveApiRoot: () => string,\n resolveAccessToken: () => string | null = () => {\n try {\n return localStorage.getItem('token');\n } catch {\n return null;\n }\n }\n): ManagedEventClient {\n return (eventName, payload, opts) =>\n emitManagedEvent(\n resolveApiRoot(),\n resolveAccessToken(),\n geniappIdentifier,\n eventName,\n payload,\n opts\n );\n}\n","import { useTranslation } from 'react-i18next';\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@genispace/geniapp/kit';\n\nexport function DatasourceReadonlyTable({\n title,\n hint,\n rows,\n columns,\n emptyLabel,\n}: {\n title: string;\n hint?: string;\n rows: Record<string, unknown>[];\n columns: Array<{ key: string; label: string; format?: (v: unknown) => string }>;\n emptyLabel?: string;\n}) {\n const { t } = useTranslation();\n\n if (rows.length === 0) {\n return (\n <Card className=\"border-dashed\">\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm\">{title}</CardTitle>\n {hint ? <CardDescription>{hint}</CardDescription> : null}\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-muted-foreground\">\n {emptyLabel ?? t('datasourceInsight.empty', 'No rows from managed datasource (install GeniApp 1.0.1+).')}\n </p>\n </CardContent>\n </Card>\n );\n }\n\n return (\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm\">{title}</CardTitle>\n {hint ? <CardDescription>{hint}</CardDescription> : null}\n </CardHeader>\n <CardContent>\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n {columns.map((c) => (\n <TableHead key={c.key}>{c.label}</TableHead>\n ))}\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((row, i) => (\n <TableRow key={i}>\n {columns.map((c) => (\n <TableCell key={c.key}>\n {c.format ? c.format(row[c.key]) : String(row[c.key] ?? '—')}\n </TableCell>\n ))}\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n </CardContent>\n </Card>\n );\n}\n","import { useCallback, useEffect, useRef, useState, type ReactNode } from 'react';\nimport {\n Table,\n TableHeader,\n TableBody,\n TableRow,\n TableHead,\n TableCell,\n Button,\n Checkbox,\n useIsMobile,\n} from '@genispace/geniapp/kit';\n\nexport type SortDir = 'asc' | 'desc';\n\n/**\n * One column of a {@link ServerDataTable}. User-facing text is passed in by the\n * caller (i18n-agnostic). A column is sortable when `sortKey` is set; the table\n * then emits the server sort token `${sortKey}_${dir}` (e.g. `last_purchase_desc`),\n * which the datasource maps to a whitelisted `ORDER BY` via CASE.\n */\nexport interface ServerColumn<Row> {\n /** Stable column id (used for React keys). */\n key: string;\n /** Header content (already localized by the caller). */\n header: ReactNode;\n /** Server sort token base; presence makes the column sortable. */\n sortKey?: string;\n /** Cell renderer; defaults to the row's value at `key` stringified. */\n cell?: (row: Row) => ReactNode;\n className?: string;\n headClassName?: string;\n}\n\nexport interface ServerDataTableLabels {\n empty: string;\n error: string;\n retry: string;\n previous: string;\n next: string;\n /** Localized \"Page N\" label; receives the 1-based page number. */\n page: (page: number) => string;\n /** Accessible label for ascending sort toggle. */\n sortAscLabel?: string;\n /** Accessible label for descending sort toggle. */\n sortDescLabel?: string;\n /** Accessible label for the header \"select all on this page\" checkbox. */\n selectAllLabel?: string;\n /** Accessible label for a per-row select checkbox. */\n selectRowLabel?: string;\n}\n\nexport interface ServerDataTableProps<Row> {\n columns: ServerColumn<Row>[];\n /**\n * Fetch one page. Return up to `limit` rows; the table internally requests\n * `pageSize + 1` to detect \"has more\" without a COUNT query.\n */\n fetchRows: (args: { limit: number; offset: number; sort?: string }) => Promise<Row[]>;\n rowKey: (row: Row) => string;\n labels: ServerDataTableLabels;\n pageSize?: number;\n /**\n * When this value changes (e.g. the caller's search/filter state), pagination\n * resets to the first page. `fetchRows` should be memoized over the same deps.\n */\n resetKey?: unknown;\n initialSort?: { sortKey: string; dir: SortDir };\n onRowClick?: (row: Row) => void;\n emptyContent?: ReactNode;\n className?: string;\n /**\n * Enable a leading checkbox column for row selection. Off by default so every\n * existing usage is unchanged. When on, `selectedIds`/`onSelectionChange` make\n * the selection controlled by the caller (keyed by `rowKey`).\n */\n selectable?: boolean;\n /** Controlled set of selected row keys (only used when `selectable`). */\n selectedIds?: Set<string>;\n /** Called with the next selection whenever the user toggles a checkbox. */\n onSelectionChange?: (next: Set<string>) => void;\n /**\n * Mobile (H5) row renderer. When provided, the table falls back to a stacked\n * card list below the `sm` breakpoint instead of a horizontally-scrolling\n * `<table>` — the H5 pattern for entity lists (see 12-h5-mobile-design.md §2.3).\n * Receives the row; return the card body (the frame, tap target, selection\n * checkbox and pagination are supplied by the table). Desktop is unaffected.\n */\n mobileCard?: (row: Row) => ReactNode;\n}\n\n/** Stable empty selection so an uncontrolled (`selectable` off) table never reallocates. */\nconst EMPTY_SELECTION: Set<string> = new Set();\n\nfunction SortIndicator({ active, dir }: { active: boolean; dir: SortDir }) {\n return (\n <span aria-hidden className=\"ml-1 inline-flex text-[0.7em] leading-none text-muted-foreground\">\n {active ? (dir === 'asc' ? '▲' : '▼') : '↕'}\n </span>\n );\n}\n\n/**\n * Server-paginated, server-sorted data table for managed datasources. Renders one\n * bounded page at a time (default 50 rows) — no client-side load-all, no COUNT.\n * Generic over the row shape; all labels are injected for i18n.\n */\nexport function ServerDataTable<Row>({\n columns,\n fetchRows,\n rowKey,\n labels,\n pageSize = 50,\n resetKey,\n initialSort,\n onRowClick,\n emptyContent,\n className,\n selectable = false,\n selectedIds,\n onSelectionChange,\n mobileCard,\n}: ServerDataTableProps<Row>) {\n const isMobile = useIsMobile();\n const [pageIndex, setPageIndex] = useState(0);\n const [sort, setSort] = useState<{ sortKey: string; dir: SortDir } | null>(initialSort ?? null);\n const [rows, setRows] = useState<Row[]>([]);\n const [hasMore, setHasMore] = useState(false);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n const reqId = useRef(0);\n const sortToken = sort ? `${sort.sortKey}_${sort.dir}` : undefined;\n\n const runFetch = useCallback(async () => {\n const myId = ++reqId.current;\n setLoading(true);\n setError(null);\n try {\n const fetched = await fetchRows({ limit: pageSize + 1, offset: pageIndex * pageSize, sort: sortToken });\n if (myId !== reqId.current) return;\n setHasMore(fetched.length > pageSize);\n setRows(fetched.slice(0, pageSize));\n } catch (e) {\n if (myId !== reqId.current) return;\n setError(e instanceof Error ? e.message : String(e));\n setRows([]);\n setHasMore(false);\n } finally {\n if (myId === reqId.current) setLoading(false);\n }\n }, [fetchRows, pageSize, pageIndex, sortToken]);\n\n useEffect(() => {\n void runFetch();\n }, [runFetch]);\n\n // Reset to the first page whenever the caller's filter/search state changes.\n const firstRender = useRef(true);\n useEffect(() => {\n if (firstRender.current) {\n firstRender.current = false;\n return;\n }\n setPageIndex(0);\n }, [resetKey]);\n\n const toggleSort = useCallback((colSortKey: string) => {\n setPageIndex(0);\n setSort((prev) => {\n if (!prev || prev.sortKey !== colSortKey) return { sortKey: colSortKey, dir: 'asc' };\n if (prev.dir === 'asc') return { sortKey: colSortKey, dir: 'desc' };\n return null;\n });\n }, []);\n\n // Row selection (only active when `selectable`). Selection is controlled by the\n // caller; we derive page-level header state from the visible rows + rowKey.\n const selection = selectedIds ?? EMPTY_SELECTION;\n const pageKeys = rows.map((r) => rowKey(r));\n const selectedOnPage = pageKeys.filter((k) => selection.has(k)).length;\n const allPageSelected = pageKeys.length > 0 && selectedOnPage === pageKeys.length;\n const somePageSelected = selectedOnPage > 0 && !allPageSelected;\n\n const toggleRow = useCallback(\n (key: string) => {\n if (!onSelectionChange) return;\n const next = new Set(selection);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n onSelectionChange(next);\n },\n [onSelectionChange, selection]\n );\n\n const togglePage = useCallback(() => {\n if (!onSelectionChange) return;\n const next = new Set(selection);\n if (allPageSelected) {\n for (const k of pageKeys) next.delete(k);\n } else {\n for (const k of pageKeys) next.add(k);\n }\n onSelectionChange(next);\n }, [onSelectionChange, selection, allPageSelected, pageKeys]);\n\n // Shared inline states (identical in both table and card layouts).\n const loadingState =\n loading && rows.length === 0 ? (\n <div className=\"space-y-2 p-4\" aria-busy>\n <div className=\"h-8 animate-pulse rounded bg-muted\" />\n <div className=\"h-8 animate-pulse rounded bg-muted\" />\n <div className=\"h-8 animate-pulse rounded bg-muted\" />\n </div>\n ) : null;\n\n const errorState = error ? (\n <div className=\"flex flex-col items-center gap-2 p-8 text-center\">\n <p className=\"text-sm text-destructive\">{error}</p>\n <Button variant=\"outline\" size=\"sm\" onClick={() => void runFetch()}>\n {labels.retry}\n </Button>\n </div>\n ) : null;\n\n const emptyState =\n !loading && !error && rows.length === 0 ? (\n <div className=\"p-12 text-center text-sm text-muted-foreground\">{emptyContent ?? labels.empty}</div>\n ) : null;\n\n const pagination =\n (pageIndex > 0 || hasMore) && !error ? (\n <div className=\"mt-3 flex items-center justify-end gap-2\">\n <span className=\"text-sm text-muted-foreground\">{labels.page(pageIndex + 1)}</span>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={pageIndex === 0 || loading}\n onClick={() => setPageIndex((p) => Math.max(0, p - 1))}\n >\n {labels.previous}\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={!hasMore || loading}\n onClick={() => setPageIndex((p) => p + 1)}\n >\n {labels.next}\n </Button>\n </div>\n ) : null;\n\n // H5 card-list layout: one tappable card per row instead of a scrolling table.\n if (isMobile && mobileCard) {\n return (\n <div className={className}>\n {selectable && rows.length > 0 ? (\n <label className=\"mb-2 flex min-h-[44px] items-center gap-2 px-1 text-sm text-muted-foreground\">\n <Checkbox\n checked={allPageSelected ? true : somePageSelected ? 'indeterminate' : false}\n onCheckedChange={togglePage}\n aria-label={labels.selectAllLabel}\n />\n {labels.selectAllLabel}\n </label>\n ) : null}\n\n <div className=\"space-y-2\">\n {rows.map((row) => {\n const key = rowKey(row);\n const interactive = Boolean(onRowClick);\n return (\n <div\n key={key}\n className={`flex items-start gap-3 rounded-xl border border-border bg-card p-3 text-card-foreground shadow-sm${\n interactive ? ' cursor-pointer transition-colors active:bg-accent/40' : ''\n }`}\n onClick={interactive ? () => onRowClick?.(row) : undefined}\n >\n {selectable ? (\n <div className=\"pt-0.5\" onClick={(e) => e.stopPropagation()}>\n <Checkbox\n checked={selection.has(key)}\n onCheckedChange={() => toggleRow(key)}\n aria-label={labels.selectRowLabel}\n />\n </div>\n ) : null}\n <div className=\"min-w-0 flex-1\">{mobileCard(row)}</div>\n </div>\n );\n })}\n </div>\n\n {loadingState}\n {errorState}\n {emptyState}\n {pagination}\n </div>\n );\n }\n\n return (\n <div className={className}>\n <div className=\"overflow-x-auto rounded-xl border border-border bg-card shadow-sm\">\n <Table>\n <TableHeader>\n <TableRow>\n {selectable ? (\n <TableHead className=\"w-10\">\n <Checkbox\n checked={allPageSelected ? true : somePageSelected ? 'indeterminate' : false}\n onCheckedChange={togglePage}\n disabled={rows.length === 0}\n aria-label={labels.selectAllLabel}\n />\n </TableHead>\n ) : null}\n {columns.map((c) => {\n const sortable = Boolean(c.sortKey);\n const active = sortable && sort?.sortKey === c.sortKey;\n return (\n <TableHead key={c.key} className={c.headClassName}>\n {sortable ? (\n <button\n type=\"button\"\n className=\"inline-flex items-center font-medium hover:text-foreground\"\n onClick={() => toggleSort(c.sortKey as string)}\n aria-label={\n active && sort?.dir === 'asc' ? labels.sortDescLabel : labels.sortAscLabel\n }\n >\n {c.header}\n <SortIndicator active={Boolean(active)} dir={active ? (sort as { dir: SortDir }).dir : 'asc'} />\n </button>\n ) : (\n c.header\n )}\n </TableHead>\n );\n })}\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((row) => {\n const key = rowKey(row);\n return (\n <TableRow\n key={key}\n className={onRowClick ? 'cursor-pointer' : undefined}\n onClick={onRowClick ? () => onRowClick(row) : undefined}\n >\n {selectable ? (\n <TableCell\n className=\"w-10\"\n onClick={(e) => e.stopPropagation()}\n >\n <Checkbox\n checked={selection.has(key)}\n onCheckedChange={() => toggleRow(key)}\n aria-label={labels.selectRowLabel}\n />\n </TableCell>\n ) : null}\n {columns.map((c) => (\n <TableCell key={c.key} className={c.className}>\n {c.cell ? c.cell(row) : String((row as Record<string, unknown>)[c.key] ?? '—')}\n </TableCell>\n ))}\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n\n {/* Inline states keep the header/pagination chrome stable. */}\n {loadingState}\n {errorState}\n {emptyState}\n </div>\n\n {pagination}\n </div>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n Button,\n Input,\n Popover,\n PopoverTrigger,\n PopoverContent,\n ScrollArea,\n} from '@genispace/geniapp/kit';\n\nexport interface AsyncOption {\n value: string;\n label: string;\n /** Optional secondary text (e.g. store of an associate). */\n hint?: string;\n}\n\nexport interface AsyncComboboxLabels {\n /** Shown on the trigger when nothing is selected. */\n placeholder: string;\n searchPlaceholder: string;\n empty: string;\n loadMore: string;\n clear: string;\n}\n\nexport interface AsyncComboboxProps {\n value: string | null;\n onChange: (value: string | null) => void;\n /**\n * Server-side search. Return up to `limit` options for the page; the combobox\n * requests `pageSize + 1` to detect \"has more\" without a COUNT.\n */\n loadOptions: (args: { search: string; limit: number; offset: number }) => Promise<AsyncOption[]>;\n /**\n * Resolve the label for the current `value` when it isn't in the loaded page\n * (e.g. a preselected id). Optional — falls back to showing the raw value.\n */\n resolveSelected?: (value: string) => Promise<AsyncOption | null>;\n labels: AsyncComboboxLabels;\n disabled?: boolean;\n allowClear?: boolean;\n pageSize?: number;\n triggerClassName?: string;\n contentClassName?: string;\n}\n\n/**\n * Searchable, paginated single-select bound to a server datasource. Replaces\n * \"load-all + client filter\" dropdowns; safe for very large option sets because\n * it only ever fetches one debounced page at a time. i18n-agnostic (labels in).\n */\nexport function AsyncCombobox({\n value,\n onChange,\n loadOptions,\n resolveSelected,\n labels,\n disabled,\n allowClear = true,\n pageSize = 20,\n triggerClassName,\n contentClassName,\n}: AsyncComboboxProps) {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [debounced, setDebounced] = useState('');\n const [options, setOptions] = useState<AsyncOption[]>([]);\n const [offset, setOffset] = useState(0);\n const [hasMore, setHasMore] = useState(false);\n const [loading, setLoading] = useState(false);\n const [selectedOption, setSelectedOption] = useState<AsyncOption | null>(null);\n\n const reqId = useRef(0);\n\n // Debounce the search input.\n useEffect(() => {\n const id = setTimeout(() => setDebounced(query.trim()), 300);\n return () => clearTimeout(id);\n }, [query]);\n\n const fetchPage = useCallback(\n async (search: string, nextOffset: number, append: boolean) => {\n const myId = ++reqId.current;\n setLoading(true);\n try {\n const fetched = await loadOptions({ search, limit: pageSize + 1, offset: nextOffset });\n if (myId !== reqId.current) return;\n const more = fetched.length > pageSize;\n const page = fetched.slice(0, pageSize);\n setHasMore(more);\n setOffset(nextOffset);\n setOptions((prev) => (append ? [...prev, ...page] : page));\n } catch {\n if (myId !== reqId.current) return;\n if (!append) setOptions([]);\n setHasMore(false);\n } finally {\n if (myId === reqId.current) setLoading(false);\n }\n },\n [loadOptions, pageSize]\n );\n\n // (Re)load from the first page when opened or when the debounced query changes.\n useEffect(() => {\n if (!open) return;\n void fetchPage(debounced, 0, false);\n }, [open, debounced, fetchPage]);\n\n // Resolve the label for a preselected value not present in the loaded page.\n useEffect(() => {\n if (!value) {\n setSelectedOption(null);\n return;\n }\n if (selectedOption?.value === value) return;\n const inOptions = options.find((o) => o.value === value);\n if (inOptions) {\n setSelectedOption(inOptions);\n return;\n }\n if (!resolveSelected) return;\n let cancelled = false;\n void resolveSelected(value).then((opt) => {\n if (!cancelled && opt) setSelectedOption(opt);\n });\n return () => {\n cancelled = true;\n };\n }, [value, options, resolveSelected, selectedOption]);\n\n const triggerLabel = selectedOption?.label ?? (value || labels.placeholder);\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n disabled={disabled}\n className={triggerClassName ?? 'min-w-[12rem] justify-between font-normal'}\n >\n <span className={selectedOption || value ? '' : 'text-muted-foreground'}>{triggerLabel}</span>\n <span aria-hidden className=\"ml-2 text-xs text-muted-foreground\">▾</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent className={contentClassName ?? 'w-[16rem] p-0'} align=\"start\">\n <div className=\"border-b border-border p-2\">\n <Input\n autoFocus\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={labels.searchPlaceholder}\n aria-label={labels.searchPlaceholder}\n />\n </div>\n <ScrollArea className=\"max-h-64\">\n <div className=\"p-1\">\n {allowClear && value ? (\n <button\n type=\"button\"\n className=\"block w-full rounded px-2 py-1.5 text-left text-sm text-muted-foreground hover:bg-accent\"\n onClick={() => {\n onChange(null);\n setSelectedOption(null);\n setOpen(false);\n }}\n >\n {labels.clear}\n </button>\n ) : null}\n\n {options.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n className={`block w-full rounded px-2 py-1.5 text-left text-sm hover:bg-accent ${\n opt.value === value ? 'bg-accent font-medium' : ''\n }`}\n onClick={() => {\n onChange(opt.value);\n setSelectedOption(opt);\n setOpen(false);\n }}\n >\n <span>{opt.label}</span>\n {opt.hint ? <span className=\"ml-2 text-xs text-muted-foreground\">{opt.hint}</span> : null}\n </button>\n ))}\n\n {!loading && options.length === 0 ? (\n <p className=\"px-2 py-6 text-center text-sm text-muted-foreground\">{labels.empty}</p>\n ) : null}\n\n {loading ? (\n <div className=\"space-y-1 p-1\" aria-busy>\n <div className=\"h-7 animate-pulse rounded bg-muted\" />\n <div className=\"h-7 animate-pulse rounded bg-muted\" />\n </div>\n ) : null}\n\n {hasMore && !loading ? (\n <button\n type=\"button\"\n className=\"mt-1 block w-full rounded px-2 py-1.5 text-center text-sm text-primary hover:bg-accent\"\n onClick={() => void fetchPage(debounced, offset + pageSize, true)}\n >\n {labels.loadMore}\n </button>\n ) : null}\n </div>\n </ScrollArea>\n </PopoverContent>\n </Popover>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface UseInfiniteRowsResult<Row> {\n rows: Row[];\n loading: boolean;\n hasMore: boolean;\n error: string | null;\n /** Manually request the next page. */\n loadMore: () => void;\n /** Clear + reload from offset 0. */\n reset: () => void;\n /** Attach to a sentinel element at the list tail; auto-loads on intersect. */\n sentinelRef: (el: HTMLElement | null) => void;\n}\n\n/**\n * Accumulating infinite-scroll over a paginated fetcher. `fetchPage` returns up\n * to `limit` rows; when fewer than `limit` come back, there is no more data.\n * Pass a `resetKey` that changes when the query identity changes (e.g. a new\n * entity id or filter) to clear and reload from the top.\n */\nexport function useInfiniteRows<Row>(\n fetchPage: (args: { limit: number; offset: number }) => Promise<Row[]>,\n opts?: { pageSize?: number; resetKey?: unknown }\n): UseInfiniteRowsResult<Row> {\n const pageSize = opts?.pageSize ?? 20;\n const resetKey = opts?.resetKey;\n\n const [rows, setRows] = useState<Row[]>([]);\n const [loading, setLoading] = useState(false);\n const [hasMore, setHasMore] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n const offsetRef = useRef(0);\n const loadingRef = useRef(false);\n const hasMoreRef = useRef(true);\n const fetchRef = useRef(fetchPage);\n fetchRef.current = fetchPage;\n const observerRef = useRef<IntersectionObserver | null>(null);\n\n const loadMore = useCallback(async () => {\n if (loadingRef.current || !hasMoreRef.current) return;\n loadingRef.current = true;\n setLoading(true);\n setError(null);\n const offset = offsetRef.current;\n try {\n const batch = await fetchRef.current({ limit: pageSize, offset });\n const got = Array.isArray(batch) ? batch : [];\n setRows((prev) => (offset === 0 ? got : [...prev, ...got]));\n offsetRef.current = offset + got.length;\n const more = got.length === pageSize;\n hasMoreRef.current = more;\n setHasMore(more);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n hasMoreRef.current = false;\n setHasMore(false);\n } finally {\n loadingRef.current = false;\n setLoading(false);\n }\n }, [pageSize]);\n\n const reset = useCallback(() => {\n offsetRef.current = 0;\n hasMoreRef.current = true;\n loadingRef.current = false;\n setRows([]);\n setHasMore(true);\n setError(null);\n void loadMore();\n }, [loadMore]);\n\n // Reload whenever the query identity changes.\n useEffect(() => {\n reset();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [resetKey]);\n\n const sentinelRef = useCallback(\n (el: HTMLElement | null) => {\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n if (!el) return;\n observerRef.current = new IntersectionObserver(\n (entries) => {\n if (entries.some((en) => en.isIntersecting) && hasMoreRef.current && !loadingRef.current) {\n void loadMore();\n }\n },\n { rootMargin: '200px' }\n );\n observerRef.current.observe(el);\n },\n [loadMore]\n );\n\n useEffect(() => () => observerRef.current?.disconnect(), []);\n\n return { rows, loading, hasMore, error, loadMore, reset, sentinelRef };\n}\n","import type { ComponentType, ReactNode } from 'react';\n\nexport interface TimelineProps {\n children: ReactNode;\n className?: string;\n}\n\n/** Vertical activity timeline rail. Wrap a list of <TimelineItem>. */\nexport function Timeline({ children, className }: TimelineProps) {\n return <ol className={`relative flex flex-col gap-12 ${className ?? ''}`}>{children}</ol>;\n}\n\nexport interface TimelineItemProps {\n /** Lucide icon for the node chip. */\n icon?: ComponentType<{ className?: string }>;\n /** Tailwind text-color class for the icon (e.g. \"text-emerald-600\"). */\n dotClassName?: string;\n /** Tailwind background tint for the node chip (e.g. \"bg-emerald-500/10\"). Defaults to muted. */\n nodeClassName?: string;\n /** Tailwind left-border accent class for the event card (e.g. \"border-l-emerald-500\"). */\n accentClassName?: string;\n title: ReactNode;\n /** Right-aligned timestamp / relative time. */\n time?: ReactNode;\n /** Secondary meta line (channel, store, SA…). */\n meta?: ReactNode;\n /** Rich body (badges, amount, content). */\n children?: ReactNode;\n /** Hide the connector below the node (last item). */\n isLast?: boolean;\n}\n\n/**\n * One node on the vertical timeline: a filled, ringed icon chip on the rail (left)\n * and a styled event card (right) with an accent edge. Newest-first ordering is\n * the caller's job; pass node/accent classes per event type for distinct styling.\n */\nexport function TimelineItem({\n icon: Icon,\n dotClassName = 'text-foreground',\n nodeClassName = 'bg-muted',\n accentClassName = 'border-l-border',\n title,\n time,\n meta,\n children,\n isLast,\n}: TimelineItemProps) {\n return (\n <li className=\"relative flex items-start gap-5\">\n {/* rail + node — self-stretch so the connector only spans this row, not the inter-row gap */}\n <div className=\"relative flex w-9 shrink-0 flex-col items-center self-stretch\">\n <span\n className={`z-10 flex h-9 w-9 shrink-0 items-center justify-center rounded-full ring-4 ring-background ${nodeClassName} ${dotClassName}`}\n >\n {Icon ? <Icon className=\"h-4 w-4\" /> : <span className=\"h-2 w-2 rounded-full bg-current\" />}\n </span>\n {!isLast ? (\n <span\n className=\"mt-3 w-px flex-1 min-h-[1.5rem] bg-gradient-to-b from-border to-transparent\"\n aria-hidden\n />\n ) : null}\n </div>\n {/* event card */}\n <div\n className={`min-w-0 flex-1 space-y-3 rounded-xl border border-l-2 border-border bg-card px-4 py-4 shadow-sm transition-shadow hover:shadow-md ${accentClassName}`}\n >\n <div className=\"flex items-start justify-between gap-4\">\n <p className=\"text-sm font-semibold leading-normal text-foreground\">{title}</p>\n {time ? (\n <span className=\"shrink-0 text-xs leading-5 tabular-nums text-muted-foreground\">{time}</span>\n ) : null}\n </div>\n {meta ? <p className=\"text-xs leading-relaxed text-muted-foreground\">{meta}</p> : null}\n {children ? <div className=\"pt-1\">{children}</div> : null}\n </div>\n </li>\n );\n}\n","import { useCallback, useEffect, useRef, useState, type ReactNode } from 'react';\n\n/**\n * Resolves opaque entity ids (e.g. `cust_123`) to human-readable names in batch,\n * with an internal cache so a given id is fetched at most once. Pair it with\n * {@link EntityRef} to render references as \"name\" instead of raw ids.\n *\n * The `resolver` receives the de-duplicated set of ids that aren't cached yet and\n * returns a `{ id: name }` map; ids missing from the map are remembered as\n * \"resolved to nothing\" so they aren't retried on every render.\n */\nexport interface UseEntityNamesResult {\n /** Cached display name for `id`, or `undefined` until resolved (or if unknown). */\n resolve: (id: string) => string | undefined;\n /** Queue ids for resolution; already-cached/in-flight ids are skipped. */\n ensure: (ids: ReadonlyArray<string>) => void;\n /** True while at least one batch is in flight. */\n loading: boolean;\n}\n\nexport function useEntityNames(\n resolver: (ids: string[]) => Promise<Record<string, string>>\n): UseEntityNamesResult {\n // `version` bumps to force a re-render when the cache mutates; the cache and the\n // in-flight set live in refs so they survive renders without being deps.\n const cache = useRef<Map<string, string | undefined>>(new Map());\n const inFlight = useRef<Set<string>>(new Set());\n const pending = useRef<Set<string>>(new Set());\n const flushHandle = useRef<ReturnType<typeof setTimeout> | null>(null);\n const [, setVersion] = useState(0);\n const [loadingCount, setLoadingCount] = useState(0);\n\n // Keep the latest resolver without making `ensure` change identity each render.\n const resolverRef = useRef(resolver);\n resolverRef.current = resolver;\n\n const flush = useCallback(async () => {\n flushHandle.current = null;\n const batch = Array.from(pending.current);\n pending.current.clear();\n if (batch.length === 0) return;\n\n batch.forEach((id) => inFlight.current.add(id));\n setLoadingCount((c) => c + 1);\n try {\n const map = await resolverRef.current(batch);\n // Record every requested id — even ones absent from the result — so unknown\n // ids resolve to `undefined` permanently instead of refetching forever.\n batch.forEach((id) => cache.current.set(id, map[id]));\n } catch {\n // On failure, drop the ids from the cache so a later ensure() can retry.\n batch.forEach((id) => cache.current.delete(id));\n } finally {\n batch.forEach((id) => inFlight.current.delete(id));\n setLoadingCount((c) => Math.max(0, c - 1));\n setVersion((v) => v + 1);\n }\n }, []);\n\n const ensure = useCallback(\n (ids: ReadonlyArray<string>) => {\n let added = false;\n for (const id of ids) {\n if (!id) continue;\n if (cache.current.has(id) || inFlight.current.has(id) || pending.current.has(id)) continue;\n pending.current.add(id);\n added = true;\n }\n if (!added) return;\n // Batch synchronous bursts of ensure() into one resolver call.\n if (flushHandle.current === null) {\n flushHandle.current = setTimeout(() => void flush(), 0);\n }\n },\n [flush]\n );\n\n useEffect(() => {\n return () => {\n if (flushHandle.current !== null) clearTimeout(flushHandle.current);\n };\n }, []);\n\n const resolve = useCallback((id: string): string | undefined => cache.current.get(id), []);\n\n return { resolve, ensure, loading: loadingCount > 0 };\n}\n\nexport interface EntityRefProps {\n /** The raw entity id being referenced. */\n value: string;\n /** Resolved display name; when undefined the ref renders a muted `value`. */\n name?: string;\n /** Render as a link to this href (takes precedence over `onClick`). */\n href?: string;\n /** Render as a button invoking this handler when there is no `href`. */\n onClick?: () => void;\n /** Shown when `name` is undefined, before falling back to `value`. */\n fallback?: ReactNode;\n className?: string;\n}\n\n/**\n * Renders an entity reference as its display name (with an optional link/button),\n * falling back to a muted raw id while the name is unresolved. i18n-agnostic:\n * the caller supplies `name`/`fallback`; only layout symbols are hardcoded.\n */\nexport function EntityRef({ value, name, href, onClick, fallback, className }: EntityRefProps) {\n const resolved = name !== undefined;\n const content: ReactNode = resolved ? name : (fallback ?? value);\n const baseClass = resolved ? '' : 'text-muted-foreground';\n const merged = className ? `${baseClass} ${className}`.trim() : baseClass || undefined;\n\n if (href) {\n return (\n <a\n href={href}\n onClick={onClick}\n className={\n merged ? `${merged} underline-offset-2 hover:underline` : 'underline-offset-2 hover:underline'\n }\n >\n {content}\n </a>\n );\n }\n\n if (onClick) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={\n merged\n ? `${merged} underline-offset-2 hover:underline`\n : 'underline-offset-2 hover:underline'\n }\n >\n {content}\n </button>\n );\n }\n\n return <span className={merged}>{content}</span>;\n}\n","import { type ReactNode } from 'react';\nimport { Button, type ButtonProps } from '@genispace/geniapp/kit';\n\n/** One action button rendered in a {@link BulkActionBar}. */\nexport interface BulkAction {\n /** Stable id (used for React keys). */\n key: string;\n /** Button content (already localized by the caller). */\n label: ReactNode;\n onClick: () => void;\n /** Button visual variant; forwarded to the kit `Button`. */\n variant?: ButtonProps['variant'];\n disabled?: boolean;\n}\n\nexport interface BulkActionBarLabels {\n /** Localized \"N selected\" label; receives the current selected count. */\n selected: (n: number) => string;\n /** Localized \"select all M matching\" affordance; receives the total match count. */\n selectAllMatching?: (m: number) => string;\n /** Localized \"clear selection\" label. */\n clear: string;\n}\n\nexport interface BulkActionBarProps {\n /** Number of currently selected rows. */\n selectedCount: number;\n /** Total rows matching the active filter (across all pages), if known. */\n totalMatching?: number;\n /** Whether every matching row (not just the visible page) is already selected. */\n allMatchingSelected?: boolean;\n /** Promote the current page selection to \"all M matching\". */\n onSelectAllMatching?: () => void;\n /** Clear the entire selection. */\n onClear: () => void;\n actions: BulkAction[];\n labels: BulkActionBarLabels;\n className?: string;\n}\n\n/**\n * Sticky toolbar surfaced when rows are selected. Shows the selected count, an\n * optional \"select all M matching\" affordance (for selecting beyond the visible\n * page), the caller's bulk actions, and a clear control. Renders nothing when the\n * selection is empty. i18n-agnostic — all text comes from `labels`/`actions`.\n */\nexport function BulkActionBar({\n selectedCount,\n totalMatching,\n allMatchingSelected,\n onSelectAllMatching,\n onClear,\n actions,\n labels,\n className,\n}: BulkActionBarProps) {\n if (selectedCount <= 0) return null;\n\n // Offer \"select all matching\" only when there are more matches than selected,\n // the caller wired up a handler, and a localized label is available.\n const canSelectAllMatching =\n !allMatchingSelected &&\n Boolean(onSelectAllMatching) &&\n Boolean(labels.selectAllMatching) &&\n typeof totalMatching === 'number' &&\n totalMatching > selectedCount;\n\n return (\n <div\n className={\n className ??\n 'sticky bottom-0 z-10 flex flex-wrap items-center gap-x-3 gap-y-2 rounded-xl border border-border bg-background/95 px-4 py-2.5 shadow-md backdrop-blur supports-[backdrop-filter]:bg-background/80'\n }\n role=\"toolbar\"\n >\n <span className=\"text-sm font-medium\">{labels.selected(selectedCount)}</span>\n\n {canSelectAllMatching ? (\n <Button variant=\"link\" size=\"sm\" className=\"h-auto px-0\" onClick={onSelectAllMatching}>\n {(labels.selectAllMatching as (m: number) => string)(totalMatching as number)}\n </Button>\n ) : null}\n\n <div className=\"ml-auto flex flex-wrap items-center gap-2\">\n {actions.map((action) => (\n <Button\n key={action.key}\n variant={action.variant ?? 'outline'}\n size=\"sm\"\n disabled={action.disabled}\n onClick={action.onClick}\n >\n {action.label}\n </Button>\n ))}\n <Button variant=\"ghost\" size=\"sm\" onClick={onClear}>\n {labels.clear}\n </Button>\n </div>\n </div>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { Check, Circle, Loader2 } from 'lucide-react';\nimport { Button } from '@genispace/geniapp/kit';\n\n/**\n * Async agent-invoke progress UX v1.\n *\n * `useAgentJobRunner` drives a background AGENT_INVOKE job (SDK\n * `agents.invokeAsync`) through an explicit state machine and exposes a live\n * elapsed ticker + server phase; `AgentJobProgressInline` renders it as a\n * rounded card in the same visual family as AiDraftBanner. Both are\n * i18n-agnostic — every user-facing string comes in via label props with\n * sensible English defaults; apps pass t() values.\n */\n\nexport type AgentRunState = 'idle' | 'starting' | 'running' | 'succeeded' | 'failed' | 'cancelled';\n\n/** Structural subset of the SDK AgentJob DTO the runner needs. */\nexport interface AgentJobLike {\n id: string;\n status?: string;\n phase?: string | null;\n cancelRequested?: boolean;\n createdAt?: string;\n error?: string | null;\n}\n\n/** Context handed to the task function passed to {@link UseAgentJobRunnerResult.start}. */\nexport interface AgentTaskContext {\n /** Thread as BOTH `onCreated` and `onProgress` of `agents.invokeAsync`. */\n onJob: (job: AgentJobLike) => void;\n /** Report an app-level retry (e.g. schema-invalid re-invoke): call with 2, 3, ... */\n onAttempt: (n: number) => void;\n /** Thread as `invokeAsync({ signal })`; aborted automatically on unmount. */\n signal: AbortSignal;\n}\n\nexport interface AgentJobStartOptions {\n /**\n * Cooperative server-side cancel, e.g. `(id) => client.agentJobs.cancel(id)`.\n * Called by {@link UseAgentJobRunnerResult.cancel} once a job id is known;\n * without it (or before a job exists) cancel falls back to aborting the\n * polling signal locally.\n */\n cancel?: (jobId: string) => Promise<unknown> | unknown;\n}\n\nexport interface UseAgentJobRunnerResult {\n state: AgentRunState;\n /** Latest server phase ('resolve' | 'invoke' | 'finalize' | ...), null before the first snapshot. */\n phase: string | null;\n /** Wall-clock since job.createdAt (when parseable) or the local start; ticks every second. */\n elapsedMs: number;\n /** Latest observed job snapshot (null until the 202 create lands). */\n job: AgentJobLike | null;\n /** Raw error message of a failed run (apps usually map their typed errors instead). */\n error: string | null;\n /** Current attempt number (1-based); >1 after noteAttempt/onAttempt. */\n attempt: number;\n /** True once cancel() was called or the server echoed job.cancelRequested. */\n cancelRequested: boolean;\n /**\n * Run `task`. Resolves with the task result on success, resolves `null` when\n * the run was cancelled/superseded, and REJECTS with the task's error on\n * failure (after moving the state machine to 'failed') so callers keep their\n * typed-error handling. No-op (resolves null) while a run is in flight.\n */\n start: <T>(task: (ctx: AgentTaskContext) => Promise<T>, opts?: AgentJobStartOptions) => Promise<T | null>;\n /** Request cooperative cancellation of the in-flight run. */\n cancel: () => void;\n /** Back to 'idle', invalidating any in-flight run (its late updates are dropped). */\n reset: () => void;\n /** Feed a job snapshot into the runner (what the task ctx.onJob does). */\n observe: (job: AgentJobLike) => void;\n /** Mark an app-level retry attempt (what the task ctx.onAttempt does). */\n noteAttempt: (n: number) => void;\n}\n\n/**\n * State machine + 1s elapsed ticker for one background agent invoke at a time.\n * Stale updates from a superseded run are dropped via a monotonic run-id guard\n * (mirrors JobProgress.tsx); the AbortController wired into the task signal is\n * aborted on unmount so polling never outlives the component — the job itself\n * keeps running server-side unless cancel() reached the platform.\n */\nexport function useAgentJobRunner(): UseAgentJobRunnerResult {\n const [state, setState] = useState<AgentRunState>('idle');\n const [phase, setPhase] = useState<string | null>(null);\n const [elapsedMs, setElapsedMs] = useState(0);\n const [job, setJob] = useState<AgentJobLike | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [attempt, setAttempt] = useState(1);\n const [cancelRequested, setCancelRequested] = useState(false);\n\n const runId = useRef(0);\n const runningRef = useRef(false);\n const abortRef = useRef<AbortController | null>(null);\n const jobRef = useRef<AgentJobLike | null>(null);\n const cancelFnRef = useRef<AgentJobStartOptions['cancel']>(undefined);\n const cancelRequestedRef = useRef(false);\n /** Elapsed baseline: job.createdAt when parseable, else the local start. */\n const baselineRef = useRef<number | null>(null);\n\n // Abort in-flight polling when the component unmounts.\n useEffect(() => {\n return () => {\n runId.current += 1;\n abortRef.current?.abort();\n };\n }, []);\n\n // 1s ticker while a run is active.\n const ticking = state === 'starting' || state === 'running';\n useEffect(() => {\n if (!ticking) return;\n const tick = () => {\n const base = baselineRef.current;\n if (base != null) setElapsedMs(Math.max(0, Date.now() - base));\n };\n tick();\n const timer = setInterval(tick, 1000);\n return () => clearInterval(timer);\n }, [ticking]);\n\n const observe = useCallback((snapshot: AgentJobLike) => {\n if (!runningRef.current) return;\n jobRef.current = snapshot;\n setJob(snapshot);\n setState((s) => (s === 'starting' ? 'running' : s));\n setPhase(snapshot.phase ?? null);\n if (snapshot.cancelRequested) setCancelRequested(true);\n if (snapshot.createdAt) {\n const created = Date.parse(snapshot.createdAt);\n // Guard against clock skew: never move the baseline into the future.\n if (Number.isFinite(created) && baselineRef.current != null && created < baselineRef.current) {\n baselineRef.current = created;\n }\n }\n }, []);\n\n const noteAttempt = useCallback((n: number) => {\n if (!runningRef.current) return;\n setAttempt(n);\n }, []);\n\n const start = useCallback(\n async <T,>(task: (ctx: AgentTaskContext) => Promise<T>, opts?: AgentJobStartOptions): Promise<T | null> => {\n if (runningRef.current) return null;\n const myId = ++runId.current;\n runningRef.current = true;\n cancelRequestedRef.current = false;\n cancelFnRef.current = opts?.cancel;\n jobRef.current = null;\n baselineRef.current = Date.now();\n const controller = new AbortController();\n abortRef.current = controller;\n\n setState('starting');\n setPhase(null);\n setElapsedMs(0);\n setJob(null);\n setError(null);\n setAttempt(1);\n setCancelRequested(false);\n\n const guard = <A extends unknown[]>(fn: (...args: A) => void) => (...args: A) => {\n if (myId === runId.current) fn(...args);\n };\n\n try {\n const result = await task({\n onJob: guard(observe),\n onAttempt: guard(noteAttempt),\n signal: controller.signal,\n });\n if (myId !== runId.current) return null;\n setState('succeeded');\n return result;\n } catch (e) {\n if (myId !== runId.current) return null;\n const aborted =\n cancelRequestedRef.current ||\n controller.signal.aborted ||\n (e instanceof Error && e.name === 'AbortError');\n if (aborted) {\n setState('cancelled');\n return null;\n }\n setState('failed');\n setError(e instanceof Error ? e.message : String(e));\n throw e;\n } finally {\n if (myId === runId.current) runningRef.current = false;\n }\n },\n [observe, noteAttempt]\n );\n\n const cancel = useCallback(() => {\n if (!runningRef.current || cancelRequestedRef.current) return;\n cancelRequestedRef.current = true;\n setCancelRequested(true);\n const jobId = jobRef.current?.id;\n const fn = cancelFnRef.current;\n if (jobId && fn) {\n // Cooperative: keep polling so the UI can show \"cancelling…\" until the\n // server flips the job to CANCELLED. Fall back to a local abort when the\n // cancel endpoint is unreachable (older platforms).\n Promise.resolve()\n .then(() => fn(jobId))\n .catch(() => abortRef.current?.abort());\n } else {\n abortRef.current?.abort();\n }\n }, []);\n\n const reset = useCallback(() => {\n runId.current += 1;\n runningRef.current = false;\n abortRef.current?.abort();\n abortRef.current = null;\n jobRef.current = null;\n baselineRef.current = null;\n cancelRequestedRef.current = false;\n setState('idle');\n setPhase(null);\n setElapsedMs(0);\n setJob(null);\n setError(null);\n setAttempt(1);\n setCancelRequested(false);\n }, []);\n\n return { state, phase, elapsedMs, job, error, attempt, cancelRequested, start, cancel, reset, observe, noteAttempt };\n}\n\nexport interface AgentJobProgressLabels {\n /** Primary action line, e.g. \"AI is generating the draft\". */\n title?: string;\n /** \"Elapsed Xs\" fragment appended to the title. */\n elapsed?: (seconds: number) => string;\n /** Expected-duration fragment after the elapsed one, e.g. \" (usually ~30s)\". */\n expectedNote?: string;\n /** Swapped in for expectedNote once elapsed exceeds 1.5x expectedSeconds. */\n slow?: string;\n /** Step-list labels (server phases queued -> resolve -> invoke -> finalize). */\n queued?: string;\n resolve?: string;\n invoke?: string;\n finalize?: string;\n /** Notice line shown when attempt > 1 (app-level schema retry). */\n retryNotice?: string;\n cancel?: string;\n cancelling?: string;\n /** Fallback failed line when no `error` prop is passed. */\n failed?: string;\n retry?: string;\n cancelled?: string;\n}\n\nconst DEFAULT_LABELS: Required<Pick<\n AgentJobProgressLabels,\n 'title' | 'expectedNote' | 'slow' | 'queued' | 'resolve' | 'invoke' | 'finalize' | 'retryNotice' | 'cancel' | 'cancelling' | 'failed' | 'retry' | 'cancelled'\n>> & { elapsed: (seconds: number) => string } = {\n title: 'Working…',\n elapsed: (seconds: number) => `${seconds}s elapsed`,\n expectedNote: '',\n slow: 'Taking longer than usual — still working…',\n queued: 'Queued',\n resolve: 'Locating agent',\n invoke: 'Running',\n finalize: 'Finalizing',\n retryNotice: 'First result was invalid — retrying once…',\n cancel: 'Cancel',\n cancelling: 'Cancelling…',\n failed: 'The AI task failed.',\n retry: 'Retry',\n cancelled: 'Cancelled.',\n};\n\nconst STEP_KEYS = ['queued', 'resolve', 'invoke', 'finalize'] as const;\n\n/** Map runner state + server phase to the active step index. Unknown/missing phases count as 'invoke'. */\nfunction activeStepIndex(state: AgentRunState, phase: string | null | undefined): number {\n if (state === 'starting') return 0;\n if (phase === 'resolve') return 1;\n if (phase === 'finalize') return 3;\n return 2; // 'invoke', missing, or unknown\n}\n\nexport interface AgentJobProgressInlineProps {\n state: AgentRunState;\n phase?: string | null;\n elapsedMs: number;\n /** Typical duration; drives the slow-hint swap (elapsed > 1.5x expected). */\n expectedSeconds?: number;\n /** 1-based attempt count; >1 renders the retry notice line. */\n attempt?: number;\n /** True once cancellation was requested (button flips to a disabled \"cancelling\"). */\n cancelRequested?: boolean;\n /** Localized error text supplied by the app for the failed state. */\n error?: string | null;\n onCancel?: () => void;\n onRetry?: () => void;\n labels?: AgentJobProgressLabels;\n className?: string;\n}\n\n/**\n * Inline progress card for a background agent invoke — spinner + elapsed\n * primary line, queued→resolve→invoke→finalize step list, indeterminate pulse\n * bar and a cooperative cancel button while running; destructive line + retry\n * when failed; muted line + retry when cancelled; nothing when idle/succeeded.\n * Same visual family as AiDraftBanner (status-info tokens while running).\n */\nexport function AgentJobProgressInline({\n state,\n phase,\n elapsedMs,\n expectedSeconds,\n attempt = 1,\n cancelRequested = false,\n error,\n onCancel,\n onRetry,\n labels,\n className,\n}: AgentJobProgressInlineProps) {\n const l = { ...DEFAULT_LABELS, ...labels };\n\n if (state === 'idle' || state === 'succeeded') return null;\n\n if (state === 'failed') {\n return (\n <div role=\"alert\" className={`space-y-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 ${className ?? ''}`}>\n <p className=\"text-sm text-destructive\">{error || l.failed}</p>\n {onRetry ? (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={onRetry}>\n {l.retry}\n </Button>\n ) : null}\n </div>\n );\n }\n\n if (state === 'cancelled') {\n return (\n <div role=\"status\" className={`space-y-2 rounded-lg border border-border bg-muted/40 p-3 ${className ?? ''}`}>\n <p className=\"text-sm text-muted-foreground\">{l.cancelled}</p>\n {onRetry ? (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={onRetry}>\n {l.retry}\n </Button>\n ) : null}\n </div>\n );\n }\n\n // starting | running\n const seconds = Math.floor(elapsedMs / 1000);\n const slow = expectedSeconds != null && elapsedMs > expectedSeconds * 1500;\n const note = slow ? l.slow : l.expectedNote;\n const stepIdx = activeStepIndex(state, phase);\n\n return (\n <div\n role=\"status\"\n aria-busy\n className={`space-y-2.5 rounded-lg border border-status-info/40 bg-status-info/10 p-3 ${className ?? ''}`}\n >\n <div className=\"flex items-start gap-2.5\">\n <Loader2 className=\"mt-0.5 h-4 w-4 shrink-0 animate-spin text-status-info\" aria-hidden />\n <div className=\"min-w-0 flex-1 space-y-0.5\">\n <p className=\"text-sm font-medium text-foreground\">\n {l.title} · {l.elapsed(seconds)}\n {note ? <span className={slow ? 'text-status-warning' : 'text-muted-foreground'}>{note}</span> : null}\n </p>\n {attempt > 1 ? <p className=\"text-xs text-muted-foreground\">{l.retryNotice}</p> : null}\n </div>\n {onCancel ? (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={onCancel} disabled={cancelRequested}>\n {cancelRequested ? l.cancelling : l.cancel}\n </Button>\n ) : null}\n </div>\n\n <ul className=\"space-y-1 pl-[26px]\">\n {STEP_KEYS.map((key, i) => {\n const isDone = i < stepIdx;\n const isCurrent = i === stepIdx;\n return (\n <li\n key={key}\n className={`flex items-center gap-1.5 text-xs ${\n isCurrent ? 'font-medium text-foreground' : isDone ? 'text-muted-foreground' : 'text-muted-foreground/60'\n }`}\n >\n {isDone ? (\n <Check className=\"h-3 w-3 shrink-0 text-status-info\" aria-hidden />\n ) : isCurrent ? (\n <Loader2 className=\"h-3 w-3 shrink-0 animate-spin text-status-info\" aria-hidden />\n ) : (\n <Circle className=\"h-3 w-3 shrink-0 text-muted-foreground/45\" aria-hidden />\n )}\n {l[key]}\n </li>\n );\n })}\n </ul>\n\n <div className=\"ml-[26px] h-1 overflow-hidden rounded-full bg-status-info/20\">\n <div className=\"h-full w-full animate-pulse rounded-full bg-status-info/60\" />\n </div>\n </div>\n );\n}\n","import { useCallback, useRef, useState } from 'react';\nimport { Button, Progress } from '@genispace/geniapp/kit';\n\nexport type JobStatus = 'idle' | 'running' | 'done' | 'error';\n\n/** Progress snapshot reported by a running job. */\nexport interface JobProgressState {\n done: number;\n total: number;\n message?: string;\n}\n\n/** Terminal outcome of a job's `run` function. */\nexport interface JobResult {\n ok: boolean;\n /** Number of items that failed (for partial-success jobs). */\n failed?: number;\n /** Human-readable error (already localized by the caller, if any). */\n error?: string;\n}\n\n/** A job runner: invoked with a `report` callback to push progress updates. */\nexport type JobRunner = (\n report: (progress: JobProgressState) => void\n) => Promise<JobResult>;\n\nexport interface UseAsyncJobResult {\n status: JobStatus;\n progress: JobProgressState;\n result: JobResult | null;\n /** Begin (or restart) the job. No-op while already running. */\n start: () => void;\n /** Return to the idle state, clearing progress and result. */\n reset: () => void;\n}\n\nconst EMPTY_PROGRESS: JobProgressState = { done: 0, total: 0 };\n\n/**\n * Drives a long-running, optionally batched async job: calls `run`, threading a\n * `report` callback that updates the live progress, and captures the terminal\n * result or a thrown error. Stale reports/results from a superseded run (e.g.\n * after a retry) are ignored via a monotonic run-id guard.\n */\nexport function useAsyncJob({ run }: { run: JobRunner }): UseAsyncJobResult {\n const [status, setStatus] = useState<JobStatus>('idle');\n const [progress, setProgress] = useState<JobProgressState>(EMPTY_PROGRESS);\n const [result, setResult] = useState<JobResult | null>(null);\n\n const runId = useRef(0);\n const runningRef = useRef(false);\n\n // Keep the latest runner without making `start` change identity each render.\n const runRef = useRef(run);\n runRef.current = run;\n\n const start = useCallback(() => {\n if (runningRef.current) return;\n const myId = ++runId.current;\n runningRef.current = true;\n setStatus('running');\n setProgress(EMPTY_PROGRESS);\n setResult(null);\n\n const report = (p: JobProgressState) => {\n if (myId !== runId.current) return;\n setProgress({ done: p.done, total: p.total, message: p.message });\n };\n\n void (async () => {\n try {\n const res = await runRef.current(report);\n if (myId !== runId.current) return;\n setResult(res);\n setStatus(res.ok ? 'done' : 'error');\n } catch (e) {\n if (myId !== runId.current) return;\n const message = e instanceof Error ? e.message : String(e);\n setResult({ ok: false, error: message });\n setStatus('error');\n } finally {\n if (myId === runId.current) runningRef.current = false;\n }\n })();\n }, []);\n\n const reset = useCallback(() => {\n // Invalidate any in-flight run so its late reports/results are dropped.\n runId.current += 1;\n runningRef.current = false;\n setStatus('idle');\n setProgress(EMPTY_PROGRESS);\n setResult(null);\n }, []);\n\n return { status, progress, result, start, reset };\n}\n\nexport interface JobProgressLabels {\n /** Optional text shown in the idle state (before the job starts). */\n idle?: string;\n /** Localized \"X of Y\" running label; receives done and total counts. */\n running: (done: number, total: number) => string;\n /** Text shown when the job completes successfully. */\n done: string;\n /** Text shown when the job fails. */\n error: string;\n /** Retry button label. */\n retry: string;\n}\n\nexport interface JobProgressProps {\n /** The return value of {@link useAsyncJob}. */\n job: UseAsyncJobResult;\n labels: JobProgressLabels;\n /**\n * Invoked when the retry button is pressed. Defaults to `job.start`, so a plain\n * retry re-runs the same job; pass a custom handler to retry only failures.\n */\n onRetry?: () => void;\n className?: string;\n}\n\n/**\n * Displays the state of a {@link useAsyncJob}: a progress bar while running, a\n * status line, and a retry button on error. i18n-agnostic — every string is\n * supplied via `labels`; only the bar and layout are hardcoded.\n */\nexport function JobProgress({ job, labels, onRetry, className }: JobProgressProps) {\n const { status, progress, result } = job;\n const { done, total, message } = progress;\n const handleRetry = onRetry ?? job.start;\n\n return (\n <div className={className ?? 'space-y-2'}>\n {status === 'idle' && labels.idle ? (\n <p className=\"text-sm text-muted-foreground\">{labels.idle}</p>\n ) : null}\n\n {status === 'running' ? (\n <div className=\"space-y-1.5\" aria-busy>\n <Progress value={done} max={total > 0 ? total : 1} />\n <p className=\"text-sm text-muted-foreground\">\n {message ?? labels.running(done, total)}\n </p>\n </div>\n ) : null}\n\n {status === 'done' ? <p className=\"text-sm text-foreground\">{labels.done}</p> : null}\n\n {status === 'error' ? (\n <div className=\"space-y-2\">\n <p className=\"text-sm text-destructive\">{result?.error ?? labels.error}</p>\n <Button variant=\"outline\" size=\"sm\" onClick={handleRetry}>\n {labels.retry}\n </Button>\n </div>\n ) : null}\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport { Toaster, TooltipProvider } from '@genispace/geniapp/kit';\n\n/** Mount once at GeniApp root (enables kit toast, tooltips). */\nexport function AppUiProviders({ children }: { children: ReactNode }) {\n return (\n <TooltipProvider>\n {children}\n <Toaster />\n </TooltipProvider>\n );\n}\n","import type { CSSProperties } from 'react';\nimport type { AppModalSize } from '@genispace/geniapp/kit';\n\n/** AI adopt sidebar column (DESIGN_GUIDELINE §16.1). */\nexport const AI_SIDEBAR_MIN = '280px';\nexport const AI_SIDEBAR_MAX = '320px';\n\n/**\n * Modal size when AiSuggestionPanel is shown beside the form.\n * Uses `xl` for compatibility with published shared-ui; switch to `wide` once\n * @genispace/geniapp exports AppModalSize `'wide'`.\n */\nexport const MODAL_SIZE_WITH_AI = 'xl' as const satisfies AppModalSize;\n\nexport type ModalSizeWithAi = typeof MODAL_SIZE_WITH_AI;\n\n/** Modal / dialog: form + AI sidebar columns (inline — not dependent on Tailwind scan). */\nexport const AI_ADOPT_MODAL_GRID_STYLE: CSSProperties = {\n gridTemplateColumns: `minmax(0, 1fr) minmax(${AI_SIDEBAR_MIN}, ${AI_SIDEBAR_MAX})`,\n};\n\n/** Tailwind class for apps that include shared/ai/** in content paths (optional). */\nexport const AI_ADOPT_GRID_CLASS =\n 'grid grid-cols-[minmax(0,1fr)_minmax(280px,320px)] gap-4';\n\n/** Full-page adopt layout: same columns from lg breakpoint upward. */\nexport const AI_ADOPT_PAGE_GRID_CLASS =\n 'space-y-6 lg:grid lg:grid-cols-[1fr_minmax(280px,320px)] lg:gap-6 lg:space-y-0';\n\nexport const AI_ADOPT_MODAL_MAX_HEIGHT = 'max-h-[70vh]';\n","import type { ReactNode } from 'react';\nimport { AI_ADOPT_MODAL_MAX_HEIGHT, AI_ADOPT_MODAL_GRID_STYLE } from './layoutConstants';\n\n/**\n * Two-column body for modals/dialogs with AiSuggestionPanel (DESIGN_GUIDELINE §16.1).\n * Uses inline grid columns so layout works even when Tailwind does not scan shared/ai/**.\n */\nexport function ModalWithAiLayout({\n children,\n sidebar,\n className = '',\n}: {\n children: ReactNode;\n sidebar?: ReactNode | null;\n className?: string;\n}) {\n if (!sidebar) {\n return <div className={className}>{children}</div>;\n }\n return (\n <div\n className={`grid gap-4 ${AI_ADOPT_MODAL_MAX_HEIGHT} min-h-0 ${className}`.trim()}\n style={AI_ADOPT_MODAL_GRID_STYLE}\n >\n <div className=\"min-h-0 min-w-0 overflow-y-auto pr-1\">{children}</div>\n <div className=\"min-h-0 min-w-0 overflow-y-auto\">{sidebar}</div>\n </div>\n );\n}\n","import type { AppModalSize } from '@genispace/geniapp/kit';\nimport { MODAL_SIZE_WITH_AI } from './layoutConstants';\n\n/** Use wide modal when an AI adopt sidebar is shown; otherwise keep the app default. */\nexport function modalSizeForAi<S extends AppModalSize>(\n hasAiSidebar: boolean,\n defaultSize: S,\n): S | typeof MODAL_SIZE_WITH_AI {\n return hasAiSidebar ? MODAL_SIZE_WITH_AI : defaultSize;\n}\n","import type { ReactNode } from 'react';\nimport { AI_ADOPT_PAGE_GRID_CLASS } from '../layout/layoutConstants';\n\n/** Two-column layout: main form + optional sticky AI sidebar (full page). */\nexport function DetailPageAiLayout({ children, sidebar }: { children: ReactNode; sidebar?: ReactNode }) {\n if (!sidebar) {\n return <div className=\"space-y-6\">{children}</div>;\n }\n return (\n <div className={AI_ADOPT_PAGE_GRID_CLASS}>\n <div className=\"min-w-0 space-y-6\">{children}</div>\n <div className=\"lg:sticky lg:top-6 lg:self-start\">{sidebar}</div>\n </div>\n );\n}\n","import type { ComponentProps, ReactNode } from 'react';\nimport { cn } from '@genispace/geniapp/utils';\nimport { Button } from '@genispace/geniapp/kit';\n\n/** Read-only AI/workflow text block (matches shared-ui AiMessage; kept here for CI kit compatibility). */\nexport function AiMessage({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) {\n return (\n <div\n className={cn(\n 'rounded-lg border border-border bg-card px-3 py-2 text-sm text-foreground',\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\n/** Field suggestion row for audit adopt (matches shared-ui AiSuggestion). */\nexport function AiSuggestion({\n label,\n children,\n action,\n className,\n}: {\n label: string;\n children: ReactNode;\n action?: ReactNode;\n className?: string;\n}) {\n return (\n <div className={cn('rounded-lg border border-border bg-muted/30 p-3', className)}>\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <span className=\"text-xs font-medium text-muted-foreground\">{label}</span>\n {action}\n </div>\n <div className=\"text-sm text-foreground\">{children}</div>\n </div>\n );\n}\n\nexport function AiSuggestionAction({\n children,\n ...props\n}: ComponentProps<typeof Button>) {\n return (\n <Button type=\"button\" size=\"sm\" variant=\"outline\" {...props}>\n {children}\n </Button>\n );\n}\n","import en from './en.json';\nimport zh from './zh.json';\n\nexport type SharedAiLanguage = 'en' | 'zh';\nexport type SharedAiCopy = typeof en;\n\n/** English is the deterministic fallback; Chinese is used only after an explicit locale switch. */\nexport function sharedAiCopy(language: SharedAiLanguage): SharedAiCopy {\n return language === 'zh' ? zh : en;\n}\n","/** Parse workflow_results.summary (JSON string or plain text). */\nexport function parseAiSummary(summary: string | null | undefined): Record<string, unknown> | null {\n if (summary == null || String(summary).trim() === '') return null;\n const raw = String(summary).trim();\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n return { summary: parsed };\n } catch {\n return { summary: raw };\n }\n}\n\nexport function getByPath(obj: unknown, path: string): unknown {\n if (!path) return obj;\n const parts = path.split('.');\n let cur: unknown = obj;\n for (const part of parts) {\n if (cur == null || typeof cur !== 'object') return undefined;\n cur = (cur as Record<string, unknown>)[part];\n }\n return cur;\n}\n\n/** Prefer the active language; English is the platform default. */\nexport function localizedText(value: unknown, lang: 'zh' | 'en' = 'en'): string {\n if (value == null) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n if (Array.isArray(value)) {\n return value.map((v) => localizedText(v, lang)).filter(Boolean).join('\\n');\n }\n if (typeof value === 'object') {\n const o = value as Record<string, unknown>;\n if (typeof o[lang] === 'string') return o[lang] as string;\n if (typeof o.zh === 'string') return o.zh;\n if (typeof o.en === 'string') return o.en;\n return '';\n }\n return String(value);\n}\n\n/** Convert structured values into readable lines without exposing raw JSON. */\nexport function formatDisplayValue(value: unknown, lang: 'zh' | 'en' = 'en'): string {\n if (value == null) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n if (Array.isArray(value)) {\n return value\n .map((item) => formatDisplayValue(item, lang))\n .filter(Boolean)\n .join('\\n• ');\n }\n if (typeof value === 'object') {\n const o = value as Record<string, unknown>;\n if ('zh' in o || 'en' in o) return localizedText(o, lang);\n for (const key of [\n 'summary',\n 'recommendation',\n 'description',\n 'title',\n 'message',\n 'reason',\n 'action',\n 'suggestion',\n ]) {\n const display = localizedText(o[key], lang);\n if (display) return display;\n }\n return '';\n }\n return String(value);\n}\n","import type { WorkflowResultRow } from '../types';\nimport { parseAiSummary } from './parseAiSummary';\n\nexport type GuidanceLanguage = 'en' | 'zh';\n\nexport interface GuidanceContent {\n summary: string;\n details: string[];\n sources: string[];\n confidence: number | null;\n}\n\nexport interface ContextualWorkflowSelection {\n sourceRecordKey?: string;\n owners: readonly string[];\n limit: number;\n}\n\nconst SUMMARY_KEYS = [\n 'summary',\n 'recommendation',\n 'description',\n 'conclusion',\n 'diagnosis',\n 'analysis_summary',\n 'suggestion',\n 'reason',\n] as const;\n\nconst DETAIL_KEYS = [\n 'nextSteps',\n 'next_steps',\n 'nextActions',\n 'next_actions',\n 'recommendations',\n 'risks',\n 'issues',\n 'anomalies',\n 'stockAlerts',\n 'stock_alerts',\n] as const;\n\nfunction localizedString(value: unknown, language: GuidanceLanguage): string {\n if (typeof value === 'string') return value.trim();\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n if (!value || typeof value !== 'object' || Array.isArray(value)) return '';\n const record = value as Record<string, unknown>;\n const preferred = record[language];\n if (typeof preferred === 'string') return preferred.trim();\n const fallback = language === 'zh' ? record.en : record.zh;\n return typeof fallback === 'string' ? fallback.trim() : '';\n}\n\nfunction detailStrings(value: unknown, language: GuidanceLanguage): string[] {\n if (Array.isArray(value)) {\n return value\n .flatMap((item) => {\n const direct = localizedString(item, language);\n if (direct) return [direct];\n if (!item || typeof item !== 'object') return [];\n const record = item as Record<string, unknown>;\n for (const key of ['message', 'title', 'description', 'reason', 'action', 'suggestion']) {\n const text = localizedString(record[key], language);\n if (text) return [text];\n }\n return [];\n })\n .filter(Boolean);\n }\n const direct = localizedString(value, language);\n return direct ? [direct] : [];\n}\n\nfunction unwrapOutput(record: Record<string, unknown>): Record<string, unknown> {\n const output = record.output;\n if (output && typeof output === 'object' && !Array.isArray(output)) {\n return output as Record<string, unknown>;\n }\n return record;\n}\n\nfunction sourceStrings(record: Record<string, unknown>, language: GuidanceLanguage): string[] {\n const candidates = [record.sources, record.source_refs, record.citations, record.references];\n return [...new Set(candidates.flatMap((value) => detailStrings(value, language)))].slice(0, 5);\n}\n\nfunction confidenceValue(record: Record<string, unknown>): number | null {\n const raw = record.confidence ?? record.confidence_score;\n const number = Number(raw);\n if (!Number.isFinite(number)) return null;\n return Math.max(0, Math.min(1, number > 1 ? number / 100 : number));\n}\n\n/**\n * Extract only business-readable copy from a workflow result. Unknown objects\n * intentionally return null: raw JSON belongs in platform diagnostics, not in\n * a business application.\n */\nexport function guidanceContentFromSummary(\n rawSummary: string | null | undefined,\n language: GuidanceLanguage,\n): GuidanceContent | null {\n const parsed = parseAiSummary(rawSummary);\n if (!parsed) return null;\n const record = unwrapOutput(parsed);\n\n let summary = '';\n let summaryKey: (typeof SUMMARY_KEYS)[number] | null = null;\n for (const key of SUMMARY_KEYS) {\n summary = localizedString(record[key], language);\n if (summary) {\n summaryKey = key;\n break;\n }\n }\n\n const details: string[] = [];\n for (const key of SUMMARY_KEYS) {\n if (key !== summaryKey) details.push(...detailStrings(record[key], language));\n }\n for (const key of DETAIL_KEYS) {\n details.push(...detailStrings(record[key], language));\n }\n\n if (!summary && details.length > 0) summary = details.shift() ?? '';\n if (!summary) return null;\n return {\n summary,\n details: [...new Set(details)].filter((detail) => detail !== summary).slice(0, 5),\n sources: sourceStrings(record, language),\n confidence: confidenceValue(record),\n };\n}\n\nexport function guidanceStatus(status: WorkflowResultRow['status']):\n | 'ready'\n | 'applied'\n | 'dismissed'\n | 'attention' {\n const normalized = String(status ?? '').toLowerCase();\n if (['adopted', 'accepted', 'applied'].includes(normalized)) return 'applied';\n if (['dismissed', 'rejected', 'ignored'].includes(normalized)) return 'dismissed';\n if (['failed', 'error', 'blocked'].includes(normalized)) return 'attention';\n return 'ready';\n}\n\n/**\n * Enforce the business context again after a datasource response. Some legacy\n * adapters ignore filters, so a server response is never trusted to isolate a\n * record or an Agent/workflow owner on its own.\n */\nexport function selectContextualWorkflowResults(\n rows: readonly WorkflowResultRow[],\n { sourceRecordKey, owners, limit }: ContextualWorkflowSelection,\n): WorkflowResultRow[] {\n if (owners.length === 0 || limit <= 0) return [];\n const allowedOwners = new Set(owners);\n return [\n ...new Map(rows.map((row) => [row.id, row] as const)).values(),\n ]\n .filter(\n (row) =>\n !sourceRecordKey ||\n String(row.source_record_key ?? '') === String(sourceRecordKey),\n )\n .filter((row) => Boolean(row.owner) && allowedOwners.has(String(row.owner)))\n .sort((left, right) => {\n const leftTime = left.created_at ? Date.parse(left.created_at) : 0;\n const rightTime = right.created_at ? Date.parse(right.created_at) : 0;\n return (Number.isFinite(rightTime) ? rightTime : 0) -\n (Number.isFinite(leftTime) ? leftTime : 0);\n })\n .slice(0, limit);\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Lightbulb, Check, Loader2 } from 'lucide-react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Skeleton,\n toast,\n AlertDialog,\n} from '@genispace/geniapp/kit';\nimport { AiMessage, AiSuggestion, AiSuggestionAction } from '../layout/aiUi';\nimport { sharedAiCopy } from '../locales/sharedAiCopy';\nimport { guidanceContentFromSummary, selectContextualWorkflowResults } from './guidanceContent';\nimport { parseAiSummary, getByPath, formatDisplayValue, localizedText } from './parseAiSummary';\nimport type { AdoptFieldConfig, AppTableClient, WorkflowResultRow } from '../types';\n\nexport interface AiSuggestionPanelProps {\n recordId: string | undefined;\n resultsTable: string;\n businessTable: string;\n client: AppTableClient;\n fields: AdoptFieldConfig[];\n sourceRecordKey?: string;\n disabled?: boolean;\n className?: string;\n onAdopted?: (patch: Record<string, unknown>) => void;\n lang?: 'zh' | 'en';\n owners: readonly string[];\n title?: string;\n description?: string;\n emptyTitle?: string;\n emptyDescription?: string;\n applyLabel?: string;\n applyAllLabel?: string;\n successMessage?: string;\n allowEditing?: boolean;\n}\n\nexport function AiSuggestionPanel({\n recordId,\n resultsTable,\n businessTable,\n client,\n fields,\n sourceRecordKey,\n disabled,\n className = '',\n onAdopted,\n lang,\n owners,\n title,\n description,\n emptyTitle,\n emptyDescription,\n applyLabel,\n applyAllLabel,\n successMessage,\n allowEditing = true,\n}: AiSuggestionPanelProps) {\n const { i18n } = useTranslation();\n const resolvedLanguage =\n lang ?? (i18n.resolvedLanguage?.toLowerCase().startsWith('zh') ? 'zh' : 'en');\n const copy = suggestionCopy(resolvedLanguage);\n const [loading, setLoading] = useState(false);\n const [adopting, setAdopting] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [result, setResult] = useState<WorkflowResultRow | null>(null);\n const [drafts, setDrafts] = useState<Record<string, string>>({});\n const [appliedFields, setAppliedFields] = useState<Set<string>>(new Set());\n const [pendingTarget, setPendingTarget] = useState<string | null>(null);\n\n const key = sourceRecordKey ?? recordId;\n const parsed = useMemo(() => parseAiSummary(result?.summary), [result?.summary]);\n const evidence = useMemo(() => guidanceContentFromSummary(result?.summary, resolvedLanguage), [resolvedLanguage, result?.summary]);\n const ownerKey = owners?.join('\\u0000') ?? '';\n const fieldSignature = fields.map((field) => `${field.targetField}:${field.summaryPath}`).join('|');\n\n const load = useCallback(async () => {\n if (!key) {\n setResult(null);\n return;\n }\n setLoading(true);\n setError(null);\n try {\n const allowedOwners = ownerKey ? new Set(ownerKey.split('\\u0000')) : null;\n const ownerCandidates = allowedOwners ? [...allowedOwners] : [];\n const responses = await Promise.all(\n ownerCandidates.map((owner) =>\n client.list<WorkflowResultRow>(resultsTable, {\n filters: {\n source_record_key: key,\n ...(owner ? { owner } : {}),\n },\n limit: 20,\n }),\n ),\n );\n const items = selectContextualWorkflowResults(\n responses.flatMap((response) => response.items ?? []),\n {\n sourceRecordKey: key,\n owners: allowedOwners ? [...allowedOwners] : [],\n limit: 1,\n },\n );\n setResult(items[0] ?? null);\n } catch (e) {\n console.error(`[GeniApp] ${resultsTable} record guidance load failed`, e);\n setError(copy.loadError);\n setResult(null);\n } finally {\n setLoading(false);\n }\n }, [client, copy.loadError, key, ownerKey, resultsTable]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n useEffect(() => {\n if (!parsed) {\n setDrafts({});\n return;\n }\n const next: Record<string, string> = {};\n for (const field of fields) {\n const raw = getByPath(parsed, field.summaryPath);\n const value = field.toValue ? field.toValue(raw, parsed, resolvedLanguage) : raw;\n const display = formatDisplayValue(value, resolvedLanguage);\n if (display) next[field.targetField] = display;\n }\n setDrafts(next);\n setAppliedFields(new Set());\n }, [fieldSignature, parsed, resolvedLanguage]);\n\n const adoptField = async (field: AdoptFieldConfig) => {\n if (!recordId || !parsed) return;\n const raw = getByPath(parsed, field.summaryPath);\n const transformed = field.toValue ? field.toValue(raw, parsed, resolvedLanguage) : raw;\n const edited = drafts[field.targetField];\n const value = allowEditing && typeof edited === 'string' ? edited.trim() : transformed;\n if (value == null || (typeof value === 'string' && value.trim() === '')) {\n setError(copy.emptyField);\n return;\n }\n setAdopting(field.targetField);\n setError(null);\n try {\n const patch = { [field.targetField]: value };\n await client.update(businessTable, recordId, patch);\n onAdopted?.(patch);\n setAppliedFields((current) => new Set(current).add(field.targetField));\n toast({\n title: successMessage ?? copy.adopted,\n variant: 'success',\n });\n } catch (e) {\n console.error(`[GeniApp] ${businessTable} suggestion apply failed`, e);\n setError(copy.applyError);\n } finally {\n setAdopting(null);\n }\n };\n\n const adoptAll = async () => {\n if (!recordId || !parsed) return;\n setAdopting('__all__');\n setError(null);\n try {\n const patch: Record<string, unknown> = {};\n for (const field of fields) {\n const raw = getByPath(parsed, field.summaryPath);\n const transformed = field.toValue ? field.toValue(raw, parsed, resolvedLanguage) : raw;\n const edited = drafts[field.targetField];\n const value = allowEditing && typeof edited === 'string' ? edited.trim() : transformed;\n if (value != null && !(typeof value === 'string' && value.trim() === '')) {\n patch[field.targetField] = value;\n }\n }\n if (Object.keys(patch).length === 0) {\n setError(copy.emptyField);\n return;\n }\n await client.update(businessTable, recordId, patch);\n onAdopted?.(patch);\n setAppliedFields(new Set(Object.keys(patch)));\n toast({\n title: successMessage ?? copy.adoptedAll,\n variant: 'success',\n });\n } catch (e) {\n console.error(`[GeniApp] ${businessTable} suggestions apply failed`, e);\n setError(copy.applyAllError);\n } finally {\n setAdopting(null);\n }\n };\n\n if (!recordId) return null;\n\n return (\n <Card\n className={`border-accent/30 bg-card ${className}`}\n aria-label={title ?? copy.panelTitle}\n >\n <CardHeader className=\"pb-3\">\n <div className=\"flex items-start gap-2\">\n <div className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-accent text-accent-foreground\">\n <Lightbulb className=\"h-4 w-4\" aria-hidden />\n </div>\n <div className=\"min-w-0\">\n <CardTitle className=\"text-sm\">\n {title ?? copy.panelTitle}\n </CardTitle>\n <CardDescription>\n {description ?? copy.panelHint}\n </CardDescription>\n </div>\n </div>\n </CardHeader>\n\n <CardContent className=\"space-y-3 pt-0\">\n {loading && (\n <div className=\"space-y-2\" aria-busy=\"true\">\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-16 w-full\" />\n </div>\n )}\n\n {!loading && !result && (\n <div className=\"rounded-lg border border-dashed border-border px-3 py-4\">\n <p className=\"text-sm font-medium text-foreground\">\n {emptyTitle ?? copy.emptyTitle}\n </p>\n <p className=\"mt-1 text-sm leading-5 text-muted-foreground\">\n {emptyDescription ?? copy.noResults}\n </p>\n </div>\n )}\n\n {!loading && result && (\n <>\n <ResultMeta result={result} language={resolvedLanguage} />\n {parsed?.summary != null && typeof parsed.summary === 'string' && fields.length === 0 && (\n <AiMessage>\n <p className=\"whitespace-pre-wrap\">{parsed.summary}</p>\n </AiMessage>\n )}\n {fields.map((field) => {\n const raw = parsed ? getByPath(parsed, field.summaryPath) : undefined;\n const transformed = field.toValue ? field.toValue(raw, parsed, resolvedLanguage) : raw;\n const display = formatDisplayValue(transformed, resolvedLanguage);\n if (!display) return null;\n const applied = appliedFields.has(field.targetField);\n return (\n <AiSuggestion\n key={field.targetField}\n label={field.label}\n action={\n <AiSuggestionAction\n disabled={disabled || adopting != null || applied}\n onClick={() => setPendingTarget(field.targetField)}\n >\n {adopting === field.targetField ? (\n <Loader2 className=\"h-3 w-3 animate-spin\" />\n ) : (\n <Check className=\"h-3 w-3\" />\n )}\n {applied\n ? copy.added\n : applyLabel ?? copy.adopt}\n </AiSuggestionAction>\n }\n >\n {allowEditing ? (\n <textarea\n value={drafts[field.targetField] ?? display}\n onChange={(event) =>\n setDrafts((current) => ({\n ...current,\n [field.targetField]: event.target.value,\n }))\n }\n rows={Math.min(6, Math.max(2, (drafts[field.targetField] ?? display).split('\\n').length))}\n className=\"w-full resize-y rounded-md border border-input bg-background px-3 py-2 text-sm leading-5 text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n aria-label={field.label}\n />\n ) : (\n <p className=\"whitespace-pre-wrap leading-5\">{display}</p>\n )}\n </AiSuggestion>\n );\n })}\n {fields.length > 1 && (\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"w-full\"\n disabled={disabled || adopting != null}\n onClick={() => setPendingTarget('__all__')}\n >\n {adopting === '__all__'\n ? copy.adopting\n : applyAllLabel ?? copy.adoptAll}\n </Button>\n )}\n </>\n )}\n\n {error && (\n <p className=\"text-sm text-destructive\" role=\"alert\">\n {error}\n </p>\n )}\n {result ? <div className=\"rounded-md border bg-muted/30 px-3 py-2 text-xs text-muted-foreground\"><p className=\"font-medium text-foreground\">{copy.sources}</p><p className=\"mt-1\">{evidence?.sources.length ? evidence.sources.join(' · ') : copy.noSources}</p>{evidence?.confidence != null ? <p className=\"mt-1\">{copy.confidence}: {Math.round(evidence.confidence * 100)}%</p> : null}</div> : null}\n </CardContent>\n <AlertDialog\n isOpen={pendingTarget != null}\n type=\"info\"\n title={copy.confirmTitle}\n message={pendingTarget === '__all__' ? copy.confirmAll.replace('{{count}}', String(fields.length)) : copy.confirmOne.replace('{{field}}', fields.find((field) => field.targetField === pendingTarget)?.label ?? '')}\n confirmText={copy.confirmAction}\n cancelText={copy.cancelAction}\n showCancel\n loading={adopting != null}\n onClose={() => setPendingTarget(null)}\n onCancel={() => setPendingTarget(null)}\n onConfirm={() => {\n const target = pendingTarget;\n setPendingTarget(null);\n if (target === '__all__') void adoptAll();\n else {\n const field = fields.find((candidate) => candidate.targetField === target);\n if (field) void adoptField(field);\n }\n }}\n />\n </Card>\n );\n}\n\nfunction ResultMeta({ result, language }: { result: WorkflowResultRow; language: 'en' | 'zh' }) {\n const copy = suggestionCopy(language);\n const normalizedStatus = String(result.status ?? '').toLowerCase();\n const statusLabel = ['adopted', 'accepted', 'applied'].includes(normalizedStatus)\n ? copy.statusApplied\n : ['failed', 'error', 'blocked'].includes(normalizedStatus)\n ? copy.statusAttention\n : copy.statusReady;\n return (\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-muted-foreground\">\n <Badge variant=\"secondary\">{statusLabel}</Badge>\n {result.created_at && formatSuggestionDate(result.created_at, language) && (\n <time dateTime={result.created_at}>\n {formatSuggestionDate(result.created_at, language)}\n </time>\n )}\n </div>\n );\n}\n\nfunction formatSuggestionDate(value: string, language: 'en' | 'zh'): string {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return '';\n return new Intl.DateTimeFormat(language === 'zh' ? 'zh-CN' : 'en-US', {\n dateStyle: 'medium',\n timeStyle: 'short',\n }).format(date);\n}\n\nfunction suggestionCopy(language: 'en' | 'zh') {\n return sharedAiCopy(language).suggestion;\n}\n\n/** Common field mappers for product description agent output */\nexport const productDescriptionAdoptFields = (labels: {\n description: string;\n descriptionSale: string;\n name?: string;\n}): AdoptFieldConfig[] => {\n const fields: AdoptFieldConfig[] = [\n {\n label: labels.description,\n summaryPath: 'description',\n targetField: 'description',\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n },\n {\n label: labels.descriptionSale,\n summaryPath: 'highlights',\n targetField: 'description_sale',\n toValue: (raw, _parsed, language) => {\n if (Array.isArray(raw)) return raw.map(String).join('\\n• ');\n return localizedText(raw, language ?? 'en');\n },\n },\n ];\n if (labels.name) {\n fields.unshift({\n label: labels.name,\n summaryPath: 'title',\n targetField: 'name',\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n });\n }\n return fields;\n};\n","import { useCallback, useEffect, useMemo, useState, type ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { AlertCircle, CheckCircle2, Lightbulb, RefreshCw } from 'lucide-react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Skeleton,\n} from '@genispace/geniapp/kit';\nimport type { AppTableClient, WorkflowResultRow } from '../types';\nimport { sharedAiCopy } from '../locales/sharedAiCopy';\nimport {\n guidanceContentFromSummary,\n guidanceStatus,\n selectContextualWorkflowResults,\n} from './guidanceContent';\n\ninterface BusinessGuidancePanelBaseProps {\n client: AppTableClient;\n resultsTable: string;\n title: string;\n description: string;\n emptyTitle: string;\n emptyDescription: string;\n unreadableText?: string;\n owners: readonly string[];\n limit?: number;\n className?: string;\n footer?: ReactNode;\n renderAction?: (row: WorkflowResultRow) => ReactNode;\n}\n\nexport type BusinessGuidancePanelProps = BusinessGuidancePanelBaseProps &\n (\n | { scope: 'aggregate'; sourceRecordKey?: never }\n | { scope?: 'record'; sourceRecordKey: string }\n );\n\n/**\n * A business-page feed for useful recommendations. It deliberately hides run\n * identifiers, model payloads and raw JSON; those remain available to platform\n * diagnostics without becoming part of the user's daily navigation.\n */\nexport function BusinessGuidancePanel({\n client,\n resultsTable,\n title,\n description,\n emptyTitle,\n emptyDescription,\n unreadableText,\n sourceRecordKey,\n owners,\n limit = 3,\n className = '',\n footer,\n renderAction,\n}: BusinessGuidancePanelProps) {\n const { i18n } = useTranslation();\n const language = i18n.resolvedLanguage?.toLowerCase().startsWith('zh') ? 'zh' : 'en';\n const copy = sharedAiCopy(language).businessGuidance;\n const [rows, setRows] = useState<WorkflowResultRow[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState(false);\n const ownerKey = owners?.join('\\u0000') ?? '';\n\n const load = useCallback(async () => {\n setLoading(true);\n setError(false);\n try {\n const allowedOwners = ownerKey ? new Set(ownerKey.split('\\u0000')) : null;\n const ownerCandidates = allowedOwners ? [...allowedOwners] : [];\n const responses = await Promise.all(\n ownerCandidates.map((owner) =>\n client.list<WorkflowResultRow>(resultsTable, {\n filters: {\n ...(sourceRecordKey ? { source_record_key: sourceRecordKey } : {}),\n ...(owner ? { owner } : {}),\n },\n limit: Math.max(limit * 4, 20),\n }),\n ),\n );\n setRows(\n selectContextualWorkflowResults(\n responses.flatMap((response) => response.items ?? []),\n {\n sourceRecordKey,\n owners: allowedOwners ? [...allowedOwners] : [],\n limit,\n },\n ),\n );\n } catch (reason) {\n console.error(`[GeniApp] ${resultsTable} guidance load failed`, reason);\n setRows([]);\n setError(true);\n } finally {\n setLoading(false);\n }\n }, [client, limit, ownerKey, resultsTable, sourceRecordKey]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n const readableRows = useMemo(\n () => rows.map((row) => ({ row, content: guidanceContentFromSummary(row.summary, language) })),\n [language, rows],\n );\n\n return (\n <Card className={`border-border bg-card ${className}`} aria-label={title}>\n <CardHeader className=\"gap-3 pb-3 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex min-w-0 items-start gap-3\">\n <div className=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-lg border border-border bg-muted/40 text-foreground\">\n <Lightbulb className=\"h-4 w-4\" aria-hidden />\n </div>\n <div className=\"min-w-0\">\n <CardTitle className=\"text-base\">{title}</CardTitle>\n <CardDescription className=\"mt-1 max-w-3xl leading-5\">{description}</CardDescription>\n </div>\n </div>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"shrink-0\" onClick={() => void load()}>\n <RefreshCw className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden />\n {copy.refresh}\n </Button>\n </CardHeader>\n <CardContent className=\"space-y-3 pt-0\">\n {loading ? (\n <div className=\"space-y-3\" aria-busy=\"true\">\n <Skeleton className=\"h-20 w-full\" />\n <Skeleton className=\"h-20 w-full\" />\n </div>\n ) : error ? (\n <div className=\"flex items-start gap-2 rounded-lg border border-destructive/30 bg-destructive/5 p-3 text-sm\" role=\"alert\">\n <AlertCircle className=\"mt-0.5 h-4 w-4 shrink-0 text-destructive\" aria-hidden />\n <div>\n <p className=\"font-medium text-foreground\">\n {copy.errorTitle}\n </p>\n <p className=\"mt-0.5 text-muted-foreground\">\n {copy.errorDescription}\n </p>\n </div>\n </div>\n ) : readableRows.length === 0 ? (\n <div className=\"rounded-lg border border-dashed border-border px-4 py-5\">\n <div className=\"flex items-start gap-2\">\n <CheckCircle2 className=\"mt-0.5 h-4 w-4 shrink-0 text-status-success\" aria-hidden />\n <div>\n <p className=\"text-sm font-medium text-foreground\">{emptyTitle}</p>\n <p className=\"mt-1 text-sm leading-5 text-muted-foreground\">{emptyDescription}</p>\n </div>\n </div>\n </div>\n ) : (\n readableRows.map(({ row, content }) => {\n const state = guidanceStatus(row.status);\n return (\n <article key={row.id} className=\"rounded-lg border border-border p-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"mb-2 flex flex-wrap items-center gap-2\">\n <Badge variant={state === 'attention' ? 'destructive' : 'secondary'}>\n {state === 'applied'\n ? copy.applied\n : state === 'dismissed'\n ? copy.dismissed\n : state === 'attention'\n ? copy.attention\n : copy.ready}\n </Badge>\n {row.created_at ? (\n <time className=\"text-xs text-muted-foreground\" dateTime={row.created_at}>\n {formatGuidanceDate(row.created_at, language)}\n </time>\n ) : null}\n </div>\n {content ? (\n <>\n <p className=\"text-sm font-medium leading-6 text-foreground\">{content.summary}</p>\n {content.details.length > 0 ? (\n <ul className=\"mt-2 space-y-1.5 text-sm leading-5 text-muted-foreground\">\n {content.details.map((detail) => (\n <li key={detail} className=\"flex gap-2\">\n <span aria-hidden>•</span>\n <span>{detail}</span>\n </li>\n ))}\n </ul>\n ) : null}\n <div className=\"mt-3 flex flex-wrap gap-3 text-xs text-muted-foreground\">\n {content.sources.length > 0 ? <span>{copy.sources}: {content.sources.join(' · ')}</span> : <span>{copy.noSources}</span>}\n {content.confidence != null ? <span>{copy.confidence}: {Math.round(content.confidence * 100)}%</span> : null}\n </div>\n </>\n ) : (\n <p className=\"text-sm leading-5 text-muted-foreground\">\n {unreadableText ?? copy.unreadable}\n </p>\n )}\n </div>\n {renderAction ? <div className=\"shrink-0\">{renderAction(row)}</div> : null}\n </div>\n </article>\n );\n })\n )}\n {footer}\n </CardContent>\n </Card>\n );\n}\n\nfunction formatGuidanceDate(value: string, language: 'en' | 'zh'): string {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return '';\n return new Intl.DateTimeFormat(language === 'zh' ? 'zh-CN' : 'en-US', {\n dateStyle: 'medium',\n timeStyle: 'short',\n }).format(date);\n}\n","import { localizedText } from './parseAiSummary';\nimport type { AdoptFieldConfig } from '../types';\n\nexport function genericSummaryField(label: string, targetField: string): AdoptFieldConfig {\n return {\n label,\n summaryPath: 'summary',\n targetField,\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n };\n}\n\nexport function narrationAdoptField(label: string): AdoptFieldConfig {\n return {\n label,\n summaryPath: 'narration',\n targetField: 'narration',\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n };\n}\n\nexport function recommendationAdoptField(label: string, targetField = 'ref'): AdoptFieldConfig {\n return {\n label,\n summaryPath: 'recommendation',\n targetField,\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n };\n}\n\nexport function synopsisAdoptField(label: string, targetField = 'synopsis'): AdoptFieldConfig {\n return {\n label,\n summaryPath: 'synopsis',\n targetField,\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n };\n}\n\nexport function noteAdoptField(label: string, targetField = 'note'): AdoptFieldConfig {\n return {\n label,\n summaryPath: 'note',\n targetField,\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n };\n}\n\nexport function internalNotesAdoptField(label: string): AdoptFieldConfig {\n return {\n label,\n summaryPath: 'internal_notes',\n targetField: 'internal_notes',\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n };\n}\n\nexport function jobTitleAdoptField(label: string): AdoptFieldConfig {\n return {\n label,\n summaryPath: 'job_title',\n targetField: 'job_title',\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n };\n}\n\nexport function descriptionAdoptField(label: string, targetField = 'description'): AdoptFieldConfig {\n return {\n label,\n summaryPath: 'description',\n targetField,\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n };\n}\n\nexport function appendTextAdoptField(\n label: string,\n summaryPath: string,\n targetField: string,\n currentValue: string | null | undefined,\n): AdoptFieldConfig {\n return {\n label,\n summaryPath,\n targetField,\n toValue: (raw, _parsed, language) => {\n const suggestion = localizedText(raw, language ?? 'en').trim();\n const existing = currentValue?.trim() ?? '';\n if (!suggestion || existing === suggestion || existing.includes(suggestion)) {\n return existing || suggestion;\n }\n return existing ? `${existing}\\n\\n${suggestion}` : suggestion;\n },\n };\n}\n","import {\n createGeniSpaceClient,\n findManagedAppDataSourceId,\n queryManagedDatasourceRows,\n} from '../../managed-data/queryManagedDatasource';\n\nexport const PARTNER_GENIAPP = 'partner';\nexport const PARTNER_RECORD_PICKER_DS = 'partner_record_picker';\n\nexport type PartnerRecordRole =\n | 'customer'\n | 'supplier'\n | 'prospect'\n | 'service_provider'\n | 'manufacturer'\n | 'carrier'\n | 'franchisee'\n | 'equipment_owner';\n\nexport type PartnerRecordOption = {\n id: string;\n label: string;\n secondary?: string;\n /** Read-only business details published by Partner for directory and picker experiences. */\n snapshot?: Record<string, unknown>;\n};\n\nexport type LoadPartnerRecordOptionsParams = {\n role?: PartnerRecordRole;\n partyType?: 'organization' | 'person';\n legalEntityRef?: string;\n limit?: number;\n offset?: number;\n ensureIds?: string[];\n};\n\nexport async function probePartnerRecordPicker(apiRoot: string, token: string | null): Promise<boolean> {\n if (!apiRoot || !token) return false;\n const gs = createGeniSpaceClient(apiRoot, token);\n return (await findManagedAppDataSourceId(gs, PARTNER_RECORD_PICKER_DS, PARTNER_GENIAPP)) != null;\n}\n\nfunction mapPartnerRecord(row: Record<string, unknown>): PartnerRecordOption | null {\n const id = String(row.id ?? '').trim();\n const label = String(row.primary ?? row.display_name ?? row.legal_name ?? '').trim();\n if (!id || !label) return null;\n const secondary = String(row.secondary ?? row.partner_number ?? '').trim();\n const snapshot = parseSnapshot(row.snapshot);\n return {\n id,\n label,\n ...(secondary ? { secondary } : {}),\n ...(snapshot ? { snapshot } : {}),\n };\n}\n\nfunction parseSnapshot(value: unknown): Record<string, unknown> | undefined {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n if (typeof value !== 'string' || value.trim() === '') return undefined;\n try {\n const parsed = JSON.parse(value) as unknown;\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed)\n ? parsed as Record<string, unknown>\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function queryPartnerRecords(\n apiRoot: string,\n token: string,\n params: LoadPartnerRecordOptionsParams,\n extra: { id?: string; limit: number; offset: number },\n): Promise<Record<string, unknown>[]> {\n return queryManagedDatasourceRows(apiRoot, token, PARTNER_GENIAPP, PARTNER_RECORD_PICKER_DS, {\n role: params.role ?? '',\n party_type: params.partyType ?? '',\n legal_entity_ref: params.legalEntityRef ?? '',\n id: extra.id ?? '',\n search: '',\n limit: extra.limit,\n offset: extra.offset,\n });\n}\n\nexport async function loadPartnerRecordOptions(\n apiRoot: string,\n token: string | null,\n params: LoadPartnerRecordOptionsParams = {},\n): Promise<PartnerRecordOption[]> {\n if (!apiRoot || !token || !(await probePartnerRecordPicker(apiRoot, token))) return [];\n\n const pageSize = Math.min(Math.max(params.limit ?? 100, 1), 100);\n const byId = new Map<string, PartnerRecordOption>();\n let offset = Math.max(params.offset ?? 0, 0);\n while (true) {\n const rows = await queryPartnerRecords(apiRoot, token, params, { limit: pageSize, offset });\n for (const row of rows) {\n const option = mapPartnerRecord(row);\n if (option) byId.set(option.id, option);\n }\n if (rows.length < pageSize) break;\n offset += pageSize;\n if (offset > 5000) break;\n }\n\n await Promise.all((params.ensureIds ?? []).filter((id) => id && !byId.has(id)).map(async (id) => {\n const rows = await queryPartnerRecords(apiRoot, token, params, { id, limit: 1, offset: 0 });\n const option = rows.length > 0 ? mapPartnerRecord(rows[0]) : null;\n if (option) byId.set(option.id, option);\n }));\n return [...byId.values()];\n}\n","import { createUseManagedAppPicker } from '@genispace/geniapp/hooks';\nimport {\n loadPartnerRecordOptions,\n probePartnerRecordPicker,\n type PartnerRecordRole,\n} from './partnerRecordPicker';\n\nfunction readToken(): string | null {\n try {\n return localStorage.getItem('token');\n } catch {\n return null;\n }\n}\n\nexport type PartnerRecordPickerHookOptions = {\n role?: PartnerRecordRole;\n partyType?: 'organization' | 'person';\n legalEntityRef?: string;\n};\n\nexport function createPartnerRecordPickerHook(\n buildApiRoot: () => string,\n hookOptions: PartnerRecordPickerHookOptions = {},\n) {\n return createUseManagedAppPicker({\n providerGeniappId: 'partner',\n datasourceIdentifier: 'partner_record_picker',\n buildApiRoot,\n readToken,\n probePicker: probePartnerRecordPicker,\n loadOptions: async (apiRoot, token, ensureIds) => {\n const rows = await loadPartnerRecordOptions(apiRoot, token, { ...hookOptions, ensureIds });\n return rows.map(({ id, label }) => ({ id, label }));\n },\n });\n}\n"],"names":["createTableClient","handlers","table","options","params","metaBool","v","DS_LIST_PAGE","DS_LIST_MAX_PAGES","matchesManaged","x","seedIdentifier","geniappIdentifier","meta","findManagedAppDataSourceId","client","items","hit","page","createGeniSpaceClient","apiRoot","accessToken","baseURL","GeniSpace","asNonNegativeInt","n","rowsOf","payload","r","API_DEFAULT_LIMIT","queryReadRowsPaged","gs","datasourceId","rawOffset","rest","offset","limit","windowSize","fetchWindow","windowIndex","windowOffset","firstWindow","skip","head","tail","queryManagedDatasourceRows","id","DATASOURCE_PAGE_SIZE","queryManagedDatasourceRowsAll","all","rows","executeManagedDatasourceOperation","body","k","res","text","parsed","msg","executeManagedDatasourceTransaction","payloadParamName","createTransactionDatasourceClient","resolveApiRoot","resolveAccessToken","emitManagedEvent","eventName","opts","createManagedEventClient","DatasourceReadonlyTable","title","hint","columns","emptyLabel","t","useTranslation","jsxs","Card","CardHeader","jsx","CardTitle","CardDescription","CardContent","Table","TableHeader","TableRow","c","TableHead","TableBody","row","TableCell","EMPTY_SELECTION","SortIndicator","active","dir","ServerDataTable","fetchRows","rowKey","labels","pageSize","resetKey","initialSort","onRowClick","emptyContent","className","selectable","selectedIds","onSelectionChange","mobileCard","isMobile","useIsMobile","pageIndex","setPageIndex","useState","sort","setSort","setRows","hasMore","setHasMore","loading","setLoading","error","setError","reqId","useRef","sortToken","runFetch","useCallback","myId","fetched","e","useEffect","firstRender","toggleSort","colSortKey","prev","selection","pageKeys","selectedOnPage","allPageSelected","somePageSelected","toggleRow","key","next","togglePage","loadingState","errorState","Button","emptyState","pagination","p","Checkbox","interactive","sortable","AsyncCombobox","value","onChange","loadOptions","resolveSelected","disabled","allowClear","triggerClassName","contentClassName","open","setOpen","query","setQuery","debounced","setDebounced","setOptions","setOffset","selectedOption","setSelectedOption","fetchPage","search","nextOffset","append","more","inOptions","o","cancelled","opt","triggerLabel","Popover","PopoverTrigger","PopoverContent","Input","ScrollArea","useInfiniteRows","offsetRef","loadingRef","hasMoreRef","fetchRef","observerRef","loadMore","batch","got","reset","sentinelRef","el","entries","en","Timeline","children","TimelineItem","Icon","dotClassName","nodeClassName","accentClassName","time","isLast","useEntityNames","resolver","cache","inFlight","pending","flushHandle","setVersion","loadingCount","setLoadingCount","resolverRef","flush","map","ensure","ids","added","EntityRef","name","href","onClick","fallback","resolved","content","baseClass","merged","BulkActionBar","selectedCount","totalMatching","allMatchingSelected","onSelectAllMatching","onClear","actions","canSelectAllMatching","action","useAgentJobRunner","state","setState","phase","setPhase","elapsedMs","setElapsedMs","job","setJob","attempt","setAttempt","cancelRequested","setCancelRequested","runId","runningRef","abortRef","jobRef","cancelFnRef","cancelRequestedRef","baselineRef","ticking","tick","base","timer","observe","snapshot","s","created","noteAttempt","start","task","controller","guard","fn","args","result","cancel","jobId","DEFAULT_LABELS","seconds","STEP_KEYS","activeStepIndex","AgentJobProgressInline","expectedSeconds","onCancel","onRetry","l","slow","note","stepIdx","Loader2","i","isDone","isCurrent","Check","Circle","EMPTY_PROGRESS","useAsyncJob","run","status","setStatus","progress","setProgress","setResult","runRef","report","message","JobProgress","done","total","handleRetry","Progress","AppUiProviders","TooltipProvider","Toaster","AI_SIDEBAR_MIN","AI_SIDEBAR_MAX","MODAL_SIZE_WITH_AI","AI_ADOPT_MODAL_GRID_STYLE","AI_ADOPT_GRID_CLASS","AI_ADOPT_PAGE_GRID_CLASS","AI_ADOPT_MODAL_MAX_HEIGHT","ModalWithAiLayout","sidebar","modalSizeForAi","hasAiSidebar","defaultSize","DetailPageAiLayout","AiMessage","cn","AiSuggestion","label","AiSuggestionAction","props","sharedAiCopy","language","zh","parseAiSummary","summary","raw","getByPath","obj","path","parts","cur","part","localizedText","lang","formatDisplayValue","item","display","SUMMARY_KEYS","DETAIL_KEYS","localizedString","record","preferred","detailStrings","direct","unwrapOutput","output","sourceStrings","candidates","confidenceValue","number","guidanceContentFromSummary","rawSummary","summaryKey","details","detail","guidanceStatus","normalized","selectContextualWorkflowResults","sourceRecordKey","owners","allowedOwners","left","right","leftTime","rightTime","AiSuggestionPanel","recordId","resultsTable","businessTable","fields","onAdopted","description","emptyTitle","emptyDescription","applyLabel","applyAllLabel","successMessage","allowEditing","i18n","resolvedLanguage","copy","suggestionCopy","adopting","setAdopting","drafts","setDrafts","appliedFields","setAppliedFields","pendingTarget","setPendingTarget","useMemo","evidence","ownerKey","fieldSignature","field","load","ownerCandidates","responses","owner","response","adoptField","transformed","edited","patch","current","toast","adoptAll","Lightbulb","Skeleton","Fragment","ResultMeta","applied","event","AlertDialog","target","candidate","normalizedStatus","statusLabel","Badge","formatSuggestionDate","date","productDescriptionAdoptFields","_parsed","BusinessGuidancePanel","unreadableText","footer","renderAction","reason","readableRows","RefreshCw","AlertCircle","CheckCircle2","formatGuidanceDate","genericSummaryField","targetField","narrationAdoptField","recommendationAdoptField","synopsisAdoptField","noteAdoptField","internalNotesAdoptField","jobTitleAdoptField","descriptionAdoptField","appendTextAdoptField","summaryPath","currentValue","suggestion","existing","PARTNER_GENIAPP","PARTNER_RECORD_PICKER_DS","probePartnerRecordPicker","token","mapPartnerRecord","secondary","parseSnapshot","queryPartnerRecords","extra","loadPartnerRecordOptions","byId","option","readToken","createPartnerRecordPickerHook","buildApiRoot","hookOptions","createUseManagedAppPicker","ensureIds"],"mappings":"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"}
1
+ {"version":3,"file":"ai.js","sources":["../src/ai/managed-data/createTableClient.ts","../src/ai/managed-data/queryManagedDatasource.ts","../src/ai/managed-data/executeManagedDatasource.ts","../src/ai/managed-data/emitManagedEvent.ts","../src/ai/managed-data/DatasourceReadonlyTable.tsx","../src/ai/components/ServerDataTable.tsx","../src/ai/components/AsyncCombobox.tsx","../src/ai/components/useInfiniteRows.ts","../src/ai/components/Timeline.tsx","../src/ai/components/EntityRef.tsx","../src/ai/components/BulkActionBar.tsx","../src/ai/components/AgentJobProgress.tsx","../src/ai/components/JobProgress.tsx","../src/ai/providers/AppUiProviders.tsx","../src/ai/layout/layoutConstants.ts","../src/ai/layout/ModalWithAiLayout.tsx","../src/ai/layout/modalSizeForAi.ts","../src/ai/adopt/DetailPageAiLayout.tsx","../src/ai/layout/aiUi.tsx","../src/ai/locales/sharedAiCopy.ts","../src/ai/adopt/parseAiSummary.ts","../src/ai/adopt/guidanceContent.ts","../src/ai/adopt/AiSuggestionPanel.tsx","../src/ai/adopt/BusinessGuidancePanel.tsx","../src/ai/adopt/adoptPresets.ts","../src/ai/integrations/partner/partnerRecordPicker.ts","../src/ai/integrations/partner/createPartnerRecordPickerHook.ts"],"sourcesContent":["import type { AppTableClient } from '../types';\n\n/** Adapter for apps using apiList / apiUpdate style helpers. */\nexport function createTableClient(handlers: {\n list: <T>(table: string, params?: Record<string, string | number | boolean | null>) => Promise<T[]>;\n update: (table: string, id: string, payload: Record<string, unknown>) => Promise<unknown>;\n}): AppTableClient {\n return {\n async list<T>(\n table: string,\n options?: { filters?: Record<string, string | number | boolean | null>; limit?: number; offset?: number }\n ) {\n const params: Record<string, string | number | boolean | null> = {\n ...(options?.filters ?? {}),\n };\n if (options?.limit != null) params.limit = options.limit;\n if (options?.offset != null) params.offset = options.offset;\n const items = await handlers.list<T>(table, params);\n return { items };\n },\n update: handlers.update,\n };\n}\n","import { GeniSpace } from '@genispace/sdk';\n\nfunction metaBool(v: unknown): boolean {\n return v === true || v === 'true';\n}\n\n/**\n * Max datasources per list page. `GET /datasources` on older/deployed API\n * versions validates `limit` as 1-100 (a single `limit: 500` call 400s there —\n * the message even reads \"between 1-100\"), so we page in bounded 100-row\n * windows rather than one oversized request. This mirrors the agent-resolution\n * pattern (precheck/aiDraft/scheduleAdvisor) and keeps cross-app datasource\n * resolution working in spaces that publish 500+ datasources (e.g. retail-crm\n * alone ships 240+), where the target row falls past the first page.\n */\nconst DS_LIST_PAGE = 100;\n/** Hard ceiling on pages scanned so a mis-provisioned space can't loop forever. */\nconst DS_LIST_MAX_PAGES = 50;\n\nfunction matchesManaged(\n x: { identifier?: string | null; metadata?: unknown },\n seedIdentifier: string,\n geniappIdentifier: string\n): boolean {\n const meta = x.metadata as Record<string, unknown> | null | undefined;\n return (\n String(x.identifier || '') === seedIdentifier &&\n metaBool(meta?.managedByGeniapp) &&\n String(meta?.geniappIdentifier || '') === geniappIdentifier\n );\n}\n\nexport async function findManagedAppDataSourceId(\n client: GeniSpace,\n seedIdentifier: string,\n geniappIdentifier: string\n): Promise<string | null> {\n // Fast path: server-side name search narrows to the handful of datasources\n // whose name/description contain the identifier (managed datasource names are\n // seeded from the identifier), so the match is almost always on page 1.\n try {\n const { items } = await client.dataSources.listDataSources({ search: seedIdentifier, limit: DS_LIST_PAGE });\n const hit = items.find((x) => matchesManaged(x, seedIdentifier, geniappIdentifier));\n if (hit?.id != null) return String(hit.id);\n } catch {\n // Search unsupported on this API version — fall through to full paging.\n }\n\n // Fallback: page through the space's datasources in bounded windows. Stop as\n // soon as a page is short (last page) so we never over-fetch.\n for (let page = 1; page <= DS_LIST_MAX_PAGES; page += 1) {\n const { items } = await client.dataSources.listDataSources({ page, limit: DS_LIST_PAGE });\n const hit = items.find((x) => matchesManaged(x, seedIdentifier, geniappIdentifier));\n if (hit?.id != null) return String(hit.id);\n if (items.length < DS_LIST_PAGE) break;\n }\n return null;\n}\n\nexport function createGeniSpaceClient(apiRoot: string, accessToken: string | null): GeniSpace {\n const baseURL = apiRoot.replace(/\\/$/, '');\n const client = new GeniSpace({ baseURL, apiKey: accessToken || '' });\n if (accessToken) client.updateAccessToken(accessToken);\n return client;\n}\n\ntype DsQueryParams = Record<string, string | number | boolean | undefined>;\n\nfunction asNonNegativeInt(v: string | number | boolean | undefined): number | null {\n if (typeof v === 'boolean' || v === undefined) return null;\n const n = typeof v === 'number' ? v : Number(String(v).trim());\n return Number.isInteger(n) && n >= 0 ? n : null;\n}\n\nfunction rowsOf(payload: { data?: unknown[] | null }): Record<string, unknown>[] {\n return (payload.data || []).filter((r): r is Record<string, unknown> => r != null && typeof r === 'object');\n}\n\n/** Mirrors the API's default page size when the request carries no `limit`. */\nconst API_DEFAULT_LIMIT = 20;\n\n/**\n * Run one READ query with pagination expressed in a way EVERY API version\n * honors.\n *\n * Why this exists: `GET /datasources/:id/data` derives the `{{offset}}` SQL\n * binding from `(page - 1) * limit` and OVERWRITES any `offset` sent as a plain\n * query param (see api datasource.service `getDataSourceData`). So a bare\n * `{ limit, offset }` GET silently pins `{{offset}}` to 0 — page turns fetch\n * the same first page. Newer API branches may honor the `offset` param\n * directly, so every request here keeps `page`, `limit` and `offset` mutually\n * consistent (`offset === (page - 1) * limit`); both interpretations then\n * yield the same window.\n *\n * - `offset` aligned to `limit` → one request with the matching `page`.\n * - misaligned `offset` (e.g. ServerDataTable's `limit = pageSize + 1`,\n * `offset = pageIndex * pageSize`) → stitch the two aligned windows that\n * cover the requested range.\n */\nexport async function queryReadRowsPaged(\n gs: GeniSpace,\n datasourceId: string,\n params: DsQueryParams\n): Promise<Record<string, unknown>[]> {\n const { offset: rawOffset, ...rest } = params;\n const offset = asNonNegativeInt(rawOffset);\n\n // No usable offset (absent/0/non-numeric): page 1 on every API version.\n if (!offset) {\n return rowsOf(await gs.dataSources.queryDataSourceRead(datasourceId, params));\n }\n\n const limit = asNonNegativeInt(params.limit);\n const windowSize = limit && limit > 0 ? limit : API_DEFAULT_LIMIT;\n\n const fetchWindow = async (windowIndex: number): Promise<Record<string, unknown>[]> => {\n const windowOffset = windowIndex * windowSize;\n const payload = await gs.dataSources.queryDataSourceRead(datasourceId, {\n ...rest,\n page: windowIndex + 1,\n limit: windowSize,\n offset: windowOffset,\n });\n return rowsOf(payload);\n };\n\n // Aligned: the requested range IS one window.\n if (offset % windowSize === 0) {\n return fetchWindow(offset / windowSize);\n }\n\n // Misaligned: stitch the two adjacent aligned windows covering\n // [offset, offset + windowSize).\n const firstWindow = Math.floor(offset / windowSize);\n const skip = offset - firstWindow * windowSize;\n const head = (await fetchWindow(firstWindow)).slice(skip);\n // Only fetch the next window when the first was full (i.e. more rows may exist).\n if (head.length + skip < windowSize) return head;\n const tail = await fetchWindow(firstWindow + 1);\n return head.concat(tail.slice(0, windowSize - head.length));\n}\n\nexport async function queryManagedDatasourceRows(\n apiRoot: string,\n accessToken: string | null,\n geniappIdentifier: string,\n seedIdentifier: string,\n params: DsQueryParams = { limit: 50 }\n): Promise<Record<string, unknown>[]> {\n if (!apiRoot || !accessToken) return [];\n const gs = createGeniSpaceClient(apiRoot, accessToken);\n const id = await findManagedAppDataSourceId(gs, seedIdentifier, geniappIdentifier);\n if (!id) return [];\n return queryReadRowsPaged(gs, id, params);\n}\n\nconst DATASOURCE_PAGE_SIZE = 1000;\n\n/** Fetch all rows from a managed datasource, paginating at the API max limit (1000). */\nexport async function queryManagedDatasourceRowsAll(\n apiRoot: string,\n accessToken: string | null,\n geniappIdentifier: string,\n seedIdentifier: string,\n params: Record<string, string | number | boolean | undefined> = {}\n): Promise<Record<string, unknown>[]> {\n const all: Record<string, unknown>[] = [];\n let offset = 0;\n while (true) {\n const rows = await queryManagedDatasourceRows(apiRoot, accessToken, geniappIdentifier, seedIdentifier, {\n ...params,\n limit: DATASOURCE_PAGE_SIZE,\n offset,\n });\n all.push(...rows);\n if (rows.length < DATASOURCE_PAGE_SIZE) break;\n offset += DATASOURCE_PAGE_SIZE;\n }\n return all;\n}\n","import {\n createGeniSpaceClient,\n findManagedAppDataSourceId,\n} from './queryManagedDatasource';\n\n/** Result from POST /datasources/:id/data for TRANSACTION / CREATE / UPDATE operations. */\nexport type ManagedDatasourceOperationResult = {\n operationType?: string;\n affectedRows?: number;\n insertId?: number | string;\n executionTime?: number;\n statementCount?: number;\n [key: string]: unknown;\n};\n\nexport type ExecuteManagedDatasourceParams = Record<string, string | number | boolean | null | undefined>;\n\n/**\n * Execute a managed GeniApp datasource write operation (TRANSACTION, CREATE, UPDATE, etc.)\n * via POST /datasources/:id/data. For TRANSACTION datasources with JSON payloads, pass\n * `payload` as a JSON string (SQL uses `{{payload}}::jsonb`).\n */\nexport async function executeManagedDatasourceOperation(\n apiRoot: string,\n accessToken: string | null,\n geniappIdentifier: string,\n seedIdentifier: string,\n params: ExecuteManagedDatasourceParams\n): Promise<ManagedDatasourceOperationResult> {\n if (!apiRoot?.trim()) {\n throw new Error('API root is not configured.');\n }\n if (!accessToken?.trim()) {\n throw new Error('Authentication required to execute datasource operation.');\n }\n\n const gs = createGeniSpaceClient(apiRoot, accessToken);\n const id = await findManagedAppDataSourceId(gs, seedIdentifier, geniappIdentifier);\n if (!id) {\n throw new Error(`Managed datasource \"${seedIdentifier}\" is not installed for app \"${geniappIdentifier}\". Upgrade the application.`);\n }\n\n const body: Record<string, string | number | boolean> = {};\n for (const [k, v] of Object.entries(params)) {\n if (v === undefined || v === null) continue;\n body[k] = v;\n }\n\n const baseURL = apiRoot.replace(/\\/$/, '');\n const res = await fetch(`${baseURL}/datasources/${encodeURIComponent(id)}/data`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify(body),\n });\n\n const text = await res.text();\n let parsed: { success?: boolean; data?: ManagedDatasourceOperationResult; message?: string } = {};\n if (text) {\n try {\n parsed = JSON.parse(text) as typeof parsed;\n } catch {\n throw new Error(text || `Datasource operation failed (${res.status})`);\n }\n }\n\n if (!res.ok) {\n const msg = parsed.message || text || `Datasource operation failed (${res.status})`;\n throw new Error(msg);\n }\n\n return parsed.data ?? {};\n}\n\n/** Convenience wrapper for TRANSACTION datasources that accept a single JSON payload parameter. */\nexport async function executeManagedDatasourceTransaction(\n apiRoot: string,\n accessToken: string | null,\n geniappIdentifier: string,\n seedIdentifier: string,\n payload: unknown,\n payloadParamName = 'payload'\n): Promise<ManagedDatasourceOperationResult> {\n return executeManagedDatasourceOperation(apiRoot, accessToken, geniappIdentifier, seedIdentifier, {\n [payloadParamName]: JSON.stringify(payload),\n });\n}\n\nexport type TransactionDatasourceClient = (\n seedIdentifier: string,\n payload: unknown\n) => Promise<ManagedDatasourceOperationResult>;\n\n/** Factory for per-app transaction executors. */\nexport function createTransactionDatasourceClient(\n geniappIdentifier: string,\n resolveApiRoot: () => string,\n resolveAccessToken: () => string | null = () => {\n try {\n return localStorage.getItem('token');\n } catch {\n return null;\n }\n }\n): TransactionDatasourceClient {\n return (seedIdentifier, payload) =>\n executeManagedDatasourceTransaction(\n resolveApiRoot(),\n resolveAccessToken(),\n geniappIdentifier,\n seedIdentifier,\n payload\n );\n}\n","export type EmittedEventEnvelope = {\n id: string;\n status: string;\n eventName: string;\n [k: string]: unknown;\n};\n\n/**\n * Emit a Space-level event from a GeniApp. The app's installed events.json must\n * declare the event; the payload is validated server-side against its schema.\n */\nexport async function emitManagedEvent(\n apiRoot: string,\n accessToken: string | null,\n geniappIdentifier: string,\n eventName: string,\n payload: Record<string, unknown>,\n opts?: { idempotencyKey?: string }\n): Promise<EmittedEventEnvelope> {\n if (!apiRoot?.trim()) {\n throw new Error('API root is not configured.');\n }\n if (!accessToken?.trim()) {\n throw new Error('Authentication required to emit event.');\n }\n\n const body: Record<string, unknown> = {\n appIdentifier: geniappIdentifier,\n event: eventName,\n payload,\n };\n if (opts?.idempotencyKey) {\n body.idempotencyKey = opts.idempotencyKey;\n }\n\n const baseURL = apiRoot.replace(/\\/$/, '');\n const res = await fetch(`${baseURL}/events/emit`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify(body),\n });\n\n const text = await res.text();\n let parsed: { success?: boolean; data?: EmittedEventEnvelope; message?: string } = {};\n if (text) {\n try {\n parsed = JSON.parse(text) as typeof parsed;\n } catch {\n throw new Error(text || `Event emit failed (${res.status})`);\n }\n }\n\n if (!res.ok) {\n const msg = parsed.message || text || `Event emit failed (${res.status})`;\n throw new Error(msg);\n }\n\n return parsed.data ?? ({} as EmittedEventEnvelope);\n}\n\nexport type ManagedEventClient = (\n eventName: string,\n payload: Record<string, unknown>,\n opts?: { idempotencyKey?: string }\n) => Promise<EmittedEventEnvelope>;\n\n/** Factory for per-app event emitters. */\nexport function createManagedEventClient(\n geniappIdentifier: string,\n resolveApiRoot: () => string,\n resolveAccessToken: () => string | null = () => {\n try {\n return localStorage.getItem('token');\n } catch {\n return null;\n }\n }\n): ManagedEventClient {\n return (eventName, payload, opts) =>\n emitManagedEvent(\n resolveApiRoot(),\n resolveAccessToken(),\n geniappIdentifier,\n eventName,\n payload,\n opts\n );\n}\n","import { useTranslation } from 'react-i18next';\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@genispace/geniapp/kit';\n\nexport function DatasourceReadonlyTable({\n title,\n hint,\n rows,\n columns,\n emptyLabel,\n}: {\n title: string;\n hint?: string;\n rows: Record<string, unknown>[];\n columns: Array<{ key: string; label: string; format?: (v: unknown) => string }>;\n emptyLabel?: string;\n}) {\n const { t } = useTranslation();\n\n if (rows.length === 0) {\n return (\n <Card className=\"border-dashed\">\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm\">{title}</CardTitle>\n {hint ? <CardDescription>{hint}</CardDescription> : null}\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-muted-foreground\">\n {emptyLabel ?? t('datasourceInsight.empty', 'No rows from managed datasource (install GeniApp 1.0.1+).')}\n </p>\n </CardContent>\n </Card>\n );\n }\n\n return (\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm\">{title}</CardTitle>\n {hint ? <CardDescription>{hint}</CardDescription> : null}\n </CardHeader>\n <CardContent>\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n {columns.map((c) => (\n <TableHead key={c.key}>{c.label}</TableHead>\n ))}\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((row, i) => (\n <TableRow key={i}>\n {columns.map((c) => (\n <TableCell key={c.key}>\n {c.format ? c.format(row[c.key]) : String(row[c.key] ?? '—')}\n </TableCell>\n ))}\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n </CardContent>\n </Card>\n );\n}\n","import { useCallback, useEffect, useRef, useState, type ReactNode } from 'react';\nimport {\n Table,\n TableHeader,\n TableBody,\n TableRow,\n TableHead,\n TableCell,\n Button,\n Checkbox,\n useIsMobile,\n} from '@genispace/geniapp/kit';\n\nexport type SortDir = 'asc' | 'desc';\n\n/**\n * One column of a {@link ServerDataTable}. User-facing text is passed in by the\n * caller (i18n-agnostic). A column is sortable when `sortKey` is set; the table\n * then emits the server sort token `${sortKey}_${dir}` (e.g. `last_purchase_desc`),\n * which the datasource maps to a whitelisted `ORDER BY` via CASE.\n */\nexport interface ServerColumn<Row> {\n /** Stable column id (used for React keys). */\n key: string;\n /** Header content (already localized by the caller). */\n header: ReactNode;\n /** Server sort token base; presence makes the column sortable. */\n sortKey?: string;\n /** Cell renderer; defaults to the row's value at `key` stringified. */\n cell?: (row: Row) => ReactNode;\n className?: string;\n headClassName?: string;\n}\n\nexport interface ServerDataTableLabels {\n empty: string;\n error: string;\n retry: string;\n previous: string;\n next: string;\n /** Localized \"Page N\" label; receives the 1-based page number. */\n page: (page: number) => string;\n /** Accessible label for ascending sort toggle. */\n sortAscLabel?: string;\n /** Accessible label for descending sort toggle. */\n sortDescLabel?: string;\n /** Accessible label for the header \"select all on this page\" checkbox. */\n selectAllLabel?: string;\n /** Accessible label for a per-row select checkbox. */\n selectRowLabel?: string;\n}\n\nexport interface ServerDataTableProps<Row> {\n columns: ServerColumn<Row>[];\n /**\n * Fetch one page. Return up to `limit` rows; the table internally requests\n * `pageSize + 1` to detect \"has more\" without a COUNT query.\n */\n fetchRows: (args: { limit: number; offset: number; sort?: string }) => Promise<Row[]>;\n rowKey: (row: Row) => string;\n labels: ServerDataTableLabels;\n pageSize?: number;\n /**\n * When this value changes (e.g. the caller's search/filter state), pagination\n * resets to the first page. `fetchRows` should be memoized over the same deps.\n */\n resetKey?: unknown;\n initialSort?: { sortKey: string; dir: SortDir };\n onRowClick?: (row: Row) => void;\n emptyContent?: ReactNode;\n className?: string;\n /**\n * Enable a leading checkbox column for row selection. Off by default so every\n * existing usage is unchanged. When on, `selectedIds`/`onSelectionChange` make\n * the selection controlled by the caller (keyed by `rowKey`).\n */\n selectable?: boolean;\n /** Controlled set of selected row keys (only used when `selectable`). */\n selectedIds?: Set<string>;\n /** Called with the next selection whenever the user toggles a checkbox. */\n onSelectionChange?: (next: Set<string>) => void;\n /**\n * Mobile (H5) row renderer. When provided, the table falls back to a stacked\n * card list below the `sm` breakpoint instead of a horizontally-scrolling\n * `<table>` — the H5 pattern for entity lists (see 12-h5-mobile-design.md §2.3).\n * Receives the row; return the card body (the frame, tap target, selection\n * checkbox and pagination are supplied by the table). Desktop is unaffected.\n */\n mobileCard?: (row: Row) => ReactNode;\n}\n\n/** Stable empty selection so an uncontrolled (`selectable` off) table never reallocates. */\nconst EMPTY_SELECTION: Set<string> = new Set();\n\nfunction SortIndicator({ active, dir }: { active: boolean; dir: SortDir }) {\n return (\n <span aria-hidden className=\"ml-1 inline-flex text-[0.7em] leading-none text-muted-foreground\">\n {active ? (dir === 'asc' ? '▲' : '▼') : '↕'}\n </span>\n );\n}\n\n/**\n * Server-paginated, server-sorted data table for managed datasources. Renders one\n * bounded page at a time (default 50 rows) — no client-side load-all, no COUNT.\n * Generic over the row shape; all labels are injected for i18n.\n */\nexport function ServerDataTable<Row>({\n columns,\n fetchRows,\n rowKey,\n labels,\n pageSize = 50,\n resetKey,\n initialSort,\n onRowClick,\n emptyContent,\n className,\n selectable = false,\n selectedIds,\n onSelectionChange,\n mobileCard,\n}: ServerDataTableProps<Row>) {\n const isMobile = useIsMobile();\n const [pageIndex, setPageIndex] = useState(0);\n const [sort, setSort] = useState<{ sortKey: string; dir: SortDir } | null>(initialSort ?? null);\n const [rows, setRows] = useState<Row[]>([]);\n const [hasMore, setHasMore] = useState(false);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n const reqId = useRef(0);\n const sortToken = sort ? `${sort.sortKey}_${sort.dir}` : undefined;\n\n const runFetch = useCallback(async () => {\n const myId = ++reqId.current;\n setLoading(true);\n setError(null);\n try {\n const fetched = await fetchRows({ limit: pageSize + 1, offset: pageIndex * pageSize, sort: sortToken });\n if (myId !== reqId.current) return;\n setHasMore(fetched.length > pageSize);\n setRows(fetched.slice(0, pageSize));\n } catch (e) {\n if (myId !== reqId.current) return;\n setError(e instanceof Error ? e.message : String(e));\n setRows([]);\n setHasMore(false);\n } finally {\n if (myId === reqId.current) setLoading(false);\n }\n }, [fetchRows, pageSize, pageIndex, sortToken]);\n\n useEffect(() => {\n void runFetch();\n }, [runFetch]);\n\n // Reset to the first page whenever the caller's filter/search state changes.\n const firstRender = useRef(true);\n useEffect(() => {\n if (firstRender.current) {\n firstRender.current = false;\n return;\n }\n setPageIndex(0);\n }, [resetKey]);\n\n const toggleSort = useCallback((colSortKey: string) => {\n setPageIndex(0);\n setSort((prev) => {\n if (!prev || prev.sortKey !== colSortKey) return { sortKey: colSortKey, dir: 'asc' };\n if (prev.dir === 'asc') return { sortKey: colSortKey, dir: 'desc' };\n return null;\n });\n }, []);\n\n // Row selection (only active when `selectable`). Selection is controlled by the\n // caller; we derive page-level header state from the visible rows + rowKey.\n const selection = selectedIds ?? EMPTY_SELECTION;\n const pageKeys = rows.map((r) => rowKey(r));\n const selectedOnPage = pageKeys.filter((k) => selection.has(k)).length;\n const allPageSelected = pageKeys.length > 0 && selectedOnPage === pageKeys.length;\n const somePageSelected = selectedOnPage > 0 && !allPageSelected;\n\n const toggleRow = useCallback(\n (key: string) => {\n if (!onSelectionChange) return;\n const next = new Set(selection);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n onSelectionChange(next);\n },\n [onSelectionChange, selection]\n );\n\n const togglePage = useCallback(() => {\n if (!onSelectionChange) return;\n const next = new Set(selection);\n if (allPageSelected) {\n for (const k of pageKeys) next.delete(k);\n } else {\n for (const k of pageKeys) next.add(k);\n }\n onSelectionChange(next);\n }, [onSelectionChange, selection, allPageSelected, pageKeys]);\n\n // Shared inline states (identical in both table and card layouts).\n const loadingState =\n loading && rows.length === 0 ? (\n <div className=\"space-y-2 p-4\" aria-busy>\n <div className=\"h-8 animate-pulse rounded bg-muted\" />\n <div className=\"h-8 animate-pulse rounded bg-muted\" />\n <div className=\"h-8 animate-pulse rounded bg-muted\" />\n </div>\n ) : null;\n\n const errorState = error ? (\n <div className=\"flex flex-col items-center gap-2 p-8 text-center\">\n <p className=\"text-sm text-destructive\">{error}</p>\n <Button variant=\"outline\" size=\"sm\" onClick={() => void runFetch()}>\n {labels.retry}\n </Button>\n </div>\n ) : null;\n\n const emptyState =\n !loading && !error && rows.length === 0 ? (\n <div className=\"p-12 text-center text-sm text-muted-foreground\">{emptyContent ?? labels.empty}</div>\n ) : null;\n\n const pagination =\n (pageIndex > 0 || hasMore) && !error ? (\n <div className=\"mt-3 flex items-center justify-end gap-2\">\n <span className=\"text-sm text-muted-foreground\">{labels.page(pageIndex + 1)}</span>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={pageIndex === 0 || loading}\n onClick={() => setPageIndex((p) => Math.max(0, p - 1))}\n >\n {labels.previous}\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={!hasMore || loading}\n onClick={() => setPageIndex((p) => p + 1)}\n >\n {labels.next}\n </Button>\n </div>\n ) : null;\n\n // H5 card-list layout: one tappable card per row instead of a scrolling table.\n if (isMobile && mobileCard) {\n return (\n <div className={className}>\n {selectable && rows.length > 0 ? (\n <label className=\"mb-2 flex min-h-[44px] items-center gap-2 px-1 text-sm text-muted-foreground\">\n <Checkbox\n checked={allPageSelected ? true : somePageSelected ? 'indeterminate' : false}\n onCheckedChange={togglePage}\n aria-label={labels.selectAllLabel}\n />\n {labels.selectAllLabel}\n </label>\n ) : null}\n\n <div className=\"space-y-2\">\n {rows.map((row) => {\n const key = rowKey(row);\n const interactive = Boolean(onRowClick);\n return (\n <div\n key={key}\n className={`flex items-start gap-3 rounded-xl border border-border bg-card p-3 text-card-foreground shadow-sm${\n interactive ? ' cursor-pointer transition-colors active:bg-accent/40' : ''\n }`}\n onClick={interactive ? () => onRowClick?.(row) : undefined}\n >\n {selectable ? (\n <div className=\"pt-0.5\" onClick={(e) => e.stopPropagation()}>\n <Checkbox\n checked={selection.has(key)}\n onCheckedChange={() => toggleRow(key)}\n aria-label={labels.selectRowLabel}\n />\n </div>\n ) : null}\n <div className=\"min-w-0 flex-1\">{mobileCard(row)}</div>\n </div>\n );\n })}\n </div>\n\n {loadingState}\n {errorState}\n {emptyState}\n {pagination}\n </div>\n );\n }\n\n return (\n <div className={className}>\n <div className=\"overflow-x-auto rounded-xl border border-border bg-card shadow-sm\">\n <Table>\n <TableHeader>\n <TableRow>\n {selectable ? (\n <TableHead className=\"w-10\">\n <Checkbox\n checked={allPageSelected ? true : somePageSelected ? 'indeterminate' : false}\n onCheckedChange={togglePage}\n disabled={rows.length === 0}\n aria-label={labels.selectAllLabel}\n />\n </TableHead>\n ) : null}\n {columns.map((c) => {\n const sortable = Boolean(c.sortKey);\n const active = sortable && sort?.sortKey === c.sortKey;\n return (\n <TableHead key={c.key} className={c.headClassName}>\n {sortable ? (\n <button\n type=\"button\"\n className=\"inline-flex items-center font-medium hover:text-foreground\"\n onClick={() => toggleSort(c.sortKey as string)}\n aria-label={\n active && sort?.dir === 'asc' ? labels.sortDescLabel : labels.sortAscLabel\n }\n >\n {c.header}\n <SortIndicator active={Boolean(active)} dir={active ? (sort as { dir: SortDir }).dir : 'asc'} />\n </button>\n ) : (\n c.header\n )}\n </TableHead>\n );\n })}\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((row) => {\n const key = rowKey(row);\n return (\n <TableRow\n key={key}\n className={onRowClick ? 'cursor-pointer' : undefined}\n onClick={onRowClick ? () => onRowClick(row) : undefined}\n >\n {selectable ? (\n <TableCell\n className=\"w-10\"\n onClick={(e) => e.stopPropagation()}\n >\n <Checkbox\n checked={selection.has(key)}\n onCheckedChange={() => toggleRow(key)}\n aria-label={labels.selectRowLabel}\n />\n </TableCell>\n ) : null}\n {columns.map((c) => (\n <TableCell key={c.key} className={c.className}>\n {c.cell ? c.cell(row) : String((row as Record<string, unknown>)[c.key] ?? '—')}\n </TableCell>\n ))}\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n\n {/* Inline states keep the header/pagination chrome stable. */}\n {loadingState}\n {errorState}\n {emptyState}\n </div>\n\n {pagination}\n </div>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n Button,\n Input,\n Popover,\n PopoverTrigger,\n PopoverContent,\n ScrollArea,\n} from '@genispace/geniapp/kit';\n\nexport interface AsyncOption {\n value: string;\n label: string;\n /** Optional secondary text (e.g. store of an associate). */\n hint?: string;\n}\n\nexport interface AsyncComboboxLabels {\n /** Shown on the trigger when nothing is selected. */\n placeholder: string;\n searchPlaceholder: string;\n empty: string;\n loadMore: string;\n clear: string;\n}\n\nexport interface AsyncComboboxProps {\n value: string | null;\n onChange: (value: string | null) => void;\n /**\n * Server-side search. Return up to `limit` options for the page; the combobox\n * requests `pageSize + 1` to detect \"has more\" without a COUNT.\n */\n loadOptions: (args: { search: string; limit: number; offset: number }) => Promise<AsyncOption[]>;\n /**\n * Resolve the label for the current `value` when it isn't in the loaded page\n * (e.g. a preselected id). Optional — falls back to showing the raw value.\n */\n resolveSelected?: (value: string) => Promise<AsyncOption | null>;\n labels: AsyncComboboxLabels;\n disabled?: boolean;\n allowClear?: boolean;\n pageSize?: number;\n triggerClassName?: string;\n contentClassName?: string;\n}\n\n/**\n * Searchable, paginated single-select bound to a server datasource. Replaces\n * \"load-all + client filter\" dropdowns; safe for very large option sets because\n * it only ever fetches one debounced page at a time. i18n-agnostic (labels in).\n */\nexport function AsyncCombobox({\n value,\n onChange,\n loadOptions,\n resolveSelected,\n labels,\n disabled,\n allowClear = true,\n pageSize = 20,\n triggerClassName,\n contentClassName,\n}: AsyncComboboxProps) {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [debounced, setDebounced] = useState('');\n const [options, setOptions] = useState<AsyncOption[]>([]);\n const [offset, setOffset] = useState(0);\n const [hasMore, setHasMore] = useState(false);\n const [loading, setLoading] = useState(false);\n const [selectedOption, setSelectedOption] = useState<AsyncOption | null>(null);\n\n const reqId = useRef(0);\n\n // Debounce the search input.\n useEffect(() => {\n const id = setTimeout(() => setDebounced(query.trim()), 300);\n return () => clearTimeout(id);\n }, [query]);\n\n const fetchPage = useCallback(\n async (search: string, nextOffset: number, append: boolean) => {\n const myId = ++reqId.current;\n setLoading(true);\n try {\n const fetched = await loadOptions({ search, limit: pageSize + 1, offset: nextOffset });\n if (myId !== reqId.current) return;\n const more = fetched.length > pageSize;\n const page = fetched.slice(0, pageSize);\n setHasMore(more);\n setOffset(nextOffset);\n setOptions((prev) => (append ? [...prev, ...page] : page));\n } catch {\n if (myId !== reqId.current) return;\n if (!append) setOptions([]);\n setHasMore(false);\n } finally {\n if (myId === reqId.current) setLoading(false);\n }\n },\n [loadOptions, pageSize]\n );\n\n // (Re)load from the first page when opened or when the debounced query changes.\n useEffect(() => {\n if (!open) return;\n void fetchPage(debounced, 0, false);\n }, [open, debounced, fetchPage]);\n\n // Resolve the label for a preselected value not present in the loaded page.\n useEffect(() => {\n if (!value) {\n setSelectedOption(null);\n return;\n }\n if (selectedOption?.value === value) return;\n const inOptions = options.find((o) => o.value === value);\n if (inOptions) {\n setSelectedOption(inOptions);\n return;\n }\n if (!resolveSelected) return;\n let cancelled = false;\n void resolveSelected(value).then((opt) => {\n if (!cancelled && opt) setSelectedOption(opt);\n });\n return () => {\n cancelled = true;\n };\n }, [value, options, resolveSelected, selectedOption]);\n\n const triggerLabel = selectedOption?.label ?? (value || labels.placeholder);\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n disabled={disabled}\n className={triggerClassName ?? 'min-w-[12rem] justify-between font-normal'}\n >\n <span className={selectedOption || value ? '' : 'text-muted-foreground'}>{triggerLabel}</span>\n <span aria-hidden className=\"ml-2 text-xs text-muted-foreground\">▾</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent className={contentClassName ?? 'w-[16rem] p-0'} align=\"start\">\n <div className=\"border-b border-border p-2\">\n <Input\n autoFocus\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={labels.searchPlaceholder}\n aria-label={labels.searchPlaceholder}\n />\n </div>\n <ScrollArea className=\"max-h-64\">\n <div className=\"p-1\">\n {allowClear && value ? (\n <button\n type=\"button\"\n className=\"block w-full rounded px-2 py-1.5 text-left text-sm text-muted-foreground hover:bg-accent\"\n onClick={() => {\n onChange(null);\n setSelectedOption(null);\n setOpen(false);\n }}\n >\n {labels.clear}\n </button>\n ) : null}\n\n {options.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n className={`block w-full rounded px-2 py-1.5 text-left text-sm hover:bg-accent ${\n opt.value === value ? 'bg-accent font-medium' : ''\n }`}\n onClick={() => {\n onChange(opt.value);\n setSelectedOption(opt);\n setOpen(false);\n }}\n >\n <span>{opt.label}</span>\n {opt.hint ? <span className=\"ml-2 text-xs text-muted-foreground\">{opt.hint}</span> : null}\n </button>\n ))}\n\n {!loading && options.length === 0 ? (\n <p className=\"px-2 py-6 text-center text-sm text-muted-foreground\">{labels.empty}</p>\n ) : null}\n\n {loading ? (\n <div className=\"space-y-1 p-1\" aria-busy>\n <div className=\"h-7 animate-pulse rounded bg-muted\" />\n <div className=\"h-7 animate-pulse rounded bg-muted\" />\n </div>\n ) : null}\n\n {hasMore && !loading ? (\n <button\n type=\"button\"\n className=\"mt-1 block w-full rounded px-2 py-1.5 text-center text-sm text-primary hover:bg-accent\"\n onClick={() => void fetchPage(debounced, offset + pageSize, true)}\n >\n {labels.loadMore}\n </button>\n ) : null}\n </div>\n </ScrollArea>\n </PopoverContent>\n </Popover>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface UseInfiniteRowsResult<Row> {\n rows: Row[];\n loading: boolean;\n hasMore: boolean;\n error: string | null;\n /** Manually request the next page. */\n loadMore: () => void;\n /** Clear + reload from offset 0. */\n reset: () => void;\n /** Attach to a sentinel element at the list tail; auto-loads on intersect. */\n sentinelRef: (el: HTMLElement | null) => void;\n}\n\n/**\n * Accumulating infinite-scroll over a paginated fetcher. `fetchPage` returns up\n * to `limit` rows; when fewer than `limit` come back, there is no more data.\n * Pass a `resetKey` that changes when the query identity changes (e.g. a new\n * entity id or filter) to clear and reload from the top.\n */\nexport function useInfiniteRows<Row>(\n fetchPage: (args: { limit: number; offset: number }) => Promise<Row[]>,\n opts?: { pageSize?: number; resetKey?: unknown }\n): UseInfiniteRowsResult<Row> {\n const pageSize = opts?.pageSize ?? 20;\n const resetKey = opts?.resetKey;\n\n const [rows, setRows] = useState<Row[]>([]);\n const [loading, setLoading] = useState(false);\n const [hasMore, setHasMore] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n const offsetRef = useRef(0);\n const loadingRef = useRef(false);\n const hasMoreRef = useRef(true);\n const fetchRef = useRef(fetchPage);\n fetchRef.current = fetchPage;\n const observerRef = useRef<IntersectionObserver | null>(null);\n\n const loadMore = useCallback(async () => {\n if (loadingRef.current || !hasMoreRef.current) return;\n loadingRef.current = true;\n setLoading(true);\n setError(null);\n const offset = offsetRef.current;\n try {\n const batch = await fetchRef.current({ limit: pageSize, offset });\n const got = Array.isArray(batch) ? batch : [];\n setRows((prev) => (offset === 0 ? got : [...prev, ...got]));\n offsetRef.current = offset + got.length;\n const more = got.length === pageSize;\n hasMoreRef.current = more;\n setHasMore(more);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n hasMoreRef.current = false;\n setHasMore(false);\n } finally {\n loadingRef.current = false;\n setLoading(false);\n }\n }, [pageSize]);\n\n const reset = useCallback(() => {\n offsetRef.current = 0;\n hasMoreRef.current = true;\n loadingRef.current = false;\n setRows([]);\n setHasMore(true);\n setError(null);\n void loadMore();\n }, [loadMore]);\n\n // Reload whenever the query identity changes.\n useEffect(() => {\n reset();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [resetKey]);\n\n const sentinelRef = useCallback(\n (el: HTMLElement | null) => {\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n if (!el) return;\n observerRef.current = new IntersectionObserver(\n (entries) => {\n if (entries.some((en) => en.isIntersecting) && hasMoreRef.current && !loadingRef.current) {\n void loadMore();\n }\n },\n { rootMargin: '200px' }\n );\n observerRef.current.observe(el);\n },\n [loadMore]\n );\n\n useEffect(() => () => observerRef.current?.disconnect(), []);\n\n return { rows, loading, hasMore, error, loadMore, reset, sentinelRef };\n}\n","import type { ComponentType, ReactNode } from 'react';\n\nexport interface TimelineProps {\n children: ReactNode;\n className?: string;\n}\n\n/** Vertical activity timeline rail. Wrap a list of <TimelineItem>. */\nexport function Timeline({ children, className }: TimelineProps) {\n return <ol className={`relative flex flex-col gap-12 ${className ?? ''}`}>{children}</ol>;\n}\n\nexport interface TimelineItemProps {\n /** Lucide icon for the node chip. */\n icon?: ComponentType<{ className?: string }>;\n /** Tailwind text-color class for the icon (e.g. \"text-emerald-600\"). */\n dotClassName?: string;\n /** Tailwind background tint for the node chip (e.g. \"bg-emerald-500/10\"). Defaults to muted. */\n nodeClassName?: string;\n /** Tailwind left-border accent class for the event card (e.g. \"border-l-emerald-500\"). */\n accentClassName?: string;\n title: ReactNode;\n /** Right-aligned timestamp / relative time. */\n time?: ReactNode;\n /** Secondary meta line (channel, store, SA…). */\n meta?: ReactNode;\n /** Rich body (badges, amount, content). */\n children?: ReactNode;\n /** Hide the connector below the node (last item). */\n isLast?: boolean;\n}\n\n/**\n * One node on the vertical timeline: a filled, ringed icon chip on the rail (left)\n * and a styled event card (right) with an accent edge. Newest-first ordering is\n * the caller's job; pass node/accent classes per event type for distinct styling.\n */\nexport function TimelineItem({\n icon: Icon,\n dotClassName = 'text-foreground',\n nodeClassName = 'bg-muted',\n accentClassName = 'border-l-border',\n title,\n time,\n meta,\n children,\n isLast,\n}: TimelineItemProps) {\n return (\n <li className=\"relative flex items-start gap-5\">\n {/* rail + node — self-stretch so the connector only spans this row, not the inter-row gap */}\n <div className=\"relative flex w-9 shrink-0 flex-col items-center self-stretch\">\n <span\n className={`z-10 flex h-9 w-9 shrink-0 items-center justify-center rounded-full ring-4 ring-background ${nodeClassName} ${dotClassName}`}\n >\n {Icon ? <Icon className=\"h-4 w-4\" /> : <span className=\"h-2 w-2 rounded-full bg-current\" />}\n </span>\n {!isLast ? (\n <span\n className=\"mt-3 w-px flex-1 min-h-[1.5rem] bg-gradient-to-b from-border to-transparent\"\n aria-hidden\n />\n ) : null}\n </div>\n {/* event card */}\n <div\n className={`min-w-0 flex-1 space-y-3 rounded-xl border border-l-2 border-border bg-card px-4 py-4 shadow-sm transition-shadow hover:shadow-md ${accentClassName}`}\n >\n <div className=\"flex items-start justify-between gap-4\">\n <p className=\"text-sm font-semibold leading-normal text-foreground\">{title}</p>\n {time ? (\n <span className=\"shrink-0 text-xs leading-5 tabular-nums text-muted-foreground\">{time}</span>\n ) : null}\n </div>\n {meta ? <p className=\"text-xs leading-relaxed text-muted-foreground\">{meta}</p> : null}\n {children ? <div className=\"pt-1\">{children}</div> : null}\n </div>\n </li>\n );\n}\n","import { useCallback, useEffect, useRef, useState, type ReactNode } from 'react';\n\n/**\n * Resolves opaque entity ids (e.g. `cust_123`) to human-readable names in batch,\n * with an internal cache so a given id is fetched at most once. Pair it with\n * {@link EntityRef} to render references as \"name\" instead of raw ids.\n *\n * The `resolver` receives the de-duplicated set of ids that aren't cached yet and\n * returns a `{ id: name }` map; ids missing from the map are remembered as\n * \"resolved to nothing\" so they aren't retried on every render.\n */\nexport interface UseEntityNamesResult {\n /** Cached display name for `id`, or `undefined` until resolved (or if unknown). */\n resolve: (id: string) => string | undefined;\n /** Queue ids for resolution; already-cached/in-flight ids are skipped. */\n ensure: (ids: ReadonlyArray<string>) => void;\n /** True while at least one batch is in flight. */\n loading: boolean;\n}\n\nexport function useEntityNames(\n resolver: (ids: string[]) => Promise<Record<string, string>>\n): UseEntityNamesResult {\n // `version` bumps to force a re-render when the cache mutates; the cache and the\n // in-flight set live in refs so they survive renders without being deps.\n const cache = useRef<Map<string, string | undefined>>(new Map());\n const inFlight = useRef<Set<string>>(new Set());\n const pending = useRef<Set<string>>(new Set());\n const flushHandle = useRef<ReturnType<typeof setTimeout> | null>(null);\n const [, setVersion] = useState(0);\n const [loadingCount, setLoadingCount] = useState(0);\n\n // Keep the latest resolver without making `ensure` change identity each render.\n const resolverRef = useRef(resolver);\n resolverRef.current = resolver;\n\n const flush = useCallback(async () => {\n flushHandle.current = null;\n const batch = Array.from(pending.current);\n pending.current.clear();\n if (batch.length === 0) return;\n\n batch.forEach((id) => inFlight.current.add(id));\n setLoadingCount((c) => c + 1);\n try {\n const map = await resolverRef.current(batch);\n // Record every requested id — even ones absent from the result — so unknown\n // ids resolve to `undefined` permanently instead of refetching forever.\n batch.forEach((id) => cache.current.set(id, map[id]));\n } catch {\n // On failure, drop the ids from the cache so a later ensure() can retry.\n batch.forEach((id) => cache.current.delete(id));\n } finally {\n batch.forEach((id) => inFlight.current.delete(id));\n setLoadingCount((c) => Math.max(0, c - 1));\n setVersion((v) => v + 1);\n }\n }, []);\n\n const ensure = useCallback(\n (ids: ReadonlyArray<string>) => {\n let added = false;\n for (const id of ids) {\n if (!id) continue;\n if (cache.current.has(id) || inFlight.current.has(id) || pending.current.has(id)) continue;\n pending.current.add(id);\n added = true;\n }\n if (!added) return;\n // Batch synchronous bursts of ensure() into one resolver call.\n if (flushHandle.current === null) {\n flushHandle.current = setTimeout(() => void flush(), 0);\n }\n },\n [flush]\n );\n\n useEffect(() => {\n return () => {\n if (flushHandle.current !== null) clearTimeout(flushHandle.current);\n };\n }, []);\n\n const resolve = useCallback((id: string): string | undefined => cache.current.get(id), []);\n\n return { resolve, ensure, loading: loadingCount > 0 };\n}\n\nexport interface EntityRefProps {\n /** The raw entity id being referenced. */\n value: string;\n /** Resolved display name; when undefined the ref renders a muted `value`. */\n name?: string;\n /** Render as a link to this href (takes precedence over `onClick`). */\n href?: string;\n /** Render as a button invoking this handler when there is no `href`. */\n onClick?: () => void;\n /** Shown when `name` is undefined, before falling back to `value`. */\n fallback?: ReactNode;\n className?: string;\n}\n\n/**\n * Renders an entity reference as its display name (with an optional link/button),\n * falling back to a muted raw id while the name is unresolved. i18n-agnostic:\n * the caller supplies `name`/`fallback`; only layout symbols are hardcoded.\n */\nexport function EntityRef({ value, name, href, onClick, fallback, className }: EntityRefProps) {\n const resolved = name !== undefined;\n const content: ReactNode = resolved ? name : (fallback ?? value);\n const baseClass = resolved ? '' : 'text-muted-foreground';\n const merged = className ? `${baseClass} ${className}`.trim() : baseClass || undefined;\n\n if (href) {\n return (\n <a\n href={href}\n onClick={onClick}\n className={\n merged ? `${merged} underline-offset-2 hover:underline` : 'underline-offset-2 hover:underline'\n }\n >\n {content}\n </a>\n );\n }\n\n if (onClick) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={\n merged\n ? `${merged} underline-offset-2 hover:underline`\n : 'underline-offset-2 hover:underline'\n }\n >\n {content}\n </button>\n );\n }\n\n return <span className={merged}>{content}</span>;\n}\n","import { type ReactNode } from 'react';\nimport { Button, type ButtonProps } from '@genispace/geniapp/kit';\n\n/** One action button rendered in a {@link BulkActionBar}. */\nexport interface BulkAction {\n /** Stable id (used for React keys). */\n key: string;\n /** Button content (already localized by the caller). */\n label: ReactNode;\n onClick: () => void;\n /** Button visual variant; forwarded to the kit `Button`. */\n variant?: ButtonProps['variant'];\n disabled?: boolean;\n}\n\nexport interface BulkActionBarLabels {\n /** Localized \"N selected\" label; receives the current selected count. */\n selected: (n: number) => string;\n /** Localized \"select all M matching\" affordance; receives the total match count. */\n selectAllMatching?: (m: number) => string;\n /** Localized \"clear selection\" label. */\n clear: string;\n}\n\nexport interface BulkActionBarProps {\n /** Number of currently selected rows. */\n selectedCount: number;\n /** Total rows matching the active filter (across all pages), if known. */\n totalMatching?: number;\n /** Whether every matching row (not just the visible page) is already selected. */\n allMatchingSelected?: boolean;\n /** Promote the current page selection to \"all M matching\". */\n onSelectAllMatching?: () => void;\n /** Clear the entire selection. */\n onClear: () => void;\n actions: BulkAction[];\n labels: BulkActionBarLabels;\n className?: string;\n}\n\n/**\n * Sticky toolbar surfaced when rows are selected. Shows the selected count, an\n * optional \"select all M matching\" affordance (for selecting beyond the visible\n * page), the caller's bulk actions, and a clear control. Renders nothing when the\n * selection is empty. i18n-agnostic — all text comes from `labels`/`actions`.\n */\nexport function BulkActionBar({\n selectedCount,\n totalMatching,\n allMatchingSelected,\n onSelectAllMatching,\n onClear,\n actions,\n labels,\n className,\n}: BulkActionBarProps) {\n if (selectedCount <= 0) return null;\n\n // Offer \"select all matching\" only when there are more matches than selected,\n // the caller wired up a handler, and a localized label is available.\n const canSelectAllMatching =\n !allMatchingSelected &&\n Boolean(onSelectAllMatching) &&\n Boolean(labels.selectAllMatching) &&\n typeof totalMatching === 'number' &&\n totalMatching > selectedCount;\n\n return (\n <div\n className={\n className ??\n 'sticky bottom-0 z-10 flex flex-wrap items-center gap-x-3 gap-y-2 rounded-xl border border-border bg-background/95 px-4 py-2.5 shadow-md backdrop-blur supports-[backdrop-filter]:bg-background/80'\n }\n role=\"toolbar\"\n >\n <span className=\"text-sm font-medium\">{labels.selected(selectedCount)}</span>\n\n {canSelectAllMatching ? (\n <Button variant=\"link\" size=\"sm\" className=\"h-auto px-0\" onClick={onSelectAllMatching}>\n {(labels.selectAllMatching as (m: number) => string)(totalMatching as number)}\n </Button>\n ) : null}\n\n <div className=\"ml-auto flex flex-wrap items-center gap-2\">\n {actions.map((action) => (\n <Button\n key={action.key}\n variant={action.variant ?? 'outline'}\n size=\"sm\"\n disabled={action.disabled}\n onClick={action.onClick}\n >\n {action.label}\n </Button>\n ))}\n <Button variant=\"ghost\" size=\"sm\" onClick={onClear}>\n {labels.clear}\n </Button>\n </div>\n </div>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { Check, Circle, Loader2 } from 'lucide-react';\nimport { Button } from '@genispace/geniapp/kit';\n\n/**\n * Async agent-invoke progress UX v1.\n *\n * `useAgentJobRunner` drives a background AGENT_INVOKE job (SDK\n * `agents.invokeAsync`) through an explicit state machine and exposes a live\n * elapsed ticker + server phase; `AgentJobProgressInline` renders it as a\n * rounded card in the same visual family as AiDraftBanner. Both are\n * i18n-agnostic — every user-facing string comes in via label props with\n * sensible English defaults; apps pass t() values.\n */\n\nexport type AgentRunState = 'idle' | 'starting' | 'running' | 'succeeded' | 'failed' | 'cancelled';\n\n/** Structural subset of the SDK AgentJob DTO the runner needs. */\nexport interface AgentJobLike {\n id: string;\n status?: string;\n phase?: string | null;\n cancelRequested?: boolean;\n createdAt?: string;\n error?: string | null;\n}\n\n/** Context handed to the task function passed to {@link UseAgentJobRunnerResult.start}. */\nexport interface AgentTaskContext {\n /** Thread as BOTH `onCreated` and `onProgress` of `agents.invokeAsync`. */\n onJob: (job: AgentJobLike) => void;\n /** Report an app-level retry (e.g. schema-invalid re-invoke): call with 2, 3, ... */\n onAttempt: (n: number) => void;\n /** Thread as `invokeAsync({ signal })`; aborted automatically on unmount. */\n signal: AbortSignal;\n}\n\nexport interface AgentJobStartOptions {\n /**\n * Cooperative server-side cancel, e.g. `(id) => client.agentJobs.cancel(id)`.\n * Called by {@link UseAgentJobRunnerResult.cancel} once a job id is known;\n * without it (or before a job exists) cancel falls back to aborting the\n * polling signal locally.\n */\n cancel?: (jobId: string) => Promise<unknown> | unknown;\n}\n\nexport interface UseAgentJobRunnerResult {\n state: AgentRunState;\n /** Latest server phase ('resolve' | 'invoke' | 'finalize' | ...), null before the first snapshot. */\n phase: string | null;\n /** Wall-clock since job.createdAt (when parseable) or the local start; ticks every second. */\n elapsedMs: number;\n /** Latest observed job snapshot (null until the 202 create lands). */\n job: AgentJobLike | null;\n /** Raw error message of a failed run (apps usually map their typed errors instead). */\n error: string | null;\n /** Current attempt number (1-based); >1 after noteAttempt/onAttempt. */\n attempt: number;\n /** True once cancel() was called or the server echoed job.cancelRequested. */\n cancelRequested: boolean;\n /**\n * Run `task`. Resolves with the task result on success, resolves `null` when\n * the run was cancelled/superseded, and REJECTS with the task's error on\n * failure (after moving the state machine to 'failed') so callers keep their\n * typed-error handling. No-op (resolves null) while a run is in flight.\n */\n start: <T>(task: (ctx: AgentTaskContext) => Promise<T>, opts?: AgentJobStartOptions) => Promise<T | null>;\n /** Request cooperative cancellation of the in-flight run. */\n cancel: () => void;\n /** Back to 'idle', invalidating any in-flight run (its late updates are dropped). */\n reset: () => void;\n /** Feed a job snapshot into the runner (what the task ctx.onJob does). */\n observe: (job: AgentJobLike) => void;\n /** Mark an app-level retry attempt (what the task ctx.onAttempt does). */\n noteAttempt: (n: number) => void;\n}\n\n/**\n * State machine + 1s elapsed ticker for one background agent invoke at a time.\n * Stale updates from a superseded run are dropped via a monotonic run-id guard\n * (mirrors JobProgress.tsx); the AbortController wired into the task signal is\n * aborted on unmount so polling never outlives the component — the job itself\n * keeps running server-side unless cancel() reached the platform.\n */\nexport function useAgentJobRunner(): UseAgentJobRunnerResult {\n const [state, setState] = useState<AgentRunState>('idle');\n const [phase, setPhase] = useState<string | null>(null);\n const [elapsedMs, setElapsedMs] = useState(0);\n const [job, setJob] = useState<AgentJobLike | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [attempt, setAttempt] = useState(1);\n const [cancelRequested, setCancelRequested] = useState(false);\n\n const runId = useRef(0);\n const runningRef = useRef(false);\n const abortRef = useRef<AbortController | null>(null);\n const jobRef = useRef<AgentJobLike | null>(null);\n const cancelFnRef = useRef<AgentJobStartOptions['cancel']>(undefined);\n const cancelRequestedRef = useRef(false);\n /** Elapsed baseline: job.createdAt when parseable, else the local start. */\n const baselineRef = useRef<number | null>(null);\n\n // Abort in-flight polling when the component unmounts.\n useEffect(() => {\n return () => {\n runId.current += 1;\n abortRef.current?.abort();\n };\n }, []);\n\n // 1s ticker while a run is active.\n const ticking = state === 'starting' || state === 'running';\n useEffect(() => {\n if (!ticking) return;\n const tick = () => {\n const base = baselineRef.current;\n if (base != null) setElapsedMs(Math.max(0, Date.now() - base));\n };\n tick();\n const timer = setInterval(tick, 1000);\n return () => clearInterval(timer);\n }, [ticking]);\n\n const observe = useCallback((snapshot: AgentJobLike) => {\n if (!runningRef.current) return;\n jobRef.current = snapshot;\n setJob(snapshot);\n setState((s) => (s === 'starting' ? 'running' : s));\n setPhase(snapshot.phase ?? null);\n if (snapshot.cancelRequested) setCancelRequested(true);\n if (snapshot.createdAt) {\n const created = Date.parse(snapshot.createdAt);\n // Guard against clock skew: never move the baseline into the future.\n if (Number.isFinite(created) && baselineRef.current != null && created < baselineRef.current) {\n baselineRef.current = created;\n }\n }\n }, []);\n\n const noteAttempt = useCallback((n: number) => {\n if (!runningRef.current) return;\n setAttempt(n);\n }, []);\n\n const start = useCallback(\n async <T,>(task: (ctx: AgentTaskContext) => Promise<T>, opts?: AgentJobStartOptions): Promise<T | null> => {\n if (runningRef.current) return null;\n const myId = ++runId.current;\n runningRef.current = true;\n cancelRequestedRef.current = false;\n cancelFnRef.current = opts?.cancel;\n jobRef.current = null;\n baselineRef.current = Date.now();\n const controller = new AbortController();\n abortRef.current = controller;\n\n setState('starting');\n setPhase(null);\n setElapsedMs(0);\n setJob(null);\n setError(null);\n setAttempt(1);\n setCancelRequested(false);\n\n const guard = <A extends unknown[]>(fn: (...args: A) => void) => (...args: A) => {\n if (myId === runId.current) fn(...args);\n };\n\n try {\n const result = await task({\n onJob: guard(observe),\n onAttempt: guard(noteAttempt),\n signal: controller.signal,\n });\n if (myId !== runId.current) return null;\n setState('succeeded');\n return result;\n } catch (e) {\n if (myId !== runId.current) return null;\n const aborted =\n cancelRequestedRef.current ||\n controller.signal.aborted ||\n (e instanceof Error && e.name === 'AbortError');\n if (aborted) {\n setState('cancelled');\n return null;\n }\n setState('failed');\n setError(e instanceof Error ? e.message : String(e));\n throw e;\n } finally {\n if (myId === runId.current) runningRef.current = false;\n }\n },\n [observe, noteAttempt]\n );\n\n const cancel = useCallback(() => {\n if (!runningRef.current || cancelRequestedRef.current) return;\n cancelRequestedRef.current = true;\n setCancelRequested(true);\n const jobId = jobRef.current?.id;\n const fn = cancelFnRef.current;\n if (jobId && fn) {\n // Cooperative: keep polling so the UI can show \"cancelling…\" until the\n // server flips the job to CANCELLED. Fall back to a local abort when the\n // cancel endpoint is unreachable (older platforms).\n Promise.resolve()\n .then(() => fn(jobId))\n .catch(() => abortRef.current?.abort());\n } else {\n abortRef.current?.abort();\n }\n }, []);\n\n const reset = useCallback(() => {\n runId.current += 1;\n runningRef.current = false;\n abortRef.current?.abort();\n abortRef.current = null;\n jobRef.current = null;\n baselineRef.current = null;\n cancelRequestedRef.current = false;\n setState('idle');\n setPhase(null);\n setElapsedMs(0);\n setJob(null);\n setError(null);\n setAttempt(1);\n setCancelRequested(false);\n }, []);\n\n return { state, phase, elapsedMs, job, error, attempt, cancelRequested, start, cancel, reset, observe, noteAttempt };\n}\n\nexport interface AgentJobProgressLabels {\n /** Primary action line, e.g. \"AI is generating the draft\". */\n title?: string;\n /** \"Elapsed Xs\" fragment appended to the title. */\n elapsed?: (seconds: number) => string;\n /** Expected-duration fragment after the elapsed one, e.g. \" (usually ~30s)\". */\n expectedNote?: string;\n /** Swapped in for expectedNote once elapsed exceeds 1.5x expectedSeconds. */\n slow?: string;\n /** Step-list labels (server phases queued -> resolve -> invoke -> finalize). */\n queued?: string;\n resolve?: string;\n invoke?: string;\n finalize?: string;\n /** Notice line shown when attempt > 1 (app-level schema retry). */\n retryNotice?: string;\n cancel?: string;\n cancelling?: string;\n /** Fallback failed line when no `error` prop is passed. */\n failed?: string;\n retry?: string;\n cancelled?: string;\n}\n\nconst DEFAULT_LABELS: Required<Pick<\n AgentJobProgressLabels,\n 'title' | 'expectedNote' | 'slow' | 'queued' | 'resolve' | 'invoke' | 'finalize' | 'retryNotice' | 'cancel' | 'cancelling' | 'failed' | 'retry' | 'cancelled'\n>> & { elapsed: (seconds: number) => string } = {\n title: 'Working…',\n elapsed: (seconds: number) => `${seconds}s elapsed`,\n expectedNote: '',\n slow: 'Taking longer than usual — still working…',\n queued: 'Queued',\n resolve: 'Locating agent',\n invoke: 'Running',\n finalize: 'Finalizing',\n retryNotice: 'First result was invalid — retrying once…',\n cancel: 'Cancel',\n cancelling: 'Cancelling…',\n failed: 'The AI task failed.',\n retry: 'Retry',\n cancelled: 'Cancelled.',\n};\n\nconst STEP_KEYS = ['queued', 'resolve', 'invoke', 'finalize'] as const;\n\n/** Map runner state + server phase to the active step index. Unknown/missing phases count as 'invoke'. */\nfunction activeStepIndex(state: AgentRunState, phase: string | null | undefined): number {\n if (state === 'starting') return 0;\n if (phase === 'resolve') return 1;\n if (phase === 'finalize') return 3;\n return 2; // 'invoke', missing, or unknown\n}\n\nexport interface AgentJobProgressInlineProps {\n state: AgentRunState;\n phase?: string | null;\n elapsedMs: number;\n /** Typical duration; drives the slow-hint swap (elapsed > 1.5x expected). */\n expectedSeconds?: number;\n /** 1-based attempt count; >1 renders the retry notice line. */\n attempt?: number;\n /** True once cancellation was requested (button flips to a disabled \"cancelling\"). */\n cancelRequested?: boolean;\n /** Localized error text supplied by the app for the failed state. */\n error?: string | null;\n onCancel?: () => void;\n onRetry?: () => void;\n labels?: AgentJobProgressLabels;\n className?: string;\n}\n\n/**\n * Inline progress card for a background agent invoke — spinner + elapsed\n * primary line, queued→resolve→invoke→finalize step list, indeterminate pulse\n * bar and a cooperative cancel button while running; destructive line + retry\n * when failed; muted line + retry when cancelled; nothing when idle/succeeded.\n * Same visual family as AiDraftBanner (status-info tokens while running).\n */\nexport function AgentJobProgressInline({\n state,\n phase,\n elapsedMs,\n expectedSeconds,\n attempt = 1,\n cancelRequested = false,\n error,\n onCancel,\n onRetry,\n labels,\n className,\n}: AgentJobProgressInlineProps) {\n const l = { ...DEFAULT_LABELS, ...labels };\n\n if (state === 'idle' || state === 'succeeded') return null;\n\n if (state === 'failed') {\n return (\n <div role=\"alert\" className={`space-y-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 ${className ?? ''}`}>\n <p className=\"text-sm text-destructive\">{error || l.failed}</p>\n {onRetry ? (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={onRetry}>\n {l.retry}\n </Button>\n ) : null}\n </div>\n );\n }\n\n if (state === 'cancelled') {\n return (\n <div role=\"status\" className={`space-y-2 rounded-lg border border-border bg-muted/40 p-3 ${className ?? ''}`}>\n <p className=\"text-sm text-muted-foreground\">{l.cancelled}</p>\n {onRetry ? (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={onRetry}>\n {l.retry}\n </Button>\n ) : null}\n </div>\n );\n }\n\n // starting | running\n const seconds = Math.floor(elapsedMs / 1000);\n const slow = expectedSeconds != null && elapsedMs > expectedSeconds * 1500;\n const note = slow ? l.slow : l.expectedNote;\n const stepIdx = activeStepIndex(state, phase);\n\n return (\n <div\n role=\"status\"\n aria-busy\n className={`space-y-2.5 rounded-lg border border-status-info/40 bg-status-info/10 p-3 ${className ?? ''}`}\n >\n <div className=\"flex items-start gap-2.5\">\n <Loader2 className=\"mt-0.5 h-4 w-4 shrink-0 animate-spin text-status-info\" aria-hidden />\n <div className=\"min-w-0 flex-1 space-y-0.5\">\n <p className=\"text-sm font-medium text-foreground\">\n {l.title} · {l.elapsed(seconds)}\n {note ? <span className={slow ? 'text-status-warning' : 'text-muted-foreground'}>{note}</span> : null}\n </p>\n {attempt > 1 ? <p className=\"text-xs text-muted-foreground\">{l.retryNotice}</p> : null}\n </div>\n {onCancel ? (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={onCancel} disabled={cancelRequested}>\n {cancelRequested ? l.cancelling : l.cancel}\n </Button>\n ) : null}\n </div>\n\n <ul className=\"space-y-1 pl-[26px]\">\n {STEP_KEYS.map((key, i) => {\n const isDone = i < stepIdx;\n const isCurrent = i === stepIdx;\n return (\n <li\n key={key}\n className={`flex items-center gap-1.5 text-xs ${\n isCurrent ? 'font-medium text-foreground' : isDone ? 'text-muted-foreground' : 'text-muted-foreground/60'\n }`}\n >\n {isDone ? (\n <Check className=\"h-3 w-3 shrink-0 text-status-info\" aria-hidden />\n ) : isCurrent ? (\n <Loader2 className=\"h-3 w-3 shrink-0 animate-spin text-status-info\" aria-hidden />\n ) : (\n <Circle className=\"h-3 w-3 shrink-0 text-muted-foreground/45\" aria-hidden />\n )}\n {l[key]}\n </li>\n );\n })}\n </ul>\n\n <div className=\"ml-[26px] h-1 overflow-hidden rounded-full bg-status-info/20\">\n <div className=\"h-full w-full animate-pulse rounded-full bg-status-info/60\" />\n </div>\n </div>\n );\n}\n","import { useCallback, useRef, useState } from 'react';\nimport { Button, Progress } from '@genispace/geniapp/kit';\n\nexport type JobStatus = 'idle' | 'running' | 'done' | 'error';\n\n/** Progress snapshot reported by a running job. */\nexport interface JobProgressState {\n done: number;\n total: number;\n message?: string;\n}\n\n/** Terminal outcome of a job's `run` function. */\nexport interface JobResult {\n ok: boolean;\n /** Number of items that failed (for partial-success jobs). */\n failed?: number;\n /** Human-readable error (already localized by the caller, if any). */\n error?: string;\n}\n\n/** A job runner: invoked with a `report` callback to push progress updates. */\nexport type JobRunner = (\n report: (progress: JobProgressState) => void\n) => Promise<JobResult>;\n\nexport interface UseAsyncJobResult {\n status: JobStatus;\n progress: JobProgressState;\n result: JobResult | null;\n /** Begin (or restart) the job. No-op while already running. */\n start: () => void;\n /** Return to the idle state, clearing progress and result. */\n reset: () => void;\n}\n\nconst EMPTY_PROGRESS: JobProgressState = { done: 0, total: 0 };\n\n/**\n * Drives a long-running, optionally batched async job: calls `run`, threading a\n * `report` callback that updates the live progress, and captures the terminal\n * result or a thrown error. Stale reports/results from a superseded run (e.g.\n * after a retry) are ignored via a monotonic run-id guard.\n */\nexport function useAsyncJob({ run }: { run: JobRunner }): UseAsyncJobResult {\n const [status, setStatus] = useState<JobStatus>('idle');\n const [progress, setProgress] = useState<JobProgressState>(EMPTY_PROGRESS);\n const [result, setResult] = useState<JobResult | null>(null);\n\n const runId = useRef(0);\n const runningRef = useRef(false);\n\n // Keep the latest runner without making `start` change identity each render.\n const runRef = useRef(run);\n runRef.current = run;\n\n const start = useCallback(() => {\n if (runningRef.current) return;\n const myId = ++runId.current;\n runningRef.current = true;\n setStatus('running');\n setProgress(EMPTY_PROGRESS);\n setResult(null);\n\n const report = (p: JobProgressState) => {\n if (myId !== runId.current) return;\n setProgress({ done: p.done, total: p.total, message: p.message });\n };\n\n void (async () => {\n try {\n const res = await runRef.current(report);\n if (myId !== runId.current) return;\n setResult(res);\n setStatus(res.ok ? 'done' : 'error');\n } catch (e) {\n if (myId !== runId.current) return;\n const message = e instanceof Error ? e.message : String(e);\n setResult({ ok: false, error: message });\n setStatus('error');\n } finally {\n if (myId === runId.current) runningRef.current = false;\n }\n })();\n }, []);\n\n const reset = useCallback(() => {\n // Invalidate any in-flight run so its late reports/results are dropped.\n runId.current += 1;\n runningRef.current = false;\n setStatus('idle');\n setProgress(EMPTY_PROGRESS);\n setResult(null);\n }, []);\n\n return { status, progress, result, start, reset };\n}\n\nexport interface JobProgressLabels {\n /** Optional text shown in the idle state (before the job starts). */\n idle?: string;\n /** Localized \"X of Y\" running label; receives done and total counts. */\n running: (done: number, total: number) => string;\n /** Text shown when the job completes successfully. */\n done: string;\n /** Text shown when the job fails. */\n error: string;\n /** Retry button label. */\n retry: string;\n}\n\nexport interface JobProgressProps {\n /** The return value of {@link useAsyncJob}. */\n job: UseAsyncJobResult;\n labels: JobProgressLabels;\n /**\n * Invoked when the retry button is pressed. Defaults to `job.start`, so a plain\n * retry re-runs the same job; pass a custom handler to retry only failures.\n */\n onRetry?: () => void;\n className?: string;\n}\n\n/**\n * Displays the state of a {@link useAsyncJob}: a progress bar while running, a\n * status line, and a retry button on error. i18n-agnostic — every string is\n * supplied via `labels`; only the bar and layout are hardcoded.\n */\nexport function JobProgress({ job, labels, onRetry, className }: JobProgressProps) {\n const { status, progress, result } = job;\n const { done, total, message } = progress;\n const handleRetry = onRetry ?? job.start;\n\n return (\n <div className={className ?? 'space-y-2'}>\n {status === 'idle' && labels.idle ? (\n <p className=\"text-sm text-muted-foreground\">{labels.idle}</p>\n ) : null}\n\n {status === 'running' ? (\n <div className=\"space-y-1.5\" aria-busy>\n <Progress value={done} max={total > 0 ? total : 1} />\n <p className=\"text-sm text-muted-foreground\">\n {message ?? labels.running(done, total)}\n </p>\n </div>\n ) : null}\n\n {status === 'done' ? <p className=\"text-sm text-foreground\">{labels.done}</p> : null}\n\n {status === 'error' ? (\n <div className=\"space-y-2\">\n <p className=\"text-sm text-destructive\">{result?.error ?? labels.error}</p>\n <Button variant=\"outline\" size=\"sm\" onClick={handleRetry}>\n {labels.retry}\n </Button>\n </div>\n ) : null}\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport { Toaster, TooltipProvider } from '@genispace/geniapp/kit';\n\n/** Mount once at GeniApp root (enables kit toast, tooltips). */\nexport function AppUiProviders({ children }: { children: ReactNode }) {\n return (\n <TooltipProvider>\n {children}\n <Toaster />\n </TooltipProvider>\n );\n}\n","import type { CSSProperties } from 'react';\nimport type { AppModalSize } from '@genispace/geniapp/kit';\n\n/** AI adopt sidebar column (DESIGN_GUIDELINE §16.1). */\nexport const AI_SIDEBAR_MIN = '280px';\nexport const AI_SIDEBAR_MAX = '320px';\n\n/**\n * Modal size when AiSuggestionPanel is shown beside the form.\n * Uses `xl` for compatibility with published shared-ui; switch to `wide` once\n * @genispace/geniapp exports AppModalSize `'wide'`.\n */\nexport const MODAL_SIZE_WITH_AI = 'xl' as const satisfies AppModalSize;\n\nexport type ModalSizeWithAi = typeof MODAL_SIZE_WITH_AI;\n\n/** Modal / dialog: form + AI sidebar columns (inline — not dependent on Tailwind scan). */\nexport const AI_ADOPT_MODAL_GRID_STYLE: CSSProperties = {\n gridTemplateColumns: `minmax(0, 1fr) minmax(${AI_SIDEBAR_MIN}, ${AI_SIDEBAR_MAX})`,\n};\n\n/** Tailwind class for apps that include shared/ai/** in content paths (optional). */\nexport const AI_ADOPT_GRID_CLASS =\n 'grid grid-cols-[minmax(0,1fr)_minmax(280px,320px)] gap-4';\n\n/** Full-page adopt layout: same columns from lg breakpoint upward. */\nexport const AI_ADOPT_PAGE_GRID_CLASS =\n 'space-y-6 lg:grid lg:grid-cols-[1fr_minmax(280px,320px)] lg:gap-6 lg:space-y-0';\n\nexport const AI_ADOPT_MODAL_MAX_HEIGHT = 'max-h-[70vh]';\n","import type { ReactNode } from 'react';\nimport { AI_ADOPT_MODAL_MAX_HEIGHT, AI_ADOPT_MODAL_GRID_STYLE } from './layoutConstants';\n\n/**\n * Two-column body for modals/dialogs with AiSuggestionPanel (DESIGN_GUIDELINE §16.1).\n * Uses inline grid columns so layout works even when Tailwind does not scan shared/ai/**.\n */\nexport function ModalWithAiLayout({\n children,\n sidebar,\n className = '',\n}: {\n children: ReactNode;\n sidebar?: ReactNode | null;\n className?: string;\n}) {\n if (!sidebar) {\n return <div className={className}>{children}</div>;\n }\n return (\n <div\n className={`grid gap-4 ${AI_ADOPT_MODAL_MAX_HEIGHT} min-h-0 ${className}`.trim()}\n style={AI_ADOPT_MODAL_GRID_STYLE}\n >\n <div className=\"min-h-0 min-w-0 overflow-y-auto pr-1\">{children}</div>\n <div className=\"min-h-0 min-w-0 overflow-y-auto\">{sidebar}</div>\n </div>\n );\n}\n","import type { AppModalSize } from '@genispace/geniapp/kit';\nimport { MODAL_SIZE_WITH_AI } from './layoutConstants';\n\n/** Use wide modal when an AI adopt sidebar is shown; otherwise keep the app default. */\nexport function modalSizeForAi<S extends AppModalSize>(\n hasAiSidebar: boolean,\n defaultSize: S,\n): S | typeof MODAL_SIZE_WITH_AI {\n return hasAiSidebar ? MODAL_SIZE_WITH_AI : defaultSize;\n}\n","import type { ReactNode } from 'react';\nimport { AI_ADOPT_PAGE_GRID_CLASS } from '../layout/layoutConstants';\n\n/** Two-column layout: main form + optional sticky AI sidebar (full page). */\nexport function DetailPageAiLayout({ children, sidebar }: { children: ReactNode; sidebar?: ReactNode }) {\n if (!sidebar) {\n return <div className=\"space-y-6\">{children}</div>;\n }\n return (\n <div className={AI_ADOPT_PAGE_GRID_CLASS}>\n <div className=\"min-w-0 space-y-6\">{children}</div>\n <div className=\"lg:sticky lg:top-6 lg:self-start\">{sidebar}</div>\n </div>\n );\n}\n","import type { ComponentProps, ReactNode } from 'react';\nimport { cn } from '@genispace/geniapp/utils';\nimport { Button } from '@genispace/geniapp/kit';\n\n/** Read-only AI/workflow text block (matches shared-ui AiMessage; kept here for CI kit compatibility). */\nexport function AiMessage({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) {\n return (\n <div\n className={cn(\n 'rounded-lg border border-border bg-card px-3 py-2 text-sm text-foreground',\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\n/** Field suggestion row for audit adopt (matches shared-ui AiSuggestion). */\nexport function AiSuggestion({\n label,\n children,\n action,\n className,\n}: {\n label: string;\n children: ReactNode;\n action?: ReactNode;\n className?: string;\n}) {\n return (\n <div className={cn('rounded-lg border border-border bg-muted/30 p-3', className)}>\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <span className=\"text-xs font-medium text-muted-foreground\">{label}</span>\n {action}\n </div>\n <div className=\"text-sm text-foreground\">{children}</div>\n </div>\n );\n}\n\nexport function AiSuggestionAction({\n children,\n ...props\n}: ComponentProps<typeof Button>) {\n return (\n <Button type=\"button\" size=\"sm\" variant=\"outline\" {...props}>\n {children}\n </Button>\n );\n}\n","import en from './en.json';\nimport zh from './zh.json';\n\nexport type SharedAiLanguage = 'en' | 'zh';\nexport type SharedAiCopy = typeof en;\n\n/** English is the deterministic fallback; Chinese is used only after an explicit locale switch. */\nexport function sharedAiCopy(language: SharedAiLanguage): SharedAiCopy {\n return language === 'zh' ? zh : en;\n}\n","/** Parse workflow_results.summary (JSON string or plain text). */\nexport function parseAiSummary(summary: string | null | undefined): Record<string, unknown> | null {\n if (summary == null || String(summary).trim() === '') return null;\n const raw = String(summary).trim();\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n return { summary: parsed };\n } catch {\n return { summary: raw };\n }\n}\n\nexport function getByPath(obj: unknown, path: string): unknown {\n if (!path) return obj;\n const parts = path.split('.');\n let cur: unknown = obj;\n for (const part of parts) {\n if (cur == null || typeof cur !== 'object') return undefined;\n cur = (cur as Record<string, unknown>)[part];\n }\n return cur;\n}\n\n/** Prefer the active language; English is the platform default. */\nexport function localizedText(value: unknown, lang: 'zh' | 'en' = 'en'): string {\n if (value == null) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n if (Array.isArray(value)) {\n return value.map((v) => localizedText(v, lang)).filter(Boolean).join('\\n');\n }\n if (typeof value === 'object') {\n const o = value as Record<string, unknown>;\n if (typeof o[lang] === 'string') return o[lang] as string;\n if (typeof o.zh === 'string') return o.zh;\n if (typeof o.en === 'string') return o.en;\n return '';\n }\n return String(value);\n}\n\n/** Convert structured values into readable lines without exposing raw JSON. */\nexport function formatDisplayValue(value: unknown, lang: 'zh' | 'en' = 'en'): string {\n if (value == null) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n if (Array.isArray(value)) {\n return value\n .map((item) => formatDisplayValue(item, lang))\n .filter(Boolean)\n .join('\\n• ');\n }\n if (typeof value === 'object') {\n const o = value as Record<string, unknown>;\n if ('zh' in o || 'en' in o) return localizedText(o, lang);\n for (const key of [\n 'summary',\n 'recommendation',\n 'description',\n 'title',\n 'message',\n 'reason',\n 'action',\n 'suggestion',\n ]) {\n const display = localizedText(o[key], lang);\n if (display) return display;\n }\n return '';\n }\n return String(value);\n}\n","import type { WorkflowResultRow } from '../types';\nimport { parseAiSummary } from './parseAiSummary';\n\nexport type GuidanceLanguage = 'en' | 'zh';\n\nexport interface GuidanceContent {\n summary: string;\n details: string[];\n sources: string[];\n confidence: number | null;\n}\n\nexport interface ContextualWorkflowSelection {\n sourceRecordKey?: string;\n owners: readonly string[];\n limit: number;\n}\n\nconst SUMMARY_KEYS = [\n 'summary',\n 'recommendation',\n 'description',\n 'conclusion',\n 'diagnosis',\n 'analysis_summary',\n 'suggestion',\n 'reason',\n] as const;\n\nconst DETAIL_KEYS = [\n 'nextSteps',\n 'next_steps',\n 'nextActions',\n 'next_actions',\n 'recommendations',\n 'risks',\n 'issues',\n 'anomalies',\n 'stockAlerts',\n 'stock_alerts',\n] as const;\n\nfunction localizedString(value: unknown, language: GuidanceLanguage): string {\n if (typeof value === 'string') return value.trim();\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n if (!value || typeof value !== 'object' || Array.isArray(value)) return '';\n const record = value as Record<string, unknown>;\n const preferred = record[language];\n if (typeof preferred === 'string') return preferred.trim();\n const fallback = language === 'zh' ? record.en : record.zh;\n return typeof fallback === 'string' ? fallback.trim() : '';\n}\n\nfunction detailStrings(value: unknown, language: GuidanceLanguage): string[] {\n if (Array.isArray(value)) {\n return value\n .flatMap((item) => {\n const direct = localizedString(item, language);\n if (direct) return [direct];\n if (!item || typeof item !== 'object') return [];\n const record = item as Record<string, unknown>;\n for (const key of ['message', 'title', 'description', 'reason', 'action', 'suggestion']) {\n const text = localizedString(record[key], language);\n if (text) return [text];\n }\n return [];\n })\n .filter(Boolean);\n }\n const direct = localizedString(value, language);\n return direct ? [direct] : [];\n}\n\nfunction unwrapOutput(record: Record<string, unknown>): Record<string, unknown> {\n const output = record.output;\n if (output && typeof output === 'object' && !Array.isArray(output)) {\n return output as Record<string, unknown>;\n }\n return record;\n}\n\nfunction sourceStrings(record: Record<string, unknown>, language: GuidanceLanguage): string[] {\n const candidates = [record.sources, record.source_refs, record.citations, record.references];\n return [...new Set(candidates.flatMap((value) => detailStrings(value, language)))].slice(0, 5);\n}\n\nfunction confidenceValue(record: Record<string, unknown>): number | null {\n const raw = record.confidence ?? record.confidence_score;\n const number = Number(raw);\n if (!Number.isFinite(number)) return null;\n return Math.max(0, Math.min(1, number > 1 ? number / 100 : number));\n}\n\n/**\n * Extract only business-readable copy from a workflow result. Unknown objects\n * intentionally return null: raw JSON belongs in platform diagnostics, not in\n * a business application.\n */\nexport function guidanceContentFromSummary(\n rawSummary: string | null | undefined,\n language: GuidanceLanguage,\n): GuidanceContent | null {\n const parsed = parseAiSummary(rawSummary);\n if (!parsed) return null;\n const record = unwrapOutput(parsed);\n\n let summary = '';\n let summaryKey: (typeof SUMMARY_KEYS)[number] | null = null;\n for (const key of SUMMARY_KEYS) {\n summary = localizedString(record[key], language);\n if (summary) {\n summaryKey = key;\n break;\n }\n }\n\n const details: string[] = [];\n for (const key of SUMMARY_KEYS) {\n if (key !== summaryKey) details.push(...detailStrings(record[key], language));\n }\n for (const key of DETAIL_KEYS) {\n details.push(...detailStrings(record[key], language));\n }\n\n if (!summary && details.length > 0) summary = details.shift() ?? '';\n if (!summary) return null;\n return {\n summary,\n details: [...new Set(details)].filter((detail) => detail !== summary).slice(0, 5),\n sources: sourceStrings(record, language),\n confidence: confidenceValue(record),\n };\n}\n\nexport function guidanceStatus(status: WorkflowResultRow['status']):\n | 'ready'\n | 'applied'\n | 'dismissed'\n | 'attention' {\n const normalized = String(status ?? '').toLowerCase();\n if (['adopted', 'accepted', 'applied'].includes(normalized)) return 'applied';\n if (['dismissed', 'rejected', 'ignored'].includes(normalized)) return 'dismissed';\n if (['failed', 'error', 'blocked'].includes(normalized)) return 'attention';\n return 'ready';\n}\n\n/**\n * Enforce the business context again after a datasource response. Some legacy\n * adapters ignore filters, so a server response is never trusted to isolate a\n * record or an Agent/workflow owner on its own.\n */\nexport function selectContextualWorkflowResults(\n rows: readonly WorkflowResultRow[],\n { sourceRecordKey, owners, limit }: ContextualWorkflowSelection,\n): WorkflowResultRow[] {\n if (owners.length === 0 || limit <= 0) return [];\n const allowedOwners = new Set(owners);\n return [\n ...new Map(rows.map((row) => [row.id, row] as const)).values(),\n ]\n .filter(\n (row) =>\n !sourceRecordKey ||\n String(row.source_record_key ?? '') === String(sourceRecordKey),\n )\n .filter((row) => Boolean(row.owner) && allowedOwners.has(String(row.owner)))\n .sort((left, right) => {\n const leftTime = left.created_at ? Date.parse(left.created_at) : 0;\n const rightTime = right.created_at ? Date.parse(right.created_at) : 0;\n return (Number.isFinite(rightTime) ? rightTime : 0) -\n (Number.isFinite(leftTime) ? leftTime : 0);\n })\n .slice(0, limit);\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Lightbulb, Check, Loader2 } from 'lucide-react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Skeleton,\n toast,\n AlertDialog,\n} from '@genispace/geniapp/kit';\nimport { AiMessage, AiSuggestion, AiSuggestionAction } from '../layout/aiUi';\nimport { sharedAiCopy } from '../locales/sharedAiCopy';\nimport { guidanceContentFromSummary, selectContextualWorkflowResults } from './guidanceContent';\nimport { parseAiSummary, getByPath, formatDisplayValue, localizedText } from './parseAiSummary';\nimport type { AdoptFieldConfig, AppTableClient, WorkflowResultRow } from '../types';\n\nexport interface AiSuggestionPanelProps {\n recordId: string | undefined;\n resultsTable: string;\n businessTable: string;\n client: AppTableClient;\n fields: AdoptFieldConfig[];\n sourceRecordKey?: string;\n disabled?: boolean;\n className?: string;\n onAdopted?: (patch: Record<string, unknown>) => void;\n lang?: 'zh' | 'en';\n owners: readonly string[];\n title?: string;\n description?: string;\n emptyTitle?: string;\n emptyDescription?: string;\n applyLabel?: string;\n applyAllLabel?: string;\n successMessage?: string;\n allowEditing?: boolean;\n}\n\nexport function AiSuggestionPanel({\n recordId,\n resultsTable,\n businessTable,\n client,\n fields,\n sourceRecordKey,\n disabled,\n className = '',\n onAdopted,\n lang,\n owners,\n title,\n description,\n emptyTitle,\n emptyDescription,\n applyLabel,\n applyAllLabel,\n successMessage,\n allowEditing = true,\n}: AiSuggestionPanelProps) {\n const { i18n } = useTranslation();\n const resolvedLanguage =\n lang ?? (i18n.resolvedLanguage?.toLowerCase().startsWith('zh') ? 'zh' : 'en');\n const copy = suggestionCopy(resolvedLanguage);\n const [loading, setLoading] = useState(false);\n const [adopting, setAdopting] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [result, setResult] = useState<WorkflowResultRow | null>(null);\n const [drafts, setDrafts] = useState<Record<string, string>>({});\n const [appliedFields, setAppliedFields] = useState<Set<string>>(new Set());\n const [pendingTarget, setPendingTarget] = useState<string | null>(null);\n\n const key = sourceRecordKey ?? recordId;\n const parsed = useMemo(() => parseAiSummary(result?.summary), [result?.summary]);\n const evidence = useMemo(() => guidanceContentFromSummary(result?.summary, resolvedLanguage), [resolvedLanguage, result?.summary]);\n const ownerKey = owners?.join('\\u0000') ?? '';\n const fieldSignature = fields.map((field) => `${field.targetField}:${field.summaryPath}`).join('|');\n\n const load = useCallback(async () => {\n if (!key) {\n setResult(null);\n return;\n }\n setLoading(true);\n setError(null);\n try {\n const allowedOwners = ownerKey ? new Set(ownerKey.split('\\u0000')) : null;\n const ownerCandidates = allowedOwners ? [...allowedOwners] : [];\n const responses = await Promise.all(\n ownerCandidates.map((owner) =>\n client.list<WorkflowResultRow>(resultsTable, {\n filters: {\n source_record_key: key,\n ...(owner ? { owner } : {}),\n },\n limit: 20,\n }),\n ),\n );\n const items = selectContextualWorkflowResults(\n responses.flatMap((response) => response.items ?? []),\n {\n sourceRecordKey: key,\n owners: allowedOwners ? [...allowedOwners] : [],\n limit: 1,\n },\n );\n setResult(items[0] ?? null);\n } catch (e) {\n console.error(`[GeniApp] ${resultsTable} record guidance load failed`, e);\n setError(copy.loadError);\n setResult(null);\n } finally {\n setLoading(false);\n }\n }, [client, copy.loadError, key, ownerKey, resultsTable]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n useEffect(() => {\n if (!parsed) {\n setDrafts({});\n return;\n }\n const next: Record<string, string> = {};\n for (const field of fields) {\n const raw = getByPath(parsed, field.summaryPath);\n const value = field.toValue ? field.toValue(raw, parsed, resolvedLanguage) : raw;\n const display = formatDisplayValue(value, resolvedLanguage);\n if (display) next[field.targetField] = display;\n }\n setDrafts(next);\n setAppliedFields(new Set());\n }, [fieldSignature, parsed, resolvedLanguage]);\n\n const adoptField = async (field: AdoptFieldConfig) => {\n if (!recordId || !parsed) return;\n const raw = getByPath(parsed, field.summaryPath);\n const transformed = field.toValue ? field.toValue(raw, parsed, resolvedLanguage) : raw;\n const edited = drafts[field.targetField];\n const value = allowEditing && typeof edited === 'string' ? edited.trim() : transformed;\n if (value == null || (typeof value === 'string' && value.trim() === '')) {\n setError(copy.emptyField);\n return;\n }\n setAdopting(field.targetField);\n setError(null);\n try {\n const patch = { [field.targetField]: value };\n await client.update(businessTable, recordId, patch);\n onAdopted?.(patch);\n setAppliedFields((current) => new Set(current).add(field.targetField));\n toast({\n title: successMessage ?? copy.adopted,\n variant: 'success',\n });\n } catch (e) {\n console.error(`[GeniApp] ${businessTable} suggestion apply failed`, e);\n setError(copy.applyError);\n } finally {\n setAdopting(null);\n }\n };\n\n const adoptAll = async () => {\n if (!recordId || !parsed) return;\n setAdopting('__all__');\n setError(null);\n try {\n const patch: Record<string, unknown> = {};\n for (const field of fields) {\n const raw = getByPath(parsed, field.summaryPath);\n const transformed = field.toValue ? field.toValue(raw, parsed, resolvedLanguage) : raw;\n const edited = drafts[field.targetField];\n const value = allowEditing && typeof edited === 'string' ? edited.trim() : transformed;\n if (value != null && !(typeof value === 'string' && value.trim() === '')) {\n patch[field.targetField] = value;\n }\n }\n if (Object.keys(patch).length === 0) {\n setError(copy.emptyField);\n return;\n }\n await client.update(businessTable, recordId, patch);\n onAdopted?.(patch);\n setAppliedFields(new Set(Object.keys(patch)));\n toast({\n title: successMessage ?? copy.adoptedAll,\n variant: 'success',\n });\n } catch (e) {\n console.error(`[GeniApp] ${businessTable} suggestions apply failed`, e);\n setError(copy.applyAllError);\n } finally {\n setAdopting(null);\n }\n };\n\n if (!recordId) return null;\n\n return (\n <Card\n className={`border-accent/30 bg-card ${className}`}\n aria-label={title ?? copy.panelTitle}\n >\n <CardHeader className=\"pb-3\">\n <div className=\"flex items-start gap-2\">\n <div className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-accent text-accent-foreground\">\n <Lightbulb className=\"h-4 w-4\" aria-hidden />\n </div>\n <div className=\"min-w-0\">\n <CardTitle className=\"text-sm\">\n {title ?? copy.panelTitle}\n </CardTitle>\n <CardDescription>\n {description ?? copy.panelHint}\n </CardDescription>\n </div>\n </div>\n </CardHeader>\n\n <CardContent className=\"space-y-3 pt-0\">\n {loading && (\n <div className=\"space-y-2\" aria-busy=\"true\">\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-16 w-full\" />\n </div>\n )}\n\n {!loading && !result && (\n <div className=\"rounded-lg border border-dashed border-border px-3 py-4\">\n <p className=\"text-sm font-medium text-foreground\">\n {emptyTitle ?? copy.emptyTitle}\n </p>\n <p className=\"mt-1 text-sm leading-5 text-muted-foreground\">\n {emptyDescription ?? copy.noResults}\n </p>\n </div>\n )}\n\n {!loading && result && (\n <>\n <ResultMeta result={result} language={resolvedLanguage} />\n {parsed?.summary != null && typeof parsed.summary === 'string' && fields.length === 0 && (\n <AiMessage>\n <p className=\"whitespace-pre-wrap\">{parsed.summary}</p>\n </AiMessage>\n )}\n {fields.map((field) => {\n const raw = parsed ? getByPath(parsed, field.summaryPath) : undefined;\n const transformed = field.toValue ? field.toValue(raw, parsed, resolvedLanguage) : raw;\n const display = formatDisplayValue(transformed, resolvedLanguage);\n if (!display) return null;\n const applied = appliedFields.has(field.targetField);\n return (\n <AiSuggestion\n key={field.targetField}\n label={field.label}\n action={\n <AiSuggestionAction\n disabled={disabled || adopting != null || applied}\n onClick={() => setPendingTarget(field.targetField)}\n >\n {adopting === field.targetField ? (\n <Loader2 className=\"h-3 w-3 animate-spin\" />\n ) : (\n <Check className=\"h-3 w-3\" />\n )}\n {applied\n ? copy.added\n : applyLabel ?? copy.adopt}\n </AiSuggestionAction>\n }\n >\n {allowEditing ? (\n <textarea\n value={drafts[field.targetField] ?? display}\n onChange={(event) =>\n setDrafts((current) => ({\n ...current,\n [field.targetField]: event.target.value,\n }))\n }\n rows={Math.min(6, Math.max(2, (drafts[field.targetField] ?? display).split('\\n').length))}\n className=\"w-full resize-y rounded-md border border-input bg-background px-3 py-2 text-sm leading-5 text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n aria-label={field.label}\n />\n ) : (\n <p className=\"whitespace-pre-wrap leading-5\">{display}</p>\n )}\n </AiSuggestion>\n );\n })}\n {fields.length > 1 && (\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"w-full\"\n disabled={disabled || adopting != null}\n onClick={() => setPendingTarget('__all__')}\n >\n {adopting === '__all__'\n ? copy.adopting\n : applyAllLabel ?? copy.adoptAll}\n </Button>\n )}\n </>\n )}\n\n {error && (\n <p className=\"text-sm text-destructive\" role=\"alert\">\n {error}\n </p>\n )}\n {result ? <div className=\"rounded-md border bg-muted/30 px-3 py-2 text-xs text-muted-foreground\"><p className=\"font-medium text-foreground\">{copy.sources}</p><p className=\"mt-1\">{evidence?.sources.length ? evidence.sources.join(' · ') : copy.noSources}</p>{evidence?.confidence != null ? <p className=\"mt-1\">{copy.confidence}: {Math.round(evidence.confidence * 100)}%</p> : null}</div> : null}\n </CardContent>\n <AlertDialog\n isOpen={pendingTarget != null}\n type=\"info\"\n title={copy.confirmTitle}\n message={pendingTarget === '__all__' ? copy.confirmAll.replace('{{count}}', String(fields.length)) : copy.confirmOne.replace('{{field}}', fields.find((field) => field.targetField === pendingTarget)?.label ?? '')}\n confirmText={copy.confirmAction}\n cancelText={copy.cancelAction}\n showCancel\n loading={adopting != null}\n onClose={() => setPendingTarget(null)}\n onCancel={() => setPendingTarget(null)}\n onConfirm={() => {\n const target = pendingTarget;\n setPendingTarget(null);\n if (target === '__all__') void adoptAll();\n else {\n const field = fields.find((candidate) => candidate.targetField === target);\n if (field) void adoptField(field);\n }\n }}\n />\n </Card>\n );\n}\n\nfunction ResultMeta({ result, language }: { result: WorkflowResultRow; language: 'en' | 'zh' }) {\n const copy = suggestionCopy(language);\n const normalizedStatus = String(result.status ?? '').toLowerCase();\n const statusLabel = ['adopted', 'accepted', 'applied'].includes(normalizedStatus)\n ? copy.statusApplied\n : ['failed', 'error', 'blocked'].includes(normalizedStatus)\n ? copy.statusAttention\n : copy.statusReady;\n return (\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-muted-foreground\">\n <Badge variant=\"secondary\">{statusLabel}</Badge>\n {result.created_at && formatSuggestionDate(result.created_at, language) && (\n <time dateTime={result.created_at}>\n {formatSuggestionDate(result.created_at, language)}\n </time>\n )}\n </div>\n );\n}\n\nfunction formatSuggestionDate(value: string, language: 'en' | 'zh'): string {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return '';\n return new Intl.DateTimeFormat(language === 'zh' ? 'zh-CN' : 'en-US', {\n dateStyle: 'medium',\n timeStyle: 'short',\n }).format(date);\n}\n\nfunction suggestionCopy(language: 'en' | 'zh') {\n return sharedAiCopy(language).suggestion;\n}\n\n/** Common field mappers for product description agent output */\nexport const productDescriptionAdoptFields = (labels: {\n description: string;\n descriptionSale: string;\n name?: string;\n}): AdoptFieldConfig[] => {\n const fields: AdoptFieldConfig[] = [\n {\n label: labels.description,\n summaryPath: 'description',\n targetField: 'description',\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n },\n {\n label: labels.descriptionSale,\n summaryPath: 'highlights',\n targetField: 'description_sale',\n toValue: (raw, _parsed, language) => {\n if (Array.isArray(raw)) return raw.map(String).join('\\n• ');\n return localizedText(raw, language ?? 'en');\n },\n },\n ];\n if (labels.name) {\n fields.unshift({\n label: labels.name,\n summaryPath: 'title',\n targetField: 'name',\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n });\n }\n return fields;\n};\n","import { useCallback, useEffect, useMemo, useState, type ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { AlertCircle, CheckCircle2, Lightbulb, RefreshCw } from 'lucide-react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Skeleton,\n} from '@genispace/geniapp/kit';\nimport type { AppTableClient, WorkflowResultRow } from '../types';\nimport { sharedAiCopy } from '../locales/sharedAiCopy';\nimport {\n guidanceContentFromSummary,\n guidanceStatus,\n selectContextualWorkflowResults,\n} from './guidanceContent';\n\ninterface BusinessGuidancePanelBaseProps {\n client: AppTableClient;\n resultsTable: string;\n title: string;\n description: string;\n emptyTitle: string;\n emptyDescription: string;\n unreadableText?: string;\n owners: readonly string[];\n limit?: number;\n className?: string;\n footer?: ReactNode;\n renderAction?: (row: WorkflowResultRow) => ReactNode;\n}\n\nexport type BusinessGuidancePanelProps = BusinessGuidancePanelBaseProps &\n (\n | { scope: 'aggregate'; sourceRecordKey?: never }\n | { scope?: 'record'; sourceRecordKey: string }\n );\n\n/**\n * A business-page feed for useful recommendations. It deliberately hides run\n * identifiers, model payloads and raw JSON; those remain available to platform\n * diagnostics without becoming part of the user's daily navigation.\n */\nexport function BusinessGuidancePanel({\n client,\n resultsTable,\n title,\n description,\n emptyTitle,\n emptyDescription,\n unreadableText,\n sourceRecordKey,\n owners,\n limit = 3,\n className = '',\n footer,\n renderAction,\n}: BusinessGuidancePanelProps) {\n const { i18n } = useTranslation();\n const language = i18n.resolvedLanguage?.toLowerCase().startsWith('zh') ? 'zh' : 'en';\n const copy = sharedAiCopy(language).businessGuidance;\n const [rows, setRows] = useState<WorkflowResultRow[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState(false);\n const ownerKey = owners?.join('\\u0000') ?? '';\n\n const load = useCallback(async () => {\n setLoading(true);\n setError(false);\n try {\n const allowedOwners = ownerKey ? new Set(ownerKey.split('\\u0000')) : null;\n const ownerCandidates = allowedOwners ? [...allowedOwners] : [];\n const responses = await Promise.all(\n ownerCandidates.map((owner) =>\n client.list<WorkflowResultRow>(resultsTable, {\n filters: {\n ...(sourceRecordKey ? { source_record_key: sourceRecordKey } : {}),\n ...(owner ? { owner } : {}),\n },\n limit: Math.max(limit * 4, 20),\n }),\n ),\n );\n setRows(\n selectContextualWorkflowResults(\n responses.flatMap((response) => response.items ?? []),\n {\n sourceRecordKey,\n owners: allowedOwners ? [...allowedOwners] : [],\n limit,\n },\n ),\n );\n } catch (reason) {\n console.error(`[GeniApp] ${resultsTable} guidance load failed`, reason);\n setRows([]);\n setError(true);\n } finally {\n setLoading(false);\n }\n }, [client, limit, ownerKey, resultsTable, sourceRecordKey]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n const readableRows = useMemo(\n () => rows.map((row) => ({ row, content: guidanceContentFromSummary(row.summary, language) })),\n [language, rows],\n );\n\n return (\n <Card className={`border-border bg-card ${className}`} aria-label={title}>\n <CardHeader className=\"gap-3 pb-3 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex min-w-0 items-start gap-3\">\n <div className=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-lg border border-border bg-muted/40 text-foreground\">\n <Lightbulb className=\"h-4 w-4\" aria-hidden />\n </div>\n <div className=\"min-w-0\">\n <CardTitle className=\"text-base\">{title}</CardTitle>\n <CardDescription className=\"mt-1 max-w-3xl leading-5\">{description}</CardDescription>\n </div>\n </div>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"shrink-0\" onClick={() => void load()}>\n <RefreshCw className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden />\n {copy.refresh}\n </Button>\n </CardHeader>\n <CardContent className=\"space-y-3 pt-0\">\n {loading ? (\n <div className=\"space-y-3\" aria-busy=\"true\">\n <Skeleton className=\"h-20 w-full\" />\n <Skeleton className=\"h-20 w-full\" />\n </div>\n ) : error ? (\n <div className=\"flex items-start gap-2 rounded-lg border border-destructive/30 bg-destructive/5 p-3 text-sm\" role=\"alert\">\n <AlertCircle className=\"mt-0.5 h-4 w-4 shrink-0 text-destructive\" aria-hidden />\n <div>\n <p className=\"font-medium text-foreground\">\n {copy.errorTitle}\n </p>\n <p className=\"mt-0.5 text-muted-foreground\">\n {copy.errorDescription}\n </p>\n </div>\n </div>\n ) : readableRows.length === 0 ? (\n <div className=\"rounded-lg border border-dashed border-border px-4 py-5\">\n <div className=\"flex items-start gap-2\">\n <CheckCircle2 className=\"mt-0.5 h-4 w-4 shrink-0 text-status-success\" aria-hidden />\n <div>\n <p className=\"text-sm font-medium text-foreground\">{emptyTitle}</p>\n <p className=\"mt-1 text-sm leading-5 text-muted-foreground\">{emptyDescription}</p>\n </div>\n </div>\n </div>\n ) : (\n readableRows.map(({ row, content }) => {\n const state = guidanceStatus(row.status);\n return (\n <article key={row.id} className=\"rounded-lg border border-border p-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"mb-2 flex flex-wrap items-center gap-2\">\n <Badge variant={state === 'attention' ? 'destructive' : 'secondary'}>\n {state === 'applied'\n ? copy.applied\n : state === 'dismissed'\n ? copy.dismissed\n : state === 'attention'\n ? copy.attention\n : copy.ready}\n </Badge>\n {row.created_at ? (\n <time className=\"text-xs text-muted-foreground\" dateTime={row.created_at}>\n {formatGuidanceDate(row.created_at, language)}\n </time>\n ) : null}\n </div>\n {content ? (\n <>\n <p className=\"text-sm font-medium leading-6 text-foreground\">{content.summary}</p>\n {content.details.length > 0 ? (\n <ul className=\"mt-2 space-y-1.5 text-sm leading-5 text-muted-foreground\">\n {content.details.map((detail) => (\n <li key={detail} className=\"flex gap-2\">\n <span aria-hidden>•</span>\n <span>{detail}</span>\n </li>\n ))}\n </ul>\n ) : null}\n <div className=\"mt-3 flex flex-wrap gap-3 text-xs text-muted-foreground\">\n {content.sources.length > 0 ? <span>{copy.sources}: {content.sources.join(' · ')}</span> : <span>{copy.noSources}</span>}\n {content.confidence != null ? <span>{copy.confidence}: {Math.round(content.confidence * 100)}%</span> : null}\n </div>\n </>\n ) : (\n <p className=\"text-sm leading-5 text-muted-foreground\">\n {unreadableText ?? copy.unreadable}\n </p>\n )}\n </div>\n {renderAction ? <div className=\"shrink-0\">{renderAction(row)}</div> : null}\n </div>\n </article>\n );\n })\n )}\n {footer}\n </CardContent>\n </Card>\n );\n}\n\nfunction formatGuidanceDate(value: string, language: 'en' | 'zh'): string {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return '';\n return new Intl.DateTimeFormat(language === 'zh' ? 'zh-CN' : 'en-US', {\n dateStyle: 'medium',\n timeStyle: 'short',\n }).format(date);\n}\n","import { localizedText } from './parseAiSummary';\nimport type { AdoptFieldConfig } from '../types';\n\nexport function genericSummaryField(label: string, targetField: string): AdoptFieldConfig {\n return {\n label,\n summaryPath: 'summary',\n targetField,\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n };\n}\n\nexport function narrationAdoptField(label: string): AdoptFieldConfig {\n return {\n label,\n summaryPath: 'narration',\n targetField: 'narration',\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n };\n}\n\nexport function recommendationAdoptField(label: string, targetField = 'ref'): AdoptFieldConfig {\n return {\n label,\n summaryPath: 'recommendation',\n targetField,\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n };\n}\n\nexport function synopsisAdoptField(label: string, targetField = 'synopsis'): AdoptFieldConfig {\n return {\n label,\n summaryPath: 'synopsis',\n targetField,\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n };\n}\n\nexport function noteAdoptField(label: string, targetField = 'note'): AdoptFieldConfig {\n return {\n label,\n summaryPath: 'note',\n targetField,\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n };\n}\n\nexport function internalNotesAdoptField(label: string): AdoptFieldConfig {\n return {\n label,\n summaryPath: 'internal_notes',\n targetField: 'internal_notes',\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n };\n}\n\nexport function jobTitleAdoptField(label: string): AdoptFieldConfig {\n return {\n label,\n summaryPath: 'job_title',\n targetField: 'job_title',\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n };\n}\n\nexport function descriptionAdoptField(label: string, targetField = 'description'): AdoptFieldConfig {\n return {\n label,\n summaryPath: 'description',\n targetField,\n toValue: (raw, _parsed, language) => localizedText(raw, language ?? 'en'),\n };\n}\n\nexport function appendTextAdoptField(\n label: string,\n summaryPath: string,\n targetField: string,\n currentValue: string | null | undefined,\n): AdoptFieldConfig {\n return {\n label,\n summaryPath,\n targetField,\n toValue: (raw, _parsed, language) => {\n const suggestion = localizedText(raw, language ?? 'en').trim();\n const existing = currentValue?.trim() ?? '';\n if (!suggestion || existing === suggestion || existing.includes(suggestion)) {\n return existing || suggestion;\n }\n return existing ? `${existing}\\n\\n${suggestion}` : suggestion;\n },\n };\n}\n","import {\n createGeniSpaceClient,\n findManagedAppDataSourceId,\n queryManagedDatasourceRows,\n} from '../../managed-data/queryManagedDatasource';\n\nexport const PARTNER_GENIAPP = 'partner';\nexport const PARTNER_RECORD_PICKER_DS = 'partner_record_picker';\n\nexport type PartnerRecordRole =\n | 'customer'\n | 'supplier'\n | 'prospect'\n | 'service_provider'\n | 'manufacturer'\n | 'carrier'\n | 'franchisee'\n | 'equipment_owner';\n\nexport type PartnerRecordOption = {\n id: string;\n label: string;\n secondary?: string;\n /** Read-only business details published by Partner for directory and picker experiences. */\n snapshot?: Record<string, unknown>;\n};\n\nexport type LoadPartnerRecordOptionsParams = {\n role?: PartnerRecordRole;\n partyType?: 'organization' | 'person';\n legalEntityRef?: string;\n limit?: number;\n offset?: number;\n ensureIds?: string[];\n};\n\nexport async function probePartnerRecordPicker(apiRoot: string, token: string | null): Promise<boolean> {\n if (!apiRoot || !token) return false;\n const gs = createGeniSpaceClient(apiRoot, token);\n return (await findManagedAppDataSourceId(gs, PARTNER_RECORD_PICKER_DS, PARTNER_GENIAPP)) != null;\n}\n\nfunction mapPartnerRecord(row: Record<string, unknown>): PartnerRecordOption | null {\n const id = String(row.id ?? '').trim();\n const label = String(row.primary ?? row.display_name ?? row.legal_name ?? '').trim();\n if (!id || !label) return null;\n const secondary = String(row.secondary ?? row.partner_number ?? '').trim();\n const snapshot = parseSnapshot(row.snapshot);\n return {\n id,\n label,\n ...(secondary ? { secondary } : {}),\n ...(snapshot ? { snapshot } : {}),\n };\n}\n\nfunction parseSnapshot(value: unknown): Record<string, unknown> | undefined {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n if (typeof value !== 'string' || value.trim() === '') return undefined;\n try {\n const parsed = JSON.parse(value) as unknown;\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed)\n ? parsed as Record<string, unknown>\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function queryPartnerRecords(\n apiRoot: string,\n token: string,\n params: LoadPartnerRecordOptionsParams,\n extra: { id?: string; limit: number; offset: number },\n): Promise<Record<string, unknown>[]> {\n return queryManagedDatasourceRows(apiRoot, token, PARTNER_GENIAPP, PARTNER_RECORD_PICKER_DS, {\n role: params.role ?? '',\n party_type: params.partyType ?? '',\n legal_entity_ref: params.legalEntityRef ?? '',\n id: extra.id ?? '',\n search: '',\n limit: extra.limit,\n offset: extra.offset,\n });\n}\n\nexport async function loadPartnerRecordOptions(\n apiRoot: string,\n token: string | null,\n params: LoadPartnerRecordOptionsParams = {},\n): Promise<PartnerRecordOption[]> {\n if (!apiRoot || !token || !(await probePartnerRecordPicker(apiRoot, token))) return [];\n\n const pageSize = Math.min(Math.max(params.limit ?? 100, 1), 100);\n const byId = new Map<string, PartnerRecordOption>();\n let offset = Math.max(params.offset ?? 0, 0);\n while (true) {\n const rows = await queryPartnerRecords(apiRoot, token, params, { limit: pageSize, offset });\n for (const row of rows) {\n const option = mapPartnerRecord(row);\n if (option) byId.set(option.id, option);\n }\n if (rows.length < pageSize) break;\n offset += pageSize;\n if (offset > 5000) break;\n }\n\n await Promise.all((params.ensureIds ?? []).filter((id) => id && !byId.has(id)).map(async (id) => {\n const rows = await queryPartnerRecords(apiRoot, token, params, { id, limit: 1, offset: 0 });\n const option = rows.length > 0 ? mapPartnerRecord(rows[0]) : null;\n if (option) byId.set(option.id, option);\n }));\n return [...byId.values()];\n}\n","import { createUseManagedAppPicker } from '@genispace/geniapp/hooks';\nimport {\n loadPartnerRecordOptions,\n probePartnerRecordPicker,\n type PartnerRecordRole,\n} from './partnerRecordPicker';\n\nfunction readToken(): string | null {\n try {\n return localStorage.getItem('token');\n } catch {\n return null;\n }\n}\n\nexport type PartnerRecordPickerHookOptions = {\n role?: PartnerRecordRole;\n partyType?: 'organization' | 'person';\n legalEntityRef?: string;\n};\n\nexport function createPartnerRecordPickerHook(\n buildApiRoot: () => string,\n hookOptions: PartnerRecordPickerHookOptions = {},\n) {\n return createUseManagedAppPicker({\n providerGeniappId: 'partner',\n datasourceIdentifier: 'partner_record_picker',\n buildApiRoot,\n readToken,\n probePicker: probePartnerRecordPicker,\n loadOptions: async (apiRoot, token, ensureIds) => {\n const rows = await loadPartnerRecordOptions(apiRoot, token, { ...hookOptions, ensureIds });\n return rows.map(({ id, label }) => ({ id, label }));\n },\n });\n}\n"],"names":["createTableClient","handlers","table","options","params","metaBool","v","DS_LIST_PAGE","DS_LIST_MAX_PAGES","matchesManaged","x","seedIdentifier","geniappIdentifier","meta","findManagedAppDataSourceId","client","items","hit","page","createGeniSpaceClient","apiRoot","accessToken","baseURL","GeniSpace","asNonNegativeInt","n","rowsOf","payload","r","API_DEFAULT_LIMIT","queryReadRowsPaged","gs","datasourceId","rawOffset","rest","offset","limit","windowSize","fetchWindow","windowIndex","windowOffset","firstWindow","skip","head","tail","queryManagedDatasourceRows","id","DATASOURCE_PAGE_SIZE","queryManagedDatasourceRowsAll","all","rows","executeManagedDatasourceOperation","body","k","res","text","parsed","msg","executeManagedDatasourceTransaction","payloadParamName","createTransactionDatasourceClient","resolveApiRoot","resolveAccessToken","emitManagedEvent","eventName","opts","createManagedEventClient","DatasourceReadonlyTable","title","hint","columns","emptyLabel","t","useTranslation","jsxs","Card","CardHeader","jsx","CardTitle","CardDescription","CardContent","Table","TableHeader","TableRow","c","TableHead","TableBody","row","TableCell","EMPTY_SELECTION","SortIndicator","active","dir","ServerDataTable","fetchRows","rowKey","labels","pageSize","resetKey","initialSort","onRowClick","emptyContent","className","selectable","selectedIds","onSelectionChange","mobileCard","isMobile","useIsMobile","pageIndex","setPageIndex","useState","sort","setSort","setRows","hasMore","setHasMore","loading","setLoading","error","setError","reqId","useRef","sortToken","runFetch","useCallback","myId","fetched","e","useEffect","firstRender","toggleSort","colSortKey","prev","selection","pageKeys","selectedOnPage","allPageSelected","somePageSelected","toggleRow","key","next","togglePage","loadingState","errorState","Button","emptyState","pagination","p","Checkbox","interactive","sortable","AsyncCombobox","value","onChange","loadOptions","resolveSelected","disabled","allowClear","triggerClassName","contentClassName","open","setOpen","query","setQuery","debounced","setDebounced","setOptions","setOffset","selectedOption","setSelectedOption","fetchPage","search","nextOffset","append","more","inOptions","o","cancelled","opt","triggerLabel","Popover","PopoverTrigger","PopoverContent","Input","ScrollArea","useInfiniteRows","offsetRef","loadingRef","hasMoreRef","fetchRef","observerRef","loadMore","batch","got","reset","sentinelRef","el","entries","en","Timeline","children","TimelineItem","Icon","dotClassName","nodeClassName","accentClassName","time","isLast","useEntityNames","resolver","cache","inFlight","pending","flushHandle","setVersion","loadingCount","setLoadingCount","resolverRef","flush","map","ensure","ids","added","EntityRef","name","href","onClick","fallback","resolved","content","baseClass","merged","BulkActionBar","selectedCount","totalMatching","allMatchingSelected","onSelectAllMatching","onClear","actions","canSelectAllMatching","action","useAgentJobRunner","state","setState","phase","setPhase","elapsedMs","setElapsedMs","job","setJob","attempt","setAttempt","cancelRequested","setCancelRequested","runId","runningRef","abortRef","jobRef","cancelFnRef","cancelRequestedRef","baselineRef","ticking","tick","base","timer","observe","snapshot","s","created","noteAttempt","start","task","controller","guard","fn","args","result","cancel","jobId","DEFAULT_LABELS","seconds","STEP_KEYS","activeStepIndex","AgentJobProgressInline","expectedSeconds","onCancel","onRetry","l","slow","note","stepIdx","Loader2","i","isDone","isCurrent","Check","Circle","EMPTY_PROGRESS","useAsyncJob","run","status","setStatus","progress","setProgress","setResult","runRef","report","message","JobProgress","done","total","handleRetry","Progress","AppUiProviders","TooltipProvider","Toaster","AI_SIDEBAR_MIN","AI_SIDEBAR_MAX","MODAL_SIZE_WITH_AI","AI_ADOPT_MODAL_GRID_STYLE","AI_ADOPT_GRID_CLASS","AI_ADOPT_PAGE_GRID_CLASS","AI_ADOPT_MODAL_MAX_HEIGHT","ModalWithAiLayout","sidebar","modalSizeForAi","hasAiSidebar","defaultSize","DetailPageAiLayout","AiMessage","cn","AiSuggestion","label","AiSuggestionAction","props","sharedAiCopy","language","zh","parseAiSummary","summary","raw","getByPath","obj","path","parts","cur","part","localizedText","lang","formatDisplayValue","item","display","SUMMARY_KEYS","DETAIL_KEYS","localizedString","record","preferred","detailStrings","direct","unwrapOutput","output","sourceStrings","candidates","confidenceValue","number","guidanceContentFromSummary","rawSummary","summaryKey","details","detail","guidanceStatus","normalized","selectContextualWorkflowResults","sourceRecordKey","owners","allowedOwners","left","right","leftTime","rightTime","AiSuggestionPanel","recordId","resultsTable","businessTable","fields","onAdopted","description","emptyTitle","emptyDescription","applyLabel","applyAllLabel","successMessage","allowEditing","i18n","resolvedLanguage","copy","suggestionCopy","adopting","setAdopting","drafts","setDrafts","appliedFields","setAppliedFields","pendingTarget","setPendingTarget","useMemo","evidence","ownerKey","fieldSignature","field","load","ownerCandidates","responses","owner","response","adoptField","transformed","edited","patch","current","toast","adoptAll","Lightbulb","Skeleton","Fragment","ResultMeta","applied","event","AlertDialog","target","candidate","normalizedStatus","statusLabel","Badge","formatSuggestionDate","date","productDescriptionAdoptFields","_parsed","BusinessGuidancePanel","unreadableText","footer","renderAction","reason","readableRows","RefreshCw","AlertCircle","CheckCircle2","formatGuidanceDate","genericSummaryField","targetField","narrationAdoptField","recommendationAdoptField","synopsisAdoptField","noteAdoptField","internalNotesAdoptField","jobTitleAdoptField","descriptionAdoptField","appendTextAdoptField","summaryPath","currentValue","suggestion","existing","PARTNER_GENIAPP","PARTNER_RECORD_PICKER_DS","probePartnerRecordPicker","token","mapPartnerRecord","secondary","parseSnapshot","queryPartnerRecords","extra","loadPartnerRecordOptions","byId","option","readToken","createPartnerRecordPickerHook","buildApiRoot","hookOptions","createUseManagedAppPicker","ensureIds"],"mappings":"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"}