@maykonpaulo/maestro-admin 0.3.0 → 0.4.0-next.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/README.md +40 -12
- package/dist/index.d.ts +281 -3
- package/dist/index.js +1285 -469
- package/dist/index.js.map +1 -1
- package/package.json +2 -3
- package/src/styles.css +1716 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/MaestroAdmin.tsx","../src/client/MaestroClient.ts","../src/AdminContext.tsx","../src/hooks.ts","../src/components/Sidebar.tsx","../src/grouping.ts","../src/i18n.ts","../src/components/EntityList.tsx","../src/components/ui.tsx","../src/components/RelationValue.tsx","../src/components/ObjectValue.tsx","../src/components/FieldValue.tsx","../src/components/menu.tsx","../src/clipboard.ts","../src/components/EntityDetail.tsx","../src/components/EntityForm.tsx","../src/components/JsonInput.tsx","../src/components/FieldInput.tsx","../src/labels.ts","../src/recents.ts"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { MaestroClient, type MaestroClientConfig } from '../client/MaestroClient.js';\nimport { AdminClientProvider, AdminEntitiesProvider } from '../AdminContext.js';\nimport { useMetadata } from '../hooks.js';\nimport { Sidebar } from './Sidebar.js';\nimport { EntityList } from './EntityList.js';\nimport { EntityDetail } from './EntityDetail.js';\nimport { EntityForm } from './EntityForm.js';\nimport { ErrorBanner, Spinner } from './ui.js';\nimport { I18nProvider, stringsFor, useT, type AdminLocale } from '../i18n.js';\nimport { applyLabels, type AdminLabels } from '../labels.js';\nimport { useRecents } from '../recents.js';\n\nexport interface MaestroAdminProps {\n /** Base URL of the running maestro-server. Ignored when `client` is given. */\n apiUrl?: string;\n /** Per-request headers (auth). Ignored when `client` is given. */\n headers?: MaestroClientConfig['headers'];\n /** A pre-built client, for full control (custom fetch, SSR, tests). */\n client?: MaestroClient;\n /** Sidebar title. Defaults to \"Maestro Admin\". */\n title?: string;\n /** UI-chrome language (buttons, menus, pagination). Defaults to `en`. */\n locale?: AdminLocale;\n /** Label rewrites (localization/humanization) applied over the served metadata. */\n labels?: AdminLabels;\n}\n\ntype View =\n | { kind: 'list'; entityId: string }\n | { kind: 'detail'; entityId: string; id: string }\n | { kind: 'create'; entityId: string; cloneFromId?: string }\n | { kind: 'edit'; entityId: string; id: string };\n\nfunction AdminShell({ title, labels }: { title: string; labels?: AdminLabels }) {\n const { data, error, loading } = useMetadata();\n const t = useT();\n const [view, setView] = useState<View | undefined>(undefined);\n const { recents, push: pushRecent } = useRecents();\n\n const metadata = useMemo(() => (data ? applyLabels(data, labels) : undefined), [data, labels]);\n const entities = metadata?.entities ?? [];\n const activeId = view?.entityId ?? entities[0]?.id;\n const activeEntity = entities.find((e) => e.id === activeId);\n const effectiveView: View | undefined = view ?? (activeId ? { kind: 'list', entityId: activeId } : undefined);\n\n const openEntity = (entityId: string): void => {\n pushRecent(entityId);\n setView({ kind: 'list', entityId });\n };\n\n const navigateToRecord = (entityId: string, id: string): void => {\n pushRecent(entityId);\n setView({ kind: 'detail', entityId, id });\n };\n\n if (loading && !data) {\n return (\n <div className=\"flex h-full items-center justify-center\">\n <Spinner label={t.loadingMetadata} />\n </div>\n );\n }\n\n return (\n <AdminEntitiesProvider value={entities}>\n <div className=\"flex h-screen overflow-hidden bg-white text-slate-800\">\n <Sidebar\n entities={entities}\n activeId={activeId}\n title={title}\n labels={labels}\n recents={recents}\n onSelect={openEntity}\n />\n <main className=\"flex-1 overflow-y-auto p-6\">\n {error && <ErrorBanner error={error} />}\n {activeEntity && effectiveView && effectiveView.kind === 'list' && (\n <EntityList\n entity={activeEntity}\n onOpen={(id) => setView({ kind: 'detail', entityId: activeEntity.id, id })}\n onCreate={() => setView({ kind: 'create', entityId: activeEntity.id })}\n onEdit={(id) => setView({ kind: 'edit', entityId: activeEntity.id, id })}\n onClone={(id) => setView({ kind: 'create', entityId: activeEntity.id, cloneFromId: id })}\n onNavigate={navigateToRecord}\n />\n )}\n {activeEntity && effectiveView?.kind === 'detail' && (\n <EntityDetail\n entity={activeEntity}\n id={effectiveView.id}\n onBack={() => setView({ kind: 'list', entityId: activeEntity.id })}\n onEdit={() => setView({ kind: 'edit', entityId: activeEntity.id, id: effectiveView.id })}\n onClone={() =>\n setView({ kind: 'create', entityId: activeEntity.id, cloneFromId: effectiveView.id })\n }\n onDeleted={() => setView({ kind: 'list', entityId: activeEntity.id })}\n onNavigate={navigateToRecord}\n />\n )}\n {activeEntity && (effectiveView?.kind === 'create' || effectiveView?.kind === 'edit') && (\n <EntityForm\n entity={activeEntity}\n mode={effectiveView.kind}\n id={effectiveView.kind === 'edit' ? effectiveView.id : undefined}\n cloneFromId={effectiveView.kind === 'create' ? effectiveView.cloneFromId : undefined}\n onCancel={() => setView({ kind: 'list', entityId: activeEntity.id })}\n onSaved={() => setView({ kind: 'list', entityId: activeEntity.id })}\n />\n )}\n </main>\n </div>\n </AdminEntitiesProvider>\n );\n}\n\n/**\n * The whole metadata-driven admin in one component. Point it at a running maestro-server and it reads\n * `GET /metadata` and auto-builds navigation, tables, detail views and create/update forms for every\n * entity — respecting each entity's capabilities and the server's RBAC. No per-entity code.\n */\nexport function MaestroAdmin(props: MaestroAdminProps) {\n const client = useMemo(\n () => props.client ?? new MaestroClient({ apiUrl: props.apiUrl ?? '', headers: props.headers }),\n [props.client, props.apiUrl, props.headers],\n );\n const strings = useMemo(() => stringsFor(props.locale ?? 'en'), [props.locale]);\n\n return (\n <AdminClientProvider value={client}>\n <I18nProvider value={strings}>\n <AdminShell title={props.title ?? 'Maestro Admin'} labels={props.labels} />\n </I18nProvider>\n </AdminClientProvider>\n );\n}\n","import type { EntityMetadata, ListQuery, ListResult, MaestroMetadata, Record_ } from './types.js';\n\nexport interface MaestroClientConfig {\n /** Base URL of the running maestro-server, e.g. `http://localhost:3000` or `/api/admin`. */\n apiUrl: string;\n /** Extra headers sent on every request — the place to inject an auth token (`Authorization`, `X-Role`, …). */\n headers?: Record<string, string> | (() => Record<string, string>);\n /** Custom fetch (SSR, tests). Defaults to the global `fetch`. */\n fetch?: typeof fetch;\n}\n\n/** Thrown for any non-2xx response, carrying the HTTP status and the parsed error body when present. */\nexport class MaestroApiError extends Error {\n constructor(\n readonly status: number,\n readonly code: string,\n message: string,\n ) {\n super(message);\n this.name = 'MaestroApiError';\n }\n}\n\nfunction buildListParams(query: ListQuery = {}): string {\n const params = new URLSearchParams();\n if (query.page !== undefined) params.set('page', String(query.page));\n if (query.pageSize !== undefined) params.set('pageSize', String(query.pageSize));\n if (query.search) {\n params.set('search', query.search);\n if (query.searchFields?.length) params.set('searchFields', query.searchFields.join(','));\n }\n for (const s of query.sort ?? []) params.append('sort', `${s.field}:${s.direction}`);\n for (const f of query.filters ?? []) {\n params.append('filter', f.value === undefined ? `${f.field}:${f.operator}` : `${f.field}:${f.operator}:${f.value}`);\n }\n const qs = params.toString();\n return qs ? `?${qs}` : '';\n}\n\n/**\n * A thin, framework-free client for the Maestro HTTP contract. Every admin component talks to the server\n * through this — it is the single seam where auth headers, base URL and error handling live.\n */\nexport class MaestroClient {\n private readonly base: string;\n private readonly doFetch: typeof fetch;\n\n constructor(private readonly config: MaestroClientConfig) {\n this.base = config.apiUrl.replace(/\\/$/, '');\n this.doFetch = config.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n private resolveHeaders(): Record<string, string> {\n const h = typeof this.config.headers === 'function' ? this.config.headers() : this.config.headers;\n return { ...h };\n }\n\n private async request<T>(path: string, init?: RequestInit): Promise<T> {\n const res = await this.doFetch(`${this.base}${path}`, {\n ...init,\n headers: {\n Accept: 'application/json',\n ...(init?.body ? { 'Content-Type': 'application/json' } : {}),\n ...this.resolveHeaders(),\n ...(init?.headers as Record<string, string> | undefined),\n },\n });\n\n if (res.status === 204) return undefined as T;\n\n const text = await res.text();\n const body = text ? (JSON.parse(text) as unknown) : undefined;\n\n if (!res.ok) {\n const err = body as { error?: string; message?: string } | undefined;\n throw new MaestroApiError(res.status, err?.error ?? 'ERROR', err?.message ?? res.statusText);\n }\n return body as T;\n }\n\n async getMetadata(): Promise<MaestroMetadata> {\n return this.request<MaestroMetadata>('/metadata');\n }\n\n async getEntityMetadata(entityId: string): Promise<EntityMetadata> {\n return this.request<EntityMetadata>(`/metadata/${encodeURIComponent(entityId)}`);\n }\n\n async list(entityId: string, query?: ListQuery): Promise<ListResult> {\n return this.request<ListResult>(`/entities/${encodeURIComponent(entityId)}${buildListParams(query)}`);\n }\n\n async findById(entityId: string, id: string): Promise<Record_> {\n return this.request<Record_>(`/entities/${encodeURIComponent(entityId)}/${encodeURIComponent(id)}`);\n }\n\n async create(entityId: string, data: Record_): Promise<Record_> {\n return this.request<Record_>(`/entities/${encodeURIComponent(entityId)}`, {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async update(entityId: string, id: string, data: Record_): Promise<Record_> {\n return this.request<Record_>(`/entities/${encodeURIComponent(entityId)}/${encodeURIComponent(id)}`, {\n method: 'PATCH',\n body: JSON.stringify(data),\n });\n }\n\n async remove(entityId: string, id: string): Promise<void> {\n await this.request<void>(`/entities/${encodeURIComponent(entityId)}/${encodeURIComponent(id)}`, {\n method: 'DELETE',\n });\n }\n}\n","import { createContext, useContext } from 'react';\nimport type { MaestroClient } from './client/MaestroClient.js';\nimport type { EntityMetadata } from './client/types.js';\n\nconst ClientContext = createContext<MaestroClient | null>(null);\n\nexport const AdminClientProvider = ClientContext.Provider;\n\n/** Returns the `MaestroClient` provided at the root of the admin. Throws if used outside the provider. */\nexport function useClient(): MaestroClient {\n const client = useContext(ClientContext);\n if (!client) {\n throw new Error('useClient must be used within a <MaestroAdmin> (no MaestroClient in context).');\n }\n return client;\n}\n\nconst EntitiesContext = createContext<EntityMetadata[]>([]);\n\nexport const AdminEntitiesProvider = EntitiesContext.Provider;\n\n/** All entities from the loaded metadata — lets deep components (relation chips) resolve a target entity. */\nexport function useEntities(): EntityMetadata[] {\n return useContext(EntitiesContext);\n}\n\nexport function useEntity(entityId: string | undefined): EntityMetadata | undefined {\n const entities = useEntities();\n return entityId ? entities.find((e) => e.id === entityId) : undefined;\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { useClient } from './AdminContext.js';\nimport type { EntityMetadata, FieldMetadata, ListQuery, ListResult, MaestroMetadata } from './client/types.js';\n\nexport interface AsyncState<T> {\n data: T | undefined;\n error: Error | undefined;\n loading: boolean;\n reload: () => void;\n}\n\n/** Runs an async producer, tracking loading/error and exposing a manual `reload`. Re-runs when `deps` change. */\nexport function useAsync<T>(producer: () => Promise<T>, deps: readonly unknown[]): AsyncState<T> {\n const [data, setData] = useState<T | undefined>(undefined);\n const [error, setError] = useState<Error | undefined>(undefined);\n const [loading, setLoading] = useState(true);\n const [tick, setTick] = useState(0);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n setError(undefined);\n producer()\n .then((result) => {\n if (!cancelled) setData(result);\n })\n .catch((err: unknown) => {\n if (!cancelled) setError(err instanceof Error ? err : new Error(String(err)));\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n return () => {\n cancelled = true;\n };\n }, [...deps, tick]);\n\n const reload = useCallback(() => setTick((t) => t + 1), []);\n return { data, error, loading, reload };\n}\n\n/** Loads the full metadata document (`GET /metadata`). */\nexport function useMetadata(): AsyncState<MaestroMetadata> {\n const client = useClient();\n return useAsync(() => client.getMetadata(), []);\n}\n\n/** Loads a page of records for one entity. */\nexport function useEntityList(entityId: string, query: ListQuery): AsyncState<ListResult> {\n const client = useClient();\n const key = JSON.stringify(query);\n return useAsync(() => client.list(entityId, query), [entityId, key]);\n}\n\n/** Loads a single record by id. */\nexport function useEntityRecord(\n entityId: string,\n id: string | undefined,\n): AsyncState<globalThis.Record<string, unknown>> {\n const client = useClient();\n return useAsync(async () => (id ? client.findById(entityId, id) : {}), [entityId, id]);\n}\n\n/** Fields shown in the list table, ordered, honoring per-field list visibility. */\nexport function listFields(entity: EntityMetadata) {\n return entity.fields\n .filter((f) => f.list.visible && !f.hidden)\n .sort((a, b) => (a.list.order ?? 0) - (b.list.order ?? 0));\n}\n\n// Types that never make a useful table column: unbounded blobs and structures.\nconst LIST_EXCLUDED_TYPES = new Set(['json', 'array', 'text']);\n\n// Lower rank ⇒ more \"principal\": identity texts first, then classification, relations, status,\n// dates, numbers; opaque values (uuid, long urls) last.\nfunction listColumnRank(field: FieldMetadata): number {\n switch (field.type) {\n case 'string':\n case 'email':\n case 'document':\n case 'phone':\n return 1;\n case 'enum':\n return 2;\n case 'relation':\n return 3;\n case 'boolean':\n return 4;\n case 'date':\n case 'datetime':\n case 'time':\n return 5;\n case 'uuid':\n return 7;\n case 'url':\n return 8;\n default:\n return 6;\n }\n}\n\n/**\n * The \"principal\" columns for an entity's table: instead of dumping every field, picks up to `max`\n * of the most identifying ones — the display field first, then searchable/required texts, enums,\n * relations, status booleans and dates — and drops blobs (`json`/`array`/`text`), sensitive values\n * and the primary key. Everything remains visible in the detail view. When any field carries an\n * explicit `list.order`/`list.width` (a curated schema), the curator's selection is honored as-is.\n */\nexport function primaryListFields(entity: EntityMetadata, max = 8): FieldMetadata[] {\n const all = listFields(entity);\n const curated = all.some((f) => f.list.order !== undefined || f.list.width !== undefined);\n if (curated || all.length <= max) return all;\n\n const scored = all\n .filter((f) => !f.sensitive && f.name !== entity.primaryKey && !LIST_EXCLUDED_TYPES.has(f.type))\n .map((field, index) => {\n let score = listColumnRank(field) * 10 + index * 0.01;\n if (field.searchable) score -= 5;\n if (field.required) score -= 2;\n if (field.name === entity.displayField) score = -100;\n return { field, score };\n })\n .sort((a, b) => a.score - b.score);\n\n return scored.slice(0, max).map((s) => s.field);\n}\n\n/** Fields shown in the detail view, ordered. */\nexport function detailFields(entity: EntityMetadata) {\n return entity.fields\n .filter((f) => f.detail.visible)\n .sort((a, b) => (a.detail.order ?? 0) - (b.detail.order ?? 0));\n}\n\n/** Fields editable in the create/update form, ordered, per mode. */\nexport function formFields(entity: EntityMetadata, mode: 'create' | 'edit') {\n return entity.fields\n .filter((f) => (mode === 'create' ? f.form.creatable : f.form.editable))\n .sort((a, b) => (a.form.order ?? 0) - (b.form.order ?? 0));\n}\n","import { useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\nimport type { EntityMetadata } from '../client/types.js';\nimport type { AdminLabels } from '../labels.js';\nimport { buildMenu } from '../grouping.js';\nimport { useT } from '../i18n.js';\n\n/** Lowercases and strips diacritics, so \"usuario\" finds \"Usuários\". */\nfunction normalize(text: string): string {\n return text.toLowerCase().normalize('NFD').replace(/\\p{M}/gu, '');\n}\n\n/**\n * The label with the matched substring highlighted (accent-insensitive, first occurrence). Folding\n * diacritics changes string length (\"á\" → \"a\" + combining mark under NFD), so match positions are\n * found in a folded copy and mapped back to original-label indices character by character.\n */\nfunction Highlight({ label, query }: { label: string; query: string }): ReactNode {\n const foldedQuery = normalize(query);\n if (!foldedQuery) return label;\n\n const folded: string[] = [];\n const originalIndex: number[] = [];\n for (let i = 0; i < label.length; i += 1) {\n for (const ch of normalize(label[i])) {\n folded.push(ch);\n originalIndex.push(i);\n }\n }\n\n const idx = folded.join('').indexOf(foldedQuery);\n if (idx === -1) return label;\n const start = originalIndex[idx];\n const end = (originalIndex[idx + foldedQuery.length - 1] ?? label.length - 1) + 1;\n\n return (\n <>\n {label.slice(0, start)}\n <mark className=\"rounded-sm bg-amber-200 text-inherit\">{label.slice(start, end)}</mark>\n {label.slice(end)}\n </>\n );\n}\n\nfunction EntityButton({\n entity,\n active,\n onSelect,\n subtitle,\n query,\n}: {\n entity: EntityMetadata;\n active: boolean;\n onSelect: (entityId: string) => void;\n subtitle?: string;\n query?: string;\n}) {\n return (\n <button\n onClick={() => onSelect(entity.id)}\n className={`flex w-full flex-col rounded-md px-3 py-1.5 text-left text-sm transition-colors ${\n active ? 'bg-indigo-100 font-medium text-indigo-700' : 'text-slate-700 hover:bg-slate-100'\n }`}\n >\n <span className=\"truncate\">\n {query ? <Highlight label={entity.label.plural} query={query} /> : entity.label.plural}\n </span>\n {subtitle && <span className=\"truncate text-xs font-normal text-slate-400\">{subtitle}</span>}\n </button>\n );\n}\n\nfunction SectionTitle({ children }: { children: ReactNode }) {\n return (\n <div className=\"px-3 pb-1 pt-3 text-xs font-semibold uppercase tracking-wide text-slate-400\">{children}</div>\n );\n}\n\nexport function Sidebar({\n entities,\n activeId,\n onSelect,\n title,\n labels,\n recents = [],\n}: {\n entities: EntityMetadata[];\n activeId: string | undefined;\n onSelect: (entityId: string) => void;\n title: string;\n /** Same object given to `<MaestroAdmin labels>` — supplies folder assignments and folder names. */\n labels?: AdminLabels;\n /** Recently-visited entity ids, most recent first. */\n recents?: string[];\n}) {\n const t = useT();\n const [query, setQuery] = useState('');\n const [expanded, setExpanded] = useState<Record<string, boolean>>({});\n const searchRef = useRef<HTMLInputElement>(null);\n\n const menu = useMemo(() => buildMenu(entities, labels), [entities, labels]);\n const groupOf = useMemo(() => {\n const map = new Map<string, string>();\n for (const group of menu.groups) for (const e of group.entities) map.set(e.id, group.label);\n return map;\n }, [menu]);\n\n const recentEntities = recents\n .map((id) => entities.find((e) => e.id === id))\n .filter((e): e is EntityMetadata => Boolean(e))\n .slice(0, 6);\n\n const results = useMemo(() => {\n if (!query) return [];\n const q = normalize(query);\n return entities\n .filter((e) => normalize(`${e.label.plural} ${e.label.singular} ${e.table}`).includes(q))\n .sort((a, b) => a.label.plural.localeCompare(b.label.plural));\n }, [entities, query]);\n\n // Ctrl+K / Cmd+K focuses the menu search from anywhere.\n useEffect(() => {\n const onKey = (e: KeyboardEvent): void => {\n if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'k') {\n e.preventDefault();\n searchRef.current?.focus();\n }\n };\n document.addEventListener('keydown', onKey);\n return () => document.removeEventListener('keydown', onKey);\n }, []);\n\n const select = (entityId: string): void => {\n setQuery('');\n onSelect(entityId);\n };\n\n const isExpanded = (groupId: string, hasActive: boolean): boolean => expanded[groupId] ?? hasActive;\n\n return (\n <aside className=\"flex w-64 shrink-0 flex-col border-r border-slate-200 bg-slate-50\">\n <div className=\"border-b border-slate-200 px-4 py-4\">\n <span className=\"text-sm font-semibold tracking-tight text-slate-900\">{title}</span>\n </div>\n\n <div className=\"px-2 pt-2\">\n <input\n ref={searchRef}\n type=\"search\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Escape') setQuery('');\n if (e.key === 'Enter' && results[0]) select(results[0].id);\n }}\n placeholder={`${t.searchMenu} (Ctrl+K)`}\n className=\"w-full rounded-md border border-slate-300 bg-white px-3 py-1.5 text-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500\"\n />\n </div>\n\n <nav className=\"flex-1 overflow-y-auto p-2\">\n {query ? (\n results.length === 0 ? (\n <p className=\"px-3 py-2 text-sm text-slate-400\">{t.noMenuResults}</p>\n ) : (\n results.map((e) => (\n <EntityButton\n key={e.id}\n entity={e}\n active={e.id === activeId}\n onSelect={select}\n subtitle={groupOf.get(e.id)}\n query={query}\n />\n ))\n )\n ) : (\n <>\n {recentEntities.length > 0 && (\n <>\n <SectionTitle>{t.recents}</SectionTitle>\n {recentEntities.map((e) => (\n <EntityButton key={e.id} entity={e} active={e.id === activeId} onSelect={select} />\n ))}\n </>\n )}\n\n <SectionTitle>{t.menus}</SectionTitle>\n {menu.groups.map((group) => {\n const hasActive = group.entities.some((e) => e.id === activeId);\n const open = isExpanded(group.id, hasActive);\n return (\n <div key={group.id}>\n <button\n onClick={() => setExpanded((prev) => ({ ...prev, [group.id]: !open }))}\n className=\"flex w-full items-center gap-1.5 rounded-md px-3 py-1.5 text-left text-sm font-medium text-slate-600 hover:bg-slate-100\"\n >\n <span className=\"text-xs text-slate-400\">{open ? '▾' : '▸'}</span>\n <span className=\"truncate\">{group.label}</span>\n <span className=\"ml-auto text-xs text-slate-400\">{group.entities.length}</span>\n </button>\n {open && (\n <div className=\"ml-3 border-l border-slate-200 pl-1\">\n {group.entities.map((e) => (\n <EntityButton key={e.id} entity={e} active={e.id === activeId} onSelect={select} />\n ))}\n </div>\n )}\n </div>\n );\n })}\n {menu.ungrouped.map((e) => (\n <EntityButton key={e.id} entity={e} active={e.id === activeId} onSelect={select} />\n ))}\n </>\n )}\n </nav>\n\n <div className=\"border-t border-slate-200 px-4 py-3 text-xs text-slate-400\">\n {t.entitiesFooter(entities.length)}\n </div>\n </aside>\n );\n}\n","import type { EntityMetadata } from './client/types.js';\nimport type { AdminLabels } from './labels.js';\n\nexport interface MenuGroup {\n /** Stable key: the explicit group name, or the heuristic table-name prefix. */\n id: string;\n label: string;\n entities: EntityMetadata[];\n}\n\nexport interface SidebarMenu {\n groups: MenuGroup[];\n /** Entities that belong to no group — rendered flat after the folders. */\n ungrouped: EntityMetadata[];\n}\n\n// A heuristic cluster needs a meaningful shared prefix (≥ 4 chars keeps `ai*`-style accidents out)\n// and at least two members — a \"folder\" of one is worse than a flat item.\nconst MIN_PREFIX = 4;\n\nfunction commonPrefix(a: string, b: string): string {\n let i = 0;\n while (i < a.length && i < b.length && a[i] === b[i]) i += 1;\n return a.slice(0, i);\n}\n\nfunction humanize(prefix: string): string {\n return prefix.charAt(0).toUpperCase() + prefix.slice(1);\n}\n\n/**\n * Builds the sidebar menu structure: explicit groups first (an entity override's `group` in\n * `AdminLabels` always wins), then heuristic clustering of what's left — collections sharing a\n * table-name prefix (`recoveryactions`, `recoveryscores`, … → \"Recovery\") become a folder, since a\n * shared prefix is how schemaless databases usually encode the module a collection belongs to.\n * Heuristic folder names can be localized via `labels.groups` (prefix → display name). Everything\n * else stays flat. Groups and their entities are sorted by label.\n */\nexport function buildMenu(entities: EntityMetadata[], labels?: AdminLabels): SidebarMenu {\n const byGroup = new Map<string, MenuGroup>();\n const rest: EntityMetadata[] = [];\n\n for (const entity of entities) {\n const override = labels?.entities?.[entity.id] ?? labels?.entities?.[entity.table];\n if (override?.group) {\n const existing = byGroup.get(override.group);\n if (existing) existing.entities.push(entity);\n else byGroup.set(override.group, { id: override.group, label: override.group, entities: [entity] });\n } else {\n rest.push(entity);\n }\n }\n\n // Heuristic pass: walk tables in lexicographic order and greedily grow clusters while the common\n // prefix across every member stays meaningful.\n const sorted = [...rest].sort((a, b) => (a.table < b.table ? -1 : a.table > b.table ? 1 : 0));\n const ungrouped: EntityMetadata[] = [];\n let i = 0;\n while (i < sorted.length) {\n let prefix = i + 1 < sorted.length ? commonPrefix(sorted[i].table, sorted[i + 1].table) : '';\n if (prefix.length < MIN_PREFIX) {\n ungrouped.push(sorted[i]);\n i += 1;\n continue;\n }\n let end = i + 1;\n while (end + 1 < sorted.length) {\n const next = commonPrefix(prefix, sorted[end + 1].table);\n if (next.length < MIN_PREFIX) break;\n prefix = next;\n end += 1;\n }\n const members = sorted.slice(i, end + 1);\n const label = labels?.groups?.[prefix] ?? humanize(prefix);\n const existing = byGroup.get(prefix);\n if (existing) existing.entities.push(...members);\n else byGroup.set(prefix, { id: prefix, label, entities: members });\n i = end + 1;\n }\n\n const collator = (a: string, b: string): number => a.localeCompare(b);\n const groups = [...byGroup.values()].sort((a, b) => collator(a.label, b.label));\n for (const group of groups) {\n group.entities.sort((a, b) => collator(a.label.plural, b.label.plural));\n }\n ungrouped.sort((a, b) => collator(a.label.plural, b.label.plural));\n\n return { groups, ungrouped };\n}\n","import { createContext, useContext } from 'react';\n\nexport type AdminLocale = 'en' | 'pt-BR';\n\n/**\n * Every user-facing string the admin chrome renders. Entity/field labels are NOT here — those come\n * from the server metadata (optionally rewritten via `AdminLabels`); this dictionary covers only the\n * UI around them (buttons, menus, pagination, confirmations).\n */\nexport interface AdminStrings {\n loading: string;\n loadingMetadata: string;\n records: (total: number) => string;\n searchPlaceholder: (plural: string) => string;\n newRecord: string;\n view: string;\n edit: string;\n clone: string;\n remove: string;\n copyId: string;\n copyObject: string;\n copyValue: string;\n copied: string;\n addToFilter: string;\n openRelated: (label: string) => string;\n filters: string;\n clearFilters: string;\n actions: string;\n noRecords: string;\n tryDifferentSearch: string;\n deleteConfirm: (singular: string) => string;\n page: (page: number, total: number) => string;\n previous: string;\n next: string;\n cancel: string;\n save: string;\n saving: string;\n create: string;\n newTitle: (singular: string) => string;\n editTitle: (singular: string) => string;\n cloneTitle: (singular: string) => string;\n entitiesFooter: (count: number) => string;\n yes: string;\n no: string;\n jsonFormMode: string;\n jsonRawMode: string;\n jsonInvalid: string;\n emptyObject: string;\n addItem: string;\n removeItem: string;\n searchMenu: string;\n recents: string;\n menus: string;\n noMenuResults: string;\n}\n\nconst EN: AdminStrings = {\n loading: 'Loading…',\n loadingMetadata: 'Loading metadata…',\n records: (total) => `${total} record${total === 1 ? '' : 's'}`,\n searchPlaceholder: (plural) => `Search ${plural.toLowerCase()}…`,\n newRecord: '+ New',\n view: 'View',\n edit: 'Edit',\n clone: 'Clone',\n remove: 'Remove',\n copyId: 'Copy ID',\n copyObject: 'Copy object',\n copyValue: 'Copy value',\n copied: 'Copied!',\n addToFilter: 'Add to filter',\n openRelated: (label) => `Open ${label}`,\n filters: 'Filters',\n clearFilters: 'Clear filters',\n actions: 'Actions',\n noRecords: 'No records',\n tryDifferentSearch: 'Try a different search.',\n deleteConfirm: (singular) => `Delete this ${singular.toLowerCase()}? This cannot be undone.`,\n page: (page, total) => `Page ${page} of ${total}`,\n previous: 'Previous',\n next: 'Next',\n cancel: 'Cancel',\n save: 'Save',\n saving: 'Saving…',\n create: 'Create',\n newTitle: (singular) => `New ${singular}`,\n editTitle: (singular) => `Edit ${singular}`,\n cloneTitle: (singular) => `Clone ${singular}`,\n entitiesFooter: (count) => `${count} entities · Maestro`,\n yes: 'true',\n no: 'false',\n jsonFormMode: 'Fields',\n jsonRawMode: 'JSON',\n jsonInvalid: 'Invalid JSON — fix it to apply this change.',\n emptyObject: '(empty)',\n addItem: 'Add item',\n removeItem: 'Remove item',\n searchMenu: 'Search menu…',\n recents: 'Recents',\n menus: 'Menus',\n noMenuResults: 'No matches',\n};\n\nconst PT_BR: AdminStrings = {\n loading: 'Carregando…',\n loadingMetadata: 'Carregando metadados…',\n records: (total) => `${total} registro${total === 1 ? '' : 's'}`,\n searchPlaceholder: (plural) => `Buscar ${plural.toLowerCase()}…`,\n newRecord: '+ Novo',\n view: 'Visualizar',\n edit: 'Editar',\n clone: 'Clonar',\n remove: 'Remover',\n copyId: 'Copiar ID',\n copyObject: 'Copiar objeto',\n copyValue: 'Copiar valor',\n copied: 'Copiado!',\n addToFilter: 'Adicionar ao filtro',\n openRelated: (label) => `Abrir ${label}`,\n filters: 'Filtros',\n clearFilters: 'Limpar filtros',\n actions: 'Ações',\n noRecords: 'Nenhum registro',\n tryDifferentSearch: 'Tente uma busca diferente.',\n deleteConfirm: (singular) => `Remover este registro de ${singular}? Essa ação não pode ser desfeita.`,\n page: (page, total) => `Página ${page} de ${total}`,\n previous: 'Anterior',\n next: 'Próxima',\n cancel: 'Cancelar',\n save: 'Salvar',\n saving: 'Salvando…',\n create: 'Criar',\n newTitle: (singular) => `Novo(a) ${singular}`,\n editTitle: (singular) => `Editar ${singular}`,\n cloneTitle: (singular) => `Clonar ${singular}`,\n entitiesFooter: (count) => `${count} entidades · Maestro`,\n yes: 'sim',\n no: 'não',\n jsonFormMode: 'Campos',\n jsonRawMode: 'JSON',\n jsonInvalid: 'JSON inválido — corrija para aplicar esta alteração.',\n emptyObject: '(vazio)',\n addItem: 'Adicionar item',\n removeItem: 'Remover item',\n searchMenu: 'Buscar no menu…',\n recents: 'Recentes',\n menus: 'Menus',\n noMenuResults: 'Nada encontrado',\n};\n\nconst LOCALES: Record<AdminLocale, AdminStrings> = { en: EN, 'pt-BR': PT_BR };\n\nexport function stringsFor(locale: AdminLocale): AdminStrings {\n return LOCALES[locale] ?? EN;\n}\n\nconst I18nContext = createContext<AdminStrings>(EN);\n\nexport const I18nProvider = I18nContext.Provider;\n\n/** The active UI-string dictionary (set by `<MaestroAdmin locale>`; defaults to English). */\nexport function useT(): AdminStrings {\n return useContext(I18nContext);\n}\n","import { useMemo, useState } from 'react';\nimport type { EntityMetadata, FieldMetadata, FilterInput, ListQuery, Record_, SortInput } from '../client/types.js';\nimport { useClient, useEntities } from '../AdminContext.js';\nimport { primaryListFields, useEntityList } from '../hooks.js';\nimport { FieldValue } from './FieldValue.js';\nimport { Button, EmptyState, ErrorBanner, Spinner } from './ui.js';\nimport { PopMenu, MenuButton, type MenuAnchor, type MenuItem } from './menu.js';\nimport { useT } from '../i18n.js';\nimport { copyText } from '../clipboard.js';\n\nconst PAGE_SIZE = 20;\n\ninterface CellMenuState {\n anchor: MenuAnchor;\n field: FieldMetadata;\n record: Record_;\n}\n\nfunction filterFor(field: FieldMetadata, value: unknown): FilterInput | undefined {\n if (value === null || value === undefined) return { field: field.name, operator: 'isNull' };\n if (field.type === 'boolean') return { field: field.name, operator: value ? 'isTrue' : 'isFalse' };\n if (field.type === 'json' || field.type === 'array') return undefined;\n return { field: field.name, operator: 'equals', value: String(value) };\n}\n\nfunction filterChipText(entity: EntityMetadata, filter: FilterInput): string {\n const label = entity.fields.find((f) => f.name === filter.field)?.label ?? filter.field;\n if (filter.operator === 'isNull') return `${label} = ∅`;\n if (filter.operator === 'isTrue') return `${label} = ✓`;\n if (filter.operator === 'isFalse') return `${label} = ✗`;\n const value = filter.value ?? '';\n return `${label} = ${value.length > 24 ? `${value.slice(0, 24)}…` : value}`;\n}\n\nexport function EntityList({\n entity,\n onOpen,\n onCreate,\n onEdit,\n onClone,\n onNavigate,\n initialFilters,\n}: {\n entity: EntityMetadata;\n onOpen: (id: string) => void;\n onCreate: () => void;\n onEdit: (id: string) => void;\n onClone: (id: string) => void;\n onNavigate: (entityId: string, id: string) => void;\n initialFilters?: FilterInput[];\n}) {\n const client = useClient();\n const t = useT();\n const entities = useEntities();\n const relatedLabel = (entityId: string): string =>\n entities.find((e) => e.id === entityId)?.label.singular ?? entityId;\n const columns = useMemo(() => primaryListFields(entity), [entity]);\n const searchFields = useMemo(() => entity.fields.filter((f) => f.searchable).map((f) => f.name), [entity]);\n\n const [page, setPage] = useState(1);\n const [search, setSearch] = useState('');\n const [sort, setSort] = useState<SortInput | undefined>(undefined);\n const [filters, setFilters] = useState<FilterInput[]>(initialFilters ?? []);\n const [cellMenu, setCellMenu] = useState<CellMenuState | undefined>(undefined);\n const [copied, setCopied] = useState(false);\n\n const query: ListQuery = {\n page,\n pageSize: PAGE_SIZE,\n search: search || undefined,\n searchFields,\n sort: sort ? [sort] : undefined,\n filters: filters.length ? filters : undefined,\n };\n const { data, error, loading, reload } = useEntityList(entity.id, query);\n\n const toggleSort = (fieldName: string): void => {\n setSort((prev) =>\n prev?.field === fieldName\n ? { field: fieldName, direction: prev.direction === 'asc' ? 'desc' : 'asc' }\n : { field: fieldName, direction: 'asc' },\n );\n };\n\n const flashCopied = (): void => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n };\n\n const copy = async (text: string): Promise<void> => {\n await copyText(text);\n flashCopied();\n };\n\n const addFilter = (filter: FilterInput): void => {\n setFilters((prev) => {\n const others = prev.filter((f) => f.field !== filter.field);\n return [...others, filter];\n });\n setPage(1);\n };\n\n const onDelete = async (id: string): Promise<void> => {\n if (!globalThis.confirm(t.deleteConfirm(entity.label.singular))) return;\n await client.remove(entity.id, id);\n reload();\n };\n\n const rowMenuItems = (record: Record_): MenuItem[] => {\n const id = String(record[entity.primaryKey]);\n const items: MenuItem[] = [{ id: 'view', label: `👁 ${t.view}`, onSelect: () => onOpen(id) }];\n if (entity.capabilities.update) items.push({ id: 'edit', label: `✏️ ${t.edit}`, onSelect: () => onEdit(id) });\n if (entity.capabilities.clone && entity.capabilities.create) {\n items.push({ id: 'clone', label: `⧉ ${t.clone}`, onSelect: () => onClone(id) });\n }\n items.push(\n { id: 'copy-id', label: `⎘ ${t.copyId}`, onSelect: () => void copy(id) },\n { id: 'copy-object', label: `{} ${t.copyObject}`, onSelect: () => void copy(JSON.stringify(record, null, 2)) },\n );\n if (entity.capabilities.delete) {\n items.push({ id: 'remove', label: `🗑 ${t.remove}`, danger: true, onSelect: () => void onDelete(id) });\n }\n return items;\n };\n\n const cellMenuItems = (state: CellMenuState): MenuItem[] => {\n const { field, record } = state;\n const id = String(record[entity.primaryKey]);\n const value = record[field.name];\n const items: MenuItem[] = [];\n\n const filter = filterFor(field, value);\n if (filter) items.push({ id: 'filter', label: `▼ ${t.addToFilter}`, onSelect: () => addFilter(filter) });\n\n items.push({ id: 'view', label: `👁 ${t.view}`, onSelect: () => onOpen(id) });\n if (entity.capabilities.update) items.push({ id: 'edit', label: `✏️ ${t.edit}`, onSelect: () => onEdit(id) });\n\n if (field.type === 'relation' && field.relationEntity && value !== null && value !== undefined) {\n const targetId = field.relationEntity;\n items.push({\n id: 'open-related',\n label: `↗ ${t.openRelated(relatedLabel(targetId))}`,\n onSelect: () => onNavigate(targetId, String(value)),\n });\n }\n\n if (value !== null && value !== undefined) {\n items.push({\n id: 'copy-value',\n label: `⎘ ${t.copyValue}`,\n onSelect: () => void copy(typeof value === 'object' ? JSON.stringify(value) : String(value)),\n });\n }\n return items;\n };\n\n const totalPages = data?.totalPages ?? (data ? Math.max(1, Math.ceil(data.total / PAGE_SIZE)) : 1);\n\n return (\n <section className=\"space-y-4\">\n <header className=\"flex flex-wrap items-center justify-between gap-3\">\n <div>\n <h1 className=\"text-lg font-semibold text-slate-900\">{entity.label.plural}</h1>\n {data && <p className=\"text-sm text-slate-500\">{t.records(data.total)}</p>}\n </div>\n <div className=\"flex items-center gap-2\">\n {searchFields.length > 0 && (\n <input\n type=\"search\"\n placeholder={t.searchPlaceholder(entity.label.plural)}\n value={search}\n onChange={(e) => {\n setSearch(e.target.value);\n setPage(1);\n }}\n className=\"rounded-md border border-slate-300 px-3 py-1.5 text-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500\"\n />\n )}\n {entity.capabilities.create && (\n <Button variant=\"primary\" onClick={onCreate}>\n {t.newRecord}\n </Button>\n )}\n </div>\n </header>\n\n {filters.length > 0 && (\n <div className=\"flex flex-wrap items-center gap-2 text-sm\">\n <span className=\"text-slate-500\">{t.filters}:</span>\n {filters.map((f) => (\n <button\n key={f.field}\n onClick={() => {\n setFilters((prev) => prev.filter((p) => p.field !== f.field));\n setPage(1);\n }}\n title={f.value}\n className=\"inline-flex items-center gap-1 rounded-full bg-indigo-50 px-2.5 py-0.5 text-xs font-medium text-indigo-700 hover:bg-indigo-100\"\n >\n {filterChipText(entity, f)}\n <span aria-hidden>×</span>\n </button>\n ))}\n <button\n onClick={() => {\n setFilters([]);\n setPage(1);\n }}\n className=\"text-xs text-slate-500 underline hover:text-slate-700\"\n >\n {t.clearFilters}\n </button>\n </div>\n )}\n\n {error && <ErrorBanner error={error} />}\n\n {loading && !data ? (\n <Spinner label={t.loading} />\n ) : data && data.records.length === 0 ? (\n <EmptyState title={t.noRecords} hint={search || filters.length ? t.tryDifferentSearch : undefined} />\n ) : (\n <div className=\"overflow-x-auto rounded-lg border border-slate-200\">\n <table className=\"min-w-full divide-y divide-slate-200 text-sm\">\n <thead className=\"bg-slate-50\">\n <tr>\n {columns.map((f) => (\n <th\n key={f.name}\n onClick={() => f.sortable && toggleSort(f.name)}\n className={`px-3 py-2 text-left font-medium text-slate-600 ${f.sortable ? 'cursor-pointer select-none hover:text-slate-900' : ''}`}\n >\n {f.label}\n {sort?.field === f.name && (sort.direction === 'asc' ? ' ▲' : ' ▼')}\n </th>\n ))}\n <th className=\"px-3 py-2 text-right font-medium text-slate-600\">{t.actions}</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-slate-100 bg-white\">\n {data?.records.map((record, i) => {\n const id = String(record[entity.primaryKey]);\n return (\n <tr key={id || i} className=\"hover:bg-slate-50\">\n {columns.map((f) => (\n <td\n key={f.name}\n className=\"cursor-pointer px-3 py-2 align-top\"\n onClick={(e) =>\n setCellMenu({ anchor: { x: e.clientX, y: e.clientY }, field: f, record })\n }\n onDoubleClick={() => onOpen(id)}\n >\n <FieldValue field={f} value={record[f.name]} compact />\n </td>\n ))}\n <td className=\"whitespace-nowrap px-3 py-2 text-right\">\n <MenuButton label={t.actions} items={rowMenuItems(record)} />\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n )}\n\n {cellMenu && (\n <PopMenu anchor={cellMenu.anchor} items={cellMenuItems(cellMenu)} onClose={() => setCellMenu(undefined)} />\n )}\n\n {copied && (\n <div className=\"fixed bottom-4 right-4 z-50 rounded-md bg-slate-900 px-3 py-1.5 text-sm text-white shadow-lg\">\n {t.copied}\n </div>\n )}\n\n {data && totalPages > 1 && (\n <div className=\"flex items-center justify-end gap-2 text-sm\">\n <Button variant=\"secondary\" disabled={page <= 1} onClick={() => setPage((p) => p - 1)}>\n {t.previous}\n </Button>\n <span className=\"text-slate-500\">{t.page(page, totalPages)}</span>\n <Button variant=\"secondary\" disabled={page >= totalPages} onClick={() => setPage((p) => p + 1)}>\n {t.next}\n </Button>\n </div>\n )}\n </section>\n );\n}\n","import type { ButtonHTMLAttributes, ReactNode } from 'react';\n\ntype Variant = 'primary' | 'secondary' | 'danger' | 'ghost';\n\nconst VARIANTS: Record<Variant, string> = {\n primary: 'bg-indigo-600 text-white hover:bg-indigo-500 disabled:bg-indigo-300',\n secondary: 'bg-white text-slate-700 ring-1 ring-inset ring-slate-300 hover:bg-slate-50',\n danger: 'bg-red-600 text-white hover:bg-red-500 disabled:bg-red-300',\n ghost: 'text-slate-600 hover:bg-slate-100',\n};\n\nexport function Button({\n variant = 'secondary',\n className = '',\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & { variant?: Variant }) {\n return (\n <button\n className={`inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium transition-colors disabled:cursor-not-allowed ${VARIANTS[variant]} ${className}`}\n {...props}\n />\n );\n}\n\nexport function Badge({ children, tone = 'slate' }: { children: ReactNode; tone?: 'slate' | 'green' | 'red' | 'amber' | 'indigo' }) {\n const tones: Record<string, string> = {\n slate: 'bg-slate-100 text-slate-700',\n green: 'bg-green-100 text-green-700',\n red: 'bg-red-100 text-red-700',\n amber: 'bg-amber-100 text-amber-700',\n indigo: 'bg-indigo-100 text-indigo-700',\n };\n return (\n <span className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${tones[tone]}`}>\n {children}\n </span>\n );\n}\n\nexport function Spinner({ label }: { label?: string }) {\n return (\n <div className=\"flex items-center gap-2 text-sm text-slate-500\" role=\"status\">\n <span className=\"h-4 w-4 animate-spin rounded-full border-2 border-slate-300 border-t-indigo-600\" />\n {label ?? 'Loading…'}\n </div>\n );\n}\n\nexport function EmptyState({ title, hint }: { title: string; hint?: string }) {\n return (\n <div className=\"rounded-lg border border-dashed border-slate-300 p-8 text-center\">\n <p className=\"text-sm font-medium text-slate-700\">{title}</p>\n {hint && <p className=\"mt-1 text-sm text-slate-500\">{hint}</p>}\n </div>\n );\n}\n\nexport function ErrorBanner({ error }: { error: Error }) {\n return (\n <div className=\"rounded-md border border-red-200 bg-red-50 p-3 text-sm text-red-700\" role=\"alert\">\n {error.message}\n </div>\n );\n}\n","import { useEffect, useState } from 'react';\nimport type { FieldMetadata } from '../client/types.js';\nimport { useClient, useEntity } from '../AdminContext.js';\nimport type { MaestroClient } from '../client/MaestroClient.js';\n\n// Display values already resolved this session, keyed by `entityId/recordId`. A tiny, ever-growing\n// cache is the right trade-off here: relation columns repeat the same handful of ids page after page.\nconst displayCache = new Map<string, Promise<string | undefined>>();\n\nfunction resolveDisplay(\n client: MaestroClient,\n entityId: string,\n displayField: string,\n id: string,\n): Promise<string | undefined> {\n const key = `${entityId}/${id}`;\n let cached = displayCache.get(key);\n if (!cached) {\n cached = client\n .findById(entityId, id)\n .then((record) => {\n const value = record[displayField];\n return value === null || value === undefined || value === '' ? undefined : String(value);\n })\n .catch(() => undefined);\n displayCache.set(key, cached);\n }\n return cached;\n}\n\nfunction shortId(id: string): string {\n return id.length > 12 ? `${id.slice(0, 6)}…${id.slice(-4)}` : id;\n}\n\n/**\n * Renders a relation field's value as a chip labeled with the *related record's* display value\n * (fetched lazily and cached) instead of a bare foreign id. Falls back to a shortened id while\n * loading or when the related record is unreachable.\n */\nexport function RelationValue({ field, value }: { field: FieldMetadata; value: unknown }) {\n const client = useClient();\n const target = useEntity(field.relationEntity);\n const id = String(value);\n const [display, setDisplay] = useState<string | undefined>(undefined);\n\n useEffect(() => {\n let cancelled = false;\n setDisplay(undefined);\n if (!target || target.displayField === target.primaryKey) return;\n resolveDisplay(client, target.id, target.displayField, id).then((resolved) => {\n if (!cancelled) setDisplay(resolved);\n });\n return () => {\n cancelled = true;\n };\n }, [client, target, id]);\n\n return (\n <span\n title={id}\n className=\"inline-flex max-w-56 items-center gap-1 truncate rounded border border-slate-200 bg-slate-50 px-1.5 py-0.5 text-xs font-medium text-slate-700\"\n >\n {target && <span className=\"text-slate-400\">{target.label.singular}:</span>}\n <span className=\"truncate\">{display ?? shortId(id)}</span>\n </span>\n );\n}\n","import { useT } from '../i18n.js';\n\n/** Matches ISO-8601 timestamps so object entries like `\"2026-05-12T19:46:15.347Z\"` render as local dates. */\nconst ISO_DATETIME = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}/;\n\nconst MAX_DEPTH = 4;\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction Primitive({ value }: { value: unknown }) {\n if (value === null || value === undefined) {\n return <span className=\"text-slate-400\">—</span>;\n }\n if (typeof value === 'boolean' || typeof value === 'number') {\n return <code className=\"text-xs font-medium text-indigo-700\">{String(value)}</code>;\n }\n const text = String(value);\n if (ISO_DATETIME.test(text)) {\n const d = new Date(text);\n if (!Number.isNaN(d.getTime())) {\n return <span className=\"whitespace-nowrap text-slate-700\">{d.toLocaleString()}</span>;\n }\n }\n return <span className=\"break-all text-slate-700\">{text}</span>;\n}\n\n/**\n * Read-only structured rendering for object/array values: one row per key (arrays use indexes),\n * recursing into nested objects — instead of dumping raw JSON at the user.\n */\nexport function ObjectValue({ value, depth = 0 }: { value: unknown; depth?: number }) {\n const t = useT();\n\n if (!isPlainObject(value) && !Array.isArray(value)) {\n return <Primitive value={value} />;\n }\n\n if (depth >= MAX_DEPTH) {\n return (\n <code className=\"block max-w-md overflow-x-auto rounded bg-slate-50 px-1.5 py-0.5 text-xs text-slate-700\">\n {JSON.stringify(value)}\n </code>\n );\n }\n\n const entries: Array<[string, unknown]> = Array.isArray(value)\n ? value.map((v, i) => [String(i), v] as [string, unknown])\n : Object.entries(value);\n\n if (entries.length === 0) {\n return <span className=\"text-slate-400\">{t.emptyObject}</span>;\n }\n\n return (\n <dl\n className={\n depth === 0\n ? 'w-full divide-y divide-slate-100 rounded-md border border-slate-200 bg-slate-50/50'\n : 'w-full divide-y divide-slate-100 border-l-2 border-slate-200 pl-2'\n }\n >\n {entries.map(([key, entry]) => (\n // flex-wrap + basis: deeply nested values drop to their own full-width line instead of squeezing.\n <div key={key} className=\"flex flex-wrap items-start gap-x-3 gap-y-1 px-3 py-1.5\">\n <dt className=\"w-36 shrink-0 truncate pt-px text-xs font-medium text-slate-500\" title={key}>\n {key}\n </dt>\n <dd className=\"min-w-0 flex-1 basis-56 text-sm\">\n {isPlainObject(entry) || Array.isArray(entry) ? (\n <ObjectValue value={entry} depth={depth + 1} />\n ) : (\n <Primitive value={entry} />\n )}\n </dd>\n </div>\n ))}\n </dl>\n );\n}\n","import type { FieldMetadata } from '../client/types.js';\nimport { Badge } from './ui.js';\nimport { RelationValue } from './RelationValue.js';\nimport { ObjectValue } from './ObjectValue.js';\nimport { useT } from '../i18n.js';\n\nfunction enumLabel(field: FieldMetadata, value: unknown): string {\n const opt = field.enumOptions?.find((o) => o.value === value);\n return opt ? opt.label : String(value);\n}\n\n/**\n * Renders a single record value read-only, shaped by the field's type (for tables and detail views).\n * `compact` is the table-cell mode: long text truncates instead of stretching the row.\n */\nexport function FieldValue({ field, value, compact = false }: { field: FieldMetadata; value: unknown; compact?: boolean }) {\n const t = useT();\n\n if (value === null || value === undefined || value === '') {\n return <span className=\"text-slate-400\">—</span>;\n }\n\n if (field.sensitive) {\n return <span className=\"text-slate-400\">••••••</span>;\n }\n\n switch (field.type) {\n case 'boolean':\n return value ? <Badge tone=\"green\">{t.yes}</Badge> : <Badge tone=\"slate\">{t.no}</Badge>;\n case 'enum':\n return <Badge tone=\"indigo\">{enumLabel(field, value)}</Badge>;\n case 'relation':\n return field.relationEntity ? (\n <RelationValue field={field} value={value} />\n ) : (\n <span className=\"text-slate-700\">{String(value)}</span>\n );\n case 'date':\n case 'datetime': {\n const d = new Date(String(value));\n return <span className=\"whitespace-nowrap\">{Number.isNaN(d.getTime()) ? String(value) : d.toLocaleString()}</span>;\n }\n case 'json':\n if (compact) {\n return (\n <code className=\"block max-w-xs truncate overflow-x-auto rounded bg-slate-50 px-1.5 py-0.5 text-xs text-slate-700\">\n {JSON.stringify(value)}\n </code>\n );\n }\n if (typeof value === 'object') {\n return <ObjectValue value={value} />;\n }\n return (\n <code className=\"block max-w-md overflow-x-auto rounded bg-slate-50 px-1.5 py-0.5 text-xs text-slate-700\">\n {JSON.stringify(value)}\n </code>\n );\n default:\n return <span className={`text-slate-700 ${compact ? 'block max-w-64 truncate' : ''}`}>{String(value)}</span>;\n }\n}\n","import { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\n\nexport interface MenuItem {\n id: string;\n label: ReactNode;\n danger?: boolean;\n onSelect: () => void;\n}\n\nexport interface MenuAnchor {\n x: number;\n y: number;\n}\n\n/**\n * A floating menu rendered in a portal at a fixed viewport position — immune to the table's\n * `overflow-x` clipping. Closes on outside click, Escape, scroll or resize. Purely presentational:\n * callers decide the anchor (a button's rect, a clicked cell) and the items.\n */\nexport function PopMenu({ anchor, items, onClose }: { anchor: MenuAnchor; items: MenuItem[]; onClose: () => void }) {\n const ref = useRef<HTMLDivElement>(null);\n const [pos, setPos] = useState(anchor);\n\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n setPos({\n x: Math.max(4, Math.min(anchor.x, window.innerWidth - rect.width - 8)),\n y: Math.max(4, Math.min(anchor.y, window.innerHeight - rect.height - 8)),\n });\n }, [anchor]);\n\n useEffect(() => {\n const onDown = (e: MouseEvent): void => {\n if (ref.current && !ref.current.contains(e.target as Node)) onClose();\n };\n const onKey = (e: KeyboardEvent): void => {\n if (e.key === 'Escape') onClose();\n };\n document.addEventListener('mousedown', onDown);\n document.addEventListener('keydown', onKey);\n window.addEventListener('scroll', onClose, true);\n window.addEventListener('resize', onClose);\n return () => {\n document.removeEventListener('mousedown', onDown);\n document.removeEventListener('keydown', onKey);\n window.removeEventListener('scroll', onClose, true);\n window.removeEventListener('resize', onClose);\n };\n }, [onClose]);\n\n return createPortal(\n <div\n ref={ref}\n role=\"menu\"\n style={{ position: 'fixed', left: pos.x, top: pos.y, zIndex: 50 }}\n className=\"min-w-44 rounded-md border border-slate-200 bg-white py-1 shadow-lg\"\n >\n {items.map((item) => (\n <button\n key={item.id}\n role=\"menuitem\"\n onClick={() => {\n onClose();\n item.onSelect();\n }}\n className={`block w-full px-3 py-1.5 text-left text-sm ${\n item.danger ? 'text-red-600 hover:bg-red-50' : 'text-slate-700 hover:bg-slate-100'\n }`}\n >\n {item.label}\n </button>\n ))}\n </div>,\n document.body,\n );\n}\n\n/** The row-level \"⋮\" trigger: a compact button that opens a `PopMenu` aligned under itself. */\nexport function MenuButton({ items, label }: { items: MenuItem[]; label: string }) {\n const [anchor, setAnchor] = useState<MenuAnchor | undefined>(undefined);\n\n return (\n <>\n <button\n type=\"button\"\n aria-label={label}\n title={label}\n onClick={(e) => {\n const rect = e.currentTarget.getBoundingClientRect();\n setAnchor({ x: rect.right - 176, y: rect.bottom + 4 });\n }}\n className=\"rounded-md px-2 py-1 text-slate-500 hover:bg-slate-100 hover:text-slate-900\"\n >\n ⋮\n </button>\n {anchor && <PopMenu anchor={anchor} items={items} onClose={() => setAnchor(undefined)} />}\n </>\n );\n}\n","/**\n * Copies text to the clipboard, with a hidden-textarea fallback for non-secure contexts (plain-http\n * admin deployments), where `navigator.clipboard` is unavailable.\n */\nexport async function copyText(text: string): Promise<void> {\n if (navigator.clipboard?.writeText) {\n try {\n await navigator.clipboard.writeText(text);\n return;\n } catch {\n // fall through to the textarea fallback\n }\n }\n const textarea = document.createElement('textarea');\n textarea.value = text;\n textarea.style.position = 'fixed';\n textarea.style.opacity = '0';\n document.body.appendChild(textarea);\n textarea.select();\n document.execCommand('copy');\n textarea.remove();\n}\n","import { useState } from 'react';\nimport type { EntityMetadata } from '../client/types.js';\nimport { useClient, useEntities } from '../AdminContext.js';\nimport { detailFields, useEntityRecord } from '../hooks.js';\nimport { FieldValue } from './FieldValue.js';\nimport { Button, ErrorBanner, Spinner } from './ui.js';\nimport { MenuButton, type MenuItem } from './menu.js';\nimport { useT } from '../i18n.js';\nimport { copyText } from '../clipboard.js';\n\nexport function EntityDetail({\n entity,\n id,\n onBack,\n onEdit,\n onClone,\n onDeleted,\n onNavigate,\n}: {\n entity: EntityMetadata;\n id: string;\n onBack: () => void;\n onEdit: () => void;\n onClone: () => void;\n onDeleted: () => void;\n onNavigate: (entityId: string, id: string) => void;\n}) {\n const client = useClient();\n const t = useT();\n const entities = useEntities();\n const { data, error, loading } = useEntityRecord(entity.id, id);\n const fields = detailFields(entity);\n const [copied, setCopied] = useState(false);\n\n const copy = async (text: string): Promise<void> => {\n await copyText(text);\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n };\n\n const onDelete = async (): Promise<void> => {\n if (!globalThis.confirm(t.deleteConfirm(entity.label.singular))) return;\n await client.remove(entity.id, id);\n onDeleted();\n };\n\n const menuItems: MenuItem[] = [];\n if (entity.capabilities.clone && entity.capabilities.create) {\n menuItems.push({ id: 'clone', label: `⧉ ${t.clone}`, onSelect: onClone });\n }\n menuItems.push({ id: 'copy-id', label: `⎘ ${t.copyId}`, onSelect: () => void copy(id) });\n if (data) {\n menuItems.push({\n id: 'copy-object',\n label: `{} ${t.copyObject}`,\n onSelect: () => void copy(JSON.stringify(data, null, 2)),\n });\n }\n if (entity.capabilities.delete) {\n menuItems.push({ id: 'remove', label: `🗑 ${t.remove}`, danger: true, onSelect: () => void onDelete() });\n }\n\n return (\n <section className=\"space-y-4\">\n <header className=\"flex items-center justify-between gap-3\">\n <div>\n <button onClick={onBack} className=\"text-sm text-indigo-600 hover:underline\">\n ← {entity.label.plural}\n </button>\n <h1 className=\"text-lg font-semibold text-slate-900\">\n {entity.label.singular} {data ? String(data[entity.displayField] ?? id) : ''}\n </h1>\n </div>\n <div className=\"flex items-center gap-1\">\n {entity.capabilities.update && (\n <Button variant=\"primary\" onClick={onEdit}>\n {t.edit}\n </Button>\n )}\n <MenuButton label={t.actions} items={menuItems} />\n </div>\n </header>\n\n {error && <ErrorBanner error={error} />}\n {loading && !data ? (\n <Spinner />\n ) : (\n data && (\n <dl className=\"divide-y divide-slate-100 rounded-lg border border-slate-200 bg-white\">\n {fields.map((f) => {\n const value = data[f.name];\n const isRelation = f.type === 'relation' && f.relationEntity && value !== null && value !== undefined;\n const target = isRelation ? entities.find((e) => e.id === f.relationEntity) : undefined;\n return (\n <div key={f.name} className=\"grid grid-cols-3 gap-4 px-4 py-3\">\n <dt className=\"text-sm font-medium text-slate-500\">{f.label}</dt>\n <dd className=\"col-span-2 flex items-center gap-2 text-sm\">\n <FieldValue field={f} value={value} />\n {isRelation && (\n <button\n onClick={() => onNavigate(f.relationEntity!, String(value))}\n className=\"text-xs text-indigo-600 hover:underline\"\n >\n {t.openRelated(target?.label.singular ?? f.relationEntity!)} ↗\n </button>\n )}\n </dd>\n </div>\n );\n })}\n </dl>\n )\n )}\n\n {copied && (\n <div className=\"fixed bottom-4 right-4 z-50 rounded-md bg-slate-900 px-3 py-1.5 text-sm text-white shadow-lg\">\n {t.copied}\n </div>\n )}\n </section>\n );\n}\n","import { useEffect, useState } from 'react';\nimport type { EntityMetadata, Record_ } from '../client/types.js';\nimport { useClient } from '../AdminContext.js';\nimport { formFields, useEntityRecord } from '../hooks.js';\nimport { FieldInput } from './FieldInput.js';\nimport { Button, ErrorBanner, Spinner } from './ui.js';\nimport { useT } from '../i18n.js';\n\nexport function EntityForm({\n entity,\n mode,\n id,\n cloneFromId,\n onCancel,\n onSaved,\n}: {\n entity: EntityMetadata;\n mode: 'create' | 'edit';\n id?: string;\n /** In `create` mode, prefills the form from this record (minus the primary key and non-cloneable fields). */\n cloneFromId?: string;\n onCancel: () => void;\n onSaved: (record: Record_) => void;\n}) {\n const client = useClient();\n const t = useT();\n const fields = formFields(entity, mode);\n const sourceId = mode === 'edit' ? id : cloneFromId;\n const existing = useEntityRecord(entity.id, sourceId);\n\n const [values, setValues] = useState<Record_>({});\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<Error | undefined>(undefined);\n\n useEffect(() => {\n if (!existing.data || !sourceId) return;\n if (mode === 'edit') {\n setValues(existing.data);\n return;\n }\n // Cloning: copy only cloneable, non-readonly fields; the primary key must be newly assigned.\n const seed: Record_ = {};\n for (const f of entity.fields) {\n if (f.name === entity.primaryKey) continue;\n if (!f.form.cloneable || f.readonly) continue;\n if (existing.data[f.name] !== undefined) seed[f.name] = existing.data[f.name];\n }\n setValues(seed);\n }, [mode, sourceId, existing.data, entity]);\n\n const submit = async (e: React.FormEvent): Promise<void> => {\n e.preventDefault();\n setSaving(true);\n setError(undefined);\n try {\n const payload: Record_ = {};\n for (const f of fields) {\n if (values[f.name] !== undefined) payload[f.name] = values[f.name];\n }\n const saved =\n mode === 'create'\n ? await client.create(entity.id, payload)\n : await client.update(entity.id, id!, payload);\n onSaved(saved);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setSaving(false);\n }\n };\n\n if (sourceId && existing.loading && !existing.data) {\n return <Spinner />;\n }\n\n const title =\n mode === 'edit'\n ? t.editTitle(entity.label.singular)\n : cloneFromId\n ? t.cloneTitle(entity.label.singular)\n : t.newTitle(entity.label.singular);\n\n return (\n <section className=\"space-y-4\">\n <header>\n <button onClick={onCancel} className=\"text-sm text-indigo-600 hover:underline\">\n ← {entity.label.plural}\n </button>\n <h1 className=\"text-lg font-semibold text-slate-900\">{title}</h1>\n </header>\n\n {error && <ErrorBanner error={error} />}\n\n <form onSubmit={submit} className=\"space-y-4 rounded-lg border border-slate-200 bg-white p-5\">\n {fields.map((f) => (\n <div key={f.name} className=\"space-y-1\">\n <label htmlFor={`field-${f.name}`} className=\"block text-sm font-medium text-slate-700\">\n {f.label}\n {f.required && <span className=\"ml-0.5 text-red-500\">*</span>}\n </label>\n <FieldInput\n field={f}\n value={values[f.name]}\n disabled={saving || f.readonly}\n onChange={(next) => setValues((v) => ({ ...v, [f.name]: next }))}\n />\n {f.form.helpText && <p className=\"text-xs text-slate-500\">{f.form.helpText}</p>}\n </div>\n ))}\n\n <div className=\"flex justify-end gap-2 border-t border-slate-100 pt-4\">\n <Button type=\"button\" variant=\"secondary\" onClick={onCancel} disabled={saving}>\n {t.cancel}\n </Button>\n <Button type=\"submit\" variant=\"primary\" disabled={saving}>\n {saving ? t.saving : mode === 'create' ? t.create : t.save}\n </Button>\n </div>\n </form>\n </section>\n );\n}\n","import { useEffect, useRef, useState } from 'react';\nimport type { FieldMetadata } from '../client/types.js';\nimport { useT } from '../i18n.js';\nimport { isPlainObject } from './ObjectValue.js';\n\nconst leafInputClass =\n 'w-full rounded-md border border-slate-300 px-2.5 py-1 text-sm text-slate-800 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 disabled:bg-slate-100';\n\n/** Nested objects deeper than this fall back to a raw-JSON textarea inside the structured editor. */\nconst MAX_DEPTH = 3;\n\n/**\n * Raw JSON textarea with local text state: the parsed value is only propagated while the text is valid\n * JSON, so half-typed edits never leak a plain string into the save payload. Invalid text keeps the last\n * valid value and shows a warning instead.\n */\nfunction RawJsonArea({\n id,\n value,\n onChange,\n disabled,\n rows = 8,\n placeholder,\n}: {\n id?: string;\n value: unknown;\n onChange: (next: unknown) => void;\n disabled?: boolean;\n rows?: number;\n placeholder?: string;\n}) {\n const t = useT();\n const [text, setText] = useState(() => (value === null || value === undefined ? '' : JSON.stringify(value, null, 2)));\n const [invalid, setInvalid] = useState(false);\n const lastEmitted = useRef<unknown>(value);\n\n // Re-sync only on external changes (e.g. the record finishing its async load) — never on our own\n // emissions, so the caret doesn't jump while the user types.\n useEffect(() => {\n if (value !== lastEmitted.current) {\n lastEmitted.current = value;\n setText(value === null || value === undefined ? '' : JSON.stringify(value, null, 2));\n setInvalid(false);\n }\n }, [value]);\n\n const onText = (raw: string): void => {\n setText(raw);\n if (raw.trim() === '') {\n lastEmitted.current = null;\n setInvalid(false);\n onChange(null);\n return;\n }\n try {\n const parsed: unknown = JSON.parse(raw);\n lastEmitted.current = parsed;\n setInvalid(false);\n onChange(parsed);\n } catch {\n setInvalid(true);\n }\n };\n\n return (\n <div className=\"space-y-1\">\n <textarea\n id={id}\n rows={rows}\n value={text}\n placeholder={placeholder}\n disabled={disabled}\n onChange={(e) => onText(e.target.value)}\n aria-invalid={invalid || undefined}\n className={`${leafInputClass} font-mono ${invalid ? 'border-amber-400 focus:border-amber-500 focus:ring-amber-500' : ''}`}\n />\n {invalid && (\n <p role=\"alert\" className=\"text-xs text-amber-600\">\n {t.jsonInvalid}\n </p>\n )}\n </div>\n );\n}\n\n/** Renders the control matching one object entry's current primitive type; recurses into nested objects. */\nfunction LeafEditor({\n id,\n value,\n onChange,\n disabled,\n depth,\n}: {\n id: string;\n value: unknown;\n onChange: (next: unknown) => void;\n disabled?: boolean;\n depth: number;\n}) {\n if (typeof value === 'boolean') {\n return (\n <input\n id={id}\n type=\"checkbox\"\n checked={value}\n disabled={disabled}\n onChange={(e) => onChange(e.target.checked)}\n className=\"mt-1 h-4 w-4 rounded border-slate-300 text-indigo-600 focus:ring-indigo-500\"\n />\n );\n }\n\n if (typeof value === 'number') {\n return (\n <input\n id={id}\n type=\"number\"\n value={String(value)}\n disabled={disabled}\n step=\"any\"\n onChange={(e) => onChange(e.target.value === '' ? null : Number(e.target.value))}\n className={leafInputClass}\n />\n );\n }\n\n if (typeof value === 'string') {\n return (\n <input\n id={id}\n type=\"text\"\n value={value}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value)}\n className={leafInputClass}\n />\n );\n }\n\n if (value === null || value === undefined) {\n return (\n <input\n id={id}\n type=\"text\"\n value=\"\"\n placeholder=\"null\"\n disabled={disabled}\n onChange={(e) => onChange(e.target.value === '' ? null : e.target.value)}\n className={leafInputClass}\n />\n );\n }\n\n if (isPlainObject(value) && depth < MAX_DEPTH) {\n return (\n <div className=\"rounded-md border border-slate-200\">\n <ObjectEditor idPrefix={id} value={value} onChange={onChange} disabled={disabled} depth={depth + 1} />\n </div>\n );\n }\n\n if (Array.isArray(value) && depth < MAX_DEPTH) {\n return (\n <div className=\"rounded-md border border-slate-200\">\n <ArrayEditor idPrefix={id} value={value} onChange={onChange} disabled={disabled} depth={depth + 1} />\n </div>\n );\n }\n\n // Over-deep structures: a raw-JSON island scoped to this entry.\n return <RawJsonArea id={id} value={value} onChange={onChange} disabled={disabled} rows={3} />;\n}\n\nfunction ArrayEditor({\n idPrefix,\n value,\n onChange,\n disabled,\n depth = 0,\n}: {\n idPrefix: string;\n value: unknown[];\n onChange: (next: unknown[]) => void;\n disabled?: boolean;\n depth?: number;\n}) {\n const t = useT();\n\n const setAt = (i: number, next: unknown): void => onChange(value.map((cur, idx) => (idx === i ? next : cur)));\n const removeAt = (i: number): void => onChange(value.filter((_, idx) => idx !== i));\n // New items start as a deep copy of the last one, so the row keeps its shape and control types.\n const append = (): void => {\n const last = value[value.length - 1];\n const template: unknown = last === undefined || last === null ? null : (JSON.parse(JSON.stringify(last)) as unknown);\n onChange([...value, template]);\n };\n\n return (\n <div className=\"divide-y divide-slate-100\">\n {value.map((item, i) => {\n const id = `${idPrefix}-${i}`;\n return (\n <div key={i} className=\"flex flex-wrap items-start gap-x-3 gap-y-1.5 px-3 py-2\">\n <label htmlFor={id} className=\"w-8 shrink-0 pt-1.5 text-right text-xs font-medium text-slate-400\">\n {i}\n </label>\n {!disabled && (\n <button\n type=\"button\"\n title={t.removeItem}\n aria-label={`${t.removeItem} ${i}`}\n onClick={() => removeAt(i)}\n className=\"shrink-0 pt-1.5 text-xs text-slate-400 transition-colors hover:text-red-600\"\n >\n ✕\n </button>\n )}\n <div className=\"min-w-0 flex-1 basis-64\">\n <LeafEditor id={id} value={item} onChange={(next) => setAt(i, next)} disabled={disabled} depth={depth} />\n </div>\n </div>\n );\n })}\n {value.length === 0 && <p className=\"px-3 py-2 text-xs text-slate-400\">{t.emptyObject}</p>}\n {!disabled && (\n <div className=\"px-3 py-1.5\">\n <button type=\"button\" onClick={append} className=\"text-xs font-medium text-indigo-600 hover:underline\">\n + {t.addItem}\n </button>\n </div>\n )}\n </div>\n );\n}\n\nfunction ObjectEditor({\n idPrefix,\n value,\n onChange,\n disabled,\n depth = 0,\n}: {\n idPrefix: string;\n value: Record<string, unknown>;\n onChange: (next: Record<string, unknown>) => void;\n disabled?: boolean;\n depth?: number;\n}) {\n const t = useT();\n const entries = Object.entries(value);\n\n if (entries.length === 0) {\n return <p className=\"px-3 py-2 text-xs text-slate-400\">{t.emptyObject}</p>;\n }\n\n return (\n <div className=\"divide-y divide-slate-100\">\n {entries.map(([key, entry]) => {\n const id = `${idPrefix}-${key}`;\n return (\n // flex-wrap + basis: when the label column leaves less than ~16rem for the control (deeply\n // nested groups), the control wraps to its own full-width line instead of squeezing.\n <div key={key} className=\"flex flex-wrap items-start gap-x-3 gap-y-1.5 px-3 py-2\">\n <label htmlFor={id} className=\"w-36 shrink-0 truncate pt-1.5 text-xs font-medium text-slate-500\" title={key}>\n {key}\n </label>\n <div className=\"min-w-0 flex-1 basis-64\">\n <LeafEditor\n id={id}\n value={entry}\n onChange={(next) => onChange({ ...value, [key]: next })}\n disabled={disabled}\n depth={depth}\n />\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n\n/**\n * Form control for `json` fields: a structured editor when the value is an object or array (each entry\n * gets a control matching its type; array items can be added/removed), plus a raw-JSON mode for\n * adding/removing object keys or pasting a whole value.\n */\nexport function JsonInput({\n field,\n value,\n onChange,\n disabled,\n}: {\n field: FieldMetadata;\n value: unknown;\n onChange: (next: unknown) => void;\n disabled?: boolean;\n}) {\n const t = useT();\n const [mode, setMode] = useState<'form' | 'raw'>(() => (isPlainObject(value) ? 'form' : 'raw'));\n const [modeTouched, setModeTouched] = useState(false);\n\n const structured = isPlainObject(value) || Array.isArray(value);\n\n // Records load after mount; once an object/array shows up, prefer the structured editor — unless the\n // user already picked a mode themselves.\n useEffect(() => {\n if (!modeTouched && structured) setMode('form');\n }, [structured, modeTouched]);\n\n const pick = (next: 'form' | 'raw'): void => {\n setModeTouched(true);\n setMode(next);\n };\n\n const showForm = mode === 'form' && structured;\n const toggleClass = (active: boolean): string =>\n `rounded px-2 py-0.5 text-xs font-medium transition-colors ${\n active ? 'bg-white text-slate-800 shadow-sm ring-1 ring-slate-300' : 'text-slate-500 hover:text-slate-700'\n }`;\n\n return (\n <div className=\"rounded-md border border-slate-300 shadow-sm\">\n <div className=\"flex items-center justify-end gap-1 rounded-t-md border-b border-slate-200 bg-slate-50 px-2 py-1\">\n <button\n type=\"button\"\n className={toggleClass(showForm)}\n disabled={!structured}\n onClick={() => pick('form')}\n >\n {t.jsonFormMode}\n </button>\n <button type=\"button\" className={toggleClass(!showForm)} onClick={() => pick('raw')}>\n {t.jsonRawMode}\n </button>\n </div>\n <div className=\"p-1\">\n {showForm ? (\n Array.isArray(value) ? (\n <ArrayEditor idPrefix={`field-${field.name}`} value={value} onChange={onChange} disabled={disabled} />\n ) : (\n <ObjectEditor\n idPrefix={`field-${field.name}`}\n value={value as Record<string, unknown>}\n onChange={onChange}\n disabled={disabled}\n />\n )\n ) : (\n <RawJsonArea\n id={`field-${field.name}`}\n value={value}\n onChange={onChange}\n disabled={disabled}\n placeholder={field.form.placeholder}\n />\n )}\n </div>\n </div>\n );\n}\n","import type { FieldMetadata } from '../client/types.js';\nimport { JsonInput } from './JsonInput.js';\n\nconst inputClass =\n 'w-full rounded-md border border-slate-300 px-3 py-1.5 text-sm text-slate-800 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 disabled:bg-slate-100';\n\n/**\n * Renders the right form control for a field's type and reports its next value. Values are kept as strings\n * for text/enum, numbers for numeric types, booleans for checkboxes, and parsed objects for json — matching\n * what the create/update endpoints expect.\n */\nexport function FieldInput({\n field,\n value,\n onChange,\n disabled,\n}: {\n field: FieldMetadata;\n value: unknown;\n onChange: (next: unknown) => void;\n disabled?: boolean;\n}) {\n const id = `field-${field.name}`;\n\n switch (field.type) {\n case 'boolean':\n return (\n <input\n id={id}\n type=\"checkbox\"\n checked={Boolean(value)}\n disabled={disabled}\n onChange={(e) => onChange(e.target.checked)}\n className=\"h-4 w-4 rounded border-slate-300 text-indigo-600 focus:ring-indigo-500\"\n />\n );\n\n case 'integer':\n case 'number':\n case 'float':\n case 'decimal':\n case 'currency':\n return (\n <input\n id={id}\n type=\"number\"\n value={value === null || value === undefined ? '' : String(value)}\n placeholder={field.form.placeholder}\n disabled={disabled}\n step={field.type === 'integer' ? 1 : 'any'}\n onChange={(e) => onChange(e.target.value === '' ? null : Number(e.target.value))}\n className={inputClass}\n />\n );\n\n case 'enum':\n return (\n <select\n id={id}\n value={value === null || value === undefined ? '' : String(value)}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value)}\n className={inputClass}\n >\n <option value=\"\">—</option>\n {field.enumOptions?.map((o) => (\n <option key={String(o.value)} value={String(o.value)}>\n {o.label}\n </option>\n ))}\n </select>\n );\n\n case 'date':\n return (\n <input\n id={id}\n type=\"date\"\n value={value ? String(value).slice(0, 10) : ''}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value || null)}\n className={inputClass}\n />\n );\n\n case 'json':\n return <JsonInput field={field} value={value} onChange={onChange} disabled={disabled} />;\n\n case 'text':\n return (\n <textarea\n id={id}\n rows={3}\n value={value === null || value === undefined ? '' : String(value)}\n placeholder={field.form.placeholder}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value)}\n className={inputClass}\n />\n );\n\n default:\n return (\n <input\n id={id}\n type={field.type === 'email' ? 'email' : 'text'}\n value={value === null || value === undefined ? '' : String(value)}\n placeholder={field.form.placeholder}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value)}\n className={inputClass}\n />\n );\n }\n}\n","import type { EntityMetadata, FieldMetadata, MaestroMetadata } from './client/types.js';\n\nexport interface EntityLabelOverride {\n /** Singular label (\"Usuário\"). */\n singular?: string;\n /** Plural label (\"Usuários\") — also the sidebar entry. */\n plural?: string;\n /** Sidebar folder this entity belongs to (display name). Wins over heuristic prefix grouping. */\n group?: string;\n /** Field labels for this entity only, by field name. Wins over the global `fields` map. */\n fields?: Record<string, string>;\n}\n\n/**\n * Presentation-layer label rewrites, applied on top of the metadata the server serves. This is how a\n * deployment localizes or humanizes auto-introspected names (\"recoveryactions\" → \"Ações de\n * Recuperação\") without touching the engine: keys match either the entity `id` or its source `table`.\n */\nexport interface AdminLabels {\n entities?: Record<string, EntityLabelOverride>;\n /** Global field labels by field name (`createdAt` → \"Criado em\"), for every entity. */\n fields?: Record<string, string>;\n /** Display names for heuristic sidebar folders, by shared table-name prefix (`recovery` → \"Recuperação\"). */\n groups?: Record<string, string>;\n}\n\nfunction relabelField(\n field: FieldMetadata,\n entityOverride: EntityLabelOverride | undefined,\n globalFields: Record<string, string>,\n): FieldMetadata {\n const label = entityOverride?.fields?.[field.name] ?? globalFields[field.name];\n return label ? { ...field, label } : field;\n}\n\nfunction relabelEntity(entity: EntityMetadata, labels: AdminLabels): EntityMetadata {\n const override = labels.entities?.[entity.id] ?? labels.entities?.[entity.table];\n const globalFields = labels.fields ?? {};\n return {\n ...entity,\n label: {\n singular: override?.singular ?? entity.label.singular,\n plural: override?.plural ?? override?.singular ?? entity.label.plural,\n },\n fields: entity.fields.map((f) => relabelField(f, override, globalFields)),\n };\n}\n\n/** Returns a copy of `metadata` with every label override applied. No-op when `labels` is empty. */\nexport function applyLabels(metadata: MaestroMetadata, labels: AdminLabels | undefined): MaestroMetadata {\n if (!labels || (!labels.entities && !labels.fields)) return metadata;\n return { ...metadata, entities: metadata.entities.map((e) => relabelEntity(e, labels)) };\n}\n","import { useCallback, useState } from 'react';\n\nconst STORAGE_KEY = 'maestro-admin:recents';\nconst MAX_RECENTS = 8;\n\nfunction read(key: string): string[] {\n try {\n const raw = globalThis.localStorage?.getItem(key);\n const parsed: unknown = raw ? JSON.parse(raw) : [];\n return Array.isArray(parsed) ? parsed.filter((x): x is string => typeof x === 'string') : [];\n } catch {\n return []; // storage unavailable (SSR, blocked) or corrupted — recents are best-effort\n }\n}\n\nfunction write(key: string, ids: string[]): void {\n try {\n globalThis.localStorage?.setItem(key, JSON.stringify(ids));\n } catch {\n // best-effort\n }\n}\n\n/**\n * Recently-visited entity ids, most recent first, persisted in `localStorage` so they survive\n * reloads. `push` moves (or inserts) an id to the front, capped at 8. Pass a distinct `scope` (e.g.\n * the API URL) when one browser origin hosts admins for several servers.\n */\nexport function useRecents(scope?: string): { recents: string[]; push: (entityId: string) => void } {\n const key = scope ? `${STORAGE_KEY}:${scope}` : STORAGE_KEY;\n const [recents, setRecents] = useState<string[]>(() => read(key));\n\n const push = useCallback(\n (entityId: string): void => {\n setRecents((prev) => {\n const next = [entityId, ...prev.filter((id) => id !== entityId)].slice(0, MAX_RECENTS);\n write(key, next);\n return next;\n });\n },\n [key],\n );\n\n return { recents, push };\n}\n"],"mappings":"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","names":["useMemo","useState","useEffect","useState","createContext","useContext","useState","useEffect","useMemo","useState","jsx","jsxs","useEffect","useState","jsx","jsxs","useState","useEffect","jsx","jsxs","jsx","useEffect","useRef","useState","Fragment","jsx","jsxs","jsx","jsxs","useMemo","useState","useState","jsx","jsxs","useState","useEffect","useState","useEffect","useRef","useState","jsx","jsxs","MAX_DEPTH","useState","useRef","useEffect","jsx","jsxs","jsx","jsxs","useState","useEffect","useCallback","useState","jsx","jsxs","useState","useMemo"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/MaestroAdmin.tsx","../src/client/MaestroClient.ts","../src/AdminContext.tsx","../src/hooks.ts","../src/grouping.ts","../src/components/Sidebar.tsx","../src/i18n.ts","../src/components/icons.tsx","../src/components/Header.tsx","../src/theme.tsx","../src/components/menu.tsx","../src/components/Hub.tsx","../src/components/ui.tsx","../src/components/CommandPalette.tsx","../src/components/EntityList.tsx","../src/columns.ts","../src/components/RelationValue.tsx","../src/components/ObjectValue.tsx","../src/components/FieldValue.tsx","../src/clipboard.ts","../src/components/EntityDetail.tsx","../src/components/EntityForm.tsx","../src/components/JsonInput.tsx","../src/components/FieldInput.tsx","../src/labels.ts","../src/recents.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { MaestroClient, type MaestroClientConfig } from '../client/MaestroClient.js';\nimport { AdminClientProvider, AdminEntitiesProvider, AdminRootProvider } from '../AdminContext.js';\nimport { useMetadata } from '../hooks.js';\nimport { buildMenu } from '../grouping.js';\nimport { Sidebar } from './Sidebar.js';\nimport { Header, type Crumb } from './Header.js';\nimport { Hub } from './Hub.js';\nimport { CommandPalette, entityCommands, type PaletteSection } from './CommandPalette.js';\nimport { EntityList } from './EntityList.js';\nimport { EntityDetail } from './EntityDetail.js';\nimport { EntityForm } from './EntityForm.js';\nimport { ErrorBanner, Spinner } from './ui.js';\nimport { entityIcon } from './icons.js';\nimport { I18nProvider, stringsFor, useT, type AdminLocale } from '../i18n.js';\nimport { applyLabels, type AdminLabels } from '../labels.js';\nimport { useRecents } from '../recents.js';\nimport { MaestroThemeProvider, type MaestroThemeInput } from '../theme.js';\n\nexport interface MaestroAdminProps {\n /** Base URL of the running maestro-server. Ignored when `client` is given. */\n apiUrl?: string;\n /** Per-request headers (auth). Ignored when `client` is given. */\n headers?: MaestroClientConfig['headers'];\n /** A pre-built client, for full control (custom fetch, SSR, tests). */\n client?: MaestroClient;\n /** Sidebar title. Defaults to \"Maestro Admin\". */\n title?: string;\n /** UI-chrome language (buttons, menus, pagination). Defaults to `en`. */\n locale?: AdminLocale;\n /** Label rewrites (localization/humanization) applied over the served metadata. */\n labels?: AdminLabels;\n /**\n * Appearance: `\"cobalto\" | \"latao\" | \"teal\"`, or an object to also set the light/dark scheme, the\n * row density, whether the header shows the pickers, and per-token overrides for your own brand.\n */\n theme?: MaestroThemeInput;\n}\n\ntype View =\n | { kind: 'hub' }\n | { kind: 'list'; entityId: string }\n | { kind: 'detail'; entityId: string; id: string }\n | { kind: 'create'; entityId: string; cloneFromId?: string }\n | { kind: 'edit'; entityId: string; id: string };\n\nfunction AdminShell({ title, labels }: { title: string; labels?: AdminLabels }) {\n const { data, error, loading } = useMetadata();\n const t = useT();\n const [view, setView] = useState<View>({ kind: 'hub' });\n const [paletteOpen, setPaletteOpen] = useState(false);\n const { recents, push: pushRecent } = useRecents();\n\n const metadata = useMemo(() => (data ? applyLabels(data, labels) : undefined), [data, labels]);\n const entities = useMemo(() => metadata?.entities ?? [], [metadata]);\n const activeId = view.kind === 'hub' ? undefined : view.entityId;\n const activeEntity = entities.find((e) => e.id === activeId);\n\n const groupOf = useMemo(() => {\n const map = new Map<string, string>();\n for (const group of buildMenu(entities, labels).groups) {\n for (const entity of group.entities) map.set(entity.id, group.label);\n }\n return map;\n }, [entities, labels]);\n\n const openEntity = useCallback(\n (entityId: string): void => {\n pushRecent(entityId);\n setView({ kind: 'list', entityId });\n },\n [pushRecent],\n );\n\n const navigateToRecord = useCallback(\n (entityId: string, id: string): void => {\n pushRecent(entityId);\n setView({ kind: 'detail', entityId, id });\n },\n [pushRecent],\n );\n\n // ⌘K / Ctrl+K anywhere in the admin. Bound on the document so it works from a focused table cell,\n // an open form, or the sidebar search alike.\n useEffect(() => {\n const onKey = (e: KeyboardEvent): void => {\n if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'k') {\n e.preventDefault();\n setPaletteOpen((open) => !open);\n }\n };\n document.addEventListener('keydown', onKey);\n return () => document.removeEventListener('keydown', onKey);\n }, []);\n\n const crumbs = useMemo<Crumb[]>(() => {\n const home: Crumb = { label: t.hub, icon: 'hub', onClick: view.kind === 'hub' ? undefined : () => setView({ kind: 'hub' }) };\n if (view.kind === 'hub' || !activeEntity) return [home];\n\n const entityCrumb: Crumb = {\n label: activeEntity.label.plural,\n icon: entityIcon(activeEntity),\n onClick: view.kind === 'list' ? undefined : () => setView({ kind: 'list', entityId: activeEntity.id }),\n };\n if (view.kind === 'list') return [home, entityCrumb];\n\n const leaf: Crumb =\n view.kind === 'detail'\n ? { label: view.id }\n : view.kind === 'edit'\n ? { label: t.editTitle(activeEntity.label.singular) }\n : { label: view.cloneFromId ? t.cloneTitle(activeEntity.label.singular) : t.newTitle(activeEntity.label.singular) };\n return [home, entityCrumb, leaf];\n }, [view, activeEntity, t]);\n\n const paletteSections = useMemo<PaletteSection[]>(() => {\n const goTo = entityCommands(entities, groupOf, openEntity);\n goTo.unshift({ id: 'hub', label: t.hub, icon: 'hub', run: () => setView({ kind: 'hub' }) });\n\n const screen: PaletteSection['commands'] = [];\n if (activeEntity?.capabilities.create) {\n screen.push({\n id: 'create',\n label: t.newTitle(activeEntity.label.singular),\n icon: 'plus',\n run: () => setView({ kind: 'create', entityId: activeEntity.id }),\n });\n }\n\n const sections: PaletteSection[] = [{ id: 'goto', label: t.goTo, commands: goTo }];\n if (screen.length > 0) sections.unshift({ id: 'screen', label: t.onThisScreen, commands: screen });\n return sections;\n }, [entities, groupOf, openEntity, activeEntity, t]);\n\n if (loading && !data) {\n return (\n <div className=\"mst-boot\">\n <Spinner label={t.loadingMetadata} />\n </div>\n );\n }\n\n return (\n <AdminEntitiesProvider value={entities}>\n <Sidebar\n entities={entities}\n activeId={activeId}\n title={title}\n labels={labels}\n recents={recents}\n onSelect={openEntity}\n onHome={() => setView({ kind: 'hub' })}\n homeActive={view.kind === 'hub'}\n />\n\n <div className=\"mst-main\">\n <Header crumbs={crumbs} onOpenPalette={() => setPaletteOpen(true)} />\n\n <div className=\"mst-content\">\n {error && <ErrorBanner error={error} />}\n\n {view.kind === 'hub' && <Hub entities={entities} labels={labels} onOpen={openEntity} />}\n\n {activeEntity && view.kind === 'list' && (\n <EntityList\n entity={activeEntity}\n onOpen={(id) => setView({ kind: 'detail', entityId: activeEntity.id, id })}\n onCreate={() => setView({ kind: 'create', entityId: activeEntity.id })}\n onEdit={(id) => setView({ kind: 'edit', entityId: activeEntity.id, id })}\n onClone={(id) => setView({ kind: 'create', entityId: activeEntity.id, cloneFromId: id })}\n onNavigate={navigateToRecord}\n />\n )}\n\n {activeEntity && view.kind === 'detail' && (\n <EntityDetail\n entity={activeEntity}\n id={view.id}\n onBack={() => setView({ kind: 'list', entityId: activeEntity.id })}\n onEdit={() => setView({ kind: 'edit', entityId: activeEntity.id, id: view.id })}\n onClone={() => setView({ kind: 'create', entityId: activeEntity.id, cloneFromId: view.id })}\n onDeleted={() => setView({ kind: 'list', entityId: activeEntity.id })}\n onNavigate={navigateToRecord}\n />\n )}\n\n {activeEntity && (view.kind === 'create' || view.kind === 'edit') && (\n <EntityForm\n entity={activeEntity}\n mode={view.kind}\n id={view.kind === 'edit' ? view.id : undefined}\n cloneFromId={view.kind === 'create' ? view.cloneFromId : undefined}\n onCancel={() => setView({ kind: 'list', entityId: activeEntity.id })}\n onSaved={() => setView({ kind: 'list', entityId: activeEntity.id })}\n />\n )}\n </div>\n </div>\n\n {paletteOpen && <CommandPalette sections={paletteSections} onClose={() => setPaletteOpen(false)} />}\n </AdminEntitiesProvider>\n );\n}\n\n/**\n * The whole metadata-driven admin in one component. Point it at a running maestro-server and it reads\n * `GET /metadata` and auto-builds navigation, tables, detail views and create/update forms for every\n * entity — respecting each entity's capabilities and the server's RBAC. No per-entity code.\n *\n * Styles ship separately so the host app controls bundling:\n * `import '@maykonpaulo/maestro-admin/styles.css'`.\n */\nexport function MaestroAdmin(props: MaestroAdminProps) {\n const client = useMemo(\n () => props.client ?? new MaestroClient({ apiUrl: props.apiUrl ?? '', headers: props.headers }),\n [props.client, props.apiUrl, props.headers],\n );\n const strings = useMemo(() => stringsFor(props.locale ?? 'en'), [props.locale]);\n const [root, setRoot] = useState<HTMLElement | null>(null);\n\n return (\n <AdminClientProvider value={client}>\n <I18nProvider value={strings}>\n <MaestroThemeProvider theme={props.theme} className=\"mst-root\" rootRef={setRoot}>\n <AdminRootProvider value={root}>\n <AdminShell title={props.title ?? 'Maestro Admin'} labels={props.labels} />\n </AdminRootProvider>\n </MaestroThemeProvider>\n </I18nProvider>\n </AdminClientProvider>\n );\n}\n","import type { EntityMetadata, ListQuery, ListResult, MaestroMetadata, Record_ } from './types.js';\n\nexport interface MaestroClientConfig {\n /** Base URL of the running maestro-server, e.g. `http://localhost:3000` or `/api/admin`. */\n apiUrl: string;\n /** Extra headers sent on every request — the place to inject an auth token (`Authorization`, `X-Role`, …). */\n headers?: Record<string, string> | (() => Record<string, string>);\n /** Custom fetch (SSR, tests). Defaults to the global `fetch`. */\n fetch?: typeof fetch;\n}\n\n/** Thrown for any non-2xx response, carrying the HTTP status and the parsed error body when present. */\nexport class MaestroApiError extends Error {\n constructor(\n readonly status: number,\n readonly code: string,\n message: string,\n ) {\n super(message);\n this.name = 'MaestroApiError';\n }\n}\n\nfunction buildListParams(query: ListQuery = {}): string {\n const params = new URLSearchParams();\n if (query.page !== undefined) params.set('page', String(query.page));\n if (query.pageSize !== undefined) params.set('pageSize', String(query.pageSize));\n if (query.search) {\n params.set('search', query.search);\n if (query.searchFields?.length) params.set('searchFields', query.searchFields.join(','));\n }\n for (const s of query.sort ?? []) params.append('sort', `${s.field}:${s.direction}`);\n for (const f of query.filters ?? []) {\n params.append('filter', f.value === undefined ? `${f.field}:${f.operator}` : `${f.field}:${f.operator}:${f.value}`);\n }\n const qs = params.toString();\n return qs ? `?${qs}` : '';\n}\n\n/**\n * A thin, framework-free client for the Maestro HTTP contract. Every admin component talks to the server\n * through this — it is the single seam where auth headers, base URL and error handling live.\n */\nexport class MaestroClient {\n private readonly base: string;\n private readonly doFetch: typeof fetch;\n\n constructor(private readonly config: MaestroClientConfig) {\n this.base = config.apiUrl.replace(/\\/$/, '');\n this.doFetch = config.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n private resolveHeaders(): Record<string, string> {\n const h = typeof this.config.headers === 'function' ? this.config.headers() : this.config.headers;\n return { ...h };\n }\n\n private async request<T>(path: string, init?: RequestInit): Promise<T> {\n const res = await this.doFetch(`${this.base}${path}`, {\n ...init,\n headers: {\n Accept: 'application/json',\n ...(init?.body ? { 'Content-Type': 'application/json' } : {}),\n ...this.resolveHeaders(),\n ...(init?.headers as Record<string, string> | undefined),\n },\n });\n\n if (res.status === 204) return undefined as T;\n\n const text = await res.text();\n const body = text ? (JSON.parse(text) as unknown) : undefined;\n\n if (!res.ok) {\n const err = body as { error?: string; message?: string } | undefined;\n throw new MaestroApiError(res.status, err?.error ?? 'ERROR', err?.message ?? res.statusText);\n }\n return body as T;\n }\n\n async getMetadata(): Promise<MaestroMetadata> {\n return this.request<MaestroMetadata>('/metadata');\n }\n\n async getEntityMetadata(entityId: string): Promise<EntityMetadata> {\n return this.request<EntityMetadata>(`/metadata/${encodeURIComponent(entityId)}`);\n }\n\n async list(entityId: string, query?: ListQuery): Promise<ListResult> {\n return this.request<ListResult>(`/entities/${encodeURIComponent(entityId)}${buildListParams(query)}`);\n }\n\n async findById(entityId: string, id: string): Promise<Record_> {\n return this.request<Record_>(`/entities/${encodeURIComponent(entityId)}/${encodeURIComponent(id)}`);\n }\n\n async create(entityId: string, data: Record_): Promise<Record_> {\n return this.request<Record_>(`/entities/${encodeURIComponent(entityId)}`, {\n method: 'POST',\n body: JSON.stringify(data),\n });\n }\n\n async update(entityId: string, id: string, data: Record_): Promise<Record_> {\n return this.request<Record_>(`/entities/${encodeURIComponent(entityId)}/${encodeURIComponent(id)}`, {\n method: 'PATCH',\n body: JSON.stringify(data),\n });\n }\n\n async remove(entityId: string, id: string): Promise<void> {\n await this.request<void>(`/entities/${encodeURIComponent(entityId)}/${encodeURIComponent(id)}`, {\n method: 'DELETE',\n });\n }\n}\n","import { createContext, useContext } from 'react';\nimport type { MaestroClient } from './client/MaestroClient.js';\nimport type { EntityMetadata } from './client/types.js';\n\nconst ClientContext = createContext<MaestroClient | null>(null);\n\nexport const AdminClientProvider = ClientContext.Provider;\n\n/** Returns the `MaestroClient` provided at the root of the admin. Throws if used outside the provider. */\nexport function useClient(): MaestroClient {\n const client = useContext(ClientContext);\n if (!client) {\n throw new Error('useClient must be used within a <MaestroAdmin> (no MaestroClient in context).');\n }\n return client;\n}\n\nconst EntitiesContext = createContext<EntityMetadata[]>([]);\n\nexport const AdminEntitiesProvider = EntitiesContext.Provider;\n\n/** All entities from the loaded metadata — lets deep components (relation chips) resolve a target entity. */\nexport function useEntities(): EntityMetadata[] {\n return useContext(EntitiesContext);\n}\n\nexport function useEntity(entityId: string | undefined): EntityMetadata | undefined {\n const entities = useEntities();\n return entityId ? entities.find((e) => e.id === entityId) : undefined;\n}\n\n/**\n * The admin's root element — the node carrying the theme tokens. Floating layers (menus, the command\n * palette) portal into it rather than `document.body`, so they inherit the tokens even when the admin\n * is embedded in a host app that knows nothing about them.\n */\nconst RootContext = createContext<HTMLElement | null>(null);\n\nexport const AdminRootProvider = RootContext.Provider;\n\nexport function useAdminRoot(): HTMLElement | null {\n return useContext(RootContext);\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { useClient } from './AdminContext.js';\nimport type { EntityMetadata, FieldMetadata, ListQuery, ListResult, MaestroMetadata } from './client/types.js';\n\nexport interface AsyncState<T> {\n data: T | undefined;\n error: Error | undefined;\n loading: boolean;\n reload: () => void;\n}\n\n/** Runs an async producer, tracking loading/error and exposing a manual `reload`. Re-runs when `deps` change. */\nexport function useAsync<T>(producer: () => Promise<T>, deps: readonly unknown[]): AsyncState<T> {\n const [data, setData] = useState<T | undefined>(undefined);\n const [error, setError] = useState<Error | undefined>(undefined);\n const [loading, setLoading] = useState(true);\n const [tick, setTick] = useState(0);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n setError(undefined);\n producer()\n .then((result) => {\n if (!cancelled) setData(result);\n })\n .catch((err: unknown) => {\n if (!cancelled) setError(err instanceof Error ? err : new Error(String(err)));\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n return () => {\n cancelled = true;\n };\n }, [...deps, tick]);\n\n const reload = useCallback(() => setTick((t) => t + 1), []);\n return { data, error, loading, reload };\n}\n\n/** Loads the full metadata document (`GET /metadata`). */\nexport function useMetadata(): AsyncState<MaestroMetadata> {\n const client = useClient();\n return useAsync(() => client.getMetadata(), []);\n}\n\n/** Loads a page of records for one entity. */\nexport function useEntityList(entityId: string, query: ListQuery): AsyncState<ListResult> {\n const client = useClient();\n const key = JSON.stringify(query);\n return useAsync(() => client.list(entityId, query), [entityId, key]);\n}\n\n/** Loads a single record by id. */\nexport function useEntityRecord(\n entityId: string,\n id: string | undefined,\n): AsyncState<globalThis.Record<string, unknown>> {\n const client = useClient();\n return useAsync(async () => (id ? client.findById(entityId, id) : {}), [entityId, id]);\n}\n\n/** Fields shown in the list table, ordered, honoring per-field list visibility. */\nexport function listFields(entity: EntityMetadata) {\n return entity.fields\n .filter((f) => f.list.visible && !f.hidden)\n .sort((a, b) => (a.list.order ?? 0) - (b.list.order ?? 0));\n}\n\n// Types that never make a useful table column: unbounded blobs and structures.\nconst LIST_EXCLUDED_TYPES = new Set(['json', 'array', 'text']);\n\n// Lower rank ⇒ more \"principal\": identity texts first, then classification, relations, status,\n// dates, numbers; opaque values (uuid, long urls) last.\nfunction listColumnRank(field: FieldMetadata): number {\n switch (field.type) {\n case 'string':\n case 'email':\n case 'document':\n case 'phone':\n return 1;\n case 'enum':\n return 2;\n case 'relation':\n return 3;\n case 'boolean':\n return 4;\n case 'date':\n case 'datetime':\n case 'time':\n return 5;\n case 'uuid':\n return 7;\n case 'url':\n return 8;\n default:\n return 6;\n }\n}\n\n/**\n * The \"principal\" columns for an entity's table: instead of dumping every field, picks up to `max`\n * of the most identifying ones — the display field first, then searchable/required texts, enums,\n * relations, status booleans and dates — and drops blobs (`json`/`array`/`text`), sensitive values\n * and the primary key. Everything remains visible in the detail view. When any field carries an\n * explicit `list.order`/`list.width` (a curated schema), the curator's selection is honored as-is.\n */\nexport function primaryListFields(entity: EntityMetadata, max = 8): FieldMetadata[] {\n const all = listFields(entity);\n const curated = all.some((f) => f.list.order !== undefined || f.list.width !== undefined);\n if (curated || all.length <= max) return all;\n\n const scored = all\n .filter((f) => !f.sensitive && f.name !== entity.primaryKey && !LIST_EXCLUDED_TYPES.has(f.type))\n .map((field, index) => {\n let score = listColumnRank(field) * 10 + index * 0.01;\n if (field.searchable) score -= 5;\n if (field.required) score -= 2;\n if (field.name === entity.displayField) score = -100;\n return { field, score };\n })\n .sort((a, b) => a.score - b.score);\n\n return scored.slice(0, max).map((s) => s.field);\n}\n\n/** Fields shown in the detail view, ordered. */\nexport function detailFields(entity: EntityMetadata) {\n return entity.fields\n .filter((f) => f.detail.visible)\n .sort((a, b) => (a.detail.order ?? 0) - (b.detail.order ?? 0));\n}\n\n/** Fields editable in the create/update form, ordered, per mode. */\nexport function formFields(entity: EntityMetadata, mode: 'create' | 'edit') {\n return entity.fields\n .filter((f) => (mode === 'create' ? f.form.creatable : f.form.editable))\n .sort((a, b) => (a.form.order ?? 0) - (b.form.order ?? 0));\n}\n","import type { EntityMetadata } from './client/types.js';\nimport type { AdminLabels } from './labels.js';\n\nexport interface MenuGroup {\n /** Stable key: the explicit group name, or the heuristic table-name prefix. */\n id: string;\n label: string;\n entities: EntityMetadata[];\n}\n\nexport interface SidebarMenu {\n groups: MenuGroup[];\n /** Entities that belong to no group — rendered flat after the folders. */\n ungrouped: EntityMetadata[];\n}\n\n// A heuristic cluster needs a meaningful shared prefix (≥ 4 chars keeps `ai*`-style accidents out)\n// and at least two members — a \"folder\" of one is worse than a flat item.\nconst MIN_PREFIX = 4;\n\nfunction commonPrefix(a: string, b: string): string {\n let i = 0;\n while (i < a.length && i < b.length && a[i] === b[i]) i += 1;\n return a.slice(0, i);\n}\n\nfunction humanize(prefix: string): string {\n return prefix.charAt(0).toUpperCase() + prefix.slice(1);\n}\n\n/**\n * Builds the sidebar menu structure: explicit groups first (an entity override's `group` in\n * `AdminLabels` always wins), then heuristic clustering of what's left — collections sharing a\n * table-name prefix (`recoveryactions`, `recoveryscores`, … → \"Recovery\") become a folder, since a\n * shared prefix is how schemaless databases usually encode the module a collection belongs to.\n * Heuristic folder names can be localized via `labels.groups` (prefix → display name). Everything\n * else stays flat. Groups and their entities are sorted by label.\n */\nexport function buildMenu(entities: EntityMetadata[], labels?: AdminLabels): SidebarMenu {\n const byGroup = new Map<string, MenuGroup>();\n const rest: EntityMetadata[] = [];\n\n for (const entity of entities) {\n const override = labels?.entities?.[entity.id] ?? labels?.entities?.[entity.table];\n if (override?.group) {\n const existing = byGroup.get(override.group);\n if (existing) existing.entities.push(entity);\n else byGroup.set(override.group, { id: override.group, label: override.group, entities: [entity] });\n } else {\n rest.push(entity);\n }\n }\n\n // Heuristic pass: walk tables in lexicographic order and greedily grow clusters while the common\n // prefix across every member stays meaningful.\n const sorted = [...rest].sort((a, b) => (a.table < b.table ? -1 : a.table > b.table ? 1 : 0));\n const ungrouped: EntityMetadata[] = [];\n let i = 0;\n while (i < sorted.length) {\n let prefix = i + 1 < sorted.length ? commonPrefix(sorted[i].table, sorted[i + 1].table) : '';\n if (prefix.length < MIN_PREFIX) {\n ungrouped.push(sorted[i]);\n i += 1;\n continue;\n }\n let end = i + 1;\n while (end + 1 < sorted.length) {\n const next = commonPrefix(prefix, sorted[end + 1].table);\n if (next.length < MIN_PREFIX) break;\n prefix = next;\n end += 1;\n }\n const members = sorted.slice(i, end + 1);\n const label = labels?.groups?.[prefix] ?? humanize(prefix);\n const existing = byGroup.get(prefix);\n if (existing) existing.entities.push(...members);\n else byGroup.set(prefix, { id: prefix, label, entities: members });\n i = end + 1;\n }\n\n const collator = (a: string, b: string): number => a.localeCompare(b);\n const groups = [...byGroup.values()].sort((a, b) => collator(a.label, b.label));\n for (const group of groups) {\n group.entities.sort((a, b) => collator(a.label.plural, b.label.plural));\n }\n ungrouped.sort((a, b) => collator(a.label.plural, b.label.plural));\n\n return { groups, ungrouped };\n}\n","import { useMemo, useState, type ReactNode } from 'react';\nimport type { EntityMetadata } from '../client/types.js';\nimport type { AdminLabels } from '../labels.js';\nimport { buildMenu } from '../grouping.js';\nimport { useT } from '../i18n.js';\nimport { Icon, entityIcon } from './icons.js';\n\n/** Lowercases and strips diacritics, so \"usuario\" finds \"Usuários\". */\nfunction normalize(text: string): string {\n return text.toLowerCase().normalize('NFD').replace(/\\p{M}/gu, '');\n}\n\n/**\n * The label with the matched substring highlighted (accent-insensitive, first occurrence). Folding\n * diacritics changes string length (\"á\" → \"a\" + combining mark under NFD), so match positions are\n * found in a folded copy and mapped back to original-label indices character by character.\n */\nfunction Highlight({ label, query }: { label: string; query: string }): ReactNode {\n const foldedQuery = normalize(query);\n if (!foldedQuery) return label;\n\n const folded: string[] = [];\n const originalIndex: number[] = [];\n for (let i = 0; i < label.length; i += 1) {\n for (const ch of normalize(label[i])) {\n folded.push(ch);\n originalIndex.push(i);\n }\n }\n\n const idx = folded.join('').indexOf(foldedQuery);\n if (idx === -1) return label;\n const start = originalIndex[idx];\n const end = (originalIndex[idx + foldedQuery.length - 1] ?? label.length - 1) + 1;\n\n return (\n <>\n {label.slice(0, start)}\n <mark>{label.slice(start, end)}</mark>\n {label.slice(end)}\n </>\n );\n}\n\nfunction EntityButton({\n entity,\n active,\n onSelect,\n subtitle,\n query,\n}: {\n entity: EntityMetadata;\n active: boolean;\n onSelect: (entityId: string) => void;\n subtitle?: string;\n query?: string;\n}) {\n return (\n <button\n type=\"button\"\n aria-current={active}\n onClick={() => onSelect(entity.id)}\n className=\"mst-navitem\"\n title={entity.label.plural}\n >\n <Icon name={entityIcon(entity)} size={14} />\n <span className=\"mst-navitem__label\">\n {query ? <Highlight label={entity.label.plural} query={query} /> : entity.label.plural}\n {subtitle && <span className=\"mst-navitem__sub\"> · {subtitle}</span>}\n </span>\n </button>\n );\n}\n\nexport function Sidebar({\n entities,\n activeId,\n onSelect,\n title,\n labels,\n recents = [],\n onHome,\n homeActive = false,\n}: {\n entities: EntityMetadata[];\n activeId: string | undefined;\n onSelect: (entityId: string) => void;\n title: string;\n /** Same object given to `<MaestroAdmin labels>` — supplies folder assignments and folder names. */\n labels?: AdminLabels;\n /** Recently-visited entity ids, most recent first. */\n recents?: string[];\n /** Opens the hub. Omit to hide the hub entry (standalone/embedded use). */\n onHome?: () => void;\n homeActive?: boolean;\n}) {\n const t = useT();\n const [query, setQuery] = useState('');\n const [expanded, setExpanded] = useState<Record<string, boolean>>({});\n\n const menu = useMemo(() => buildMenu(entities, labels), [entities, labels]);\n const groupOf = useMemo(() => {\n const map = new Map<string, string>();\n for (const group of menu.groups) for (const e of group.entities) map.set(e.id, group.label);\n return map;\n }, [menu]);\n\n const recentEntities = recents\n .map((id) => entities.find((e) => e.id === id))\n .filter((e): e is EntityMetadata => Boolean(e))\n .slice(0, 6);\n\n const results = useMemo(() => {\n if (!query) return [];\n const q = normalize(query);\n return entities\n .filter((e) => normalize(`${e.label.plural} ${e.label.singular} ${e.table}`).includes(q))\n .sort((a, b) => a.label.plural.localeCompare(b.label.plural));\n }, [entities, query]);\n\n const select = (entityId: string): void => {\n setQuery('');\n onSelect(entityId);\n };\n\n const isExpanded = (groupId: string, hasActive: boolean): boolean => expanded[groupId] ?? hasActive;\n\n return (\n <aside className=\"mst-side\">\n <div className=\"mst-side__brand\">\n <span className=\"mst-mark\">\n <Icon name=\"baton\" size={15} />\n </span>\n <span className=\"mst-side__title\">{title}</span>\n </div>\n\n <div className=\"mst-side__search\">\n <input\n type=\"search\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Escape') setQuery('');\n if (e.key === 'Enter' && results[0]) select(results[0].id);\n }}\n placeholder={t.searchMenu}\n aria-label={t.searchMenu}\n />\n </div>\n\n <nav className=\"mst-side__nav\">\n {query ? (\n results.length === 0 ? (\n <p className=\"mst-side__empty\">{t.noMenuResults}</p>\n ) : (\n results.map((e) => (\n <EntityButton\n key={e.id}\n entity={e}\n active={e.id === activeId}\n onSelect={select}\n subtitle={groupOf.get(e.id)}\n query={query}\n />\n ))\n )\n ) : (\n <>\n {onHome && (\n <button type=\"button\" className=\"mst-navitem\" aria-current={homeActive} onClick={onHome} title={t.hub}>\n <Icon name=\"hub\" size={14} />\n <span className=\"mst-navitem__label\">{t.hub}</span>\n </button>\n )}\n\n {recentEntities.length > 0 && (\n <>\n <p className=\"mst-side__section\">{t.recents}</p>\n {recentEntities.map((e) => (\n <EntityButton key={e.id} entity={e} active={e.id === activeId} onSelect={select} />\n ))}\n </>\n )}\n\n <p className=\"mst-side__section\">{t.menus}</p>\n {menu.groups.map((group) => {\n const hasActive = group.entities.some((e) => e.id === activeId);\n const open = isExpanded(group.id, hasActive);\n return (\n <div key={group.id}>\n <button\n type=\"button\"\n aria-expanded={open}\n onClick={() => setExpanded((prev) => ({ ...prev, [group.id]: !open }))}\n className=\"mst-navitem mst-navitem--folder\"\n >\n <Icon\n name=\"chevronRight\"\n size={12}\n className={open ? 'mst-navitem__chev mst-navitem__chev--open' : 'mst-navitem__chev'}\n />\n <span className=\"mst-navitem__label\">{group.label}</span>\n <span className=\"mst-navitem__count\">{group.entities.length}</span>\n </button>\n {open && (\n <div className=\"mst-side__children\">\n {group.entities.map((e) => (\n <EntityButton key={e.id} entity={e} active={e.id === activeId} onSelect={select} />\n ))}\n </div>\n )}\n </div>\n );\n })}\n {menu.ungrouped.map((e) => (\n <EntityButton key={e.id} entity={e} active={e.id === activeId} onSelect={select} />\n ))}\n </>\n )}\n </nav>\n\n <div className=\"mst-side__foot\">\n <span className=\"mst-pulse\" aria-hidden />\n <span>{t.entitiesFooter(entities.length)}</span>\n </div>\n </aside>\n );\n}\n","import { createContext, useContext } from 'react';\n\nexport type AdminLocale = 'en' | 'pt-BR';\n\n/**\n * Every user-facing string the admin chrome renders. Entity/field labels are NOT here — those come\n * from the server metadata (optionally rewritten via `AdminLabels`); this dictionary covers only the\n * UI around them (buttons, menus, pagination, confirmations).\n */\nexport interface AdminStrings {\n loading: string;\n loadingMetadata: string;\n records: (total: number) => string;\n searchPlaceholder: (plural: string) => string;\n newRecord: string;\n view: string;\n edit: string;\n clone: string;\n remove: string;\n copyId: string;\n copyObject: string;\n copyValue: string;\n copied: string;\n addToFilter: string;\n openRelated: (label: string) => string;\n filters: string;\n clearFilters: string;\n actions: string;\n noRecords: string;\n tryDifferentSearch: string;\n deleteConfirm: (singular: string) => string;\n page: (page: number, total: number) => string;\n previous: string;\n next: string;\n cancel: string;\n save: string;\n saving: string;\n create: string;\n newTitle: (singular: string) => string;\n editTitle: (singular: string) => string;\n cloneTitle: (singular: string) => string;\n entitiesFooter: (count: number) => string;\n yes: string;\n no: string;\n jsonFormMode: string;\n jsonRawMode: string;\n jsonInvalid: string;\n emptyObject: string;\n addItem: string;\n removeItem: string;\n searchMenu: string;\n recents: string;\n menus: string;\n noMenuResults: string;\n // Shell\n hub: string;\n breadcrumb: string;\n search: string;\n commandKey: string;\n commandPalette: string;\n palettePlaceholder: string;\n goTo: string;\n onThisScreen: string;\n appearance: string;\n palette: string;\n density: string;\n colorScheme: string;\n schemeSystem: string;\n schemeLight: string;\n schemeDark: string;\n // Hub\n entities: string;\n hubMeta: (entities: number, sources: number) => string;\n otherEntities: string;\n noEntities: string;\n noEntitiesHint: string;\n fieldCount: (count: number) => string;\n capRead: string;\n capCreate: string;\n capUpdate: string;\n capDelete: string;\n // Columns\n columns: string;\n columnsCount: (visible: number, total: number) => string;\n resetColumns: string;\n}\n\nconst EN: AdminStrings = {\n loading: 'Loading…',\n loadingMetadata: 'Loading metadata…',\n records: (total) => `${total} record${total === 1 ? '' : 's'}`,\n searchPlaceholder: (plural) => `Search ${plural.toLowerCase()}…`,\n newRecord: 'New',\n view: 'View',\n edit: 'Edit',\n clone: 'Clone',\n remove: 'Remove',\n copyId: 'Copy ID',\n copyObject: 'Copy object',\n copyValue: 'Copy value',\n copied: 'Copied!',\n addToFilter: 'Add to filter',\n openRelated: (label) => `Open ${label}`,\n filters: 'Filters',\n clearFilters: 'Clear filters',\n actions: 'Actions',\n noRecords: 'No records',\n tryDifferentSearch: 'Try a different search.',\n deleteConfirm: (singular) => `Delete this ${singular.toLowerCase()}? This cannot be undone.`,\n page: (page, total) => `Page ${page} of ${total}`,\n previous: 'Previous',\n next: 'Next',\n cancel: 'Cancel',\n save: 'Save',\n saving: 'Saving…',\n create: 'Create',\n newTitle: (singular) => `New ${singular}`,\n editTitle: (singular) => `Edit ${singular}`,\n cloneTitle: (singular) => `Clone ${singular}`,\n entitiesFooter: (count) => `${count} entities · Maestro`,\n yes: 'true',\n no: 'false',\n jsonFormMode: 'Fields',\n jsonRawMode: 'JSON',\n jsonInvalid: 'Invalid JSON — fix it to apply this change.',\n emptyObject: '(empty)',\n addItem: 'Add item',\n removeItem: 'Remove item',\n searchMenu: 'Search menu…',\n recents: 'Recents',\n menus: 'Menus',\n noMenuResults: 'No matches',\n hub: 'Hub',\n breadcrumb: 'Breadcrumb',\n search: 'Search',\n commandKey: '⌘K',\n commandPalette: 'Command palette',\n palettePlaceholder: 'Go to an entity, or run an action…',\n goTo: 'Go to',\n onThisScreen: 'On this screen',\n appearance: 'Appearance',\n palette: 'Palette',\n density: 'Density',\n colorScheme: 'Light / dark',\n schemeSystem: 'system',\n schemeLight: 'light',\n schemeDark: 'dark',\n entities: 'Entities',\n hubMeta: (entities, sources) =>\n `${entities} ${entities === 1 ? 'entity' : 'entities'} across ${sources} ${sources === 1 ? 'datasource' : 'datasources'}.`,\n otherEntities: 'Other',\n noEntities: 'No entities',\n noEntitiesHint: 'The server served an empty metadata document.',\n fieldCount: (count) => `${count} field${count === 1 ? '' : 's'}`,\n capRead: 'read',\n capCreate: 'create',\n capUpdate: 'update',\n capDelete: 'delete',\n columns: 'Columns',\n columnsCount: (visible, total) => `${visible}/${total}`,\n resetColumns: 'Reset columns',\n};\n\nconst PT_BR: AdminStrings = {\n loading: 'Carregando…',\n loadingMetadata: 'Carregando metadados…',\n records: (total) => `${total} registro${total === 1 ? '' : 's'}`,\n searchPlaceholder: (plural) => `Buscar ${plural.toLowerCase()}…`,\n newRecord: 'Novo',\n view: 'Visualizar',\n edit: 'Editar',\n clone: 'Clonar',\n remove: 'Remover',\n copyId: 'Copiar ID',\n copyObject: 'Copiar objeto',\n copyValue: 'Copiar valor',\n copied: 'Copiado!',\n addToFilter: 'Adicionar ao filtro',\n openRelated: (label) => `Abrir ${label}`,\n filters: 'Filtros',\n clearFilters: 'Limpar filtros',\n actions: 'Ações',\n noRecords: 'Nenhum registro',\n tryDifferentSearch: 'Tente uma busca diferente.',\n deleteConfirm: (singular) => `Remover este registro de ${singular}? Essa ação não pode ser desfeita.`,\n page: (page, total) => `Página ${page} de ${total}`,\n previous: 'Anterior',\n next: 'Próxima',\n cancel: 'Cancelar',\n save: 'Salvar',\n saving: 'Salvando…',\n create: 'Criar',\n newTitle: (singular) => `Novo(a) ${singular}`,\n editTitle: (singular) => `Editar ${singular}`,\n cloneTitle: (singular) => `Clonar ${singular}`,\n entitiesFooter: (count) => `${count} entidades · Maestro`,\n yes: 'sim',\n no: 'não',\n jsonFormMode: 'Campos',\n jsonRawMode: 'JSON',\n jsonInvalid: 'JSON inválido — corrija para aplicar esta alteração.',\n emptyObject: '(vazio)',\n addItem: 'Adicionar item',\n removeItem: 'Remover item',\n searchMenu: 'Buscar no menu…',\n recents: 'Recentes',\n menus: 'Menus',\n noMenuResults: 'Nada encontrado',\n hub: 'Hub',\n breadcrumb: 'Trilha',\n search: 'Buscar',\n commandKey: '⌘K',\n commandPalette: 'Paleta de comandos',\n palettePlaceholder: 'Ir para uma entidade, ou executar uma ação…',\n goTo: 'Ir para',\n onThisScreen: 'Nesta tela',\n appearance: 'Aparência',\n palette: 'Paleta',\n density: 'Densidade',\n colorScheme: 'Claro / escuro',\n schemeSystem: 'sistema',\n schemeLight: 'claro',\n schemeDark: 'escuro',\n entities: 'Entidades',\n hubMeta: (entities, sources) =>\n `${entities} ${entities === 1 ? 'entidade' : 'entidades'} em ${sources} ${sources === 1 ? 'origem de dados' : 'origens de dados'}.`,\n otherEntities: 'Outras',\n noEntities: 'Nenhuma entidade',\n noEntitiesHint: 'O servidor entregou um documento de metadados vazio.',\n fieldCount: (count) => `${count} campo${count === 1 ? '' : 's'}`,\n capRead: 'ler',\n capCreate: 'criar',\n capUpdate: 'editar',\n capDelete: 'excluir',\n columns: 'Colunas',\n columnsCount: (visible, total) => `${visible}/${total}`,\n resetColumns: 'Restaurar colunas',\n};\n\nconst LOCALES: Record<AdminLocale, AdminStrings> = { en: EN, 'pt-BR': PT_BR };\n\nexport function stringsFor(locale: AdminLocale): AdminStrings {\n return LOCALES[locale] ?? EN;\n}\n\nconst I18nContext = createContext<AdminStrings>(EN);\n\nexport const I18nProvider = I18nContext.Provider;\n\n/** The active UI-string dictionary (set by `<MaestroAdmin locale>`; defaults to English). */\nexport function useT(): AdminStrings {\n return useContext(I18nContext);\n}\n","import type { ReactElement } from 'react';\nimport type { EntityMetadata } from '../client/types.js';\n\n/**\n * The admin's icon set, inline.\n *\n * Twenty-odd 24×24 stroke glyphs are not worth a runtime dependency: `@maykonpaulo/maestro-admin`\n * ships with `dependencies: {}` and this file is why. Every glyph is drawn on the same grid with the\n * same stroke weight, and takes its colour from `currentColor`.\n */\n\nconst PATHS = {\n hub: (\n <>\n <rect x=\"3.5\" y=\"3.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"13.5\" y=\"3.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"3.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n <rect x=\"13.5\" y=\"13.5\" width=\"7\" height=\"7\" rx=\"1.5\" />\n </>\n ),\n baton: (\n <>\n <path d=\"M4 20 14 10\" />\n <circle cx=\"17\" cy=\"7\" r=\"3.2\" />\n </>\n ),\n search: (\n <>\n <circle cx=\"11\" cy=\"11\" r=\"6.5\" />\n <path d=\"m16 16 4.5 4.5\" />\n </>\n ),\n chevronRight: <path d=\"m9 5 7 7-7 7\" />,\n chevronLeft: <path d=\"M15 5 8 12l7 7\" />,\n chevronsLeft: <path d=\"M17 5l-7 7 7 7M10 5l-7 7 7 7\" />,\n chevronsRight: <path d=\"m7 5 7 7-7 7M14 5l7 7-7 7\" />,\n plus: <path d=\"M12 5v14M5 12h14\" />,\n close: <path d=\"M6 6l12 12M18 6 6 18\" />,\n check: <path d=\"m4.5 12.5 5 5 10-11\" />,\n filter: <path d=\"M3 5h18l-7 8v6l-4 2v-8L3 5Z\" />,\n download: <path d=\"M12 3v12M7.5 10.5 12 15l4.5-4.5M4 20h16\" />,\n columns: (\n <>\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" />\n <path d=\"M9.5 4v16M15 4v16\" />\n </>\n ),\n rows: (\n <>\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" />\n <path d=\"M3 9.3h18M3 14.7h18\" />\n </>\n ),\n sun: (\n <>\n <circle cx=\"12\" cy=\"12\" r=\"4.2\" />\n <path d=\"M12 2.5v2.2M12 19.3v2.2M4.2 4.2l1.6 1.6M18.2 18.2l1.6 1.6M2.5 12h2.2M19.3 12h2.2M4.2 19.8l1.6-1.6M18.2 5.8l1.6-1.6\" />\n </>\n ),\n moon: <path d=\"M20 14.5A8.5 8.5 0 0 1 9.5 4a8.5 8.5 0 1 0 10.5 10.5Z\" />,\n swatch: (\n <>\n <circle cx=\"8.5\" cy=\"8.5\" r=\"4.5\" />\n <circle cx=\"15.5\" cy=\"8.5\" r=\"4.5\" />\n <circle cx=\"12\" cy=\"15\" r=\"4.5\" />\n </>\n ),\n dots: (\n <>\n <circle cx=\"12\" cy=\"5\" r=\"1.4\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.4\" />\n <circle cx=\"12\" cy=\"19\" r=\"1.4\" />\n </>\n ),\n trash: <path d=\"M4 7h16M9 7V4.5h6V7M6.5 7l1 13h9l1-13\" />,\n pencil: <path d=\"M4 20h4L20 8l-4-4L4 16v4Z\" />,\n eye: (\n <>\n <path d=\"M2.5 12S6 5.5 12 5.5 21.5 12 21.5 12 18 18.5 12 18.5 2.5 12 2.5 12Z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </>\n ),\n copy: (\n <>\n <rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\" />\n <path d=\"M15 6.5V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h.5\" />\n </>\n ),\n clone: (\n <>\n <rect x=\"4\" y=\"4\" width=\"11\" height=\"11\" rx=\"2\" />\n <path d=\"M9 20h9a2 2 0 0 0 2-2V9\" />\n </>\n ),\n arrowUpRight: <path d=\"M7 17 17 7M9 7h8v8\" />,\n arrowLeft: <path d=\"M19 12H6M11 6l-5 6 5 6\" />,\n sort: <path d=\"M8 9 12 5l4 4M8 15l4 4 4-4\" />,\n sortAsc: <path d=\"M12 19V6M7 11l5-5 5 5\" />,\n sortDesc: <path d=\"M12 5v13M7 13l5 5 5-5\" />,\n database: (\n <>\n <ellipse cx=\"12\" cy=\"6\" rx=\"8\" ry=\"3.2\" />\n <path d=\"M4 6v12c0 1.8 3.6 3.2 8 3.2s8-1.4 8-3.2V6M4 12c0 1.8 3.6 3.2 8 3.2s8-1.4 8-3.2\" />\n </>\n ),\n table: (\n <>\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" />\n <path d=\"M3 9.5h18M9 9.5V20\" />\n </>\n ),\n users: (\n <>\n <circle cx=\"9\" cy=\"8\" r=\"3.2\" />\n <path d=\"M3 19c0-3 2.7-4.8 6-4.8s6 1.8 6 4.8\" />\n <path d=\"M16 5.5a3 3 0 0 1 0 5.6M17.5 14.6c2 .6 3.5 2.1 3.5 4.4\" />\n </>\n ),\n box: (\n <>\n <path d=\"M12 3 20.5 7.5v9L12 21l-8.5-4.5v-9L12 3Z\" />\n <path d=\"M3.5 7.5 12 12l8.5-4.5M12 12v9\" />\n </>\n ),\n receipt: (\n <>\n <path d=\"M5 3h14v18l-2.3-1.6-2.3 1.6-2.4-1.6L9.6 21l-2.3-1.6L5 21V3Z\" />\n <path d=\"M9 8h6M9 12h6\" />\n </>\n ),\n key: (\n <>\n <circle cx=\"8\" cy=\"13\" r=\"4\" />\n <path d=\"m11 11 8-8M17 5l2 2M15 7l2 2\" />\n </>\n ),\n shield: (\n <>\n <path d=\"M12 3 20 6v6c0 4.4-3.3 7.9-8 9-4.7-1.1-8-4.6-8-9V6l8-3Z\" />\n <path d=\"m9 12 2.2 2.2L15.5 10\" />\n </>\n ),\n activity: <path d=\"M3 12h4l2.5-6 4 12 2.5-6h5\" />,\n tag: (\n <>\n <path d=\"M3 11.5V4h7.5l10 10-7.5 7.5-10-10Z\" />\n <circle cx=\"7.5\" cy=\"7.5\" r=\"1.3\" />\n </>\n ),\n map: (\n <>\n <path d=\"M9 4 3 6.5v13L9 17l6 2.5 6-2.5v-13L15 6.5 9 4Z\" />\n <path d=\"M9 4v13M15 6.5v13\" />\n </>\n ),\n calendar: (\n <>\n <rect x=\"3.5\" y=\"5\" width=\"17\" height=\"15\" rx=\"2\" />\n <path d=\"M3.5 10h17M8 3v4M16 3v4\" />\n </>\n ),\n mail: (\n <>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <path d=\"m3.5 7 8.5 6 8.5-6\" />\n </>\n ),\n file: (\n <>\n <path d=\"M13 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V9l-6-6Z\" />\n <path d=\"M13 3v6h6\" />\n </>\n ),\n alert: (\n <>\n <path d=\"M12 4 2.5 20h19L12 4Z\" />\n <path d=\"M12 10v4.5M12 17.4v.2\" />\n </>\n ),\n} as const;\n\nexport type IconName = keyof typeof PATHS;\n\nexport function Icon({\n name,\n size = 15,\n className,\n title,\n}: {\n name: IconName;\n size?: number;\n className?: string;\n title?: string;\n}): ReactElement {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n className={className ? `mst-icon ${className}` : 'mst-icon'}\n aria-hidden={title ? undefined : true}\n role={title ? 'img' : undefined}\n focusable=\"false\"\n >\n {title && <title>{title}</title>}\n {PATHS[name]}\n </svg>\n );\n}\n\n// Keyword → glyph, checked against the entity id, table and labels. Ordered: the first hit wins, so\n// narrower words come before the ones they contain (\"payment\" before \"pay\").\nconst ENTITY_ICON_HINTS: ReadonlyArray<readonly [readonly string[], IconName]> = [\n [['user', 'usuario', 'people', 'pessoa', 'customer', 'cliente', 'associado', 'member', 'contact'], 'users'],\n [['invoice', 'fatura', 'cobranca', 'billing', 'receipt', 'nota'], 'receipt'],\n [['payment', 'pagamento', 'transaction', 'transacao', 'ledger'], 'table'],\n [['product', 'produto', 'item', 'sku', 'inventory', 'estoque', 'catalog'], 'box'],\n [['address', 'endereco', 'location', 'local', 'region', 'city', 'cidade'], 'map'],\n [['role', 'papel', 'permission', 'permissao', 'grant', 'token', 'credential'], 'key'],\n [['audit', 'auditoria', 'log', 'event', 'evento', 'metric'], 'activity'],\n [['policy', 'politica', 'security', 'seguranca', 'consent', 'consentimento'], 'shield'],\n [['tag', 'label', 'category', 'categoria', 'plan', 'plano', 'subscription', 'assinatura'], 'tag'],\n [['schedule', 'agenda', 'appointment', 'date', 'periodo', 'calendar'], 'calendar'],\n [['message', 'mensagem', 'email', 'notification', 'notificacao', 'ticket'], 'mail'],\n [['document', 'documento', 'file', 'arquivo', 'contract', 'contrato', 'report'], 'file'],\n];\n\nfunction fold(text: string): string {\n return text.toLowerCase().normalize('NFD').replace(/\\p{M}/gu, '');\n}\n\n/**\n * A glyph for an entity, guessed from its names. A metadata-driven admin has no idea what a\n * collection *means*, so this is deliberately a hint and not a promise: anything unrecognised gets\n * the neutral table glyph, which is always a defensible answer.\n */\nexport function entityIcon(entity: EntityMetadata): IconName {\n const haystack = fold(`${entity.id} ${entity.table} ${entity.label.singular} ${entity.label.plural}`);\n for (const [words, icon] of ENTITY_ICON_HINTS) {\n if (words.some((word) => haystack.includes(word))) return icon;\n }\n return 'table';\n}\n","import { useState } from 'react';\nimport { useT } from '../i18n.js';\nimport { MAESTRO_THEMES, useTheme } from '../theme.js';\nimport { Icon, type IconName } from './icons.js';\nimport { PopMenu, type MenuAnchor, type MenuItem } from './menu.js';\n\nexport interface Crumb {\n label: string;\n icon?: IconName;\n /** Omit on the last crumb — the current place is not a link. */\n onClick?: () => void;\n}\n\n/** Cycles system → light → dark → system, so the OS default stays reachable. */\nconst NEXT_SCHEME = { system: 'light', light: 'dark', dark: 'system' } as const;\nconst SCHEME_ICON: Record<'system' | 'light' | 'dark', IconName> = {\n system: 'swatch',\n light: 'sun',\n dark: 'moon',\n};\n\n/**\n * The bar above the content: where you are (breadcrumbs), how to get anywhere (⌘K), and how the admin\n * looks (palette, light/dark, density). The appearance controls live here rather than in a settings\n * page because they are the operator's, changed mid-task and never worth a navigation.\n */\nexport function Header({ crumbs, onOpenPalette }: { crumbs: Crumb[]; onOpenPalette: () => void }) {\n const t = useT();\n const theme = useTheme();\n const [anchor, setAnchor] = useState<MenuAnchor | undefined>(undefined);\n\n const themeItems: MenuItem[] = MAESTRO_THEMES.map((option) => ({\n id: option.id,\n label: (\n <>\n <span className=\"mst-swatch\" style={{ background: option.swatch }} />\n {option.label}\n {theme.preset === option.id && <Icon name=\"check\" size={13} />}\n </>\n ),\n onSelect: () => theme.setPreset(option.id),\n }));\n\n const schemeLabel = theme.scheme === 'system' ? t.schemeSystem : theme.scheme === 'light' ? t.schemeLight : t.schemeDark;\n\n return (\n <header className=\"mst-header\">\n <nav className=\"mst-crumbs\" aria-label={t.breadcrumb}>\n {crumbs.map((crumb, index) => (\n <span key={`${crumb.label}-${index}`} className=\"mst-crumbs__item\">\n {index > 0 && <Icon name=\"chevronRight\" size={12} className=\"mst-crumbs__sep\" />}\n {crumb.onClick ? (\n <button type=\"button\" className=\"mst-crumbs__link\" onClick={crumb.onClick}>\n {crumb.icon && <Icon name={crumb.icon} size={13} />}\n {crumb.label}\n </button>\n ) : (\n <span className=\"mst-crumbs__now\">\n {crumb.icon && <Icon name={crumb.icon} size={13} />}\n {crumb.label}\n </span>\n )}\n </span>\n ))}\n </nav>\n\n <button type=\"button\" className=\"mst-searchchip\" onClick={onOpenPalette}>\n <Icon name=\"search\" size={13} />\n <span>{t.search}</span>\n <kbd className=\"mst-kbd\">{t.commandKey}</kbd>\n </button>\n\n {theme.picker && (\n <>\n <button\n type=\"button\"\n aria-label={t.density}\n title={t.density}\n aria-pressed={theme.density === 'compact'}\n className=\"mst-iconbtn\"\n onClick={() => theme.setDensity(theme.density === 'compact' ? 'comfortable' : 'compact')}\n >\n <Icon name=\"rows\" size={14} />\n </button>\n <button\n type=\"button\"\n aria-label={t.palette}\n title={t.palette}\n className=\"mst-iconbtn\"\n onClick={(e) => {\n const rect = e.currentTarget.getBoundingClientRect();\n setAnchor({ x: rect.right - 200, y: rect.bottom + 6 });\n }}\n >\n <Icon name=\"swatch\" size={14} />\n </button>\n <button\n type=\"button\"\n aria-label={`${t.colorScheme}: ${schemeLabel}`}\n title={`${t.colorScheme}: ${schemeLabel}`}\n className=\"mst-iconbtn\"\n onClick={() => theme.setScheme(NEXT_SCHEME[theme.scheme])}\n >\n <Icon name={SCHEME_ICON[theme.scheme]} size={14} />\n </button>\n </>\n )}\n\n {anchor && <PopMenu anchor={anchor} items={themeItems} onClose={() => setAnchor(undefined)} />}\n </header>\n );\n}\n","import { createContext, useCallback, useContext, useMemo, useState, type CSSProperties, type ReactNode } from 'react';\n\n/** Built-in palettes. Each ships a light and a dark set of the same tokens. */\nexport type MaestroThemeName = 'cobalto' | 'latao' | 'teal';\n\n/** `system` follows the OS `prefers-color-scheme`; the other two force the decision. */\nexport type MaestroScheme = 'system' | 'light' | 'dark';\n\n/** Table row height. `compact` fits roughly 40% more rows on a screen and changes nothing else. */\nexport type MaestroDensity = 'comfortable' | 'compact';\n\nexport interface MaestroThemeOption {\n id: MaestroThemeName;\n label: string;\n /** Light-mode brand colour — what the picker shows as the palette's dot. */\n swatch: string;\n}\n\nexport const MAESTRO_THEMES: readonly MaestroThemeOption[] = [\n { id: 'cobalto', label: 'Grafite & Cobalto', swatch: '#3557e8' },\n { id: 'latao', label: 'Ardósia & Latão', swatch: '#9a6a22' },\n { id: 'teal', label: 'Tinta & Teal', swatch: '#0e7c74' },\n];\n\nexport interface MaestroThemeConfig {\n /** Palette to start on. Defaults to `cobalto`. */\n preset?: MaestroThemeName;\n /** Light/dark decision to start on. Defaults to `system`. */\n scheme?: MaestroScheme;\n /** Row density to start on. Defaults to `comfortable`. */\n density?: MaestroDensity;\n /**\n * Token overrides applied inline on the admin root, so they win over the preset in both schemes:\n * `{ '--maestro-brand': '#167B61' }`. Use this to dress the admin in your own brand.\n */\n tokens?: Record<string, string>;\n /** Show the palette / light-dark / density controls in the header. Defaults to `true`. */\n picker?: boolean;\n /** Remember the operator's choices in `localStorage`. Defaults to `true`. */\n remember?: boolean;\n}\n\n/** `theme=\"cobalto\"` is shorthand for `theme={{ preset: 'cobalto' }}`. */\nexport type MaestroThemeInput = MaestroThemeName | MaestroThemeConfig;\n\nexport interface MaestroThemeState {\n preset: MaestroThemeName;\n scheme: MaestroScheme;\n density: MaestroDensity;\n picker: boolean;\n setPreset: (preset: MaestroThemeName) => void;\n setScheme: (scheme: MaestroScheme) => void;\n setDensity: (density: MaestroDensity) => void;\n}\n\nconst STORAGE_KEY = 'maestro-admin:appearance';\n\nconst DEFAULTS = {\n preset: 'cobalto' as MaestroThemeName,\n scheme: 'system' as MaestroScheme,\n density: 'comfortable' as MaestroDensity,\n};\n\nfunction normalizeConfig(input: MaestroThemeInput | undefined): MaestroThemeConfig {\n if (!input) return {};\n return typeof input === 'string' ? { preset: input } : input;\n}\n\ninterface StoredAppearance {\n preset?: MaestroThemeName;\n scheme?: MaestroScheme;\n density?: MaestroDensity;\n}\n\nfunction readStored(): StoredAppearance {\n try {\n const raw = globalThis.localStorage?.getItem(STORAGE_KEY);\n const parsed: unknown = raw ? JSON.parse(raw) : null;\n return parsed && typeof parsed === 'object' ? (parsed as StoredAppearance) : {};\n } catch {\n return {}; // storage blocked or corrupted — appearance is a preference, never a hard failure\n }\n}\n\nfunction writeStored(value: StoredAppearance): void {\n try {\n globalThis.localStorage?.setItem(STORAGE_KEY, JSON.stringify(value));\n } catch {\n // best-effort\n }\n}\n\nconst ThemeContext = createContext<MaestroThemeState>({\n ...DEFAULTS,\n picker: true,\n setPreset: () => undefined,\n setScheme: () => undefined,\n setDensity: () => undefined,\n});\n\n/** The active appearance and its setters. Safe outside a provider — falls back to the defaults. */\nexport function useTheme(): MaestroThemeState {\n return useContext(ThemeContext);\n}\n\n/**\n * Owns the appearance state and paints the root element that carries the tokens. Everything below it\n * reads colours from CSS custom properties, so a theme switch is one attribute change — no re-render\n * of the tree's styles, no class swapping.\n *\n * The props are the *initial* values: once the operator picks a palette from the header it is\n * remembered (unless `remember: false`), and the stored choice wins on the next mount.\n */\nexport function MaestroThemeProvider({\n theme,\n className,\n children,\n rootRef,\n}: {\n theme?: MaestroThemeInput;\n className?: string;\n children: ReactNode;\n rootRef?: (node: HTMLDivElement | null) => void;\n}) {\n const config = useMemo(() => normalizeConfig(theme), [theme]);\n const remember = config.remember !== false;\n\n const [state, setState] = useState<StoredAppearance>(() => {\n const stored = remember ? readStored() : {};\n return {\n preset: stored.preset ?? config.preset ?? DEFAULTS.preset,\n scheme: stored.scheme ?? config.scheme ?? DEFAULTS.scheme,\n density: stored.density ?? config.density ?? DEFAULTS.density,\n };\n });\n\n const update = useCallback(\n (patch: StoredAppearance): void => {\n setState((prev) => {\n const next = { ...prev, ...patch };\n if (remember) writeStored(next);\n return next;\n });\n },\n [remember],\n );\n\n const value = useMemo<MaestroThemeState>(\n () => ({\n preset: state.preset ?? DEFAULTS.preset,\n scheme: state.scheme ?? DEFAULTS.scheme,\n density: state.density ?? DEFAULTS.density,\n picker: config.picker !== false,\n setPreset: (preset) => update({ preset }),\n setScheme: (scheme) => update({ scheme }),\n setDensity: (density) => update({ density }),\n }),\n [state, config.picker, update],\n );\n\n return (\n <ThemeContext.Provider value={value}>\n <div\n ref={rootRef}\n className={className}\n data-maestro-theme={value.preset}\n data-maestro-scheme={value.scheme}\n data-maestro-density={value.density}\n style={config.tokens as CSSProperties | undefined}\n >\n {children}\n </div>\n </ThemeContext.Provider>\n );\n}\n","import { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useAdminRoot } from '../AdminContext.js';\nimport { Icon, type IconName } from './icons.js';\n\nexport interface MenuItem {\n id: string;\n label: ReactNode;\n icon?: IconName;\n danger?: boolean;\n /** Draws a hairline above this item — for separating destructive actions from the rest. */\n separated?: boolean;\n onSelect: () => void;\n}\n\nexport interface MenuAnchor {\n x: number;\n y: number;\n}\n\n/**\n * A floating menu rendered in a portal at a fixed viewport position — immune to the table's\n * clipping. Closes on outside click, Escape, scroll or resize. Purely presentational: callers decide\n * the anchor (a button's rect, a clicked cell) and the items.\n */\nexport function PopMenu({ anchor, items, onClose }: { anchor: MenuAnchor; items: MenuItem[]; onClose: () => void }) {\n const ref = useRef<HTMLDivElement>(null);\n const [pos, setPos] = useState(anchor);\n const root = useAdminRoot();\n\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n setPos({\n x: Math.max(4, Math.min(anchor.x, window.innerWidth - rect.width - 8)),\n y: Math.max(4, Math.min(anchor.y, window.innerHeight - rect.height - 8)),\n });\n }, [anchor]);\n\n useEffect(() => {\n const onDown = (e: MouseEvent): void => {\n if (ref.current && !ref.current.contains(e.target as Node)) onClose();\n };\n const onKey = (e: KeyboardEvent): void => {\n if (e.key === 'Escape') onClose();\n };\n document.addEventListener('mousedown', onDown);\n document.addEventListener('keydown', onKey);\n window.addEventListener('scroll', onClose, true);\n window.addEventListener('resize', onClose);\n return () => {\n document.removeEventListener('mousedown', onDown);\n document.removeEventListener('keydown', onKey);\n window.removeEventListener('scroll', onClose, true);\n window.removeEventListener('resize', onClose);\n };\n }, [onClose]);\n\n return createPortal(\n <div ref={ref} role=\"menu\" style={{ left: pos.x, top: pos.y }} className=\"mst-menu\">\n {items.map((item) => (\n <div key={item.id}>\n {item.separated && <div className=\"mst-menu__sep\" />}\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={() => {\n onClose();\n item.onSelect();\n }}\n className={`mst-menu__item${item.danger ? ' mst-menu__item--danger' : ''}`}\n >\n {item.icon && <Icon name={item.icon} size={14} />}\n {item.label}\n </button>\n </div>\n ))}\n </div>,\n root ?? document.body,\n );\n}\n\n/** The row-level \"⋮\" trigger: a compact button that opens a `PopMenu` aligned under itself. */\nexport function MenuButton({ items, label }: { items: MenuItem[]; label: string }) {\n const [anchor, setAnchor] = useState<MenuAnchor | undefined>(undefined);\n\n return (\n <>\n <button\n type=\"button\"\n aria-label={label}\n title={label}\n onClick={(e) => {\n const rect = e.currentTarget.getBoundingClientRect();\n setAnchor({ x: rect.right - 184, y: rect.bottom + 4 });\n }}\n className=\"mst-iconbtn\"\n >\n <Icon name=\"dots\" size={14} />\n </button>\n {anchor && <PopMenu anchor={anchor} items={items} onClose={() => setAnchor(undefined)} />}\n </>\n );\n}\n","import { useMemo } from 'react';\nimport type { EntityMetadata } from '../client/types.js';\nimport type { AdminLabels } from '../labels.js';\nimport { buildMenu } from '../grouping.js';\nimport { useT } from '../i18n.js';\nimport { EmptyState } from './ui.js';\nimport { Icon, entityIcon } from './icons.js';\n\n/** The capability chips, in the order an operator reasons about them. */\nconst CAPS = ['list', 'create', 'update', 'delete'] as const;\n\nfunction EntityCard({ entity, onOpen }: { entity: EntityMetadata; onOpen: (entityId: string) => void }) {\n const t = useT();\n const capLabel = { list: t.capRead, create: t.capCreate, update: t.capUpdate, delete: t.capDelete };\n\n return (\n <button type=\"button\" className=\"mst-ecard\" onClick={() => onOpen(entity.id)}>\n <span className=\"mst-ecard__tile\">\n <Icon name={entityIcon(entity)} size={16} />\n </span>\n <span className=\"mst-ecard__body\">\n <span className=\"mst-ecard__name\">{entity.label.plural}</span>\n <span className=\"mst-ecard__desc\">{entity.description ?? t.fieldCount(entity.fields.length)}</span>\n <span className=\"mst-caps\">\n {CAPS.map((cap) => (\n <span key={cap} className=\"mst-cap\" data-on={String(entity.capabilities[cap])}>\n {capLabel[cap]}\n </span>\n ))}\n </span>\n <span className=\"mst-source\">\n <Icon name=\"database\" size={11} />\n <span>\n {entity.datasource} · {entity.table}\n </span>\n </span>\n </span>\n </button>\n );\n}\n\n/**\n * The landing screen: every entity the server serves, in its sidebar folder, with what you can do to\n * it and where it actually lives. That last part is the whole point — Maestro speaks a dozen\n * providers, so \"which database is this collection in\" is a real question with a real answer, and no\n * other admin can show it.\n *\n * Record counts are deliberately absent: metadata does not carry them, and one `count` request per\n * entity would turn opening the admin into thirty round-trips. The count you get is the real one, in\n * the list header, once you open an entity.\n */\nexport function Hub({\n entities,\n labels,\n onOpen,\n}: {\n entities: EntityMetadata[];\n labels?: AdminLabels;\n onOpen: (entityId: string) => void;\n}) {\n const t = useT();\n const menu = useMemo(() => buildMenu(entities, labels), [entities, labels]);\n\n const sources = useMemo(() => new Set(entities.map((e) => e.datasource)).size, [entities]);\n\n if (entities.length === 0) {\n return <EmptyState title={t.noEntities} hint={t.noEntitiesHint} />;\n }\n\n return (\n <section className=\"mst-page\">\n <div className=\"mst-pagehead\">\n <div>\n <h1 className=\"mst-pagehead__title\">{t.entities}</h1>\n <p className=\"mst-pagehead__meta\">{t.hubMeta(entities.length, sources)}</p>\n </div>\n </div>\n\n <div className=\"mst-hub\">\n {menu.groups.map((group) => (\n <div key={group.id}>\n <p className=\"mst-grouplabel\">{group.label}</p>\n <div className=\"mst-cards\">\n {group.entities.map((entity) => (\n <EntityCard key={entity.id} entity={entity} onOpen={onOpen} />\n ))}\n </div>\n </div>\n ))}\n\n {menu.ungrouped.length > 0 && (\n <div>\n {menu.groups.length > 0 && <p className=\"mst-grouplabel\">{t.otherEntities}</p>}\n <div className=\"mst-cards\">\n {menu.ungrouped.map((entity) => (\n <EntityCard key={entity.id} entity={entity} onOpen={onOpen} />\n ))}\n </div>\n </div>\n )}\n </div>\n </section>\n );\n}\n","import type { ButtonHTMLAttributes, ReactNode } from 'react';\nimport { Icon, type IconName } from './icons.js';\n\ntype Variant = 'primary' | 'secondary' | 'danger' | 'ghost';\n\nexport function Button({\n variant = 'secondary',\n icon,\n className = '',\n children,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & { variant?: Variant; icon?: IconName }) {\n return (\n <button type=\"button\" className={`mst-btn mst-btn--${variant} ${className}`.trim()} {...props}>\n {icon && <Icon name={icon} size={14} />}\n {children}\n </button>\n );\n}\n\n/** A square, label-less button. `label` is required — it is the accessible name and the tooltip. */\nexport function IconButton({\n icon,\n label,\n className = '',\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & { icon: IconName; label: string }) {\n return (\n <button type=\"button\" aria-label={label} title={label} className={`mst-iconbtn ${className}`.trim()} {...props}>\n <Icon name={icon} size={14} />\n </button>\n );\n}\n\nexport type BadgeTone = 'neutral' | 'brand' | 'ok' | 'warn' | 'danger';\n\nexport function Badge({ children, tone = 'neutral', dot = false }: { children: ReactNode; tone?: BadgeTone; dot?: boolean }) {\n const toneClass = tone === 'neutral' ? '' : ` mst-badge--${tone}`;\n return <span className={`mst-badge${toneClass}${dot ? ' mst-badge--dot' : ''}`}>{children}</span>;\n}\n\nexport function Spinner({ label }: { label?: string }) {\n return (\n <div className=\"mst-spinner\" role=\"status\">\n {label ?? 'Loading…'}\n </div>\n );\n}\n\nexport function EmptyState({ title, hint }: { title: string; hint?: string }) {\n return (\n <div className=\"mst-empty\">\n <p className=\"mst-empty__title\">{title}</p>\n {hint && <p className=\"mst-empty__hint\">{hint}</p>}\n </div>\n );\n}\n\nexport function ErrorBanner({ error }: { error: Error }) {\n return (\n <div className=\"mst-error\" role=\"alert\">\n <Icon name=\"alert\" size={15} />\n <span>{error.message}</span>\n </div>\n );\n}\n\n/** The transient confirmation strip (\"Copied!\"). Callers own the timer; this only draws it. */\nexport function Toast({ children }: { children: ReactNode }) {\n return (\n <div className=\"mst-toast\" role=\"status\">\n {children}\n </div>\n );\n}\n","import { useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\nimport type { EntityMetadata } from '../client/types.js';\nimport { useAdminRoot } from '../AdminContext.js';\nimport { useT } from '../i18n.js';\nimport { Icon, entityIcon, type IconName } from './icons.js';\n\nexport interface PaletteCommand {\n id: string;\n label: string;\n icon?: IconName;\n /** Right-aligned affordance: a shortcut, or the folder an entity belongs to. */\n hint?: string;\n /** Extra words matched by the search but never displayed (table name, singular label). */\n keywords?: string;\n run: () => void;\n}\n\nexport interface PaletteSection {\n id: string;\n label: string;\n commands: PaletteCommand[];\n}\n\nfunction normalize(text: string): string {\n return text.toLowerCase().normalize('NFD').replace(/\\p{M}/gu, '');\n}\n\nfunction Highlight({ label, query }: { label: string; query: string }): ReactNode {\n if (!query) return label;\n const folded = normalize(label);\n const idx = folded.indexOf(normalize(query));\n if (idx === -1) return label;\n return (\n <>\n {label.slice(0, idx)}\n <mark>{label.slice(idx, idx + query.length)}</mark>\n {label.slice(idx + query.length)}\n </>\n );\n}\n\n/** Turns the entity list into palette commands — the navigation half of the palette. */\nexport function entityCommands(\n entities: EntityMetadata[],\n groupOf: Map<string, string>,\n onSelect: (entityId: string) => void,\n): PaletteCommand[] {\n return entities.map((entity) => ({\n id: `entity:${entity.id}`,\n label: entity.label.plural,\n icon: entityIcon(entity),\n hint: groupOf.get(entity.id),\n keywords: `${entity.label.singular} ${entity.table} ${entity.id}`,\n run: () => onSelect(entity.id),\n }));\n}\n\n/**\n * ⌘K. Everything reachable in the admin — every entity, plus whatever the current screen can do —\n * behind one accent-insensitive search, driven entirely from the keyboard.\n */\nexport function CommandPalette({ sections, onClose }: { sections: PaletteSection[]; onClose: () => void }) {\n const t = useT();\n const root = useAdminRoot();\n const inputRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const [query, setQuery] = useState('');\n const [cursor, setCursor] = useState(0);\n\n const visible = useMemo(() => {\n if (!query) return sections;\n const q = normalize(query);\n return sections\n .map((section) => ({\n ...section,\n commands: section.commands.filter((c) => normalize(`${c.label} ${c.keywords ?? ''}`).includes(q)),\n }))\n .filter((section) => section.commands.length > 0);\n }, [sections, query]);\n\n const flat = useMemo(() => visible.flatMap((section) => section.commands), [visible]);\n const active = flat[Math.min(cursor, flat.length - 1)];\n\n useEffect(() => setCursor(0), [query]);\n useEffect(() => inputRef.current?.focus(), []);\n\n // Keep the highlighted row in view when the cursor walks past the fold.\n useEffect(() => {\n listRef.current?.querySelector('[data-active=\"true\"]')?.scrollIntoView({ block: 'nearest' });\n }, [cursor, query]);\n\n const onKeyDown = (e: React.KeyboardEvent): void => {\n if (e.key === 'Escape') {\n e.preventDefault();\n onClose();\n return;\n }\n if (e.key === 'ArrowDown' || (e.key === 'n' && e.ctrlKey)) {\n e.preventDefault();\n setCursor((c) => (flat.length === 0 ? 0 : (Math.min(c, flat.length - 1) + 1) % flat.length));\n return;\n }\n if (e.key === 'ArrowUp' || (e.key === 'p' && e.ctrlKey)) {\n e.preventDefault();\n setCursor((c) => (flat.length === 0 ? 0 : (Math.min(c, flat.length - 1) + flat.length - 1) % flat.length));\n return;\n }\n if (e.key === 'Enter' && active) {\n e.preventDefault();\n onClose();\n active.run();\n }\n };\n\n return createPortal(\n <div\n className=\"mst-overlay\"\n role=\"presentation\"\n onMouseDown={(e) => {\n if (e.target === e.currentTarget) onClose();\n }}\n >\n <div className=\"mst-palette\" role=\"dialog\" aria-modal=\"true\" aria-label={t.commandPalette}>\n <div className=\"mst-palette__input\">\n <Icon name=\"search\" size={15} />\n <input\n ref={inputRef}\n type=\"text\"\n value={query}\n placeholder={t.palettePlaceholder}\n aria-label={t.commandPalette}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={onKeyDown}\n />\n <kbd className=\"mst-kbd\">esc</kbd>\n </div>\n\n <div className=\"mst-palette__list\" ref={listRef}>\n {flat.length === 0 ? (\n <p className=\"mst-palette__empty\">{t.noMenuResults}</p>\n ) : (\n visible.map((section) => (\n <div key={section.id}>\n <p className=\"mst-palette__section\">{section.label}</p>\n {section.commands.map((command) => (\n <button\n key={command.id}\n type=\"button\"\n className=\"mst-palette__row\"\n data-active={String(command.id === active?.id)}\n onMouseEnter={() => setCursor(flat.findIndex((c) => c.id === command.id))}\n onClick={() => {\n onClose();\n command.run();\n }}\n >\n {command.icon && <Icon name={command.icon} size={14} />}\n <span className=\"mst-palette__label\">\n <Highlight label={command.label} query={query} />\n </span>\n {command.hint && <span className=\"mst-palette__hint\">{command.hint}</span>}\n </button>\n ))}\n </div>\n ))\n )}\n </div>\n </div>\n </div>,\n root ?? document.body,\n );\n}\n","import { useMemo, useState } from 'react';\nimport type { EntityMetadata, FieldMetadata, FilterInput, ListQuery, Record_, SortInput } from '../client/types.js';\nimport { useClient, useEntities } from '../AdminContext.js';\nimport { useEntityList } from '../hooks.js';\nimport { useColumnPrefs } from '../columns.js';\nimport { FieldValue } from './FieldValue.js';\nimport { Button, EmptyState, ErrorBanner, Spinner, Toast } from './ui.js';\nimport { PopMenu, MenuButton, type MenuAnchor, type MenuItem } from './menu.js';\nimport { Icon } from './icons.js';\nimport { useT } from '../i18n.js';\nimport { copyText } from '../clipboard.js';\n\nconst PAGE_SIZE = 20;\nconst ACTIONS_COLUMN_WIDTH = 44;\n\ninterface CellMenuState {\n anchor: MenuAnchor;\n field: FieldMetadata;\n record: Record_;\n}\n\nfunction filterFor(field: FieldMetadata, value: unknown): FilterInput | undefined {\n if (value === null || value === undefined) return { field: field.name, operator: 'isNull' };\n if (field.type === 'boolean') return { field: field.name, operator: value ? 'isTrue' : 'isFalse' };\n if (field.type === 'json' || field.type === 'array') return undefined;\n return { field: field.name, operator: 'equals', value: String(value) };\n}\n\nfunction filterChipText(entity: EntityMetadata, filter: FilterInput): string {\n const label = entity.fields.find((f) => f.name === filter.field)?.label ?? filter.field;\n if (filter.operator === 'isNull') return `${label} = ∅`;\n if (filter.operator === 'isTrue') return `${label} = ✓`;\n if (filter.operator === 'isFalse') return `${label} = ✗`;\n const value = filter.value ?? '';\n return `${label} = ${value.length > 24 ? `${value.slice(0, 24)}…` : value}`;\n}\n\n/** A 5-slot window around the current page — enough to jump, never enough to wrap the toolbar. */\nfunction pageWindow(page: number, totalPages: number): number[] {\n const size = Math.min(5, totalPages);\n const start = Math.max(1, Math.min(page - 2, totalPages - size + 1));\n return Array.from({ length: size }, (_, i) => start + i);\n}\n\nexport function EntityList({\n entity,\n onOpen,\n onCreate,\n onEdit,\n onClone,\n onNavigate,\n initialFilters,\n}: {\n entity: EntityMetadata;\n onOpen: (id: string) => void;\n onCreate: () => void;\n onEdit: (id: string) => void;\n onClone: (id: string) => void;\n onNavigate: (entityId: string, id: string) => void;\n initialFilters?: FilterInput[];\n}) {\n const client = useClient();\n const t = useT();\n const entities = useEntities();\n const relatedLabel = (entityId: string): string =>\n entities.find((e) => e.id === entityId)?.label.singular ?? entityId;\n const columnPrefs = useColumnPrefs(entity);\n const columns = columnPrefs.columns;\n const searchFields = useMemo(() => entity.fields.filter((f) => f.searchable).map((f) => f.name), [entity]);\n\n const [page, setPage] = useState(1);\n const [search, setSearch] = useState('');\n const [sort, setSort] = useState<SortInput | undefined>(undefined);\n const [filters, setFilters] = useState<FilterInput[]>(initialFilters ?? []);\n const [cellMenu, setCellMenu] = useState<CellMenuState | undefined>(undefined);\n const [columnMenu, setColumnMenu] = useState<MenuAnchor | undefined>(undefined);\n const [copied, setCopied] = useState(false);\n\n const query: ListQuery = {\n page,\n pageSize: PAGE_SIZE,\n search: search || undefined,\n searchFields,\n sort: sort ? [sort] : undefined,\n filters: filters.length ? filters : undefined,\n };\n const { data, error, loading, reload } = useEntityList(entity.id, query);\n\n const toggleSort = (fieldName: string): void => {\n setSort((prev) =>\n prev?.field === fieldName\n ? { field: fieldName, direction: prev.direction === 'asc' ? 'desc' : 'asc' }\n : { field: fieldName, direction: 'asc' },\n );\n };\n\n const flashCopied = (): void => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n };\n\n const copy = async (text: string): Promise<void> => {\n await copyText(text);\n flashCopied();\n };\n\n const addFilter = (filter: FilterInput): void => {\n setFilters((prev) => {\n const others = prev.filter((f) => f.field !== filter.field);\n return [...others, filter];\n });\n setPage(1);\n };\n\n const onDelete = async (id: string): Promise<void> => {\n if (!globalThis.confirm(t.deleteConfirm(entity.label.singular))) return;\n await client.remove(entity.id, id);\n reload();\n };\n\n const rowMenuItems = (record: Record_): MenuItem[] => {\n const id = String(record[entity.primaryKey]);\n const items: MenuItem[] = [{ id: 'view', label: t.view, icon: 'eye', onSelect: () => onOpen(id) }];\n if (entity.capabilities.update) {\n items.push({ id: 'edit', label: t.edit, icon: 'pencil', onSelect: () => onEdit(id) });\n }\n if (entity.capabilities.clone && entity.capabilities.create) {\n items.push({ id: 'clone', label: t.clone, icon: 'clone', onSelect: () => onClone(id) });\n }\n items.push(\n { id: 'copy-id', label: t.copyId, icon: 'copy', separated: true, onSelect: () => void copy(id) },\n {\n id: 'copy-object',\n label: t.copyObject,\n icon: 'copy',\n onSelect: () => void copy(JSON.stringify(record, null, 2)),\n },\n );\n if (entity.capabilities.delete) {\n items.push({\n id: 'remove',\n label: t.remove,\n icon: 'trash',\n danger: true,\n separated: true,\n onSelect: () => void onDelete(id),\n });\n }\n return items;\n };\n\n const cellMenuItems = (state: CellMenuState): MenuItem[] => {\n const { field, record } = state;\n const id = String(record[entity.primaryKey]);\n const value = record[field.name];\n const items: MenuItem[] = [];\n\n const filter = filterFor(field, value);\n if (filter) items.push({ id: 'filter', label: t.addToFilter, icon: 'filter', onSelect: () => addFilter(filter) });\n\n items.push({ id: 'view', label: t.view, icon: 'eye', onSelect: () => onOpen(id) });\n if (entity.capabilities.update) items.push({ id: 'edit', label: t.edit, icon: 'pencil', onSelect: () => onEdit(id) });\n\n if (field.type === 'relation' && field.relationEntity && value !== null && value !== undefined) {\n const targetId = field.relationEntity;\n items.push({\n id: 'open-related',\n label: t.openRelated(relatedLabel(targetId)),\n icon: 'arrowUpRight',\n onSelect: () => onNavigate(targetId, String(value)),\n });\n }\n\n if (value !== null && value !== undefined) {\n items.push({\n id: 'copy-value',\n label: t.copyValue,\n icon: 'copy',\n separated: true,\n onSelect: () => void copy(typeof value === 'object' ? JSON.stringify(value) : String(value)),\n });\n }\n return items;\n };\n\n const columnMenuItems: MenuItem[] = [\n ...columnPrefs.available.map((field) => ({\n id: `col:${field.name}`,\n label: field.label,\n icon: columnPrefs.visible(field.name) ? ('check' as const) : undefined,\n onSelect: () => columnPrefs.toggle(field.name),\n })),\n ...(columnPrefs.customized\n ? [{ id: 'reset', label: t.resetColumns, icon: 'rows' as const, separated: true, onSelect: columnPrefs.reset }]\n : []),\n ];\n\n const totalPages = data?.totalPages ?? (data ? Math.max(1, Math.ceil(data.total / PAGE_SIZE)) : 1);\n const firstRow = data && data.total > 0 ? (page - 1) * PAGE_SIZE + 1 : 0;\n const lastRow = data ? Math.min(page * PAGE_SIZE, data.total) : 0;\n\n return (\n <section className=\"mst-page mst-page--fill\">\n <div className=\"mst-pagehead\">\n <div>\n <h1 className=\"mst-pagehead__title\">{entity.label.plural}</h1>\n <p className=\"mst-pagehead__meta\">\n {data && <span className=\"mst-nums\">{t.records(data.total)}</span>}\n <span className=\"mst-source\">\n <Icon name=\"database\" size={11} />\n <span>\n {entity.datasource} · {entity.table}\n </span>\n </span>\n </p>\n </div>\n <div className=\"mst-pagehead__actions\">\n {searchFields.length > 0 && (\n <input\n type=\"search\"\n className=\"mst-input mst-input--inline\"\n placeholder={t.searchPlaceholder(entity.label.plural)}\n value={search}\n onChange={(e) => {\n setSearch(e.target.value);\n setPage(1);\n }}\n />\n )}\n <Button\n icon=\"columns\"\n onClick={(e) => {\n const rect = e.currentTarget.getBoundingClientRect();\n setColumnMenu({ x: rect.right - 200, y: rect.bottom + 6 });\n }}\n >\n {t.columns} <span className=\"mst-subtle mst-nums\">{t.columnsCount(columns.length, columnPrefs.available.length)}</span>\n </Button>\n {entity.capabilities.create && (\n <Button variant=\"primary\" icon=\"plus\" onClick={onCreate}>\n {t.newRecord}\n </Button>\n )}\n </div>\n </div>\n\n {filters.length > 0 && (\n <div className=\"mst-chips\">\n {filters.map((f) => (\n <button\n key={f.field}\n type=\"button\"\n className=\"mst-chip\"\n title={f.value}\n onClick={() => {\n setFilters((prev) => prev.filter((p) => p.field !== f.field));\n setPage(1);\n }}\n >\n {filterChipText(entity, f)}\n <Icon name=\"close\" size={11} />\n </button>\n ))}\n <button\n type=\"button\"\n className=\"mst-btn mst-btn--ghost\"\n onClick={() => {\n setFilters([]);\n setPage(1);\n }}\n >\n {t.clearFilters}\n </button>\n </div>\n )}\n\n {error && <ErrorBanner error={error} />}\n\n {loading && !data ? (\n <Spinner label={t.loading} />\n ) : data && data.records.length === 0 ? (\n <EmptyState title={t.noRecords} hint={search || filters.length ? t.tryDifferentSearch : undefined} />\n ) : (\n <div className=\"mst-card mst-tablewrap\">\n <div className=\"mst-tablescroll\">\n <table className=\"mst-table\">\n <thead>\n <tr>\n {columns.map((f) => (\n <th\n key={f.name}\n style={{ width: f.list.width, textAlign: f.list.align }}\n aria-sort={sort?.field === f.name ? (sort.direction === 'asc' ? 'ascending' : 'descending') : 'none'}\n >\n {f.sortable ? (\n <button type=\"button\" className=\"mst-th__button\" onClick={() => toggleSort(f.name)}>\n <span className=\"mst-th__label\">{f.label}</span>\n <Icon\n name={sort?.field === f.name ? (sort.direction === 'asc' ? 'sortAsc' : 'sortDesc') : 'sort'}\n size={11}\n />\n </button>\n ) : (\n <span className=\"mst-th__label\">{f.label}</span>\n )}\n </th>\n ))}\n <th style={{ width: ACTIONS_COLUMN_WIDTH }}>\n <span className=\"mst-sr-only\">{t.actions}</span>\n </th>\n </tr>\n </thead>\n <tbody>\n {data?.records.map((record, i) => {\n const id = String(record[entity.primaryKey]);\n return (\n <tr key={id || i}>\n {columns.map((f) => (\n <td\n key={f.name}\n className=\"mst-table__cell\"\n style={{ textAlign: f.list.align }}\n title={f.label}\n onClick={(e) => setCellMenu({ anchor: { x: e.clientX, y: e.clientY }, field: f, record })}\n onDoubleClick={() => onOpen(id)}\n >\n <FieldValue field={f} value={record[f.name]} compact />\n </td>\n ))}\n <td className=\"mst-td--actions\">\n <MenuButton label={t.actions} items={rowMenuItems(record)} />\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n\n {data && (\n <div className=\"mst-pagination\">\n <span className=\"mst-nums\">\n {firstRow}–{lastRow}\n </span>\n <span>{t.records(data.total)}</span>\n {totalPages > 1 && (\n <span className=\"mst-pagination__nums\">\n <button type=\"button\" aria-label={t.previous} disabled={page <= 1} onClick={() => setPage((p) => p - 1)}>\n <Icon name=\"chevronLeft\" size={13} />\n </button>\n {pageWindow(page, totalPages).map((p) => (\n <button key={p} type=\"button\" aria-current={p === page} onClick={() => setPage(p)}>\n {p}\n </button>\n ))}\n <button\n type=\"button\"\n aria-label={t.next}\n disabled={page >= totalPages}\n onClick={() => setPage((p) => p + 1)}\n >\n <Icon name=\"chevronRight\" size={13} />\n </button>\n </span>\n )}\n </div>\n )}\n </div>\n )}\n\n {cellMenu && (\n <PopMenu anchor={cellMenu.anchor} items={cellMenuItems(cellMenu)} onClose={() => setCellMenu(undefined)} />\n )}\n {columnMenu && <PopMenu anchor={columnMenu} items={columnMenuItems} onClose={() => setColumnMenu(undefined)} />}\n {copied && <Toast>{t.copied}</Toast>}\n </section>\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport type { EntityMetadata, FieldMetadata } from './client/types.js';\nimport { listFields, primaryListFields } from './hooks.js';\n\nconst STORAGE_PREFIX = 'maestro-admin:columns';\n\nfunction read(key: string): string[] | undefined {\n try {\n const raw = globalThis.localStorage?.getItem(key);\n const parsed: unknown = raw ? JSON.parse(raw) : undefined;\n return Array.isArray(parsed) ? parsed.filter((x): x is string => typeof x === 'string') : undefined;\n } catch {\n return undefined; // storage blocked or corrupted — fall back to the metadata's own choice\n }\n}\n\nfunction write(key: string, names: string[] | undefined): void {\n try {\n if (names) globalThis.localStorage?.setItem(key, JSON.stringify(names));\n else globalThis.localStorage?.removeItem(key);\n } catch {\n // best-effort\n }\n}\n\nexport interface ColumnPrefs {\n /** The fields to render, in metadata order. */\n columns: FieldMetadata[];\n /** Every field that *could* be a column, for the picker. */\n available: FieldMetadata[];\n visible: (name: string) => boolean;\n toggle: (name: string) => void;\n reset: () => void;\n /** True when the operator has overridden the metadata's default selection. */\n customized: boolean;\n}\n\n/**\n * Which columns an entity's table shows, remembered per entity.\n *\n * The admin never scrolls sideways, so an entity with thirty fields cannot simply render thirty\n * columns — something has to choose. The default choice is `primaryListFields`, which reads the\n * metadata; this hook lets the operator override it for the entities they actually work in, and\n * `reset` hands the decision back to the metadata.\n */\nexport function useColumnPrefs(entity: EntityMetadata, max = 6): ColumnPrefs {\n const key = `${STORAGE_PREFIX}:${entity.id}`;\n const [selection, setSelection] = useState<string[] | undefined>(() => read(key));\n\n const available = useMemo(() => listFields(entity), [entity]);\n const fallback = useMemo(() => primaryListFields(entity, max), [entity, max]);\n\n const columns = useMemo(() => {\n if (!selection) return fallback;\n const chosen = available.filter((f) => selection.includes(f.name));\n // A stored selection whose fields all vanished (schema changed under us) is worse than no\n // selection at all — fall back rather than render a table with no columns.\n return chosen.length > 0 ? chosen : fallback;\n }, [selection, available, fallback]);\n\n const toggle = useCallback(\n (name: string): void => {\n setSelection((prev) => {\n const current = prev ?? columns.map((f) => f.name);\n const next = current.includes(name) ? current.filter((n) => n !== name) : [...current, name];\n write(key, next);\n return next;\n });\n },\n [key, columns],\n );\n\n const reset = useCallback((): void => {\n write(key, undefined);\n setSelection(undefined);\n }, [key]);\n\n const visibleNames = useMemo(() => new Set(columns.map((f) => f.name)), [columns]);\n\n return {\n columns,\n available,\n visible: (name) => visibleNames.has(name),\n toggle,\n reset,\n customized: selection !== undefined,\n };\n}\n","import { useEffect, useState } from 'react';\nimport type { FieldMetadata } from '../client/types.js';\nimport { useClient, useEntity } from '../AdminContext.js';\nimport type { MaestroClient } from '../client/MaestroClient.js';\n\n// Display values already resolved this session, keyed by `entityId/recordId`. A tiny, ever-growing\n// cache is the right trade-off here: relation columns repeat the same handful of ids page after page.\nconst displayCache = new Map<string, Promise<string | undefined>>();\n\nfunction resolveDisplay(\n client: MaestroClient,\n entityId: string,\n displayField: string,\n id: string,\n): Promise<string | undefined> {\n const key = `${entityId}/${id}`;\n let cached = displayCache.get(key);\n if (!cached) {\n cached = client\n .findById(entityId, id)\n .then((record) => {\n const value = record[displayField];\n return value === null || value === undefined || value === '' ? undefined : String(value);\n })\n .catch(() => undefined);\n displayCache.set(key, cached);\n }\n return cached;\n}\n\nfunction shortId(id: string): string {\n return id.length > 12 ? `${id.slice(0, 6)}…${id.slice(-4)}` : id;\n}\n\n/**\n * Renders a relation field's value as a chip labeled with the *related record's* display value\n * (fetched lazily and cached) instead of a bare foreign id. Falls back to a shortened id while\n * loading or when the related record is unreachable.\n */\nexport function RelationValue({ field, value }: { field: FieldMetadata; value: unknown }) {\n const client = useClient();\n const target = useEntity(field.relationEntity);\n const id = String(value);\n const [display, setDisplay] = useState<string | undefined>(undefined);\n\n useEffect(() => {\n let cancelled = false;\n setDisplay(undefined);\n if (!target || target.displayField === target.primaryKey) return;\n resolveDisplay(client, target.id, target.displayField, id).then((resolved) => {\n if (!cancelled) setDisplay(resolved);\n });\n return () => {\n cancelled = true;\n };\n }, [client, target, id]);\n\n return (\n <span title={id} className=\"mst-relation\">\n {target && <span className=\"mst-subtle\">{target.label.singular}:</span>}\n <span className=\"mst-relation__label\">{display ?? shortId(id)}</span>\n </span>\n );\n}\n","import { useT } from '../i18n.js';\n\n/** Matches ISO-8601 timestamps so object entries like `\"2026-05-12T19:46:15.347Z\"` render as local dates. */\nconst ISO_DATETIME = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}/;\n\nconst MAX_DEPTH = 4;\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction Primitive({ value }: { value: unknown }) {\n if (value === null || value === undefined) {\n return <span className=\"mst-subtle\">—</span>;\n }\n if (typeof value === 'boolean' || typeof value === 'number') {\n return <code className=\"mst-mono\" style={{ color: 'var(--maestro-brand)' }}>{String(value)}</code>;\n }\n const text = String(value);\n if (ISO_DATETIME.test(text)) {\n const d = new Date(text);\n if (!Number.isNaN(d.getTime())) {\n return <span className=\"mst-nums\">{d.toLocaleString()}</span>;\n }\n }\n return <span style={{ overflowWrap: 'anywhere' }}>{text}</span>;\n}\n\n/**\n * Read-only structured rendering for object/array values: one row per key (arrays use indexes),\n * recursing into nested objects — instead of dumping raw JSON at the user.\n */\nexport function ObjectValue({ value, depth = 0 }: { value: unknown; depth?: number }) {\n const t = useT();\n\n if (!isPlainObject(value) && !Array.isArray(value)) {\n return <Primitive value={value} />;\n }\n\n if (depth >= MAX_DEPTH) {\n return <code className=\"mst-code mst-code--block\">{JSON.stringify(value)}</code>;\n }\n\n const entries: Array<[string, unknown]> = Array.isArray(value)\n ? value.map((v, i) => [String(i), v] as [string, unknown])\n : Object.entries(value);\n\n if (entries.length === 0) {\n return <span className=\"mst-subtle\">{t.emptyObject}</span>;\n }\n\n return (\n <dl className={depth === 0 ? 'mst-objectvalue mst-objectvalue--root' : 'mst-objectvalue mst-objectvalue--nested'}>\n {entries.map(([key, entry]) => (\n <div key={key} className=\"mst-objectvalue__row\">\n <dt className=\"mst-objectvalue__key\" title={key}>\n {key}\n </dt>\n <dd className=\"mst-objectvalue__val\">\n {isPlainObject(entry) || Array.isArray(entry) ? (\n <ObjectValue value={entry} depth={depth + 1} />\n ) : (\n <Primitive value={entry} />\n )}\n </dd>\n </div>\n ))}\n </dl>\n );\n}\n","import type { FieldMetadata } from '../client/types.js';\nimport { Badge } from './ui.js';\nimport { RelationValue } from './RelationValue.js';\nimport { ObjectValue } from './ObjectValue.js';\nimport { useT } from '../i18n.js';\n\nfunction enumLabel(field: FieldMetadata, value: unknown): string {\n const opt = field.enumOptions?.find((o) => o.value === value);\n return opt ? opt.label : String(value);\n}\n\n/**\n * Renders a single record value read-only, shaped by the field's type (for tables and detail views).\n * `compact` is the table-cell mode: the cell itself truncates, so this only has to avoid rendering\n * anything that would force the row taller.\n */\nexport function FieldValue({ field, value, compact = false }: { field: FieldMetadata; value: unknown; compact?: boolean }) {\n const t = useT();\n\n if (value === null || value === undefined || value === '') {\n return <span className=\"mst-subtle\">—</span>;\n }\n\n if (field.sensitive) {\n return <span className=\"mst-subtle\">••••••</span>;\n }\n\n switch (field.type) {\n case 'boolean':\n return value ? (\n <Badge tone=\"ok\" dot>\n {t.yes}\n </Badge>\n ) : (\n <Badge dot>{t.no}</Badge>\n );\n case 'enum':\n return <Badge tone=\"brand\">{enumLabel(field, value)}</Badge>;\n case 'relation':\n return field.relationEntity ? <RelationValue field={field} value={value} /> : <span>{String(value)}</span>;\n case 'date':\n case 'datetime': {\n const d = new Date(String(value));\n return <span className=\"mst-nums\">{Number.isNaN(d.getTime()) ? String(value) : d.toLocaleString()}</span>;\n }\n case 'integer':\n case 'float':\n case 'number':\n case 'decimal':\n case 'currency':\n return <span className=\"mst-nums\">{String(value)}</span>;\n case 'json':\n if (compact) {\n return <code className=\"mst-code\">{JSON.stringify(value)}</code>;\n }\n if (typeof value === 'object') {\n return <ObjectValue value={value} />;\n }\n return <code className=\"mst-code mst-code--block\">{JSON.stringify(value)}</code>;\n default:\n return <span>{String(value)}</span>;\n }\n}\n","/**\n * Copies text to the clipboard, with a hidden-textarea fallback for non-secure contexts (plain-http\n * admin deployments), where `navigator.clipboard` is unavailable.\n */\nexport async function copyText(text: string): Promise<void> {\n if (navigator.clipboard?.writeText) {\n try {\n await navigator.clipboard.writeText(text);\n return;\n } catch {\n // fall through to the textarea fallback\n }\n }\n const textarea = document.createElement('textarea');\n textarea.value = text;\n textarea.style.position = 'fixed';\n textarea.style.opacity = '0';\n document.body.appendChild(textarea);\n textarea.select();\n document.execCommand('copy');\n textarea.remove();\n}\n","import { useState } from 'react';\nimport type { EntityMetadata } from '../client/types.js';\nimport { useClient, useEntities } from '../AdminContext.js';\nimport { detailFields, useEntityRecord } from '../hooks.js';\nimport { FieldValue } from './FieldValue.js';\nimport { Button, ErrorBanner, Spinner, Toast } from './ui.js';\nimport { MenuButton, type MenuItem } from './menu.js';\nimport { Icon } from './icons.js';\nimport { useT } from '../i18n.js';\nimport { copyText } from '../clipboard.js';\n\nexport function EntityDetail({\n entity,\n id,\n onBack,\n onEdit,\n onClone,\n onDeleted,\n onNavigate,\n}: {\n entity: EntityMetadata;\n id: string;\n onBack: () => void;\n onEdit: () => void;\n onClone: () => void;\n onDeleted: () => void;\n onNavigate: (entityId: string, id: string) => void;\n}) {\n const client = useClient();\n const t = useT();\n const entities = useEntities();\n const { data, error, loading } = useEntityRecord(entity.id, id);\n const fields = detailFields(entity);\n const [copied, setCopied] = useState(false);\n\n const copy = async (text: string): Promise<void> => {\n await copyText(text);\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n };\n\n const onDelete = async (): Promise<void> => {\n if (!globalThis.confirm(t.deleteConfirm(entity.label.singular))) return;\n await client.remove(entity.id, id);\n onDeleted();\n };\n\n const menuItems: MenuItem[] = [];\n if (entity.capabilities.clone && entity.capabilities.create) {\n menuItems.push({ id: 'clone', label: t.clone, icon: 'clone', onSelect: onClone });\n }\n menuItems.push({ id: 'copy-id', label: t.copyId, icon: 'copy', onSelect: () => void copy(id) });\n if (data) {\n menuItems.push({\n id: 'copy-object',\n label: t.copyObject,\n icon: 'copy',\n onSelect: () => void copy(JSON.stringify(data, null, 2)),\n });\n }\n if (entity.capabilities.delete) {\n menuItems.push({\n id: 'remove',\n label: t.remove,\n icon: 'trash',\n danger: true,\n separated: true,\n onSelect: () => void onDelete(),\n });\n }\n\n return (\n <section className=\"mst-page\">\n <div className=\"mst-pagehead\">\n <div>\n <button type=\"button\" className=\"mst-backlink\" onClick={onBack}>\n <Icon name=\"arrowLeft\" size={12} />\n {entity.label.plural}\n </button>\n <h1 className=\"mst-pagehead__title\">\n {entity.label.singular} {data ? String(data[entity.displayField] ?? id) : ''}\n </h1>\n </div>\n <div className=\"mst-pagehead__actions\">\n {entity.capabilities.update && (\n <Button variant=\"primary\" icon=\"pencil\" onClick={onEdit}>\n {t.edit}\n </Button>\n )}\n <MenuButton label={t.actions} items={menuItems} />\n </div>\n </div>\n\n {error && <ErrorBanner error={error} />}\n {loading && !data ? (\n <Spinner />\n ) : (\n data && (\n <dl className=\"mst-fields\">\n {fields.map((f) => {\n const value = data[f.name];\n const isRelation = f.type === 'relation' && f.relationEntity && value !== null && value !== undefined;\n const target = isRelation ? entities.find((e) => e.id === f.relationEntity) : undefined;\n return (\n <div key={f.name} className=\"mst-fields__row\">\n <dt className=\"mst-fields__key\">{f.label}</dt>\n <dd className=\"mst-fields__value\">\n <FieldValue field={f} value={value} />\n {isRelation && (\n <button type=\"button\" className=\"mst-backlink\" onClick={() => onNavigate(f.relationEntity!, String(value))}>\n {t.openRelated(target?.label.singular ?? f.relationEntity!)}\n <Icon name=\"arrowUpRight\" size={11} />\n </button>\n )}\n </dd>\n </div>\n );\n })}\n </dl>\n )\n )}\n\n {copied && <Toast>{t.copied}</Toast>}\n </section>\n );\n}\n","import { useEffect, useState } from 'react';\nimport type { EntityMetadata, Record_ } from '../client/types.js';\nimport { useClient } from '../AdminContext.js';\nimport { formFields, useEntityRecord } from '../hooks.js';\nimport { FieldInput } from './FieldInput.js';\nimport { Button, ErrorBanner, Spinner } from './ui.js';\nimport { Icon } from './icons.js';\nimport { useT } from '../i18n.js';\n\nexport function EntityForm({\n entity,\n mode,\n id,\n cloneFromId,\n onCancel,\n onSaved,\n}: {\n entity: EntityMetadata;\n mode: 'create' | 'edit';\n id?: string;\n /** In `create` mode, prefills the form from this record (minus the primary key and non-cloneable fields). */\n cloneFromId?: string;\n onCancel: () => void;\n onSaved: (record: Record_) => void;\n}) {\n const client = useClient();\n const t = useT();\n const fields = formFields(entity, mode);\n const sourceId = mode === 'edit' ? id : cloneFromId;\n const existing = useEntityRecord(entity.id, sourceId);\n\n const [values, setValues] = useState<Record_>({});\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<Error | undefined>(undefined);\n\n useEffect(() => {\n if (!existing.data || !sourceId) return;\n if (mode === 'edit') {\n setValues(existing.data);\n return;\n }\n // Cloning: copy only cloneable, non-readonly fields; the primary key must be newly assigned.\n const seed: Record_ = {};\n for (const f of entity.fields) {\n if (f.name === entity.primaryKey) continue;\n if (!f.form.cloneable || f.readonly) continue;\n if (existing.data[f.name] !== undefined) seed[f.name] = existing.data[f.name];\n }\n setValues(seed);\n }, [mode, sourceId, existing.data, entity]);\n\n const submit = async (e: React.FormEvent): Promise<void> => {\n e.preventDefault();\n setSaving(true);\n setError(undefined);\n try {\n const payload: Record_ = {};\n for (const f of fields) {\n if (values[f.name] !== undefined) payload[f.name] = values[f.name];\n }\n const saved =\n mode === 'create'\n ? await client.create(entity.id, payload)\n : await client.update(entity.id, id!, payload);\n onSaved(saved);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setSaving(false);\n }\n };\n\n if (sourceId && existing.loading && !existing.data) {\n return <Spinner />;\n }\n\n const title =\n mode === 'edit'\n ? t.editTitle(entity.label.singular)\n : cloneFromId\n ? t.cloneTitle(entity.label.singular)\n : t.newTitle(entity.label.singular);\n\n return (\n <section className=\"mst-page\">\n <div className=\"mst-pagehead\">\n <div>\n <button type=\"button\" className=\"mst-backlink\" onClick={onCancel}>\n <Icon name=\"arrowLeft\" size={12} />\n {entity.label.plural}\n </button>\n <h1 className=\"mst-pagehead__title\">{title}</h1>\n </div>\n </div>\n\n {error && <ErrorBanner error={error} />}\n\n <form onSubmit={submit} className=\"mst-card mst-form\">\n {fields.map((f) => (\n <div key={f.name} className=\"mst-field\">\n <label htmlFor={`field-${f.name}`} className=\"mst-label\">\n {f.label}\n {f.required && <span className=\"mst-label__req\">*</span>}\n </label>\n <FieldInput\n field={f}\n value={values[f.name]}\n disabled={saving || f.readonly}\n onChange={(next) => setValues((v) => ({ ...v, [f.name]: next }))}\n />\n {f.form.helpText && <p className=\"mst-help\">{f.form.helpText}</p>}\n </div>\n ))}\n\n <div className=\"mst-form__foot\">\n <Button type=\"button\" variant=\"secondary\" onClick={onCancel} disabled={saving}>\n {t.cancel}\n </Button>\n <Button type=\"submit\" variant=\"primary\" disabled={saving}>\n {saving ? t.saving : mode === 'create' ? t.create : t.save}\n </Button>\n </div>\n </form>\n </section>\n );\n}\n","import { useEffect, useRef, useState } from 'react';\nimport type { FieldMetadata } from '../client/types.js';\nimport { useT } from '../i18n.js';\nimport { isPlainObject } from './ObjectValue.js';\n\nconst leafInputClass =\n 'mst-input';\n\n/** Nested objects deeper than this fall back to a raw-JSON textarea inside the structured editor. */\nconst MAX_DEPTH = 3;\n\n/**\n * Raw JSON textarea with local text state: the parsed value is only propagated while the text is valid\n * JSON, so half-typed edits never leak a plain string into the save payload. Invalid text keeps the last\n * valid value and shows a warning instead.\n */\nfunction RawJsonArea({\n id,\n value,\n onChange,\n disabled,\n rows = 8,\n placeholder,\n}: {\n id?: string;\n value: unknown;\n onChange: (next: unknown) => void;\n disabled?: boolean;\n rows?: number;\n placeholder?: string;\n}) {\n const t = useT();\n const [text, setText] = useState(() => (value === null || value === undefined ? '' : JSON.stringify(value, null, 2)));\n const [invalid, setInvalid] = useState(false);\n const lastEmitted = useRef<unknown>(value);\n\n // Re-sync only on external changes (e.g. the record finishing its async load) — never on our own\n // emissions, so the caret doesn't jump while the user types.\n useEffect(() => {\n if (value !== lastEmitted.current) {\n lastEmitted.current = value;\n setText(value === null || value === undefined ? '' : JSON.stringify(value, null, 2));\n setInvalid(false);\n }\n }, [value]);\n\n const onText = (raw: string): void => {\n setText(raw);\n if (raw.trim() === '') {\n lastEmitted.current = null;\n setInvalid(false);\n onChange(null);\n return;\n }\n try {\n const parsed: unknown = JSON.parse(raw);\n lastEmitted.current = parsed;\n setInvalid(false);\n onChange(parsed);\n } catch {\n setInvalid(true);\n }\n };\n\n return (\n <div className=\"mst-field\">\n <textarea\n id={id}\n rows={rows}\n value={text}\n placeholder={placeholder}\n disabled={disabled}\n onChange={(e) => onText(e.target.value)}\n aria-invalid={invalid || undefined}\n className={`mst-textarea mst-mono${invalid ? ' mst-input--invalid' : ''}`}\n />\n {invalid && (\n <p role=\"alert\" className=\"mst-help mst-help--warn\">\n {t.jsonInvalid}\n </p>\n )}\n </div>\n );\n}\n\n/** Renders the control matching one object entry's current primitive type; recurses into nested objects. */\nfunction LeafEditor({\n id,\n value,\n onChange,\n disabled,\n depth,\n}: {\n id: string;\n value: unknown;\n onChange: (next: unknown) => void;\n disabled?: boolean;\n depth: number;\n}) {\n if (typeof value === 'boolean') {\n return (\n <input\n id={id}\n type=\"checkbox\"\n checked={value}\n disabled={disabled}\n onChange={(e) => onChange(e.target.checked)}\n className=\"mst-checkbox\"\n />\n );\n }\n\n if (typeof value === 'number') {\n return (\n <input\n id={id}\n type=\"number\"\n value={String(value)}\n disabled={disabled}\n step=\"any\"\n onChange={(e) => onChange(e.target.value === '' ? null : Number(e.target.value))}\n className={leafInputClass}\n />\n );\n }\n\n if (typeof value === 'string') {\n return (\n <input\n id={id}\n type=\"text\"\n value={value}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value)}\n className={leafInputClass}\n />\n );\n }\n\n if (value === null || value === undefined) {\n return (\n <input\n id={id}\n type=\"text\"\n value=\"\"\n placeholder=\"null\"\n disabled={disabled}\n onChange={(e) => onChange(e.target.value === '' ? null : e.target.value)}\n className={leafInputClass}\n />\n );\n }\n\n if (isPlainObject(value) && depth < MAX_DEPTH) {\n return (\n <div className=\"mst-json__nest\">\n <ObjectEditor idPrefix={id} value={value} onChange={onChange} disabled={disabled} depth={depth + 1} />\n </div>\n );\n }\n\n if (Array.isArray(value) && depth < MAX_DEPTH) {\n return (\n <div className=\"mst-json__nest\">\n <ArrayEditor idPrefix={id} value={value} onChange={onChange} disabled={disabled} depth={depth + 1} />\n </div>\n );\n }\n\n // Over-deep structures: a raw-JSON island scoped to this entry.\n return <RawJsonArea id={id} value={value} onChange={onChange} disabled={disabled} rows={3} />;\n}\n\nfunction ArrayEditor({\n idPrefix,\n value,\n onChange,\n disabled,\n depth = 0,\n}: {\n idPrefix: string;\n value: unknown[];\n onChange: (next: unknown[]) => void;\n disabled?: boolean;\n depth?: number;\n}) {\n const t = useT();\n\n const setAt = (i: number, next: unknown): void => onChange(value.map((cur, idx) => (idx === i ? next : cur)));\n const removeAt = (i: number): void => onChange(value.filter((_, idx) => idx !== i));\n // New items start as a deep copy of the last one, so the row keeps its shape and control types.\n const append = (): void => {\n const last = value[value.length - 1];\n const template: unknown = last === undefined || last === null ? null : (JSON.parse(JSON.stringify(last)) as unknown);\n onChange([...value, template]);\n };\n\n return (\n <div className=\"mst-json__rows\">\n {value.map((item, i) => {\n const id = `${idPrefix}-${i}`;\n return (\n <div key={i} className=\"mst-json__row\">\n <label htmlFor={id} className=\"mst-json__index\">\n {i}\n </label>\n {!disabled && (\n <button\n type=\"button\"\n title={t.removeItem}\n aria-label={`${t.removeItem} ${i}`}\n onClick={() => removeAt(i)}\n className=\"mst-json__remove\"\n >\n ✕\n </button>\n )}\n <div className=\"mst-json__field\">\n <LeafEditor id={id} value={item} onChange={(next) => setAt(i, next)} disabled={disabled} depth={depth} />\n </div>\n </div>\n );\n })}\n {value.length === 0 && <p className=\"mst-json__empty\">{t.emptyObject}</p>}\n {!disabled && (\n <div className=\"mst-json__addrow\">\n <button type=\"button\" onClick={append} className=\"mst-backlink\">\n + {t.addItem}\n </button>\n </div>\n )}\n </div>\n );\n}\n\nfunction ObjectEditor({\n idPrefix,\n value,\n onChange,\n disabled,\n depth = 0,\n}: {\n idPrefix: string;\n value: Record<string, unknown>;\n onChange: (next: Record<string, unknown>) => void;\n disabled?: boolean;\n depth?: number;\n}) {\n const t = useT();\n const entries = Object.entries(value);\n\n if (entries.length === 0) {\n return <p className=\"mst-json__empty\">{t.emptyObject}</p>;\n }\n\n return (\n <div className=\"mst-json__rows\">\n {entries.map(([key, entry]) => {\n const id = `${idPrefix}-${key}`;\n return (\n // flex-wrap + basis: when the label column leaves less than ~16rem for the control (deeply\n // nested groups), the control wraps to its own full-width line instead of squeezing.\n <div key={key} className=\"mst-json__row\">\n <label htmlFor={id} className=\"mst-json__key\" title={key}>\n {key}\n </label>\n <div className=\"mst-json__field\">\n <LeafEditor\n id={id}\n value={entry}\n onChange={(next) => onChange({ ...value, [key]: next })}\n disabled={disabled}\n depth={depth}\n />\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n\n/**\n * Form control for `json` fields: a structured editor when the value is an object or array (each entry\n * gets a control matching its type; array items can be added/removed), plus a raw-JSON mode for\n * adding/removing object keys or pasting a whole value.\n */\nexport function JsonInput({\n field,\n value,\n onChange,\n disabled,\n}: {\n field: FieldMetadata;\n value: unknown;\n onChange: (next: unknown) => void;\n disabled?: boolean;\n}) {\n const t = useT();\n const [mode, setMode] = useState<'form' | 'raw'>(() => (isPlainObject(value) ? 'form' : 'raw'));\n const [modeTouched, setModeTouched] = useState(false);\n\n const structured = isPlainObject(value) || Array.isArray(value);\n\n // Records load after mount; once an object/array shows up, prefer the structured editor — unless the\n // user already picked a mode themselves.\n useEffect(() => {\n if (!modeTouched && structured) setMode('form');\n }, [structured, modeTouched]);\n\n const pick = (next: 'form' | 'raw'): void => {\n setModeTouched(true);\n setMode(next);\n };\n\n const showForm = mode === 'form' && structured;\n const toggleClass = (active: boolean): string =>\n `mst-json__tab${active ? ' mst-json__tab--active' : ''}`;\n\n return (\n <div className=\"mst-json\">\n <div className=\"mst-json__head\">\n <button\n type=\"button\"\n className={toggleClass(showForm)}\n disabled={!structured}\n onClick={() => pick('form')}\n >\n {t.jsonFormMode}\n </button>\n <button type=\"button\" className={toggleClass(!showForm)} onClick={() => pick('raw')}>\n {t.jsonRawMode}\n </button>\n </div>\n <div className=\"mst-json__body\">\n {showForm ? (\n Array.isArray(value) ? (\n <ArrayEditor idPrefix={`field-${field.name}`} value={value} onChange={onChange} disabled={disabled} />\n ) : (\n <ObjectEditor\n idPrefix={`field-${field.name}`}\n value={value as Record<string, unknown>}\n onChange={onChange}\n disabled={disabled}\n />\n )\n ) : (\n <RawJsonArea\n id={`field-${field.name}`}\n value={value}\n onChange={onChange}\n disabled={disabled}\n placeholder={field.form.placeholder}\n />\n )}\n </div>\n </div>\n );\n}\n","import type { FieldMetadata } from '../client/types.js';\nimport { JsonInput } from './JsonInput.js';\n\nconst inputClass = 'mst-input';\n\n/**\n * Renders the right form control for a field's type and reports its next value. Values are kept as strings\n * for text/enum, numbers for numeric types, booleans for checkboxes, and parsed objects for json — matching\n * what the create/update endpoints expect.\n */\nexport function FieldInput({\n field,\n value,\n onChange,\n disabled,\n}: {\n field: FieldMetadata;\n value: unknown;\n onChange: (next: unknown) => void;\n disabled?: boolean;\n}) {\n const id = `field-${field.name}`;\n\n switch (field.type) {\n case 'boolean':\n return (\n <input\n id={id}\n type=\"checkbox\"\n checked={Boolean(value)}\n disabled={disabled}\n onChange={(e) => onChange(e.target.checked)}\n className=\"mst-checkbox\"\n />\n );\n\n case 'integer':\n case 'number':\n case 'float':\n case 'decimal':\n case 'currency':\n return (\n <input\n id={id}\n type=\"number\"\n value={value === null || value === undefined ? '' : String(value)}\n placeholder={field.form.placeholder}\n disabled={disabled}\n step={field.type === 'integer' ? 1 : 'any'}\n onChange={(e) => onChange(e.target.value === '' ? null : Number(e.target.value))}\n className={inputClass}\n />\n );\n\n case 'enum':\n return (\n <select\n id={id}\n value={value === null || value === undefined ? '' : String(value)}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value)}\n className=\"mst-select\"\n >\n <option value=\"\">—</option>\n {field.enumOptions?.map((o) => (\n <option key={String(o.value)} value={String(o.value)}>\n {o.label}\n </option>\n ))}\n </select>\n );\n\n case 'date':\n return (\n <input\n id={id}\n type=\"date\"\n value={value ? String(value).slice(0, 10) : ''}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value || null)}\n className={inputClass}\n />\n );\n\n case 'json':\n return <JsonInput field={field} value={value} onChange={onChange} disabled={disabled} />;\n\n case 'text':\n return (\n <textarea\n id={id}\n rows={3}\n value={value === null || value === undefined ? '' : String(value)}\n placeholder={field.form.placeholder}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value)}\n className=\"mst-textarea\"\n />\n );\n\n default:\n return (\n <input\n id={id}\n type={field.type === 'email' ? 'email' : 'text'}\n value={value === null || value === undefined ? '' : String(value)}\n placeholder={field.form.placeholder}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value)}\n className={inputClass}\n />\n );\n }\n}\n","import type { EntityMetadata, FieldMetadata, MaestroMetadata } from './client/types.js';\n\nexport interface EntityLabelOverride {\n /** Singular label (\"Usuário\"). */\n singular?: string;\n /** Plural label (\"Usuários\") — also the sidebar entry. */\n plural?: string;\n /** Sidebar folder this entity belongs to (display name). Wins over heuristic prefix grouping. */\n group?: string;\n /** Field labels for this entity only, by field name. Wins over the global `fields` map. */\n fields?: Record<string, string>;\n}\n\n/**\n * Presentation-layer label rewrites, applied on top of the metadata the server serves. This is how a\n * deployment localizes or humanizes auto-introspected names (\"recoveryactions\" → \"Ações de\n * Recuperação\") without touching the engine: keys match either the entity `id` or its source `table`.\n */\nexport interface AdminLabels {\n entities?: Record<string, EntityLabelOverride>;\n /** Global field labels by field name (`createdAt` → \"Criado em\"), for every entity. */\n fields?: Record<string, string>;\n /** Display names for heuristic sidebar folders, by shared table-name prefix (`recovery` → \"Recuperação\"). */\n groups?: Record<string, string>;\n}\n\nfunction relabelField(\n field: FieldMetadata,\n entityOverride: EntityLabelOverride | undefined,\n globalFields: Record<string, string>,\n): FieldMetadata {\n const label = entityOverride?.fields?.[field.name] ?? globalFields[field.name];\n return label ? { ...field, label } : field;\n}\n\nfunction relabelEntity(entity: EntityMetadata, labels: AdminLabels): EntityMetadata {\n const override = labels.entities?.[entity.id] ?? labels.entities?.[entity.table];\n const globalFields = labels.fields ?? {};\n return {\n ...entity,\n label: {\n singular: override?.singular ?? entity.label.singular,\n plural: override?.plural ?? override?.singular ?? entity.label.plural,\n },\n fields: entity.fields.map((f) => relabelField(f, override, globalFields)),\n };\n}\n\n/** Returns a copy of `metadata` with every label override applied. No-op when `labels` is empty. */\nexport function applyLabels(metadata: MaestroMetadata, labels: AdminLabels | undefined): MaestroMetadata {\n if (!labels || (!labels.entities && !labels.fields)) return metadata;\n return { ...metadata, entities: metadata.entities.map((e) => relabelEntity(e, labels)) };\n}\n","import { useCallback, useState } from 'react';\n\nconst STORAGE_KEY = 'maestro-admin:recents';\nconst MAX_RECENTS = 8;\n\nfunction read(key: string): string[] {\n try {\n const raw = globalThis.localStorage?.getItem(key);\n const parsed: unknown = raw ? JSON.parse(raw) : [];\n return Array.isArray(parsed) ? parsed.filter((x): x is string => typeof x === 'string') : [];\n } catch {\n return []; // storage unavailable (SSR, blocked) or corrupted — recents are best-effort\n }\n}\n\nfunction write(key: string, ids: string[]): void {\n try {\n globalThis.localStorage?.setItem(key, JSON.stringify(ids));\n } catch {\n // best-effort\n }\n}\n\n/**\n * Recently-visited entity ids, most recent first, persisted in `localStorage` so they survive\n * reloads. `push` moves (or inserts) an id to the front, capped at 8. Pass a distinct `scope` (e.g.\n * the API URL) when one browser origin hosts admins for several servers.\n */\nexport function useRecents(scope?: string): { recents: string[]; push: (entityId: string) => void } {\n const key = scope ? `${STORAGE_KEY}:${scope}` : STORAGE_KEY;\n const [recents, setRecents] = useState<string[]>(() => read(key));\n\n const push = useCallback(\n (entityId: string): void => {\n setRecents((prev) => {\n const next = [entityId, ...prev.filter((id) => id !== entityId)].slice(0, MAX_RECENTS);\n write(key, next);\n return next;\n });\n },\n [key],\n );\n\n return { recents, push };\n}\n"],"mappings":"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","names":["useCallback","useEffect","useMemo","useState","useState","createContext","useContext","Fragment","jsx","jsxs","useState","useState","createContext","useCallback","useContext","useMemo","useState","jsx","useEffect","useState","Fragment","jsx","jsxs","useState","useEffect","Fragment","jsx","jsxs","useState","useMemo","jsx","jsxs","jsx","jsxs","useMemo","useEffect","useMemo","useRef","useState","createPortal","Fragment","jsx","jsxs","normalize","Highlight","useRef","useState","useMemo","useEffect","createPortal","useMemo","useState","useCallback","useMemo","useState","useState","useMemo","useCallback","useEffect","useState","jsx","jsxs","useState","useEffect","jsx","jsxs","jsx","jsx","jsxs","useMemo","useState","useState","jsx","jsxs","useState","useEffect","useState","useEffect","useRef","useState","jsx","jsxs","MAX_DEPTH","useState","useRef","useEffect","jsx","jsxs","jsx","jsxs","useState","useEffect","useCallback","useState","STORAGE_KEY","read","write","jsx","jsxs","useState","useMemo","useCallback","useEffect"]}
|