ngx-dynamic-entity-builder 2.1.0 → 2.2.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.
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-dynamic-entity-builder.mjs","sources":["../../src/lib/field-catalog.ts","../../src/lib/clone.ts","../../src/lib/builder-store.service.ts","../../src/lib/field-path-options.ts","../../src/lib/rule-dependencies.ts","../../src/lib/builder-text.ts","../../src/lib/components/entity-reference-config.component.ts","../../src/lib/components/rule-form.component.ts","../../src/lib/components/field-rules-list.component.ts","../../src/lib/components/referenced-field-config.component.ts","../../src/lib/components/field-inspector.component.ts","../../src/lib/components/field-inspector.component.html","../../src/lib/components/field-palette.component.ts","../../src/lib/components/tab-manager.component.ts","../../src/lib/components/entity-builder-tree-node.component.ts","../../src/lib/components/entity-builder-canvas.component.ts","../../src/lib/components/rule-dependency-graph.component.ts","../../src/lib/entity-builder.component.ts","../../src/lib/entity-builder.component.html","../../src/public-api.ts","../../src/ngx-dynamic-entity-builder.ts"],"sourcesContent":["/**\n * field-catalog.ts — re-exports shared field catalog from @dynamic-entity/core.\n * Single source of truth shared by both visual builder and renderer.\n */\nexport {\n FIELD_TYPE_CATALOG,\n getFieldTypeMeta,\n humanizeId,\n createFieldConfig,\n type FieldTypeMeta,\n type FlagValidator,\n type ParamValidator,\n} from '@dynamic-entity/core';\n","/**\n * Deep clone with a JSON fallback.\n *\n * `structuredClone` is not universally available (older browsers, and jsdom before v22),\n * so it must never be called unguarded — an unguarded call throws a ReferenceError and the\n * caller silently does nothing. Config and rule objects are JSON-safe, so the fallback is\n * lossless here.\n */\nexport function deepClone<T>(value: T): T {\n if (typeof structuredClone === 'function') return structuredClone(value);\n return JSON.parse(JSON.stringify(value)) as T;\n}\n","import { Injectable, computed, signal } from '@angular/core';\nimport type {\n AutoPatchMapping,\n DropdownOption,\n EntityFormConfig,\n EntityPermissions,\n EntityReferenceConfig,\n FormRule,\n NestedFieldConfig,\n NestedTabConfig,\n PatchOnTrueMapping,\n RichFieldType,\n} from '@dynamic-entity/core';\nimport {\n OPTION_KEY,\n computeFieldDrift,\n createFieldSnapshot,\n findTab,\n labelToId,\n normalizeConfigOptions,\n optionKeyOf,\n resolveLabel,\n} from '@dynamic-entity/core';\nimport { assignFieldRefs, collectFieldScopes, fieldRefFor, parseFieldRef, toRefToken } from '@dynamic-entity/core';\nimport { createFieldConfig, getFieldTypeMeta, humanizeId, type FlagValidator, type ParamValidator } from './field-catalog';\nimport { deepClone } from './clone';\n\nexport interface BuilderProblem {\n level: 'error' | 'warning';\n message: string;\n fieldId?: string;\n}\n\n/** One tab's own fields, for a canvas that has to reorder within the right tab. */\nexport interface BuilderFieldGroup {\n tabId: string;\n label: NestedTabConfig['label'];\n fields: NestedFieldConfig[];\n}\n\nconst clone = deepClone;\n\nconst ID_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/**\n * The regex the builder used to write into `pattern` to mean \"email\".\n *\n * Retained only to recognise configs authored before `FieldValidators.email` existed, so\n * they still show Email as ticked and do not leave a stray pattern behind when it is\n * un-ticked. Nothing writes it any more.\n */\nconst LEGACY_EMAIL_PATTERN = '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}$';\n\n/** One undoable state of the builder: the config and the rules that belong with it. */\ninterface BuilderSnapshot {\n readonly config: EntityFormConfig;\n readonly rules: FormRule[];\n /** Tab / field / rule counts, used to decide whether two edits may be coalesced. */\n readonly shape: string;\n}\n\n/**\n * Follow a field rename through a rule reference, in either spelling.\n *\n * This matched the bare id alone, while the builder authors rules by **path** —\n * `[personal.address.city]`, because a bare id cannot name one of two fields that share\n * one. So renaming a field silently orphaned every rule the builder itself had written: the\n * rule kept pointing at a path nothing resolved to, and nothing said so.\n *\n * A path's last segment is the field id, which is what makes this exact rather than a\n * substring replace — `[work.status]` must not be rewritten by renaming `statusCode`, and\n * `[status.city]` must not be rewritten by renaming `status`.\n */\nfunction repointRef(reference: string, oldId: string, newId: string): string {\n const parsed = parseFieldRef(reference);\n if (parsed.kind === 'id') return parsed.value === oldId ? newId : reference;\n\n const segments = parsed.value.split('.');\n if (segments[segments.length - 1] !== oldId) return reference;\n segments[segments.length - 1] = newId;\n return toRefToken(segments.join('.'));\n}\n\n@Injectable()\nexport class BuilderStore {\n private readonly _config = signal<EntityFormConfig>(this.emptyConfig());\n private readonly _selectedFieldId = signal<string | null>(null);\n private readonly _activeLanguage = signal<string>('en');\n /** Rules live beside the config: they are persisted per form, not inside `EntityFormConfig`. */\n private readonly _rules = signal<FormRule[]>([]);\n /**\n * Field ids the author owns — set by an explicit rename, or by loading a saved config\n * whose ids are already live data keys. Ids outside this set are still derived from the\n * field's label. Builder-session state, deliberately not part of the exported config.\n */\n private readonly manualIds = new Set<string>();\n /**\n * Fields whose `refererField` the config declared, rather than the builder stamping it.\n *\n * A declared path is a deliberate binding override and must survive a structural edit. A\n * stamped one is just the field's address, so it has to be rewritten when the field moves.\n * Without the distinction, restamping would destroy the override and not restamping would\n * leave a moved field pointing at where it used to be.\n */\n private readonly authoredRefs = new Set<string>();\n\n private readonly _isDirty = signal<boolean>(false);\n\n /**\n * Roles of the person using the builder — distinct from `availableRoles`, which is the\n * vocabulary a schema may reference. Needed so the SYSTEM_DEFAULT_CAN_EDIT predicate can\n * be asked a real question; it was previously called with a hardcoded empty array, which\n * made any role-checking predicate answer false for everyone.\n */\n private readonly _userRoles = signal<string[]>([]);\n\n // ─── Undo / redo ────────────────────────────────────────────────────────────\n //\n // History is a list of {config, rules} pairs, because the builder's state is two signals\n // and undoing one without the other would leave a rule pointing at a field that no longer\n // exists.\n //\n // Entries hold **references, not clones**. `mutate` builds a new config and `mutateField`\n // shares structure along the unchanged path, so every snapshot already refers to immutable\n // objects and unchanged subtrees are shared between entries. That also removes the usual\n // re-entrancy problem for free: undo puts the stored object back, so the recording effect\n // sees the exact reference already sitting at the cursor and skips it. No suppression flag\n // to get out of step.\n private readonly history: BuilderSnapshot[] = [];\n private readonly cursor = signal(-1);\n private readonly historyLength = signal(0);\n private lastEditAt = 0;\n\n /** Consecutive edits closer together than this fold into one undo step. */\n private static readonly COALESCE_MS = 400;\n\n readonly canUndo = computed(() => this.cursor() > 0);\n readonly canRedo = computed(() => this.cursor() < this.historyLength() - 1);\n\n /**\n * Fold the current state into history.\n *\n * Called explicitly by the write paths rather than from an `effect`. An effect would have\n * been fewer call sites, but it requires an injection context: `BuilderStore` had no\n * constructor, so `new BuilderStore()` was legal, and adding one broke every caller that\n * did it with NG0203. Explicit calls also make the timing deterministic — a test can\n * assert straight after an edit instead of flushing effects first.\n *\n * Calling it twice for one operation is harmless: the second call sees the same signal\n * references already at the cursor and returns.\n *\n * `setFieldLabel` is bound to a keystroke, so recording every emission would make undo\n * walk back one character at a time. Two consecutive edits merge when they land inside\n * `COALESCE_MS` *and* the structure is unchanged — a rename coalesces, while adding,\n * removing or moving anything always earns its own step however fast it is clicked.\n */\n private record(): void {\n const config = this._config();\n const rules = this._rules();\n const at = this.cursor();\n const top = at >= 0 ? this.history[at] : undefined;\n if (top && top.config === config && top.rules === rules) return;\n\n const now = Date.now();\n const snapshot: BuilderSnapshot = { config, rules, shape: this.shapeOf(config, rules) };\n\n if (\n top &&\n now - this.lastEditAt < BuilderStore.COALESCE_MS &&\n top.shape === snapshot.shape &&\n at === this.history.length - 1\n ) {\n this.history[at] = snapshot;\n this.lastEditAt = now;\n return;\n }\n\n // A new edit after an undo discards the redo branch, which is what every editor does.\n this.history.length = at + 1;\n this.history.push(snapshot);\n\n // Bounded, because a builder session is long and every keystroke that does not coalesce\n // earns an entry. Snapshots hold references and share unchanged subtrees, so an entry is\n // cheap — but unbounded is unbounded, and the oldest steps are the ones nobody walks\n // back to. Dropping from the front keeps the most recent 200.\n if (this.history.length > BuilderStore.MAX_HISTORY) {\n this.history.splice(0, this.history.length - BuilderStore.MAX_HISTORY);\n }\n\n this.cursor.set(this.history.length - 1);\n this.historyLength.set(this.history.length);\n this.lastEditAt = now;\n }\n\n /** How many undo steps are kept. */\n private static readonly MAX_HISTORY = 200;\n\n /** Counts that distinguish a structural edit from a value edit. */\n private shapeOf(config: EntityFormConfig, rules: FormRule[]): string {\n let fields = 0;\n let tabs = 0;\n const walkFields = (list: NestedFieldConfig[] | undefined): void => {\n for (const f of list ?? []) {\n fields += 1;\n walkFields(f.children);\n }\n };\n const walkTabs = (list: NestedTabConfig[] | undefined): void => {\n for (const t of list ?? []) {\n tabs += 1;\n walkFields(t.fields);\n walkTabs(t.children);\n }\n };\n walkTabs(config.tabs);\n return `${tabs}:${fields}:${rules.length}`;\n }\n\n /** Start history again from the state just loaded. Nothing before it is undoable. */\n private resetHistory(): void {\n this.history.length = 0;\n this.history.push({\n config: this._config(),\n rules: this._rules(),\n shape: this.shapeOf(this._config(), this._rules()),\n });\n this.cursor.set(0);\n this.historyLength.set(1);\n this.lastEditAt = 0;\n }\n\n undo(): void {\n if (!this.canUndo()) return;\n this.applyHistory(this.cursor() - 1);\n }\n\n redo(): void {\n if (!this.canRedo()) return;\n this.applyHistory(this.cursor() + 1);\n }\n\n private applyHistory(index: number): void {\n const snapshot = this.history[index];\n if (!snapshot) return;\n this.cursor.set(index);\n // Order matters only in that both land before the effect runs; it then sees references\n // identical to this entry and records nothing.\n this._config.set(snapshot.config);\n this._rules.set(snapshot.rules);\n this._isDirty.set(true);\n\n // The selected field may not exist in the state being restored.\n const selected = this._selectedFieldId();\n if (selected && !this.findFieldInTabs(snapshot.config.tabs, selected)) {\n this._selectedFieldId.set(null);\n }\n }\n\n readonly config = this._config.asReadonly();\n readonly selectedFieldId = this._selectedFieldId.asReadonly();\n readonly activeLanguage = this._activeLanguage.asReadonly();\n readonly rules = this._rules.asReadonly();\n readonly isDirty = this._isDirty.asReadonly();\n readonly userRoles = this._userRoles.asReadonly();\n\n readonly tabs = computed<NestedTabConfig[]>(() => this._config().tabs ?? []);\n\n /**\n * Every field the config declares, sub-tabs included.\n *\n * This used to stop at top-level tabs, which quietly broke three things at once: nine of\n * `insuranceClaims`'s twenty-eight fields never appeared on the canvas, the entity-reference\n * picker could not offer a nested field as a source, and the drift check looked a nested\n * field up here, got nothing, and returned without checking. The store's structural\n * operations already walked the whole tree — only this view did not.\n *\n * It deliberately does not descend into a field's own `children`: `group` and `array`\n * children are rendered by the row that owns them, not as rows of their own.\n */\n readonly fields = computed<NestedFieldConfig[]>(() => this.getAllFields(this._config().tabs ?? []));\n\n /**\n * The same fields, kept in their owning tab.\n *\n * Drag-and-drop reorders by index, so the canvas needs to know which tab an index belongs\n * to — `reorderField` has always taken a `tabId` for exactly this, and the canvas simply\n * never passed one. Without the grouping a drag on any config with more than one tab\n * reordered `tabs[0]` regardless of what was actually dragged.\n */\n readonly fieldGroups = computed<BuilderFieldGroup[]>(() =>\n this.flattenTabs(this._config().tabs ?? [])\n .filter(tab => (tab.fields ?? []).length > 0)\n .map(tab => ({ tabId: tab.id, label: tab.label, fields: tab.fields ?? [] })),\n );\n\n readonly selectedField = computed<NestedFieldConfig | null>(() => {\n const id = this._selectedFieldId();\n if (!id) return null;\n return this.findFieldInTabs(this._config().tabs, id);\n });\n\n readonly problems = computed<BuilderProblem[]>(() => this.validate(this._config()));\n readonly errors = computed<BuilderProblem[]>(() => this.problems().filter(p => p.level === 'error'));\n readonly isValid = computed<boolean>(() => this.errors().length === 0);\n\n // ─── Initialisation ─────────────────────────────────────────────────────────\n\n load(config: EntityFormConfig, rules: readonly FormRule[] = []): void {\n // Remember the paths the config declared before filling in the rest, so a deliberate\n // binding override is never mistaken for one of ours and rewritten.\n this.authoredRefs.clear();\n for (const entry of collectFieldScopes(config)) {\n if (entry.field?.id && entry.field.refererField) this.authoredRefs.add(entry.field.id);\n }\n assignFieldRefs(config);\n // Check if any fields carry both inline options and listName before normalizing options\n const fieldsWithBoth = this.getAllFields(config.tabs ?? []).filter(\n f => Array.isArray(f.options) && f.options.length > 0 && typeof f.listName === 'string' && f.listName.trim() !== '',\n );\n for (const f of fieldsWithBoth) {\n console.warn(\n `[BuilderStore] Field \"${f.id}\" carries both inline options and listName \"${f.listName}\". ` +\n `Inline options win; listName was dropped.`,\n );\n }\n\n // The other boundary where a config enters the library (the renderer's ngOnChanges is\n // the first). Authoring must start from the canonical option shape, or the builder\n // would round-trip a legacy config straight back out unchanged.\n const next = clone(normalizeConfigOptions(config));\n next.tabs = next.tabs ?? [];\n if (next.tabs.length === 0) {\n next.tabs = [{ id: 'default', label: { en: 'Default' }, fields: [] }];\n }\n this._config.set(next);\n const firstField = this.getAllFields(next.tabs)[0];\n this._selectedFieldId.set(firstField?.id ?? null);\n this._activeLanguage.set(next.defaultLanguage ?? 'en');\n\n // Ids in a saved config are live data keys — records are already stored under them.\n // Editing a label must never rewrite one, so freeze every id the config arrived with.\n this.manualIds.clear();\n for (const field of this.getAllFields(next.tabs)) this.manualIds.add(field.id);\n // Set before the baseline is taken, not after. A snapshot is a `{config, rules}` pair —\n // that is why history stores them together — so seeding them as two recorded operations\n // would put a step on the stack for a load nobody performed, and leave a fresh builder\n // offering to undo the act of opening it.\n this._rules.set(clone(rules as FormRule[]));\n this._isDirty.set(false);\n this.resetHistory();\n }\n\n reset(entity = ''): void {\n this._config.set(this.emptyConfig(entity));\n this._selectedFieldId.set(null);\n this._rules.set([]);\n this.manualIds.clear();\n this._isDirty.set(false);\n this.resetHistory();\n }\n\n resetDirty(): void {\n this._isDirty.set(false);\n }\n\n private emptyConfig(entity = ''): EntityFormConfig {\n return {\n entity,\n version: 1,\n defaultLanguage: 'en',\n tabs: [],\n };\n }\n\n // ─── Entity-level settings ──────────────────────────────────────────────────\n\n setEntityName(entity: string): void {\n this.mutate(draft => {\n draft.entity = entity.trim();\n });\n }\n\n setDefaultLanguage(language: string): void {\n this.mutate(draft => {\n draft.defaultLanguage = language;\n });\n }\n\n setMaskData(mask: boolean): void {\n this.mutate(draft => {\n draft.maskData = mask;\n });\n }\n\n setPermission(action: keyof EntityPermissions, roles: string[]): void {\n this.mutate(draft => {\n const permissions: EntityPermissions = { ...(draft.permissions ?? {}) };\n permissions[action] = roles;\n draft.permissions = permissions;\n });\n }\n\n setActiveLanguage(language: string): void {\n this._activeLanguage.set(language);\n }\n\n /** Roles of the person using the builder, for SYSTEM_DEFAULT_CAN_EDIT. */\n setUserRoles(roles: string[]): void {\n this._userRoles.set(roles ?? []);\n }\n\n // ─── Helper Traversal ───────────────────────────────────────────────────────\n\n private getAllFields(tabs: NestedTabConfig[] = []): NestedFieldConfig[] {\n const list: NestedFieldConfig[] = [];\n for (const t of tabs) {\n if (t.fields) list.push(...t.fields);\n if (t.children) list.push(...this.getAllFields(t.children));\n }\n return list;\n }\n\n /**\n * Every tab in the tree, flattened.\n *\n * The structural operations below used to iterate `draft.tabs` directly, which is only\n * the top level. A field on a sub-tab could be selected and edited but never removed,\n * duplicated, moved or reordered — the builder could author nested configs it was then\n * unable to restructure, which is the worst possible state for an authoring tool.\n */\n private flattenTabs(tabs: NestedTabConfig[] = []): NestedTabConfig[] {\n const list: NestedTabConfig[] = [];\n for (const t of tabs) {\n list.push(t);\n if (t.children) list.push(...this.flattenTabs(t.children));\n }\n return list;\n }\n\n /**\n * Every field id in the config, including `group`/`array` children.\n *\n * Id uniqueness is a whole-config invariant, not a per-tab one: rules, `showWhen`\n * conditions and `autoPatch` mappings all address fields by bare id, so two fields\n * sharing an id anywhere in the tree interfere with each other. Uniqueness checks must\n * therefore see deeper than `fields()`, which stops at a tab's own fields.\n */\n private allFieldIds(tabs: NestedTabConfig[] = []): Set<string> {\n const ids = new Set<string>();\n const walkFields = (fields: NestedFieldConfig[] | undefined) => {\n for (const f of fields ?? []) {\n ids.add(f.id);\n if (f.children?.length) walkFields(f.children);\n }\n };\n for (const tab of this.flattenTabs(tabs)) walkFields(tab.fields);\n return ids;\n }\n\n /**\n * Resolve a field by key, where a key is either its `refererField` path or a bare id.\n *\n * Every resolution in this store funnels through here, which is why a bare id was enough\n * to edit the wrong field: with `personal.address` and `work.address` both present, the\n * first match won, so selecting or editing the second one silently addressed the first.\n *\n * The path is tried across the whole tree before any bare id is, so an exact key never\n * loses to a nearer-but-wrong match. Bare ids still resolve — every existing caller and\n * spec passes one, and for an unambiguous id it is the same field either way.\n */\n private findFieldInTabs(tabs: NestedTabConfig[] = [], key: string): NestedFieldConfig | null {\n return this.findFieldBy(tabs, f => f.refererField === key) ?? this.findFieldBy(tabs, f => f.id === key);\n }\n\n private findFieldBy(tabs: NestedTabConfig[] = [], match: (f: NestedFieldConfig) => boolean): NestedFieldConfig | null {\n for (const t of tabs) {\n const found = t.fields?.find(match);\n if (found) return found;\n if (t.children) {\n const nested = this.findFieldBy(t.children, match);\n if (nested) return nested;\n }\n }\n return null;\n }\n\n /**\n * The key a caller should hand back to address this exact field. Templates use it so a\n * click on the second of two same-named fields selects that one.\n */\n keyOf(field: { id: string; refererField?: string }): string {\n return field.refererField || field.id;\n }\n\n /**\n * Whether this exact field is the selected one.\n *\n * Not `selectedFieldId() === field.id`: selection may hold a bare id or a path depending\n * on who set it, and with two fields sharing an id a bare comparison lights up both rows\n * — or neither, once the click starts storing a path. Resolving both sides answers for\n * the field itself.\n */\n isSelected(field: NestedFieldConfig): boolean {\n const key = this._selectedFieldId();\n if (!key) return false;\n // Same key, same field — and this is the path a row click takes, so it is the common\n // case. It also covers a field handed in as an @Input that the store's own config has\n // no object for, which identity alone cannot.\n if (key === this.keyOf(field)) return true;\n // Otherwise the selection is in the other form (a bare id against a field that carries a\n // path, or vice versa), so let it resolve and compare the field it names.\n const resolved = this.findFieldInTabs(this._config().tabs, key);\n return !!resolved && resolved === field;\n }\n\n // ─── Field CRUD ─────────────────────────────────────────────────────────────\n\n addField(type: RichFieldType, targetTabId?: string): string {\n const meta = getFieldTypeMeta(type);\n const prefix = meta?.idPrefix ?? 'field';\n const id = this.uniqueId(prefix, this.allFieldIds(this._config().tabs));\n\n this.mutate(draft => {\n const field = createFieldConfig(type, id, draft.defaultLanguage ?? 'en');\n const targetTab = targetTabId ? this.flattenTabs(draft.tabs).find(t => t.id === targetTabId) : draft.tabs[0];\n if (targetTab) {\n targetTab.fields = targetTab.fields ?? [];\n targetTab.fields.push(field);\n } else {\n draft.tabs.push({ id: 'main', label: { en: 'Main' }, fields: [field] });\n }\n });\n this._selectedFieldId.set(id);\n return id;\n }\n\n updateField(id: string, patch: Partial<NestedFieldConfig>): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, id);\n if (field) Object.assign(field, patch);\n });\n }\n\n /**\n * Rename a field explicitly, pinning the id so it is no longer derived from the label.\n *\n * Not reachable from the inspector — the id input is read-only by design. This exists for\n * programmatic callers that must match an id to an existing data key.\n */\n renameField(oldId: string, newId: string): void {\n const trimmed = newId.trim();\n if (!trimmed || trimmed === oldId) return;\n if (this.allFieldIds(this._config().tabs).has(trimmed)) return;\n if (!this.findFieldInTabs(this._config().tabs, oldId)) return;\n\n this.applyRename(oldId, oldId, trimmed);\n this.manualIds.delete(oldId);\n this.manualIds.add(trimmed);\n }\n\n /** Whether this field's id is pinned (loaded from storage or explicitly renamed). */\n hasManualId(id: string): boolean {\n return this.manualIds.has(id);\n }\n\n /**\n * Move a field to a new id and repoint every id-based reference in the config at it.\n *\n * Ids are the wiring between fields — rules, cascades, patches and `showWhen` all address\n * fields by id — so a rename that only touches `field.id` silently breaks that wiring.\n * That was survivable while renaming was a rare manual act; label-derived ids make it\n * routine, so the references move with it.\n */\n /**\n * `key` addresses the field to rename; `oldId` is the bare id every *reference* to it\n * carries. They were one parameter, which worked only while an id was unique across the\n * config: resolving needs the path, while `showWhen`, `parentField`, `autoPatch` targets\n * and rules are all keyed by bare id and never match a path.\n */\n private applyRename(key: string, oldId: string, newId: string): void {\n // Selection is held as whatever the caller passed — `addField` stores a bare id while a\n // canvas click stores a path — so comparing the two strings said \"not selected\" for a\n // field that plainly was, and the inspector emptied itself mid-rename. Compare the\n // fields the two keys resolve to instead.\n const selectedKey = this._selectedFieldId();\n const tabsNow = this._config().tabs;\n const wasSelected = !!selectedKey && this.findFieldInTabs(tabsNow, selectedKey) === this.findFieldInTabs(tabsNow, key);\n\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, key);\n if (!field) return;\n field.id = newId;\n\n const walkFields = (fields: NestedFieldConfig[] | undefined) => {\n for (const f of fields ?? []) {\n if (f.showWhen && oldId in f.showWhen) {\n const next: Record<string, unknown> = {};\n // Rebuild in place so condition order survives the rename.\n for (const [key, value] of Object.entries(f.showWhen)) {\n next[key === oldId ? newId : key] = value;\n }\n f.showWhen = next;\n }\n if (f.entityReference?.parentField === oldId) {\n f.entityReference = { ...f.entityReference, parentField: newId };\n }\n if (f.autoPatch) {\n // `source` names a field on the *linked* record, not this config — leave it.\n f.autoPatch = {\n ...f.autoPatch,\n mappings: f.autoPatch.mappings.map(m => (m.target === oldId ? { ...m, target: newId } : m)),\n };\n }\n if (f.patchOnTrue) {\n f.patchOnTrue = f.patchOnTrue.map(m => ({\n from: m.from === oldId ? newId : m.from,\n to: m.to === oldId ? newId : m.to,\n }));\n }\n if (f.children?.length) walkFields(f.children);\n }\n };\n const walkTabs = (tabs: NestedTabConfig[] | undefined) => {\n for (const tab of tabs ?? []) {\n walkFields(tab.fields);\n walkTabs(tab.children);\n }\n };\n walkTabs(draft.tabs);\n });\n\n this._rules.update(rules =>\n rules.map(rule => ({\n ...rule,\n fieldId: repointRef(rule.fieldId, oldId, newId),\n conditions: rule.conditions?.map(c =>\n c?.compareToField\n ? { ...c, compareToField: repointRef(c.compareToField, oldId, newId) }\n : c,\n ),\n targets: rule.targets.map(t =>\n t.type === 'field' ? { ...t, id: repointRef(t.id, oldId, newId) } : t,\n ),\n })),\n );\n\n // `mutate` restamps `refererField`, so the key's last segment moves with the id. Without\n // this the selection points at a path nothing resolves to any more, and the inspector\n // empties itself mid-keystroke as soon as a typed label derives a new id.\n this.record();\n\n if (wasSelected) {\n // Keep the shape the selection already had: a bare id stays bare, a path keeps its\n // scope and moves only its last segment.\n const cut = selectedKey!.lastIndexOf('.');\n this._selectedFieldId.set(cut === -1 ? newId : `${selectedKey!.slice(0, cut + 1)}${newId}`);\n }\n }\n\n removeField(key: string): void {\n let removedId: string | null = null;\n this.mutate(draft => {\n // Resolve inside the draft, then remove that one by identity. Filtering on\n // `f.id !== id` deleted every field sharing the id, so removing `work.address` took\n // `personal.address` with it.\n const target = this.findFieldInTabs(draft.tabs, key);\n if (!target) return;\n removedId = target.id;\n for (const tab of this.flattenTabs(draft.tabs)) {\n if (tab.fields) {\n tab.fields = tab.fields.filter(f => f !== target);\n }\n }\n });\n if (removedId === null) return;\n // `manualIds` is keyed by bare id and shared by every field carrying it, so it is only\n // safe to forget once no field uses that id any more.\n if (!this.getAllFields(this._config().tabs ?? []).some(f => f.id === removedId)) {\n this.manualIds.delete(removedId);\n }\n if (this._selectedFieldId() === key) this._selectedFieldId.set(null);\n }\n\n duplicateField(id: string): string | null {\n // Look the source up by id — not by current selection. The insert below searches by id\n // too, so falling back to the selected field could report a new id while inserting\n // nothing, or duplicate a field the caller never named.\n const source = this.findFieldInTabs(this._config().tabs, id);\n if (!source) return null;\n const meta = getFieldTypeMeta(source.type);\n const prefix = meta?.idPrefix ?? 'field';\n const newId = this.uniqueId(prefix, this.allFieldIds(this._config().tabs));\n\n this.mutate(draft => {\n for (const tab of this.flattenTabs(draft.tabs)) {\n const index = (tab.fields ?? []).findIndex(f => f.id === id);\n if (index !== -1) {\n const copy = clone(source);\n copy.id = newId;\n tab.fields!.splice(index + 1, 0, copy);\n break;\n }\n }\n });\n this._selectedFieldId.set(newId);\n return newId;\n }\n\n moveField(key: string, direction: -1 | 1): void {\n this.mutate(draft => {\n // Resolve by key, then locate that object — `f.id === id` moved whichever same-named\n // field the walk reached first, which for two `address` fields was never the one the\n // arrow button belonged to.\n const wanted = this.findFieldInTabs(draft.tabs, key);\n if (!wanted) return;\n\n for (const tab of this.flattenTabs(draft.tabs)) {\n const fields = tab.fields ?? [];\n const from = fields.findIndex(f => f === wanted);\n if (from !== -1) {\n const to = from + direction;\n if (to < 0 || to >= fields.length) return;\n const [item] = fields.splice(from, 1);\n fields.splice(to, 0, item);\n return;\n }\n }\n });\n }\n\n /**\n * Moves a field to another tab, keeping its id.\n *\n * The builder could add, remove, duplicate and reorder a field but never relocate one, so\n * a field authored on the wrong tab had to be deleted and rebuilt — losing its validators,\n * options and any rule that pointed at it.\n *\n * The field's `refererField` changes, because it is an address and the field now has a new one.\n * `mutate` restamps it and repoints the rules that named it, so a move does not silently\n * strand them.\n */\n moveFieldToTab(id: string, targetTabId: string): boolean {\n const target = this.flattenTabs(this._config().tabs).find(t => t.id === targetTabId);\n if (!target) return false;\n\n let moved = false;\n this.mutate(draft => {\n const targetTab = this.flattenTabs(draft.tabs).find(t => t.id === targetTabId);\n if (!targetTab) return;\n\n // Resolve by key first so a path names one field, then locate that object. Matching\n // `f.id === id` moved whichever same-named field came first in the walk.\n const wanted = this.findFieldInTabs(draft.tabs, id);\n if (!wanted) return;\n\n for (const tab of this.flattenTabs(draft.tabs)) {\n const index = (tab.fields ?? []).findIndex(f => f === wanted);\n if (index === -1) continue;\n if (tab.id === targetTabId) return; // already there; nothing to do\n\n const [field] = tab.fields!.splice(index, 1);\n targetTab.fields = targetTab.fields ?? [];\n targetTab.fields.push(field);\n moved = true;\n return;\n }\n });\n return moved;\n }\n\n /** Safe reorder for drag & drop within active tab or flat list */\n reorderField(fromIndex: number, toIndex: number, tabId?: string): void {\n this.mutate(draft => {\n const targetTab = tabId ? this.flattenTabs(draft.tabs).find(t => t.id === tabId) : draft.tabs[0];\n const fields = targetTab?.fields ?? [];\n if (fromIndex < 0 || toIndex < 0 || fromIndex >= fields.length || toIndex >= fields.length) {\n return;\n }\n const [item] = fields.splice(fromIndex, 1);\n fields.splice(toIndex, 0, item);\n });\n }\n\n selectField(id: string | null): void {\n this._selectedFieldId.set(id);\n }\n\n // ─── Localised text ─────────────────────────────────────────────────────────\n\n /**\n * Set a field's label, and derive the field's id from it: type \"Employee Count\", get\n * `employeeCount`. The inspector renders the id read-only, so this is the only way a\n * new field's id is set.\n *\n * Two things stop derivation: a config loaded from storage (its ids are live data keys\n * that records are already stored under — see `load`), and an explicit `renameField`\n * call, which remains available to programmatic callers.\n *\n * Only the config's default language drives the id; translating a label must not rename\n * anything.\n */\n setFieldLabel(key: string, language: string, value: string): void {\n // Bound to a keystroke event, so this uses the structural-sharing path.\n this.mutateField(key, field => ({ ...field, label: { ...field.label, [language]: value } }));\n\n if (language !== (this._config().defaultLanguage ?? 'en')) return;\n\n // The mutation is addressed by key, but everything below is about the *id*: `manualIds`\n // records bare ids, `availableId` compares bare ids, and a rename replaces one. Reading\n // the field's own id keeps the two straight — passing the path into `manualIds.has`\n // would never match, so a pinned id would silently start following the label again.\n const field = this.findFieldInTabs(this._config().tabs, key);\n if (!field) return;\n const currentId = field.id;\n if (this.manualIds.has(currentId)) return;\n\n const derived = labelToId(value);\n if (!derived || derived === currentId) return;\n\n this.applyRename(this.keyOf(field), currentId, this.availableId(derived, currentId));\n }\n\n /** `derived`, or `derived_2`, `derived_3`… if another field already holds it. */\n private availableId(derived: string, currentId: string): string {\n const taken = new Set([...this.allFieldIds(this._config().tabs)].filter(fid => fid !== currentId));\n if (!taken.has(derived)) return derived;\n\n let n = 2;\n while (taken.has(`${derived}_${n}`)) n += 1;\n return `${derived}_${n}`;\n }\n\n setFieldPlaceholder(id: string, language: string, value: string): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, id);\n if (!field) return;\n field.placeholder = { ...(field.placeholder ?? {}), [language]: value };\n });\n }\n\n /**\n * Help text shown under the control, per language.\n *\n * Separate from the placeholder for the reason the schema keeps them separate: a\n * placeholder vanishes the moment the user types, so anything they need *while* filling the\n * field in cannot live there. An author with only a placeholder box to write in tends to\n * put it there anyway.\n */\n setFieldHint(id: string, language: string, value: string): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, id);\n if (!field) return;\n field.hint = { ...(field.hint ?? {}), [language]: value };\n });\n }\n\n // ─── Validators ─────────────────────────────────────────────────────────────\n\n toggleFlagValidator(id: string, validator: FlagValidator, on: boolean): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, id);\n if (!field) return;\n field.validators = field.validators ?? {};\n if (validator === 'required') {\n if (on) field.validators.required = true;\n else delete field.validators.required;\n } else if (validator === 'email') {\n // Writes its own flag, not `pattern`. Sharing `pattern` meant a field could not have\n // both an email check and a custom regex, setting a custom pattern made the Email box\n // appear ticked, and un-ticking Email deleted whatever pattern the author had written.\n if (on) field.validators.email = true;\n else delete field.validators.email;\n // Clear the legacy encoding either way, so a config touched here stops carrying both.\n if (field.validators.pattern === LEGACY_EMAIL_PATTERN) delete field.validators.pattern;\n }\n });\n }\n\n setParamValidator(id: string, validator: ParamValidator, value: number | null): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, id);\n if (!field) return;\n field.validators = field.validators ?? {};\n if (value === null || value === undefined || Number.isNaN(value)) {\n delete field.validators[validator];\n } else {\n field.validators[validator] = value;\n }\n });\n }\n\n setPatternValidator(id: string, pattern: string | null): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, id);\n if (!field) return;\n field.validators = field.validators ?? {};\n const trimmed = pattern?.trim();\n if (!trimmed) {\n delete field.validators.pattern;\n } else {\n field.validators.pattern = trimmed;\n }\n });\n }\n\n getParamValidator(field: NestedFieldConfig, validator: ParamValidator): number | null {\n const val = field.validators?.[validator];\n return typeof val === 'number' ? val : null;\n }\n\n hasFlagValidator(field: NestedFieldConfig, validator: FlagValidator): boolean {\n if (validator === 'required') return !!field.validators?.required;\n if (validator === 'email') {\n // This used to report *any* pattern as email, so writing a custom regex silently\n // ticked the box. The legacy encoding is still recognised so a config authored by the\n // old builder keeps showing Email as ticked.\n return !!field.validators?.email || field.validators?.pattern === LEGACY_EMAIL_PATTERN;\n }\n return false;\n }\n\n // ─── Options (dropdown / multiSelect / radio) ────────────────────────────────\n\n /**\n * Where a choice field's options come from.\n *\n * `entity` is absent on purpose: in this model an entity reference is a field *type*\n * (`entity-ref`), not a data source a dropdown can switch to, so offering it here would mean\n * mutating the field's type — and rebuilding its control — from a source picker. The\n * exclusion that matters within a choice field is inline `options` vs `listName`.\n */\n fieldDataSource(field: NestedFieldConfig | undefined): 'none' | 'manual' | 'lookup' {\n if (!field) return 'none';\n // Presence, not emptiness: a source the author has picked but not filled in yet — no\n // options authored, no list name typed — must still read as that source, or the editor\n // for it disappears the moment they select it.\n if (Array.isArray(field.options)) return 'manual';\n if (typeof field.listName === 'string') return 'lookup';\n return 'none';\n }\n\n /**\n * Switch a choice field's data source, clearing the one it is leaving.\n *\n * The reference makes these mutually exclusive (doc §4.4) and it has to stay that way here:\n * `optionsFor` resolves inline options first, so a field left holding both would silently\n * ignore its list.\n */\n setFieldDataSource(fieldId: string, source: 'none' | 'manual' | 'lookup'): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n if (source === 'manual') {\n delete field.listName;\n field.options = field.options?.length ? field.options : [];\n } else if (source === 'lookup') {\n delete field.options;\n field.listName = field.listName ?? '';\n } else {\n delete field.options;\n delete field.listName;\n }\n });\n }\n\n /** Set the named list a choice field reads its options from. */\n setListName(fieldId: string, listName: string): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n const trimmed = listName.trim();\n if (trimmed) {\n field.listName = trimmed;\n // Belt and braces: inline options would win over the list at render time.\n delete field.options;\n } else {\n field.listName = '';\n }\n });\n }\n\n /** Link a field to a field defined in another entity configuration (Phase 8). */\n linkReferencedField(fieldId: string, sourceEntityKey: string, sourceField: NestedFieldConfig): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n field.isReferenced = true;\n field.referencedEntityKey = sourceEntityKey;\n field.referencedFieldId = sourceField.id;\n field.referencedSnapshot = createFieldSnapshot(sourceField);\n field.hasDrift = false;\n // Copy label, type, validators, options from source\n if (sourceField.label) field.label = clone(sourceField.label);\n if (sourceField.type) field.type = sourceField.type;\n if (sourceField.validators) field.validators = clone(sourceField.validators);\n if (sourceField.options) field.options = clone(sourceField.options);\n });\n }\n\n /** Unlink a referenced field back to an independent field. */\n unlinkReferencedField(fieldId: string): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n delete field.isReferenced;\n delete field.referencedEntityKey;\n delete field.referencedFieldId;\n delete field.referencedSnapshot;\n delete field.hasDrift;\n });\n }\n\n /** Sync a drifted referenced field with the updated source field definition. */\n syncReferencedField(fieldId: string, currentSourceField: NestedFieldConfig): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field || !field.isReferenced) return;\n field.referencedSnapshot = createFieldSnapshot(currentSourceField);\n field.hasDrift = false;\n if (currentSourceField.label) field.label = clone(currentSourceField.label);\n if (currentSourceField.type) field.type = currentSourceField.type;\n if (currentSourceField.validators) field.validators = clone(currentSourceField.validators);\n if (currentSourceField.options) field.options = clone(currentSourceField.options);\n });\n }\n\n /** Scan all referenced fields in the config and update their hasDrift state against current source configs. */\n checkDrift(sourceConfigs: Record<string, EntityFormConfig>): void {\n this.mutate(draft => {\n const scanFields = (fields: NestedFieldConfig[]) => {\n for (const f of fields) {\n if (f.isReferenced && f.referencedEntityKey && f.referencedFieldId) {\n const sourceConfig = sourceConfigs[f.referencedEntityKey];\n const sourceField = sourceConfig\n ? this.findFieldInTabs(sourceConfig.tabs ?? [], f.referencedFieldId)\n : undefined;\n f.hasDrift = computeFieldDrift(f, sourceField ?? undefined);\n }\n if (f.children?.length) scanFields(f.children);\n }\n };\n\n for (const tab of draft.tabs ?? []) {\n if (tab.fields?.length) scanFields(tab.fields);\n }\n });\n }\n\n addOption(fieldId: string): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n const options = field.options ?? [];\n const n = options.length + 1;\n const lang = draft.defaultLanguage ?? 'en';\n const label = `Option ${n}`;\n // The key is minted here, at creation, from the label the option starts with — and\n // then never rewritten, which is the entire point. Renaming an option afterwards\n // changes what it *reads*; the key is what it *is*, so every record already holding it\n // keeps matching. See `DropdownOption`.\n options.push({ [OPTION_KEY]: this.mintOptionKey(options, label), [lang]: label });\n field.options = options;\n // Authoring an inline option makes this a manual field — see `setFieldDataSource`.\n delete field.listName;\n });\n }\n\n /**\n * A key for a new option: the label slugified, made unique within its own field.\n *\n * Unique within the field and nowhere wider, because that is the scope the key has to\n * distinguish within — two fields may both offer \"Active\" and they are the same value.\n * A label that slugifies to nothing (punctuation, a script `labelToId` strips) falls back\n * to a positional name rather than an empty key, which `optionKeyOf` would ignore.\n */\n private mintOptionKey(existing: readonly DropdownOption[], label: string): string {\n const taken = new Set(existing.map(optionKeyOf).filter(Boolean) as string[]);\n const base = labelToId(label) || `option${existing.length + 1}`;\n if (!taken.has(base)) return base;\n let n = 2;\n while (taken.has(`${base}${n}`)) n += 1;\n return `${base}${n}`;\n }\n\n /**\n * Give every option in the config a key, leaving the ones that already have one alone.\n *\n * The counterpart to `optionKeyMigration` in core: that one keys stored *records* against\n * a keyed config, this one keys the config. Run this first, then ship the migration — the\n * other order leaves the migration with no keys to attach.\n *\n * Existing keys are never rewritten, so this is safe to run again on a config that is\n * already half-keyed, which is what happens as options are added to an older schema.\n */\n assignOptionKeys(): void {\n this.mutate(draft => {\n const visitFields = (fields: NestedFieldConfig[] | undefined): void => {\n for (const field of fields ?? []) {\n if (Array.isArray(field.options)) {\n const keyed: DropdownOption[] = [];\n for (const option of field.options) {\n if (!option || typeof option !== 'object' || optionKeyOf(option) !== undefined) {\n keyed.push(option);\n continue;\n }\n const label = resolveLabel(option, draft.defaultLanguage ?? 'en');\n keyed.push({ [OPTION_KEY]: this.mintOptionKey(keyed, label), ...option });\n }\n field.options = keyed;\n }\n visitFields(field.children);\n }\n };\n const visitTabs = (tabs: NestedTabConfig[] | undefined): void => {\n for (const tab of tabs ?? []) {\n visitFields(tab.fields);\n visitTabs(tab.children);\n }\n };\n visitTabs(draft.tabs);\n });\n }\n\n /** Whether any option in the config is still without a key — gates the action in the UI. */\n readonly hasUnkeyedOptions = computed(() => {\n let found = false;\n const visitFields = (fields: NestedFieldConfig[] | undefined): void => {\n for (const field of fields ?? []) {\n if (Array.isArray(field.options) && field.options.some(o => optionKeyOf(o) === undefined)) {\n found = true;\n }\n visitFields(field.children);\n }\n };\n const visitTabs = (tabs: NestedTabConfig[] | undefined): void => {\n for (const tab of tabs ?? []) {\n visitFields(tab.fields);\n visitTabs(tab.children);\n }\n };\n visitTabs(this._config().tabs);\n return found;\n });\n\n /** An option's stable key, for the inspector to show read-only. */\n optionKey(option: DropdownOption): string {\n return optionKeyOf(option) ?? '';\n }\n\n /** Merge language keys into an option. `setOptionLabel` is the usual single-language path. */\n updateOption(fieldId: string, index: number, patch: DropdownOption): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n const option = field?.options?.[index];\n if (!option) return;\n // A patch may add translations; it may not change what the option *is*. Letting one\n // rewrite an established key would orphan every record holding it, which is exactly\n // the failure the key exists to prevent.\n const existing = optionKeyOf(option);\n const merged: DropdownOption = { ...option, ...patch };\n if (existing !== undefined) merged[OPTION_KEY] = existing;\n field.options![index] = merged;\n });\n }\n\n /**\n * Set an option's text for one language.\n *\n * An option is a language-keyed object and the displayed text **is** the stored value,\n * so this is the only way to edit one — there is no separate value to set.\n */\n setOptionLabel(fieldId: string, index: number, language: string, value: string): void {\n // Also keystroke-bound.\n this.mutateField(fieldId, field => {\n const option = field.options?.[index];\n if (!option) return field;\n const options = field.options!.map((o, i) => (i === index ? { ...o, [language]: value } : o));\n return { ...field, options };\n });\n }\n\n removeOption(fieldId: string, index: number): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field?.options) return;\n field.options = field.options.filter((_, i) => i !== index);\n });\n }\n\n // ─── Entity reference / cascade ─────────────────────────────────────────────\n\n /** Merge a patch into a field's `entityReference` block, keeping it enabled. */\n updateEntityReference(fieldId: string, patch: Partial<EntityReferenceConfig>): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n const next: EntityReferenceConfig = {\n ...(field.entityReference ?? { enabled: true }),\n ...patch,\n enabled: true,\n };\n // Drop keys explicitly cleared to `undefined` so exported configs stay clean.\n for (const key of Object.keys(patch) as (keyof EntityReferenceConfig)[]) {\n if (patch[key] === undefined) delete next[key];\n }\n field.entityReference = next;\n });\n }\n\n // ─── autoPatch ──────────────────────────────────────────────────────────────\n\n addAutoPatchMapping(fieldId: string): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n const targetTab = field.autoPatch?.targetTab ?? draft.tabs[0]?.id ?? '';\n const mappings = [...(field.autoPatch?.mappings ?? []), { source: '', target: '' }];\n field.autoPatch = { targetTab, mappings };\n });\n }\n\n setAutoPatchTargetTab(fieldId: string, targetTab: string): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field?.autoPatch) return;\n field.autoPatch = { ...field.autoPatch, targetTab };\n });\n }\n\n updateAutoPatchMapping(fieldId: string, index: number, patch: Partial<AutoPatchMapping>): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field?.autoPatch?.mappings?.[index]) return;\n field.autoPatch = {\n ...field.autoPatch,\n mappings: field.autoPatch.mappings.map((m, i) => (i === index ? { ...m, ...patch } : m)),\n };\n });\n }\n\n /** Removing the last mapping drops `autoPatch` entirely — no empty config in the export. */\n removeAutoPatchMapping(fieldId: string, index: number): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field?.autoPatch) return;\n const mappings = field.autoPatch.mappings.filter((_, i) => i !== index);\n if (mappings.length === 0) delete field.autoPatch;\n else field.autoPatch = { ...field.autoPatch, mappings };\n });\n }\n\n // ─── patchOnTrue ────────────────────────────────────────────────────────────\n\n addPatchOnTrueMapping(fieldId: string): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n field.patchOnTrue = [...(field.patchOnTrue ?? []), { from: '', to: '' }];\n });\n }\n\n updatePatchOnTrueMapping(fieldId: string, index: number, patch: Partial<PatchOnTrueMapping>): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field?.patchOnTrue?.[index]) return;\n field.patchOnTrue = field.patchOnTrue.map((m, i) => (i === index ? { ...m, ...patch } : m));\n });\n }\n\n removePatchOnTrueMapping(fieldId: string, index: number): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field?.patchOnTrue) return;\n const mappings = field.patchOnTrue.filter((_, i) => i !== index);\n if (mappings.length === 0) delete field.patchOnTrue;\n else field.patchOnTrue = mappings;\n });\n }\n\n // ─── showWhen (static conditional visibility) ───────────────────────────────\n\n /** Replace a field's `showWhen` map; an empty map removes the condition. */\n setShowWhen(fieldId: string, showWhen: Record<string, unknown> | undefined): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n if (!showWhen || Object.keys(showWhen).length === 0) delete field.showWhen;\n else field.showWhen = showWhen;\n });\n }\n\n // ─── Rules ──────────────────────────────────────────────────────────────────\n\n /** Rules for the field currently selected in the inspector. */\n /**\n * Rules attached to the selected field, whichever way they name it.\n *\n * New rules are authored with the field's path — `[work.address]` — because a bare id\n * cannot distinguish two fields that share one. Rules written before paths existed name it\n * by id, and those must keep showing up here or editing an older config would look like it\n * had lost its rules.\n */\n readonly rulesForSelectedField = computed<FormRule[]>(() => {\n const id = this._selectedFieldId();\n if (!id) return [];\n const names = new Set<string>([id]);\n const ref = this.selectedField()?.refererField;\n if (ref) names.add(toRefToken(ref));\n return this._rules().filter(r => names.has(r.fieldId) || r.targets.some(t => names.has(t.id)));\n });\n\n /**\n * Replace the rules without touching the config — for a host whose rules changed on their\n * own. It records a step, because from the author's side it is an edit. Loading a config\n * passes its rules to `load` instead, so the pair arrives as one snapshot.\n */\n loadRules(rules: FormRule[]): void {\n this._rules.set(clone(rules));\n this.record();\n }\n\n addRule(rule: FormRule): string {\n const id = rule.id?.trim() || this.uniqueId('rule', new Set(this._rules().map(r => r.id ?? '')));\n this._rules.update(rules => [...rules, { ...clone(rule), id }]);\n this.record();\n return id;\n }\n\n updateRule(id: string, patch: Partial<FormRule>): void {\n this._rules.update(rules => rules.map(r => (r.id === id ? { ...r, ...clone(patch), id } : r)));\n this.record();\n }\n\n removeRule(id: string): void {\n this._rules.update(rules => rules.filter(r => r.id !== id));\n this.record();\n }\n\n toggleRule(id: string, enabled: boolean): void {\n this.updateRule(id, { enabled });\n }\n\n /** Move a rule in priority order. Priorities are renumbered 1..n so they stay contiguous. */\n moveRule(id: string, direction: -1 | 1): void {\n this._rules.update(rules => {\n const next = [...rules];\n const from = next.findIndex(r => r.id === id);\n if (from === -1) return rules;\n const to = from + direction;\n if (to < 0 || to >= next.length) return rules;\n const [item] = next.splice(from, 1);\n next.splice(to, 0, item);\n return next.map((r, i) => ({ ...r, priority: i + 1 }));\n });\n }\n\n exportRules(): FormRule[] {\n return clone(this._rules());\n }\n\n // ─── Tabs ───────────────────────────────────────────────────────────────────\n\n addTab(): string {\n // Must be unique across the whole tree, not just the top level: a tab id is the record\n // storage path, so a new top-level tab colliding with an existing sub-tab would make two\n // tabs write to the same key and break findTab/getTabPath.\n const id = this.uniqueId('tab', new Set(this.allTabIds()));\n this.mutate(draft => {\n const tabs = draft.tabs ?? (draft.tabs = []);\n const lang = draft.defaultLanguage ?? 'en';\n tabs.push({ id, label: { [lang]: humanizeId(id) }, fields: [] });\n });\n return id;\n }\n\n /** Every tab id in the tree, at any depth. Tab ids must be globally unique — they are paths. */\n private allTabIds(): string[] {\n const ids: string[] = [];\n const collect = (tabs: NestedTabConfig[] | undefined) => {\n for (const t of tabs ?? []) {\n ids.push(t.id);\n collect(t.children);\n }\n };\n collect(this._config().tabs);\n return ids;\n }\n\n addSubTab(parentId: string): string {\n const id = this.uniqueId('tab', new Set(this.allTabIds()));\n this.mutate(draft => {\n const parent = findTab(draft.tabs, parentId);\n if (parent) {\n parent.children = parent.children ?? [];\n const lang = draft.defaultLanguage ?? 'en';\n parent.children.push({ id, label: { [lang]: humanizeId(id) }, fields: [] });\n }\n });\n return id;\n }\n\n setPrimaryTab(tabId: string): void {\n this.mutate(draft => {\n const markPrimary = (tabs: NestedTabConfig[]) => {\n for (const t of tabs) {\n t.isPrimaryTab = t.id === tabId;\n if (t.children) markPrimary(t.children);\n }\n };\n markPrimary(draft.tabs ?? []);\n });\n }\n\n updateTab(id: string, patch: Partial<NestedTabConfig>): void {\n this.mutate(draft => {\n const tab = findTab(draft.tabs, id);\n if (tab) Object.assign(tab, patch);\n });\n }\n\n setTabLabel(id: string, language: string, value: string): void {\n this.mutate(draft => {\n const tab = findTab(draft.tabs, id);\n if (tab) tab.label = { ...tab.label, [language]: value };\n });\n }\n\n removeTab(id: string): void {\n this.mutate(draft => {\n const removeRecursive = (tabs: NestedTabConfig[]): NestedTabConfig[] => {\n return tabs\n .filter(t => t.id !== id)\n .map(t => ({\n ...t,\n children: t.children ? removeRecursive(t.children) : undefined,\n }));\n };\n draft.tabs = removeRecursive(draft.tabs ?? []);\n });\n }\n\n moveTab(id: string, direction: -1 | 1): void {\n this.mutate(draft => {\n const tabs = draft.tabs ?? [];\n const from = tabs.findIndex(t => t.id === id);\n if (from === -1) return;\n const to = from + direction;\n if (to < 0 || to >= tabs.length) return;\n const [item] = tabs.splice(from, 1);\n tabs.splice(to, 0, item);\n });\n }\n\n // ─── Export ─────────────────────────────────────────────────────────────────\n\n exportConfig(): EntityFormConfig {\n return clone(this._config());\n }\n\n // ─── Internals ──────────────────────────────────────────────────────────────\n\n /**\n * The single choke point for a structural edit, and therefore the one place refs are kept\n * true.\n *\n * `refererField` is a field's address, so it changes whenever the structure around it does —\n * moving a field to another tab, or into a group, gives it a new one. Rules address fields\n * by ref, so a move that only restamped the field would leave every rule pointing at an\n * address nothing occupies. Both happen here, together, or the config is inconsistent\n * between them.\n */\n private mutate(fn: (draft: EntityFormConfig) => void): void {\n const before = this.refsById(this._config());\n const draft = clone(this._config());\n draft.tabs = draft.tabs ?? [];\n fn(draft);\n this.restampFieldPaths(draft);\n this.repointRulesForMovedFields(before, this.refsById(draft));\n this._config.set(draft);\n this._isDirty.set(true);\n this.record();\n }\n\n /**\n * Rewrites the address of every field the builder owns, leaving declared overrides alone.\n *\n * `assignFieldRefs` only fills in a missing path, which is right when a config arrives and\n * wrong after a move: the field already has a path, and it is now the wrong one.\n */\n private restampFieldPaths(config: EntityFormConfig): void {\n for (const entry of collectFieldScopes(config)) {\n const field = entry.field;\n if (!field?.id || this.authoredRefs.has(field.id)) continue;\n field.refererField = fieldRefFor(entry.scope, field.id);\n }\n }\n\n /** Field id → the refs it currently has. A duplicated id has more than one. */\n private refsById(config: EntityFormConfig): Map<string, string[]> {\n const map = new Map<string, string[]>();\n for (const entry of collectFieldScopes(config)) {\n if (!entry.field?.id) continue;\n const refs = map.get(entry.field.id) ?? [];\n refs.push(fieldRefFor(entry.scope, entry.field.id));\n map.set(entry.field.id, refs);\n }\n return map;\n }\n\n /**\n * Rewrites rules that pointed at a ref a move has just changed.\n *\n * A field is matched by its id: if exactly one ref for that id disappeared and exactly one\n * appeared, that is the move and the rules follow it. Anything less clear-cut — two fields\n * sharing an id where one moved — is left alone rather than guessed at, because rewriting\n * the wrong rule is worse than leaving one to be repointed by hand.\n */\n private repointRulesForMovedFields(before: Map<string, string[]>, after: Map<string, string[]>): void {\n const moves = new Map<string, string>();\n for (const [id, oldRefs] of before) {\n const newRefs = after.get(id) ?? [];\n const gone = oldRefs.filter(r => !newRefs.includes(r));\n const added = newRefs.filter(r => !oldRefs.includes(r));\n if (gone.length === 1 && added.length === 1) moves.set(gone[0], added[0]);\n }\n if (moves.size === 0) return;\n\n const repoint = (reference: string | undefined): string | undefined => {\n if (!reference) return reference;\n const parsed = parseFieldRef(reference);\n if (parsed.kind !== 'ref') return reference;\n const moved = moves.get(parsed.value);\n return moved ? toRefToken(moved) : reference;\n };\n\n this._rules.update(rules =>\n rules.map(rule => ({\n ...rule,\n fieldId: repoint(rule.fieldId) ?? rule.fieldId,\n conditions: rule.conditions.map(c => (c.compareToField ? { ...c, compareToField: repoint(c.compareToField) } : c)),\n targets: rule.targets.map(t => ({ ...t, id: repoint(t.id) ?? t.id })),\n })),\n );\n }\n\n /**\n * Replace one field, copying only the objects on the path to it.\n *\n * `mutate` deep-clones the entire config, which is right for a structural edit but wrong\n * for the two setters bound to keystroke events: typing a label allocated a full copy of\n * the config per character. Here every tab and field outside the target's chain is reused\n * by reference, so the cost is proportional to nesting depth rather than config size —\n * while the parts that did change are still fresh objects, so change detection and the\n * signal both see a new identity.\n *\n * Returns without touching anything when the field is not found.\n */\n private mutateField(key: string, update: (field: NestedFieldConfig) => NestedFieldConfig): void {\n let found = false;\n\n // Resolve once, then match on object identity. Matching on `field.id === id` inside the\n // walk updated *every* field carrying that id, so renaming `work.address` also rewrote\n // `personal.address` — both rows changed, and the second write was silent. Identity\n // cannot be ambiguous the way a bare id can.\n const target = this.findFieldInTabs(this._config().tabs, key);\n if (!target) return;\n\n const visitFields = (fields: NestedFieldConfig[] | undefined): NestedFieldConfig[] | undefined => {\n if (!fields) return fields;\n let changed = false;\n const next = fields.map(field => {\n if (field === target) {\n found = true;\n changed = true;\n return update(field);\n }\n const children = visitFields(field.children);\n if (children !== field.children) {\n changed = true;\n return { ...field, children };\n }\n return field;\n });\n return changed ? next : fields;\n };\n\n const visitTabs = (tabs: NestedTabConfig[] | undefined): NestedTabConfig[] | undefined => {\n if (!tabs) return tabs;\n let changed = false;\n const next = tabs.map(tab => {\n const fields = visitFields(tab.fields);\n const children = visitTabs(tab.children);\n if (fields !== tab.fields || children !== tab.children) {\n changed = true;\n return { ...tab, fields, children };\n }\n return tab;\n });\n return changed ? next : tabs;\n };\n\n const current = this._config();\n const tabs = visitTabs(current.tabs);\n // `found` implies current.tabs existed and was walked, so tabs is defined here — the\n // fallback below is for the type checker, not a reachable state.\n if (!found || tabs === current.tabs) return;\n\n this._config.set({ ...current, tabs: tabs ?? [] });\n this._isDirty.set(true);\n this.record();\n }\n\n private uniqueId(prefix: string, taken: Set<string>): string {\n let n = 1;\n let candidate = `${prefix}_${n}`;\n while (taken.has(candidate)) {\n n += 1;\n candidate = `${prefix}_${n}`;\n }\n return candidate;\n }\n\n private validate(config: EntityFormConfig): BuilderProblem[] {\n const problems: BuilderProblem[] = [];\n\n // Core calls a config with no tabs an error — nothing can render — and the builder used\n // to report only a warning and leave Save enabled. That let the builder save a config\n // `dynamic-entity validate` then rejected in CI: the mirror of the bug where it refused\n // one core accepted. The builder defers to core here, as it already does for the scope\n // rule, and the message is core's so the two read the same in both places.\n if (!config.tabs?.length) {\n problems.push({ level: 'error', message: 'At least one tab is required.' });\n }\n\n if (!config.entity || !config.entity.trim()) {\n problems.push({ level: 'error', message: 'Entity name is required.' });\n } else if (!ID_PATTERN.test(config.entity)) {\n problems.push({\n level: 'error',\n message: 'Entity name must start with a letter or underscore and contain only letters, digits, and underscores.',\n });\n }\n\n const allFields = this.getAllFields(config.tabs);\n if (allFields.length === 0) {\n problems.push({ level: 'warning', message: 'This entity has no fields yet.' });\n }\n\n for (const field of allFields) {\n if (!field.id || !ID_PATTERN.test(field.id)) {\n problems.push({\n level: 'error',\n message: `Field id \"${field.id}\" is not a valid identifier.`,\n fieldId: field.id,\n });\n }\n\n const labels = field.label ?? {};\n const hasLabel = Object.values(labels).some(v => typeof v === 'string' && v.trim());\n if (!hasLabel) {\n problems.push({\n level: 'warning',\n message: `Field \"${field.id}\" has no label.`,\n fieldId: field.id,\n });\n }\n\n const meta = getFieldTypeMeta(field.type);\n // A field on the lookup source has no inline options by design — its options arrive from\n // the registry at runtime. Warn only about the missing list name.\n if (meta?.hasOptions && typeof field.listName === 'string') {\n if (!field.listName.trim()) {\n problems.push({\n level: 'warning',\n message: `Field \"${field.id}\" reads options from a named list but has no list name.`,\n fieldId: field.id,\n });\n }\n } else if (meta?.hasOptions && (!field.options || field.options.length === 0)) {\n problems.push({\n level: 'warning',\n message: `Field \"${field.id}\" is a ${field.type} but has no options.`,\n fieldId: field.id,\n });\n }\n }\n\n // Id uniqueness is a *per-scope* invariant, not a whole-config one — this counted into\n // one flat map keyed by bare id, so it rejected `personal.address` alongside\n // `work.address` and made every such config unopenable: Save is disabled while an error\n // stands, so unrelated edits could not be saved either. The runtime, the record shape\n // and `validateConfig` have all accepted per-scope ids since 1.4.0; this was the last\n // component still enforcing the old rule, and it enforced it against configs the rest\n // of the stack calls valid.\n //\n // The scope rule itself comes from core rather than being reimplemented here, so the\n // builder and the validator cannot drift apart on what \"same scope\" means.\n const scopeCounts = new Map<string, { id: string; count: number }>();\n for (const entry of collectFieldScopes(config)) {\n if (!entry.field.id) continue;\n const key = `${entry.scope}::${entry.field.id}`;\n const seen = scopeCounts.get(key);\n if (seen) seen.count += 1;\n else scopeCounts.set(key, { id: entry.field.id, count: 1 });\n }\n\n for (const [key, { id, count }] of scopeCounts) {\n if (count > 1) {\n // Still an error, and it must stay one: two fields in the same scope share a single\n // control and a single record key, so the second silently overwrites the first.\n const scope = key.slice(0, key.lastIndexOf('::'));\n problems.push({\n level: 'error',\n message: `Duplicate field id \"${id}\" (${count}×) in ${scope}. Two fields in one scope share a control and a record key.`,\n fieldId: id,\n });\n }\n }\n\n return problems;\n }\n}\n","import type { EntityFormConfig } from '@dynamic-entity/core';\nimport { collectFieldScopes, refOf, resolveLabel, toRefToken } from '@dynamic-entity/core';\n\n/** One choosable field: the reference stored, the label shown, and the path behind it. */\nexport interface FieldPathOption {\n value: string;\n label: string;\n path: string;\n}\n\n/**\n * Every field in the config, offered by path.\n *\n * Four places in the builder name a field — `showWhen` keys, `patchOnTrue` mappings,\n * `autoPatch` targets and rule triggers/targets — and each was a free-text box. Typing an id\n * is the one way left to author an ambiguous reference: ids are unique per scope, so\n * `address` names nothing in particular once two tabs have one. Choosing from this list\n * always yields a path.\n *\n * `collectFieldScopes` rather than the tab-level view, so a field nested inside a `group` is\n * offered too, and every entry carries the scope `refOf` needs.\n */\nexport function fieldPathOptions(\n config: EntityFormConfig | null | undefined,\n language: string,\n): FieldPathOption[] {\n return collectFieldScopes(config).map(entry => {\n const path = refOf(entry.field, entry.scope);\n return {\n value: toRefToken(path),\n label: resolveLabel(entry.field.label, language) || entry.field.id,\n path,\n };\n });\n}\n\n/**\n * The options plus whatever is already selected.\n *\n * A reference written before paths existed is a bare id, and one written against a field\n * since deleted is a path nothing answers to. Neither appears in the list, and a `mat-select`\n * silently drops a value it has no option for — so opening such a config and saving it would\n * quietly erase the reference. They are kept, and shown as they are.\n */\nexport function withExistingOptions(\n options: readonly FieldPathOption[],\n current: readonly (string | undefined)[],\n): FieldPathOption[] {\n const known = new Set(options.map(o => o.value));\n const extra = current\n .filter((value): value is string => !!value && !known.has(value))\n .map(value => ({ value, label: value, path: 'not in this config' }));\n return [...options, ...extra];\n}\n","import type { EntityFormConfig, FormRule, NestedFieldConfig } from '@dynamic-entity/core';\nimport {\n collectFieldScopes,\n parseFieldRef,\n refOf,\n resolveLabel,\n toRefToken,\n} from '@dynamic-entity/core';\n\nexport type DependencyType = 'rule' | 'showWhen' | 'cascade' | 'patchOnTrue' | 'autoPatch';\n\nexport interface RuleDependencyEdge {\n id: string;\n sourceKey: string;\n sourceLabel: string;\n targetKey: string;\n targetLabel: string;\n type: DependencyType;\n actionSummary: string;\n description: string;\n sourceValid: boolean;\n targetValid: boolean;\n}\n\nexport interface RuleDependencyGraphData {\n edges: RuleDependencyEdge[];\n totalRules: number;\n totalShowWhen: number;\n totalCascades: number;\n totalPatches: number;\n}\n\ninterface FieldMeta {\n key: string;\n id: string;\n label: string;\n field: NestedFieldConfig;\n}\n\n/**\n * Computes all dependency edges (rules, showWhen, cascades, patchOnTrue, autoPatch)\n * across an EntityFormConfig and its rules.\n */\nexport function computeRuleDependencies(\n config: EntityFormConfig | null | undefined,\n rules: readonly FormRule[] = [],\n language = 'en',\n): RuleDependencyGraphData {\n const edges: RuleDependencyEdge[] = [];\n let edgeIdSeq = 0;\n\n const scopes = collectFieldScopes(config);\n const byKey = new Map<string, FieldMeta>();\n const byId = new Map<string, FieldMeta>();\n const byToken = new Map<string, FieldMeta>();\n\n for (const entry of scopes) {\n const key = refOf(entry.field, entry.scope);\n const token = toRefToken(key);\n const label = resolveLabel(entry.field.label, language) || entry.field.id;\n const meta: FieldMeta = { key, id: entry.field.id, label, field: entry.field };\n\n byKey.set(key, meta);\n byId.set(entry.field.id, meta);\n byToken.set(token, meta);\n }\n\n function resolveRef(refStr: string): { key: string; label: string; valid: boolean } {\n if (!refStr) return { key: '', label: '—', valid: false };\n const parsed = parseFieldRef(refStr);\n const val = parsed.value;\n const meta =\n byKey.get(refStr) ??\n byKey.get(val) ??\n byId.get(val) ??\n byToken.get(refStr) ??\n byToken.get(toRefToken(val));\n\n if (meta) {\n return { key: meta.key, label: meta.label, valid: true };\n }\n return { key: val || refStr, label: val || refStr, valid: false };\n }\n\n let totalRules = 0;\n let totalShowWhen = 0;\n let totalCascades = 0;\n let totalPatches = 0;\n\n // 1. Form Rules\n for (const rule of rules) {\n if (!rule.fieldId) continue;\n totalRules++;\n const source = resolveRef(rule.fieldId);\n const targets = rule.targets ?? [];\n\n const actionType: string = rule.action?.type ?? 'action';\n let actionSummary = actionType;\n if (actionType === 'visibility') {\n actionSummary = rule.action?.value === false || rule.action?.value === 'false' ? 'hide' : 'show';\n } else if (actionType === 'validation' || actionType === 'validationMessage') {\n actionSummary = 'validate';\n } else if (actionType === 'info' || actionType === 'infoBanner') {\n actionSummary = 'info';\n }\n\n const conditionsText =\n rule.conditions && rule.conditions.length > 0\n ? rule.conditions.map(c => `${c.operator ?? 'EQUAL'} ${c.value ?? ''}`.trim()).join(' & ')\n : 'always';\n\n for (const target of targets) {\n const targetResolved = resolveRef(target.id);\n edges.push({\n id: `rule-${++edgeIdSeq}`,\n sourceKey: source.key,\n sourceLabel: source.label,\n targetKey: targetResolved.key,\n targetLabel: targetResolved.label,\n type: 'rule',\n actionSummary,\n description: `${actionSummary.toUpperCase()} when ${conditionsText}`,\n sourceValid: source.valid,\n targetValid: targetResolved.valid,\n });\n }\n }\n\n // 2. Field-level features: showWhen, cascade, patchOnTrue, autoPatch\n for (const entry of scopes) {\n const field = entry.field;\n const fieldKey = refOf(field, entry.scope);\n const fieldResolved = resolveRef(fieldKey);\n\n // showWhen\n if (field.showWhen && typeof field.showWhen === 'object') {\n for (const [watchedRef, expectedVal] of Object.entries(field.showWhen)) {\n totalShowWhen++;\n const source = resolveRef(watchedRef);\n const valStr = typeof expectedVal === 'object' ? JSON.stringify(expectedVal) : String(expectedVal);\n edges.push({\n id: `showWhen-${++edgeIdSeq}`,\n sourceKey: source.key,\n sourceLabel: source.label,\n targetKey: fieldResolved.key,\n targetLabel: fieldResolved.label,\n type: 'showWhen',\n actionSummary: `= ${valStr}`,\n description: `Visible when ${source.label} = ${valStr}`,\n sourceValid: source.valid,\n targetValid: fieldResolved.valid,\n });\n }\n }\n\n // cascade parentField\n if (field.entityReference?.parentField) {\n totalCascades++;\n const source = resolveRef(field.entityReference.parentField);\n edges.push({\n id: `cascade-${++edgeIdSeq}`,\n sourceKey: source.key,\n sourceLabel: source.label,\n targetKey: fieldResolved.key,\n targetLabel: fieldResolved.label,\n type: 'cascade',\n actionSummary: 'filters options',\n description: `Reloads options when ${source.label} changes`,\n sourceValid: source.valid,\n targetValid: fieldResolved.valid,\n });\n }\n\n // patchOnTrue\n if (Array.isArray(field.patchOnTrue)) {\n for (const mapping of field.patchOnTrue) {\n if (!mapping.to) continue;\n totalPatches++;\n const toResolved = resolveRef(mapping.to);\n const fromResolved = resolveRef(mapping.from);\n edges.push({\n id: `patch-${++edgeIdSeq}`,\n sourceKey: fieldResolved.key,\n sourceLabel: fieldResolved.label,\n targetKey: toResolved.key,\n targetLabel: toResolved.label,\n type: 'patchOnTrue',\n actionSummary: `copy ${fromResolved.label} → ${toResolved.label}`,\n description: `When true, copies ${fromResolved.label} to ${toResolved.label}`,\n sourceValid: fieldResolved.valid,\n targetValid: toResolved.valid,\n });\n }\n }\n\n // autoPatch\n if (field.autoPatch && Array.isArray(field.autoPatch.mappings)) {\n for (const mapping of field.autoPatch.mappings) {\n if (!mapping.target) continue;\n totalPatches++;\n const targetResolved = resolveRef(mapping.target);\n edges.push({\n id: `autopatch-${++edgeIdSeq}`,\n sourceKey: fieldResolved.key,\n sourceLabel: fieldResolved.label,\n targetKey: targetResolved.key,\n targetLabel: targetResolved.label,\n type: 'autoPatch',\n actionSummary: `patch → ${targetResolved.label}`,\n description: `Selection copies ${mapping.source} to ${targetResolved.label}`,\n sourceValid: fieldResolved.valid,\n targetValid: targetResolved.valid,\n });\n }\n }\n }\n\n return {\n edges,\n totalRules,\n totalShowWhen,\n totalCascades,\n totalPatches,\n };\n}\n","import { Injectable, InjectionToken, inject, signal } from '@angular/core';\nimport { resolveUiText, type UiTextOverridesFor, type UiTextParams } from 'ngx-dynamic-entity';\n\n/**\n * Every word the builder puts on screen that is not part of the config being authored.\n *\n * The renderer has its own list (`DEFAULT_UI_TEXT`) and the two are deliberately separate:\n * an application that ships only the renderer should not see a hundred and fifty builder\n * keys in completion, and the two vocabularies share no strings worth deduplicating. What\n * they do share is the resolution rule, which comes from `resolveUiText`.\n *\n * Keys are grouped by panel, because a translator works screen by screen.\n */\nexport const DEFAULT_BUILDER_TEXT = {\n // Toolbar and page chrome\n builderTitle: 'Entity Builder',\n undo: 'Undo',\n undoTooltip: 'Undo (Ctrl+Z)',\n redo: 'Redo',\n redoTooltip: 'Redo (Ctrl+Shift+Z)',\n issuesTooltip: '{count} issue(s) — open the list to see them',\n issuesCount: '{errors} / {total}',\n copyJson: 'Copy JSON',\n save: 'Save',\n saveBlockedTooltip: 'Fix the errors in the issue list before saving.',\n\n /*\n * The panels collapse, so each control is named in both directions — and a collapsed\n * panel leaves a rail or dock bar whose label is the only word left standing for it.\n */\n collapsePalette: 'Collapse the palette',\n expandPalette: 'Expand the palette',\n collapseInspector: 'Collapse the inspector',\n expandInspector: 'Expand the inspector',\n paletteRailLabel: 'Add fields',\n inspectorRailLabel: 'Properties',\n collapseFields: 'Collapse fields',\n expandFields: 'Expand fields',\n fieldsRailLabel: 'Fields',\n collapsePreview: 'Collapse live preview',\n expandPreview: 'Expand live preview',\n previewRailLabel: 'Live preview',\n previewHeading: 'Live preview',\n\n // Entity settings panel\n entityName: 'Entity name',\n entityNamePlaceholder: 'e.g. clients',\n editingLanguage: 'Editing language',\n maskEntity: 'Mask this entity (RBAC)',\n permissions: 'Permissions',\n actionRoles: '{action} roles',\n actionRolesPlaceholder: '{action} roles (comma-separated)',\n permissionsHint: 'Empty = no restriction for that action.',\n addField: 'Add field',\n fieldProperties: 'Field properties',\n configJson: 'Config JSON',\n\n // Field palette\n paletteSearchPlaceholder: 'Filter field types…',\n paletteSearchLabel: 'Filter field types',\n paletteSearchClear: 'Clear the filter',\n paletteNoMatch: 'No field type matches \"{query}\".',\n paletteGroupBasic: 'Basic',\n paletteGroupChoice: 'Choice',\n paletteGroupDateTime: 'Date & time',\n paletteGroupRich: 'Rich & files',\n paletteGroupStructure: 'Structure',\n paletteGroupOther: 'Other',\n\n // Canvas\n fieldsHeading: 'Fields ({count})',\n canvasEmpty: 'No fields yet. Pick a type from Add field to get started.',\n\n // Field rows in the tree\n selectField: 'Select field {field}',\n dragToReorder: 'Drag to reorder (or use the move buttons)',\n referencedFieldTooltip: 'Referenced field (linked to {entity})',\n driftDetected: 'Drift detected: source field has evolved',\n required: 'Required',\n moveUp: 'Move up',\n moveDown: 'Move down',\n duplicate: 'Duplicate',\n delete: 'Delete',\n moveFieldUp: 'Move {field} up',\n moveFieldDown: 'Move {field} down',\n duplicateField: 'Duplicate {field}',\n\n // Field inspector — identity\n inspectorEmpty: 'Select a field to edit its properties.',\n fieldId: 'Field id',\n fieldIdFixedHint: 'The stored data key for this saved field — fixed.',\n fieldIdDerivedHint: 'Derived from the label. Used as the data key.',\n tab: 'Tab',\n tabMoveHint: 'Moving the field rewrites its path and repoints the rules that named it.',\n labelInLanguage: 'Label ({language})',\n placeholderInLanguage: 'Placeholder ({language})',\n hintInLanguage: 'Help text ({language})',\n hintHint: 'An info icon beside the label, shown on hover and while the field has focus. Read out with the field.',\n defaultValue: 'Default value',\n\n // Field inspector — section headings and the layout control.\n // `validation` used to be the heading above the validator checkboxes; the inspector's\n // sections now own their headings, so `sectionValidation` replaces it.\n sectionBasics: 'Basics',\n sectionLayout: 'Layout',\n sectionValidation: 'Validation',\n sectionOptions: 'Options',\n sectionDisplay: 'Display',\n sectionVisibility: 'Visibility',\n sectionAutomation: 'Automation',\n sectionRules: 'Rules',\n sectionReference: 'Reference',\n sectionDependencies: 'Dependencies',\n width: 'Width',\n widthQuarter: '¼',\n widthThird: '⅓',\n widthHalf: '½',\n widthTwoThirds: '⅔',\n widthFull: 'Full',\n widthHint: 'How much of the 12-column row this field takes. Fields sharing a row sit side by side.',\n widthOf: '{span} of 12 columns',\n\n // Field inspector — options\n dataSource: 'Data source',\n optionsComeFrom: 'Options come from',\n optionsSourceNone: 'Nothing yet',\n optionsSourceInline: 'Options authored here',\n optionsSourceList: 'A named list',\n listName: 'List name',\n listNameHint: 'The consuming app resolves this name through its lookup registry. Options are not authored here.',\n options: 'Options',\n option: 'Option',\n optionInLanguage: 'Option ({language})',\n removeOption: 'Remove option',\n noOptionsYet: 'No options yet — add at least one.',\n optionKey: 'Key',\n optionKeyHint: 'Set once, when the option was created. Records store it, so renaming the text above is safe.',\n assignOptionKeys: 'Assign stable keys',\n\n // Field inspector — display flags\n display: 'Display',\n visible: 'Visible',\n tableColumn: 'Table column',\n readOnly: 'Read-only',\n disabled: 'Disabled',\n maskData: 'Mask data (RBAC)',\n criticalField: 'Critical field',\n criticalFieldTooltip: 'Renders locked; editing it announces a change against the session baseline.',\n showInSummary: 'Show in summary',\n showInSummaryTooltip: \"Shown in the record editor's summary panel.\",\n\n // Field inspector — conditional visibility\n showWhen: 'Show when',\n condition: 'Condition',\n watchedField: 'Watched field',\n equals: 'Equals',\n removeCondition: 'Remove condition',\n alwaysVisibleHint: 'Always visible. Add a condition to show this field only for certain values.',\n\n // Field inspector — copy on true\n copyOnTrue: 'Copy on true',\n mapping: 'Mapping',\n fromField: 'From field',\n toField: 'To field',\n removeMapping: 'Remove mapping',\n copyOnTrueHint: \"When this flips to true, copy one field's value into another.\",\n\n // Rules list\n rules: 'Rules',\n rule: 'Rule',\n noRulesOnField: 'No rules on this field.',\n rulePriority: 'priority {priority} · {targets} target(s)',\n toggleRule: 'Enable / disable',\n moveRuleUp: 'Move rule up',\n moveRuleDown: 'Move rule down',\n editRule: 'Edit rule',\n deleteRule: 'Delete rule',\n\n // Rule form\n newRuleTitle: 'New Form Rule',\n editRuleTitle: 'Edit Rule',\n triggerField: 'Trigger Field',\n applyToFields: 'Apply to fields',\n conditions: 'Conditions',\n operator: 'Operator',\n value: 'Value',\n conditionValuePlaceholder: 'Condition value',\n addCondition: 'Add Condition',\n action: 'Action',\n actionType: 'Action Type',\n actionVisibility: 'Visibility (Show/Hide)',\n actionValidationMessage: 'Validation Message',\n actionInfoBanner: 'Info Banner',\n valueOrMessage: 'Value / Message',\n valueOrMessagePlaceholder: 'false to hide, or message text',\n cancel: 'Cancel',\n saveRule: 'Save Rule',\n\n // Tab manager\n tabsManager: 'Tabs Manager',\n systemTag: '(System)',\n addTab: 'Add Tab',\n noTabs: 'No tabs — all fields render in a single section.',\n flatData: 'Flat Data',\n primaryTab: 'Primary Tab',\n maskTabData: 'Mask Tab Data',\n systemDefault: 'System Default',\n addSubTab: '+ Sub-tab',\n consumerModuleName: 'Consumer Module Name (Optional)',\n consumerModulePlaceholder: 'e.g. documents-view',\n subTabs: 'Sub-tabs:',\n moveTabUp: 'Move tab up',\n moveTabDown: 'Move tab down',\n removeTab: 'Remove tab',\n removeSubTab: 'Remove sub-tab',\n\n // Entity reference panel\n entityReference: 'Entity reference',\n registryKey: 'Registry key',\n registryKeyHint: 'Key the consumer registered a loader under. Defaults to the field id.',\n displayFields: 'Display fields',\n displayFieldsHint: 'Comma-separated record paths used to build each option label.',\n staticFilters: 'Static filters (JSON)',\n staticFiltersHint: 'Passed to the loader, e.g. &#123;\"isEmployee\": false&#125;.',\n cascade: 'Cascade',\n parentField: 'Parent field',\n parentFieldNone: 'None — load all options',\n cascadeHint: \"This field's options reload whenever the parent changes.\",\n lookupFilterPath: 'Lookup filter path',\n lookupFilterPathHint: 'Keep options whose record matches the parent value at this path.',\n lookupPath: 'Lookup path (nested options)',\n lookupPathHint: \"Take options from this array on the selected parent's record instead.\",\n autoPatchOnSelect: 'Auto-patch on select',\n targetTab: 'Target tab',\n sourceLinkedRecord: 'Source (linked record)',\n targetField: 'Target field',\n noAutoPatch: 'No auto-patch configured — selecting a reference will not copy any values.',\n\n // Referenced-field panel\n referencedField: 'Referenced Field',\n link: 'Link',\n sourceEntityKey: 'Source Entity Key',\n sourceEntityKeyPlaceholder: 'e.g. individuals',\n sourceFieldId: 'Source Field ID',\n sourceFieldIdPlaceholder: 'e.g. firstName',\n driftHeading: 'Source field definition has drifted!',\n driftBody: 'The upstream field configuration in \"{entity}\" has evolved.',\n syncWithSource: 'Sync with Source',\n\n // Validation pattern playground\n pattern: 'Validation Pattern (Regex)',\n patternHint: 'Regular expression for format validation.',\n testPattern: 'Test Pattern',\n testPatternPlaceholder: 'Type sample input to test…',\n patternMatch: 'Pattern matches',\n patternNoMatch: 'Pattern does not match',\n patternInvalid: 'Invalid regex syntax',\n patternEmptyPrompt: 'Enter regex above to test sample input',\n quickPresets: 'Presets',\n\n // Field dependencies\n dependsOn: 'Depends on',\n affects: 'Affects',\n noDependencies: 'No active rule or field dependencies for this field.',\n\n // Rule graph\n ruleGraph: 'Rule Graph',\n ruleGraphTitle: 'Rule & Dependency Graph',\n ruleGraphSubtitle: 'Schema-wide rule triggers, conditional visibility, and cascades',\n filterDependencies: 'Filter dependencies…',\n noDependenciesFound: 'No dependencies matching current filter.',\n jumpToField: 'Select {field}',\n closeDialog: 'Close',\n dependencyTypeRule: 'Rule',\n dependencyTypeShowWhen: 'Show When',\n dependencyTypeCascade: 'Cascade',\n dependencyTypePatch: 'Copy on True',\n totalDependencies: '{count} dependencies',\n};\n\n/** The keys above, as a union — checked in templates, completed in a host's overrides. */\nexport type BuilderTextKey = keyof typeof DEFAULT_BUILDER_TEXT;\n\n/** Same contract as the renderer's `UI_TEXT`, over the builder's vocabulary. */\nexport type BuilderTextOverrides = UiTextOverridesFor<BuilderTextKey>;\n\n/**\n * Overrides for the builder's own chrome.\n *\n * Accepts what `UI_TEXT` accepts: a partial map whose values are strings or `LocalizedText`\n * (`{ en, de }`), or a resolver `(key, defaultText, language) => string` for a host with an\n * existing i18n layer. `DEFAULT_BUILDER_TEXT` is the full key list with its English source\n * strings; anything left out keeps its default.\n *\n * @example\n * { provide: BUILDER_TEXT, useValue: { save: { en: 'Save', de: 'Speichern' } } }\n */\nexport const BUILDER_TEXT = new InjectionToken<BuilderTextOverrides>('BUILDER_TEXT');\n\n/**\n * Resolves the builder's own UI text.\n *\n * The language lives on the service rather than travelling through every template call,\n * because the builder already has a *different* language on screen: `activeLanguage()`\n * selects the `LocalizedText` entry being **authored**. Passing that one to the chrome\n * would flip the builder's own interface every time an author switched the label language\n * they were editing, which is the opposite of what it means.\n *\n * Root-provided and therefore shared: two builders mounted at once show one chrome\n * language. `EntityBuilderComponent`'s `uiLanguage` input is what sets it.\n */\n@Injectable({ providedIn: 'root' })\nexport class BuilderTextService {\n private readonly overrides = inject(BUILDER_TEXT, { optional: true });\n\n /** The chrome language. Not the authoring language — see the class comment. */\n readonly language = signal('en');\n\n /** One label by key. `params` fill the `{placeholder}` slots. */\n text(key: BuilderTextKey, params?: UiTextParams): string {\n return resolveUiText(this.overrides, DEFAULT_BUILDER_TEXT, key, this.language(), params);\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatDividerModule } from '@angular/material/divider';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatSelectModule } from '@angular/material/select';\nimport { MatSlideToggleModule } from '@angular/material/slide-toggle';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel, toRefToken } from '@dynamic-entity/core';\nimport { fieldPathOptions, withExistingOptions, type FieldPathOption } from '../field-path-options';\nimport { BuilderStore } from '../builder-store.service';\nimport { BuilderTextService } from '../builder-text';\n\n/**\n * EntityReferenceConfigComponent — authors the `entityReference` block of an entity-ref field:\n * registry key, display fields, static filters, and the parent→child cascade.\n *\n * Also authors `autoPatch`, since the mappings only make sense against the record the\n * selected reference returns.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-entity-reference-config',\n standalone: true,\n imports: [\n FormsModule,\n MatButtonModule,\n MatDividerModule,\n MatFormFieldModule,\n MatIconModule,\n MatInputModule,\n MatSelectModule,\n MatSlideToggleModule,\n MatTooltipModule,\n ],\n template: `\n @if (field(); as f) {\n <div class=\"deb-entity-ref\">\n <span class=\"deb-section-title\">{{ ui.text('entityReference') }}</span>\n\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('registryKey') }}</mat-label>\n <input\n matInput\n data-testid=\"entity-ref-key\"\n [ngModel]=\"ref(f).linkedEntityKey ?? ''\"\n (ngModelChange)=\"patchRef(f, { linkedEntityKey: $event || undefined })\"\n />\n <mat-hint>{{ ui.text('registryKeyHint') }}</mat-hint>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('displayFields') }}</mat-label>\n <input\n matInput\n data-testid=\"entity-ref-display-fields\"\n [ngModel]=\"displayFieldsText(f)\"\n (ngModelChange)=\"setDisplayFields(f, $event)\"\n />\n <mat-hint>{{ ui.text('displayFieldsHint') }}</mat-hint>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('staticFilters') }}</mat-label>\n <input\n matInput\n data-testid=\"entity-ref-filters\"\n [ngModel]=\"filtersText(f)\"\n (ngModelChange)=\"setFilters(f, $event)\"\n />\n @if (filtersError()) {\n <mat-hint class=\"deb-error-hint\">{{ filtersError() }}</mat-hint>\n } @else {\n <mat-hint>{{ ui.text('staticFiltersHint') }}</mat-hint>\n }\n </mat-form-field>\n\n <mat-divider></mat-divider>\n\n <!-- Cascade -->\n <span class=\"deb-section-title\">{{ ui.text('cascade') }}</span>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('parentField') }}</mat-label>\n <mat-select\n data-testid=\"entity-ref-parent\"\n [ngModel]=\"ref(f).parentField ?? ''\"\n (ngModelChange)=\"patchRef(f, { parentField: $event || undefined })\"\n >\n <mat-option value=\"\">{{ ui.text('parentFieldNone') }}</mat-option>\n @for (option of parentOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }} <span class=\"deb-path-hint\">{{ option.path }}</span>\n </mat-option>\n }\n </mat-select>\n <mat-hint>{{ ui.text('cascadeHint') }}</mat-hint>\n </mat-form-field>\n\n @if (ref(f).parentField) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('lookupFilterPath') }}</mat-label>\n <input\n matInput\n data-testid=\"entity-ref-lookup-filter\"\n [ngModel]=\"ref(f).lookupFilter ?? ''\"\n (ngModelChange)=\"patchRef(f, { lookupFilter: $event || undefined })\"\n />\n <mat-hint>{{ ui.text('lookupFilterPathHint') }}</mat-hint>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('lookupPath') }}</mat-label>\n <input\n matInput\n data-testid=\"entity-ref-lookup-path\"\n [ngModel]=\"ref(f).lookupPath ?? ''\"\n (ngModelChange)=\"patchRef(f, { lookupPath: $event || undefined })\"\n />\n <mat-hint>{{ ui.text('lookupPathHint') }}</mat-hint>\n </mat-form-field>\n }\n\n <mat-divider></mat-divider>\n\n <!-- autoPatch -->\n <div class=\"deb-row deb-row--split\">\n <span class=\"deb-section-title\">{{ ui.text('autoPatchOnSelect') }}</span>\n <button\n mat-stroked-button\n type=\"button\"\n data-testid=\"add-auto-patch\"\n (click)=\"store.addAutoPatchMapping(store.keyOf(f))\"\n >\n <mat-icon>add</mat-icon> {{ ui.text('mapping') }}\n </button>\n </div>\n\n @if (f.autoPatch) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('targetTab') }}</mat-label>\n <mat-select\n data-testid=\"auto-patch-tab\"\n [ngModel]=\"f.autoPatch.targetTab\"\n (ngModelChange)=\"store.setAutoPatchTargetTab(store.keyOf(f), $event)\"\n >\n @for (tab of store.tabs(); track tab.id) {\n <mat-option [value]=\"tab.id\">{{ tabLabel(tab.id) }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n @for (mapping of f.autoPatch.mappings; track $index) {\n <div class=\"deb-option-row\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('sourceLinkedRecord') }}</mat-label>\n <input\n matInput\n [ngModel]=\"mapping.source\"\n (ngModelChange)=\"store.updateAutoPatchMapping(store.keyOf(f), $index, { source: $event })\"\n />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('targetField') }}</mat-label>\n <mat-select\n data-testid=\"auto-patch-target\"\n [ngModel]=\"mapping.target\"\n (ngModelChange)=\"store.updateAutoPatchMapping(store.keyOf(f), $index, { target: $event })\"\n >\n @for (option of optionsWith(mapping.target); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }} <span class=\"deb-path-hint\">{{ option.path }}</span>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <button\n mat-icon-button\n type=\"button\"\n color=\"warn\"\n [matTooltip]=\"ui.text('removeMapping')\"\n (click)=\"store.removeAutoPatchMapping(store.keyOf(f), $index)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n }\n } @else {\n <p class=\"deb-hint\">\n {{ ui.text('noAutoPatch') }}\n </p>\n }\n </div>\n }\n `,\n styles: [\n `\n /*\n * .deb-row, .deb-row--split, .deb-option-row and .deb-full were copied here from the\n * builder's stylesheet, because under emulated encapsulation the originals could not\n * reach this component. That stylesheet is no longer scoped, so the copies are gone and\n * this panel takes the same definitions as every other one — which is the point of\n * having them in one place.\n */\n .deb-entity-ref {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n .deb-option-row > mat-form-field {\n flex: 1;\n }\n .deb-error-hint {\n color: #b91c1c;\n }\n `,\n ],\n})\nexport class EntityReferenceConfigComponent {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n\n protected readonly field = this.store.selectedField;\n\n /** Sibling fields that can drive a cascade — anything but this field itself. */\n protected readonly parentCandidates = computed<NestedFieldConfig[]>(() => {\n const current = this.field();\n return this.store.fields().filter(f => f.id !== current?.id);\n });\n\n private readonly fieldOptions = computed<FieldPathOption[]>(() =>\n fieldPathOptions(this.store.config(), this.store.activeLanguage()),\n );\n\n /**\n * Cascade parents, offered by path.\n *\n * The picker existed but its values were bare ids, which name a field only while no second\n * scope reuses the id — so the one control that was already a list could still produce an\n * ambiguous reference.\n */\n protected parentOptions(): FieldPathOption[] {\n const self = this.field();\n const selfValue = self ? toRefToken(self.refererField ?? self.id) : null;\n const options = this.fieldOptions().filter(o => o.value !== selfValue);\n return withExistingOptions(options, [this.field() ? this.ref(this.field()!).parentField : undefined]);\n }\n\n /** Options plus whatever is already selected, so an unknown reference is never dropped. */\n protected optionsWith(...current: (string | undefined)[]): FieldPathOption[] {\n return withExistingOptions(this.fieldOptions(), current);\n }\n\n private readonly filtersParseError = signal<string | null>(null);\n protected readonly filtersError = this.filtersParseError.asReadonly();\n\n protected ref(field: NestedFieldConfig) {\n return field.entityReference ?? { enabled: true };\n }\n\n protected patchRef(field: NestedFieldConfig, patch: Record<string, unknown>): void {\n this.store.updateEntityReference(this.store.keyOf(field), patch);\n }\n\n protected fieldLabel(field: NestedFieldConfig): string {\n return resolveLabel(field.label, this.store.activeLanguage());\n }\n\n protected tabLabel(tabId: string): string {\n const tab = this.store.tabs().find(t => t.id === tabId);\n return tab ? resolveLabel(tab.label, this.store.activeLanguage()) : tabId;\n }\n\n protected displayFieldsText(field: NestedFieldConfig): string {\n return (this.ref(field).displayFields ?? []).join(', ');\n }\n\n protected setDisplayFields(field: NestedFieldConfig, value: string): void {\n const parts = value\n .split(',')\n .map(s => s.trim())\n .filter(Boolean);\n this.patchRef(field, { displayFields: parts.length ? parts : undefined });\n }\n\n protected filtersText(field: NestedFieldConfig): string {\n const filters = this.ref(field).filters;\n return filters ? JSON.stringify(filters) : '';\n }\n\n /** Invalid JSON is reported inline and left unapplied rather than silently dropped. */\n protected setFilters(field: NestedFieldConfig, value: string): void {\n const trimmed = value.trim();\n if (!trimmed) {\n this.filtersParseError.set(null);\n this.patchRef(field, { filters: undefined });\n return;\n }\n try {\n const parsed = JSON.parse(trimmed);\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n this.filtersParseError.set('Filters must be a JSON object.');\n return;\n }\n this.filtersParseError.set(null);\n this.patchRef(field, { filters: parsed as Record<string, unknown> });\n } catch {\n this.filtersParseError.set('Invalid JSON.');\n }\n }\n}\n","import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, computed, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatSelectModule } from '@angular/material/select';\n\nimport type { FormRule, RuleOperator } from '@dynamic-entity/core';\nimport { BuilderStore } from '../builder-store.service';\nimport { fieldPathOptions, withExistingOptions, type FieldPathOption } from '../field-path-options';\nimport { BuilderTextService } from '../builder-text';\n\n/**\n * RuleFormComponent — dialog/panel form for creating or editing a FormRule.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-rule-form',\n standalone: true,\n imports: [CommonModule, FormsModule, MatButtonModule, MatFormFieldModule, MatIconModule, MatInputModule, MatSelectModule],\n template: `\n <div class=\"deb-rule-form\">\n <h3 class=\"deb-rule-form__title\">{{ ui.text(rule.id ? 'editRuleTitle' : 'newRuleTitle') }}</h3>\n\n <!-- Trigger Field -->\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('triggerField') }}</mat-label>\n <mat-select [(ngModel)]=\"rule.fieldId\" data-testid=\"rule-trigger\">\n @for (option of triggerOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }} <span class=\"deb-rule-path\">{{ option.path }}</span>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n <!-- Targets: the fields this rule acts on -->\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('applyToFields') }}</mat-label>\n <mat-select multiple data-testid=\"rule-targets\" [ngModel]=\"targetValues()\" (ngModelChange)=\"setTargets($event)\">\n @for (option of targetOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }} <span class=\"deb-rule-path\">{{ option.path }}</span>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n <!-- Conditions -->\n <div class=\"deb-rule-section\">\n <h4>{{ ui.text('conditions') }}</h4>\n @for (cond of rule.conditions; track $index) {\n <div class=\"deb-rule-row\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('operator') }}</mat-label>\n <mat-select [(ngModel)]=\"cond.operator\">\n @for (op of operators; track op) {\n <mat-option [value]=\"op\">{{ op }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('value') }}</mat-label>\n <input matInput [(ngModel)]=\"cond.value\" [placeholder]=\"ui.text('conditionValuePlaceholder')\" />\n </mat-form-field>\n <button mat-icon-button color=\"warn\" type=\"button\" (click)=\"removeCondition($index)\">\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n }\n <button mat-stroked-button type=\"button\" (click)=\"addCondition()\">\n <mat-icon>add</mat-icon> {{ ui.text('addCondition') }}\n </button>\n </div>\n\n <!-- Action -->\n <div class=\"deb-rule-section\">\n <h4>{{ ui.text('action') }}</h4>\n <div class=\"deb-rule-row\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('actionType') }}</mat-label>\n <mat-select [(ngModel)]=\"rule.action.type\">\n <mat-option value=\"visibility\">{{ ui.text('actionVisibility') }}</mat-option>\n <mat-option value=\"validation\">{{ ui.text('actionValidationMessage') }}</mat-option>\n <mat-option value=\"info\">{{ ui.text('actionInfoBanner') }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('valueOrMessage') }}</mat-label>\n <input matInput [(ngModel)]=\"rule.action.value\" [placeholder]=\"ui.text('valueOrMessagePlaceholder')\" />\n </mat-form-field>\n </div>\n </div>\n\n <div class=\"deb-rule-form__actions\">\n <button mat-button type=\"button\" (click)=\"cancel.emit()\">{{ ui.text('cancel') }}</button>\n <button mat-raised-button color=\"primary\" type=\"button\" (click)=\"save.emit(rule)\">{{ ui.text('saveRule') }}</button>\n </div>\n </div>\n `,\n styles: [\n `\n .deb-rule-form {\n display: flex;\n flex-direction: column;\n gap: 12px;\n background: #fafafa;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n padding: 16px;\n }\n .deb-rule-form__title {\n margin: 0 0 8px 0;\n font-size: 16px;\n font-weight: 600;\n }\n .deb-full {\n width: 100%;\n }\n .deb-rule-path {\n color: #888;\n font-size: 11px;\n margin-left: 6px;\n }\n .deb-rule-section {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n .deb-rule-section h4 {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: #555;\n }\n .deb-rule-row {\n display: flex;\n gap: 8px;\n align-items: center;\n }\n .deb-rule-row > * {\n flex: 1;\n }\n .deb-rule-form__actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n margin-top: 8px;\n }\n `,\n ],\n})\nexport class RuleFormComponent {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n private readonly store = inject(BuilderStore);\n\n @Input() rule: FormRule = {\n formConfigId: 'form-1',\n fieldId: '',\n conditions: [{ operator: 'EQUAL', compareType: 'value', value: '' }],\n action: { type: 'visibility', value: false },\n targets: [],\n enabled: true,\n priority: 1,\n };\n\n @Output() save = new EventEmitter<FormRule>();\n @Output() cancel = new EventEmitter<void>();\n\n readonly operators: RuleOperator[] = [\n 'EQUAL',\n 'NOT_EQUAL',\n 'CONTAINS',\n 'NOT_CONTAINS',\n 'STARTS_WITH',\n 'ENDS_WITH',\n 'IS_EMPTY',\n 'IS_NOT_EMPTY',\n 'LESS_THAN',\n 'MORE_THAN',\n 'LESS_THAN_EQUAL',\n 'MORE_THAN_EQUAL',\n 'DATE_BEFORE',\n 'DATE_AFTER',\n 'IN',\n 'NOT_IN',\n 'HAS_ITEMS',\n 'VALUE_CHANGED',\n ];\n\n protected readonly fieldOptions = computed<FieldPathOption[]>(() =>\n fieldPathOptions(this.store.config(), this.store.activeLanguage()),\n );\n\n /**\n * Methods, not `computed`. Both read `rule`, which is a plain `@Input` object mutated in\n * place rather than a signal — a computed would cache the first evaluation and never see a\n * different rule being edited.\n */\n protected triggerOptions(): FieldPathOption[] {\n return withExistingOptions(this.fieldOptions(), [this.rule.fieldId]);\n }\n\n protected targetOptions(): FieldPathOption[] {\n return withExistingOptions(this.fieldOptions(), this.targetValues());\n }\n\n private cachedTargets: string[] = [];\n\n /**\n * Field targets only — a rule may also target a tab, which this picker does not manage.\n *\n * The array identity is held stable while the contents are unchanged. This is bound through\n * `[ngModel]` on a multi-select, and a fresh array on each call made `ngModel` see a new\n * value on every change-detection pass: it wrote, which scheduled another pass, which built\n * another array. Opening the rule editor locked the browser outright.\n */\n protected targetValues(): string[] {\n const ids = this.rule.targets.filter(t => t.type === 'field').map(t => t.id);\n const unchanged = ids.length === this.cachedTargets.length && ids.every((id, i) => id === this.cachedTargets[i]);\n if (!unchanged) this.cachedTargets = ids;\n return this.cachedTargets;\n }\n\n /**\n * Replaces the field targets, leaving any tab target untouched.\n *\n * Rebuilding `targets` wholesale from this picker would drop tab targets, which it never\n * offered and so cannot know about.\n */\n protected setTargets(ids: string[]): void {\n const others = this.rule.targets.filter(t => t.type !== 'field');\n this.rule.targets = [...others, ...ids.map(id => ({ id, type: 'field' as const }))];\n }\n\n addCondition(): void {\n this.rule.conditions.push({ operator: 'EQUAL', compareType: 'value', value: '' });\n }\n\n removeCondition(index: number): void {\n this.rule.conditions.splice(index, 1);\n }\n}\n","import { ChangeDetectionStrategy, Component, inject, signal } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatSlideToggleModule } from '@angular/material/slide-toggle';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport type { FormRule } from '@dynamic-entity/core';\nimport { toRefToken } from '@dynamic-entity/core';\nimport { BuilderStore } from '../builder-store.service';\nimport { deepClone } from '../clone';\nimport { RuleFormComponent } from './rule-form.component';\nimport { BuilderTextService } from '../builder-text';\n\n/**\n * FieldRulesListComponent — the rules attached to the selected field: view, reorder,\n * enable/disable, edit, delete. `RuleFormComponent` authors one rule; this owns the set.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-field-rules-list',\n standalone: true,\n imports: [MatButtonModule, MatIconModule, MatSlideToggleModule, MatTooltipModule, RuleFormComponent],\n template: `\n <div class=\"deb-rules\">\n <div class=\"deb-rules__head\">\n <span class=\"deb-section-title\">{{ ui.text('rules') }}</span>\n <button\n mat-stroked-button\n type=\"button\"\n data-testid=\"add-rule\"\n [disabled]=\"!store.selectedFieldId()\"\n (click)=\"startCreate()\"\n >\n <mat-icon>add</mat-icon> {{ ui.text('rule') }}\n </button>\n </div>\n\n @if (editing(); as draft) {\n <ngx-rule-form [rule]=\"draft\" (save)=\"commit($event)\" (cancel)=\"editing.set(null)\" />\n }\n\n @if (store.rulesForSelectedField().length === 0 && !editing()) {\n <p class=\"deb-hint\" data-testid=\"rules-empty\">{{ ui.text('noRulesOnField') }}</p>\n }\n\n @for (rule of store.rulesForSelectedField(); track rule.id) {\n <div class=\"deb-rule-item\" [class.deb-rule-item--off]=\"!rule.enabled\" data-testid=\"rule-item\">\n <div class=\"deb-rule-item__body\">\n <span class=\"deb-rule-item__summary\">{{ summarize(rule) }}</span>\n <span class=\"deb-rule-item__meta\">\n {{ ui.text('rulePriority', { priority: rule.priority, targets: rule.targets.length }) }}\n </span>\n </div>\n <div class=\"deb-rule-item__actions\">\n <mat-slide-toggle\n color=\"primary\"\n [checked]=\"rule.enabled\"\n [matTooltip]=\"ui.text('toggleRule')\"\n (change)=\"store.toggleRule(rule.id!, $event.checked)\"\n />\n <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"ui.text('moveUp')\"\n [attr.aria-label]=\"ui.text('moveRuleUp')\"\n [attr.data-testid]=\"'rule-up-' + rule.id\"\n (click)=\"store.moveRule(rule.id!, -1)\"\n >\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"ui.text('moveDown')\"\n [attr.aria-label]=\"ui.text('moveRuleDown')\"\n [attr.data-testid]=\"'rule-down-' + rule.id\"\n (click)=\"store.moveRule(rule.id!, 1)\"\n >\n <mat-icon>arrow_downward</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"ui.text('editRule')\"\n [attr.data-testid]=\"'rule-edit-' + rule.id\"\n (click)=\"startEdit(rule)\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n color=\"warn\"\n [matTooltip]=\"ui.text('deleteRule')\"\n [attr.data-testid]=\"'rule-delete-' + rule.id\"\n (click)=\"store.removeRule(rule.id!)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n </div>\n }\n </div>\n `,\n styles: [\n `\n .deb-rules {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n .deb-rules__head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n .deb-rule-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n padding: 8px 10px;\n }\n .deb-rule-item--off {\n opacity: 0.55;\n }\n .deb-rule-item__body {\n display: flex;\n flex-direction: column;\n min-width: 0;\n }\n .deb-rule-item__summary {\n font-size: 13px;\n font-weight: 600;\n overflow-wrap: anywhere;\n }\n .deb-rule-item__meta {\n font-size: 11px;\n color: #6b7280;\n }\n .deb-rule-item__actions {\n display: flex;\n align-items: center;\n flex: 0 0 auto;\n }\n `,\n ],\n})\nexport class FieldRulesListComponent {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n\n /** The rule currently open in the editor — a new draft or a copy of an existing rule. */\n protected readonly editing = signal<FormRule | null>(null);\n\n protected startCreate(): void {\n const fieldId = this.store.selectedFieldId();\n if (!fieldId) return;\n // Author the field's path, not its id. Ids are unique per scope, so `address` may exist\n // on two tabs and a bare id cannot say which one the rule is about; `[work.address]` can.\n // A rule written by hand may still use a bare id, and both resolve at runtime.\n const ref = this.store.selectedField()?.refererField;\n const name = ref ? toRefToken(ref) : fieldId;\n this.editing.set({\n formConfigId: this.store.config().entity || 'form-1',\n fieldId: name,\n conditions: [{ operator: 'EQUAL', compareType: 'value', value: '' }],\n action: { type: 'visibility', value: false },\n targets: [{ id: name, type: 'field' }],\n enabled: true,\n priority: this.store.rules().length + 1,\n });\n }\n\n protected startEdit(rule: FormRule): void {\n this.editing.set(deepClone(rule));\n }\n\n protected commit(rule: FormRule): void {\n if (rule.id) this.store.updateRule(rule.id, rule);\n else this.store.addRule(rule);\n this.editing.set(null);\n }\n\n /** One-line human summary: `status EQUAL \"archived\" → hide`. */\n protected summarize(rule: FormRule): string {\n const cond = rule.conditions\n .map(c => {\n const rhs = c.compareType === 'field' ? c.compareToField : JSON.stringify(c.value ?? '');\n return `${c.operator} ${rhs ?? ''}`.trim();\n })\n .join(' AND ');\n\n const action =\n rule.action.type === 'visibility'\n ? rule.action.value === false || rule.action.value === 'false'\n ? 'hide'\n : 'show'\n : `${rule.action.type}: ${rule.action.value}`;\n\n return `${rule.fieldId} ${cond} → ${action}`;\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, isDevMode } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatDividerModule } from '@angular/material/divider';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatSlideToggleModule } from '@angular/material/slide-toggle';\nimport { ConfigSourceService } from 'ngx-dynamic-entity';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { BuilderStore } from '../builder-store.service';\nimport { BuilderTextService } from '../builder-text';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-referenced-field-config',\n standalone: true,\n imports: [\n CommonModule,\n FormsModule,\n MatButtonModule,\n MatDividerModule,\n MatFormFieldModule,\n MatIconModule,\n MatInputModule,\n MatSlideToggleModule,\n ],\n template: `\n @if (field(); as f) {\n <div class=\"deb-referenced-field\" style=\"margin-top: 16px;\">\n <div class=\"deb-row\" style=\"justify-content: space-between; align-items: center; margin-bottom: 8px;\">\n <span class=\"deb-section-title\" style=\"margin:0;\">{{ ui.text('referencedField') }}</span>\n <mat-slide-toggle\n color=\"primary\"\n data-testid=\"toggle-referenced\"\n [ngModel]=\"f.isReferenced ?? false\"\n (ngModelChange)=\"toggleReferenced(f, $event)\"\n >\n {{ ui.text('link') }}\n </mat-slide-toggle>\n </div>\n\n @if (f.isReferenced) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\" style=\"margin-bottom: 8px;\">\n <mat-label>{{ ui.text('sourceEntityKey') }}</mat-label>\n <input\n matInput\n data-testid=\"referenced-entity-key\"\n [ngModel]=\"f.referencedEntityKey ?? ''\"\n (ngModelChange)=\"updateEntityKey(f, $event)\"\n [placeholder]=\"ui.text('sourceEntityKeyPlaceholder')\"\n />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\" style=\"margin-bottom: 8px;\">\n <mat-label>{{ ui.text('sourceFieldId') }}</mat-label>\n <input\n matInput\n data-testid=\"referenced-field-id\"\n [ngModel]=\"f.referencedFieldId ?? ''\"\n (ngModelChange)=\"updateFieldId(f, $event)\"\n [placeholder]=\"ui.text('sourceFieldIdPlaceholder')\"\n />\n </mat-form-field>\n\n @if (f.hasDrift) {\n <div\n class=\"deb-drift-banner\"\n data-testid=\"drift-banner\"\n style=\"background: #fff3e0; border: 1px solid #ffe0b2; padding: 8px 12px; border-radius: 4px; margin-top: 8px;\"\n >\n <div class=\"deb-row\" style=\"gap: 8px; align-items: center; color: #e65100; font-weight: 500;\">\n <mat-icon style=\"font-size: 18px; width:18px; height:18px;\">warning</mat-icon>\n <span>{{ ui.text('driftHeading') }}</span>\n </div>\n <p style=\"margin: 4px 0 8px 0; font-size: 12px; color: #666;\">\n {{ ui.text('driftBody', { entity: f.referencedEntityKey ?? '' }) }}\n </p>\n <button mat-flat-button color=\"warn\" type=\"button\" data-testid=\"sync-source-btn\" (click)=\"syncWithSource(f)\">\n {{ ui.text('syncWithSource') }}\n </button>\n </div>\n }\n }\n </div>\n }\n `,\n})\nexport class ReferencedFieldConfigComponent {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n protected readonly configSource = inject(ConfigSourceService, { optional: true }) as ConfigSourceService | null;\n protected readonly field = computed(() => this.store.selectedField());\n\n protected toggleReferenced(field: NestedFieldConfig, enabled: boolean): void {\n if (enabled) {\n this.store.updateField(this.store.keyOf(field), { isReferenced: true });\n } else {\n this.store.unlinkReferencedField(this.store.keyOf(field));\n }\n }\n\n protected updateEntityKey(field: NestedFieldConfig, key: string): void {\n const trimmed = key.trim();\n this.store.updateField(this.store.keyOf(field), { referencedEntityKey: trimmed || undefined });\n // Fire-and-forget on purpose: the edit has already landed, and the drift check is a\n // decoration on top of it. `void` says so, and `checkDriftForField` swallows its own\n // failures — a source config that cannot be fetched must not reject out of a keystroke\n // handler, where nothing would catch it.\n void this.checkDriftForField(field.id);\n }\n\n protected updateFieldId(field: NestedFieldConfig, fieldId: string): void {\n const trimmed = fieldId.trim();\n this.store.updateField(this.store.keyOf(field), { referencedFieldId: trimmed || undefined });\n void this.checkDriftForField(field.id);\n }\n\n protected async syncWithSource(field: NestedFieldConfig): Promise<void> {\n if (!field.referencedEntityKey || !field.referencedFieldId || !this.configSource) return;\n const sourceConfig = await this.configSource.getConfig(field.referencedEntityKey);\n if (!sourceConfig) return;\n\n const sourceField = this.findField(sourceConfig.tabs ?? [], field.referencedFieldId);\n if (sourceField) {\n this.store.syncReferencedField(this.store.keyOf(field), sourceField);\n }\n }\n\n /**\n * Both callers pass the id of the field they just edited. This used to ignore that\n * argument and read `store.selectedField()` instead, so whenever the edited field was not\n * the selected one it checked drift against the wrong field's source entity — or bailed\n * out entirely if nothing was selected.\n */\n private async checkDriftForField(fieldId: string): Promise<void> {\n const f = this.store.fields().find(field => field.id === fieldId);\n if (!f || !f.isReferenced || !f.referencedEntityKey || !f.referencedFieldId || !this.configSource) return;\n\n // The callers are keystroke handlers that cannot await this, so a rejection here has\n // nowhere to go but the console as an unhandled promise. `getConfig` is consumer code\n // reaching for a source entity that may not load; failing to *check* drift is not a\n // reason to interrupt the edit that was already applied.\n try {\n const sourceConfig = await this.configSource.getConfig(f.referencedEntityKey);\n if (sourceConfig) {\n this.store.checkDrift({ [f.referencedEntityKey]: sourceConfig });\n }\n } catch (err) {\n if (isDevMode()) {\n console.warn(\n `[ngx-dynamic-entity-builder] Could not load \"${f.referencedEntityKey}\" to check ` +\n `drift on \"${fieldId}\". The field's link is saved; the drift flag is stale.`,\n err,\n );\n }\n }\n }\n\n private findField(tabs: any[], id: string): NestedFieldConfig | undefined {\n for (const t of tabs) {\n for (const f of t.fields ?? []) {\n if (f.id === id) return f;\n if (f.children?.length) {\n const res = this.findFieldInList(f.children, id);\n if (res) return res;\n }\n }\n }\n return undefined;\n }\n\n private findFieldInList(fields: NestedFieldConfig[], id: string): NestedFieldConfig | undefined {\n for (const f of fields) {\n if (f.id === id) return f;\n if (f.children?.length) {\n const res = this.findFieldInList(f.children, id);\n if (res) return res;\n }\n }\n return undefined;\n }\n}\n","import { Component, computed, inject, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatDividerModule } from '@angular/material/divider';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatSelectModule } from '@angular/material/select';\nimport { MatSlideToggleModule } from '@angular/material/slide-toggle';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport type { DropdownOption, NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel, resolveOptionLabel, toRefToken } from '@dynamic-entity/core';\nimport { fieldPathOptions, withExistingOptions, type FieldPathOption } from '../field-path-options';\nimport { BuilderStore } from '../builder-store.service';\nimport { getFieldTypeMeta, type FieldTypeMeta } from '../field-catalog';\nimport { computeRuleDependencies, type RuleDependencyEdge } from '../rule-dependencies';\nimport { EntityReferenceConfigComponent } from './entity-reference-config.component';\nimport { FieldRulesListComponent } from './field-rules-list.component';\nimport { ReferencedFieldConfigComponent } from './referenced-field-config.component';\nimport { BuilderTextService } from '../builder-text';\n\n/**\n * FieldInspectorComponent — edits every property of the currently selected field.\n */\n@Component({\n selector: 'ngx-field-inspector',\n standalone: true,\n imports: [\n FormsModule,\n MatButtonModule,\n MatCheckboxModule,\n MatDividerModule,\n MatFormFieldModule,\n MatIconModule,\n MatInputModule,\n MatSelectModule,\n MatSlideToggleModule,\n MatTooltipModule,\n EntityReferenceConfigComponent,\n FieldRulesListComponent,\n ReferencedFieldConfigComponent,\n ],\n templateUrl: './field-inspector.component.html',\n styles: [\n `\n .deb-inspector {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n .deb-inspector__empty {\n color: var(--deb-muted, #6b7280);\n text-align: center;\n padding: 24px 8px;\n }\n .deb-full {\n width: 100%;\n }\n .deb-row > * {\n flex: 1;\n }\n /*\n * The type chip is a label, not a field.\n *\n * The rule above gave it an equal share of the identity row, so the chip took half the\n * inspector's width and squeezed the field id into a column narrow enough to wrap its\n * hint over three lines.\n */\n .deb-row > .deb-chip {\n flex: 0 0 auto;\n }\n .deb-row--split > * {\n flex: 0 0 auto;\n }\n .deb-toggles {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px 12px;\n }\n .deb-option-row {\n display: flex;\n gap: 6px;\n align-items: center;\n }\n .deb-pattern-box {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 8px;\n padding: 12px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n }\n .deb-pattern-status {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 600;\n }\n .deb-pattern-status--match {\n background: #dcfce7;\n color: #166534;\n }\n .deb-pattern-status--no-match {\n background: #fee2e2;\n color: #991b1b;\n }\n .deb-pattern-status--invalid {\n background: #fef3c7;\n color: #92400e;\n }\n .deb-pattern-status--idle,\n .deb-pattern-status--empty {\n background: #f1f5f9;\n color: #334155;\n }\n .deb-pattern-presets {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n align-items: center;\n }\n .deb-preset-btn {\n padding: 2px 8px;\n border-radius: 4px;\n border: 1px solid #cbd5e1;\n background: #ffffff;\n font-size: 11px;\n color: #334155;\n cursor: pointer;\n transition: background 0.1s ease;\n }\n .deb-preset-btn:hover {\n background: #e2e8f0;\n }\n .deb-dep-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-top: 4px;\n margin-bottom: 12px;\n }\n .deb-dep-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 6px 10px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 6px;\n }\n .deb-dep-info {\n display: flex;\n flex-direction: column;\n min-width: 0;\n }\n .deb-dep-name {\n font-size: 12px;\n font-weight: 600;\n color: #0f172a;\n }\n .deb-dep-detail {\n font-size: 11px;\n color: #64748b;\n }\n `,\n ],\n})\nexport class FieldInspectorComponent {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n\n protected readonly field = this.store.selectedField;\n protected readonly meta = computed<FieldTypeMeta | undefined>(() => {\n const f = this.field();\n return f ? getFieldTypeMeta(f.type) : undefined;\n });\n\n /**\n * The offered widths, as fractions of the 12-column row.\n *\n * Five steps rather than all twelve: a free 1–12 spinner is a layout system, and what an\n * author actually wants is \"these two side by side\" or \"this one across the row\". The\n * fractions that divide twelve evenly cover that, and anything finer stays authorable in\n * the JSON for the rare case that needs it.\n */\n protected readonly spanChoices = [\n { span: 3, textKey: 'widthQuarter' },\n { span: 4, textKey: 'widthThird' },\n { span: 6, textKey: 'widthHalf' },\n { span: 8, textKey: 'widthTwoThirds' },\n { span: 12, textKey: 'widthFull' },\n ] as const;\n\n protected lang(): string {\n return this.store.activeLanguage();\n }\n\n /**\n * How many validators this field actually has, for the section's badge.\n *\n * `false` and an empty `custom: []` are both \"not set\" written the long way — a toggle\n * switched off leaves the key behind — so neither counts. `0` does: `minLength: 0` is a\n * value somebody typed.\n */\n protected validatorCount(field: NestedFieldConfig): number {\n return Object.values(field.validators ?? {}).filter(value => {\n if (value === undefined || value === null || value === false) return false;\n return Array.isArray(value) ? value.length > 0 : true;\n }).length;\n }\n\n /**\n * How many display flags are set away from their default.\n *\n * `visibility` counts when it is *false* and the rest when they are true, because the badge\n * is meant to say \"something here is not the default\" — counting `visibility: true` would\n * put a 1 on every field in the config and tell the author nothing.\n */\n protected displayFlagCount(field: NestedFieldConfig): number {\n const flags = [\n field.visibility === false,\n field.table?.visible === true,\n field.readonly === true,\n field.disabled === true,\n field.maskData === true,\n field.criticalField === true,\n field.showOnMinimize === true,\n ];\n return flags.filter(Boolean).length;\n }\n\n protected toNum(value: unknown): number | null {\n if (value === '' || value === null || value === undefined) return null;\n const n = Number(value);\n return Number.isNaN(n) ? null : n;\n }\n\n protected labelValue(field: NestedFieldConfig): string {\n return resolveLabel(field.label, this.lang());\n }\n\n protected placeholderValue(field: NestedFieldConfig): string {\n return resolveLabel(field.placeholder, this.lang());\n }\n\n protected hintValue(field: NestedFieldConfig): string {\n return resolveLabel(field.hint, this.lang());\n }\n\n protected optionLabel(option: DropdownOption): string {\n return resolveOptionLabel(option, this.lang());\n }\n\n /**\n * Every tab a field can live on, sub-tabs included.\n *\n * `moveFieldToTab` existed on the store with nothing calling it, so a field authored on the\n * wrong tab had to be deleted and rebuilt — losing its validators, options and every rule\n * aimed at it.\n */\n protected readonly tabOptions = computed<{ id: string; label: string }[]>(() =>\n this.store\n .fieldGroups()\n .map(group => ({ id: group.tabId, label: resolveLabel(group.label, this.lang()) || group.tabId }))\n .concat(\n this.store\n .tabs()\n .flatMap(tab => [tab, ...(tab.children ?? [])])\n .map(tab => ({ id: tab.id, label: resolveLabel(tab.label, this.lang()) || tab.id })),\n )\n .filter((tab, i, all) => all.findIndex(t => t.id === tab.id) === i),\n );\n\n /**\n * The tab the selected field currently sits on.\n *\n * Looked up by identity rather than parsed out of the path: the scope of\n * `incident.incidentDetails.incidentTime` is two segments and the field belongs to the\n * *last* of them, while a field inside a group has the group id in that position and\n * belongs to no tab of that name at all.\n */\n protected currentTabId(field: NestedFieldConfig): string {\n return this.store.fieldGroups().find(group => group.fields.includes(field))?.tabId ?? '';\n }\n\n protected moveToTab(field: NestedFieldConfig, tabId: string): void {\n if (tabId && tabId !== this.currentTabId(field)) this.store.moveFieldToTab(this.store.keyOf(field), tabId);\n }\n\n /**\n * Fields offered wherever this inspector names one — the `showWhen` key and both ends of a\n * `patchOnTrue` mapping. All three were free text, which is the one way left to write a\n * reference that names two fields at once.\n */\n protected readonly fieldOptions = computed<FieldPathOption[]>(() =>\n fieldPathOptions(this.store.config(), this.store.activeLanguage()),\n );\n\n /** Options plus whatever is already selected, so an unknown reference is never dropped. */\n protected optionsWith(...current: (string | undefined)[]): FieldPathOption[] {\n return withExistingOptions(this.fieldOptions(), current);\n }\n\n // ─── showWhen editing ───────────────────────────────────────────────────────\n\n protected showWhenEntries(field: NestedFieldConfig): { key: string; display: string }[] {\n return Object.entries(field.showWhen ?? {}).map(([key, value]) => ({\n key,\n display: this.stringifyShowWhen(value),\n }));\n }\n\n /**\n * Seeds a new condition with the first field not already watched.\n *\n * It used to seed the literal string `field`, which is not a field id at all — so a new\n * condition started out referencing nothing and silently hid the field until it was edited.\n */\n protected addShowWhen(field: NestedFieldConfig): void {\n const next = { ...(field.showWhen ?? {}) };\n const self = toRefToken(field.refererField ?? field.id);\n const candidate = this.fieldOptions().find(o => o.value !== self && !(o.value in next));\n\n // Falls back to the old placeholder only when there is genuinely nothing else to watch —\n // a config with one field. Otherwise a new condition starts on a real field instead of\n // the literal string `field`, which is not an id at all and hid the field until edited.\n let key = candidate?.value ?? 'field';\n let n = 1;\n while (key in next) key = `field_${++n}`;\n next[key] = true;\n this.store.setShowWhen(this.store.keyOf(field), next);\n }\n\n protected renameShowWhen(field: NestedFieldConfig, oldKey: string, newKey: string): void {\n const trimmed = newKey.trim();\n if (!trimmed || trimmed === oldKey) return;\n const current = field.showWhen ?? {};\n if (trimmed in current) return;\n const next: Record<string, unknown> = {};\n // Rebuild in order so the row does not jump while the user is typing.\n for (const [k, v] of Object.entries(current)) next[k === oldKey ? trimmed : k] = v;\n this.store.setShowWhen(this.store.keyOf(field), next);\n }\n\n protected setShowWhenValue(field: NestedFieldConfig, key: string, raw: string): void {\n this.store.setShowWhen(this.store.keyOf(field), { ...(field.showWhen ?? {}), [key]: this.parseShowWhen(raw) });\n }\n\n protected removeShowWhen(field: NestedFieldConfig, key: string): void {\n const next = { ...(field.showWhen ?? {}) };\n delete next[key];\n this.store.setShowWhen(this.store.keyOf(field), next);\n }\n\n /**\n * `showWhen` compares with `!==`, so the authored type has to survive the round trip:\n * \"true\"/\"false\" become booleans and numeric text becomes a number.\n */\n private parseShowWhen(raw: string): unknown {\n const trimmed = raw.trim();\n if (trimmed === 'true') return true;\n if (trimmed === 'false') return false;\n if (trimmed === 'null') return null;\n if (trimmed !== '' && !Number.isNaN(Number(trimmed))) return Number(trimmed);\n return raw;\n }\n\n private stringifyShowWhen(value: unknown): string {\n if (value === null) return 'null';\n if (typeof value === 'object') return JSON.stringify(value);\n return String(value);\n }\n\n // ─── Pattern Playground ────────────────────────────────────────────────────\n\n protected readonly testSample = signal<string>('');\n\n protected readonly regexEvaluation = computed<{\n status: 'empty' | 'idle' | 'match' | 'no-match' | 'invalid';\n error?: string;\n }>(() => {\n const f = this.field();\n const pattern = f?.validators?.pattern?.trim();\n if (!pattern) return { status: 'empty' };\n\n let regex: RegExp;\n try {\n regex = new RegExp(pattern);\n } catch (e) {\n return { status: 'invalid', error: (e as Error).message };\n }\n\n const sample = this.testSample();\n if (!sample) return { status: 'idle' };\n\n return { status: regex.test(sample) ? 'match' : 'no-match' };\n });\n\n protected readonly patternPresets = [\n { label: 'Alpha', pattern: '^[a-zA-Z]+$' },\n { label: 'Alphanumeric', pattern: '^[a-zA-Z0-9]+$' },\n { label: 'Digits', pattern: '^\\\\d+$' },\n { label: 'Postal Code', pattern: '^\\\\d{5}(-\\\\d{4})?$' },\n { label: 'Phone', pattern: '^\\\\+?[1-9]\\\\d{1,14}$' },\n { label: 'Slug', pattern: '^[a-z0-9]+(?:-[a-z0-9]+)*$' },\n ];\n\n protected supportsPattern(type: string): boolean {\n return ['text', 'textarea', 'markdown', 'email', 'password'].includes(type);\n }\n\n protected applyPreset(field: NestedFieldConfig, pattern: string): void {\n this.store.setPatternValidator(this.store.keyOf(field), pattern);\n }\n\n // ─── Dependencies ──────────────────────────────────────────────────────────\n\n protected readonly allDependencies = computed(() =>\n computeRuleDependencies(this.store.config(), this.store.rules(), this.lang()),\n );\n\n protected readonly incomingDependencies = computed<RuleDependencyEdge[]>(() => {\n const f = this.field();\n if (!f) return [];\n const key = this.store.keyOf(f);\n const id = f.id;\n return this.allDependencies().edges.filter(\n e => e.targetKey === key || e.targetKey === id,\n );\n });\n\n protected readonly outgoingDependencies = computed<RuleDependencyEdge[]>(() => {\n const f = this.field();\n if (!f) return [];\n const key = this.store.keyOf(f);\n const id = f.id;\n return this.allDependencies().edges.filter(\n e => e.sourceKey === key || e.sourceKey === id,\n );\n });\n\n protected selectField(key: string): void {\n if (key) this.store.selectField(key);\n }\n}\n","@if (field(); as f) {\n <!--\n The inspector, in collapsible sections.\n\n It used to be one flat scroll of fifteen divider-separated blocks, so renaming a field\n meant scrolling past every advanced setting a field has, and finding the rules list meant\n scrolling past all of them.\n\n All inspector sections start expanded by default so authors have immediate access to\n validation, automation, visibility conditions, rules, dependencies, and reference settings\n without needing to manually unfold each section. Sections can still be collapsed as desired.\n\n `<details>` rather than mat-expansion-panel: the inspector already sits inside a card in a\n scrolling rail, and a third level of Material elevation inside that read as noise.\n -->\n <div class=\"deb-inspector\">\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionBasics') }}\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n <!-- Identity -->\n <div class=\"deb-row\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('fieldId') }}</mat-label>\n <input matInput data-testid=\"field-id\" [value]=\"f.id\" disabled />\n @if (store.hasManualId(f.id)) {\n <mat-hint>{{ ui.text('fieldIdFixedHint') }}</mat-hint>\n } @else {\n <mat-hint>{{ ui.text('fieldIdDerivedHint') }}</mat-hint>\n }\n </mat-form-field>\n <span class=\"deb-chip\">{{ meta()?.label || f.type }}</span>\n </div>\n\n @if (tabOptions().length > 1) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('tab') }}</mat-label>\n <mat-select data-testid=\"field-tab\" [ngModel]=\"currentTabId(f)\" (ngModelChange)=\"moveToTab(f, $event)\">\n @for (tab of tabOptions(); track tab.id) {\n <mat-option [value]=\"tab.id\">{{ tab.label }}</mat-option>\n }\n </mat-select>\n <mat-hint>{{ ui.text('tabMoveHint') }}</mat-hint>\n </mat-form-field>\n }\n\n <!-- Localised text (active language) -->\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('labelInLanguage', { language: lang() }) }}</mat-label>\n <input\n matInput\n data-testid=\"field-label\"\n [ngModel]=\"labelValue(f)\"\n (ngModelChange)=\"store.setFieldLabel(store.keyOf(f), lang(), $event)\"\n />\n </mat-form-field>\n\n @if (meta()?.supportsPlaceholder) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('placeholderInLanguage', { language: lang() }) }}</mat-label>\n <input\n matInput\n [ngModel]=\"placeholderValue(f)\"\n (ngModelChange)=\"store.setFieldPlaceholder(store.keyOf(f), lang(), $event)\"\n />\n </mat-form-field>\n }\n\n <!--\n Help text, offered on every field type — including the ones with no placeholder,\n which are exactly the ones most likely to need explaining. Its hint says what it is\n *for*, because the box above it is the one authors reach for by habit and a\n placeholder is gone the moment somebody types.\n -->\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('hintInLanguage', { language: lang() }) }}</mat-label>\n <input\n matInput\n data-testid=\"field-hint\"\n [ngModel]=\"hintValue(f)\"\n (ngModelChange)=\"store.setFieldHint(store.keyOf(f), lang(), $event)\"\n />\n <mat-hint>{{ ui.text('hintHint') }}</mat-hint>\n </mat-form-field>\n\n @if (meta()?.supportsDefaultValue) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('defaultValue') }}</mat-label>\n <input\n matInput\n [ngModel]=\"f.defaultValue ?? ''\"\n (ngModelChange)=\"store.updateField(store.keyOf(f), { defaultValue: $event })\"\n />\n </mat-form-field>\n }\n </div>\n </details>\n\n <!--\n Width.\n\n `colSpan` has been in the schema and honoured by the renderer since the 12-column grid\n existed, and the builder had no control for it — so every form authored here came out a\n single-column ladder, and the only way to put two fields on one row was to hand-edit the\n JSON. This is that control.\n -->\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionLayout') }}\n <span class=\"deb-inspector__count\" data-testid=\"layout-count\">{{ f.colSpan ?? 12 }}/12</span>\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n <div class=\"deb-span-picker\" role=\"group\" [attr.aria-label]=\"ui.text('width')\">\n @for (choice of spanChoices; track choice.span) {\n <button\n type=\"button\"\n class=\"deb-span-picker__btn\"\n [class.deb-span-picker__btn--active]=\"(f.colSpan ?? 12) === choice.span\"\n [attr.data-testid]=\"'field-span-' + choice.span\"\n [attr.aria-pressed]=\"(f.colSpan ?? 12) === choice.span\"\n [matTooltip]=\"ui.text('widthOf', { span: choice.span })\"\n (click)=\"store.updateField(store.keyOf(f), { colSpan: choice.span })\"\n >\n {{ ui.text(choice.textKey) }}\n </button>\n }\n </div>\n <p class=\"deb-hint\">{{ ui.text('widthHint') }}</p>\n </div>\n </details>\n\n <!-- Validators -->\n <!-- Validators -->\n @if (meta(); as m) {\n @if (m.flagValidators.length || m.paramValidators.length || supportsPattern(f.type) || f.validators?.pattern) {\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionValidation') }}\n @if (validatorCount(f); as count) {\n <span class=\"deb-inspector__count\" data-testid=\"validation-count\">{{ count }}</span>\n }\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n @if (m.flagValidators.length) {\n <div class=\"deb-flags-row\">\n @for (v of m.flagValidators; track v) {\n <mat-checkbox\n color=\"primary\"\n [ngModel]=\"store.hasFlagValidator(f, v)\"\n (ngModelChange)=\"store.toggleFlagValidator(store.keyOf(f), v, $event)\"\n >{{ v }}</mat-checkbox\n >\n }\n </div>\n }\n @if (m.paramValidators.length) {\n <div class=\"deb-param-validators-grid\">\n @for (v of m.paramValidators; track v) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ v }}</mat-label>\n <input\n matInput\n type=\"number\"\n [ngModel]=\"store.getParamValidator(f, v)\"\n (ngModelChange)=\"store.setParamValidator(store.keyOf(f), v, toNum($event))\"\n />\n </mat-form-field>\n }\n </div>\n }\n\n @if (supportsPattern(f.type) || f.validators?.pattern) {\n <div class=\"deb-pattern-box\" data-testid=\"pattern-playground\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('pattern') }}</mat-label>\n <input\n matInput\n data-testid=\"field-pattern-input\"\n [ngModel]=\"f.validators?.pattern ?? ''\"\n (ngModelChange)=\"store.setPatternValidator(store.keyOf(f), $event)\"\n />\n <mat-hint>{{ ui.text('patternHint') }}</mat-hint>\n </mat-form-field>\n\n <div class=\"deb-pattern-presets\">\n <span class=\"deb-section-title\">{{ ui.text('quickPresets') }}:</span>\n @for (preset of patternPresets; track preset.label) {\n <button\n type=\"button\"\n class=\"deb-preset-btn\"\n [attr.data-testid]=\"'preset-' + preset.label.toLowerCase()\"\n (click)=\"applyPreset(f, preset.pattern)\"\n >\n {{ preset.label }}\n </button>\n }\n </div>\n\n <div class=\"deb-row deb-row--split\">\n <span class=\"deb-section-title\">{{ ui.text('testPattern') }}</span>\n <div\n class=\"deb-pattern-status\"\n [class.deb-pattern-status--match]=\"regexEvaluation().status === 'match'\"\n [class.deb-pattern-status--no-match]=\"regexEvaluation().status === 'no-match'\"\n [class.deb-pattern-status--invalid]=\"regexEvaluation().status === 'invalid'\"\n [class.deb-pattern-status--idle]=\"regexEvaluation().status === 'idle'\"\n [class.deb-pattern-status--empty]=\"regexEvaluation().status === 'empty'\"\n data-testid=\"regex-test-status\"\n >\n @switch (regexEvaluation().status) {\n @case ('match') {\n <mat-icon>check_circle</mat-icon> {{ ui.text('patternMatch') }}\n }\n @case ('no-match') {\n <mat-icon>cancel</mat-icon> {{ ui.text('patternNoMatch') }}\n }\n @case ('invalid') {\n <mat-icon>error</mat-icon> {{ ui.text('patternInvalid') }}\n }\n @case ('idle') {\n <mat-icon>edit_note</mat-icon> {{ ui.text('testPatternPlaceholder') }}\n }\n @case ('empty') {\n <mat-icon>info</mat-icon> {{ ui.text('patternEmptyPrompt') }}\n }\n }\n </div>\n </div>\n\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <input\n matInput\n data-testid=\"regex-test-input\"\n [placeholder]=\"ui.text('testPatternPlaceholder')\"\n [ngModel]=\"testSample()\"\n (ngModelChange)=\"testSample.set($event)\"\n />\n </mat-form-field>\n </div>\n }\n </div>\n </details>\n }\n }\n\n <!-- Options (dropdown / radio / multiSelect) -->\n @if (meta()?.hasOptions) {\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionOptions') }}\n @if ((f.options ?? []).length; as count) {\n <span class=\"deb-inspector__count\" data-testid=\"options-count\">{{ count }}</span>\n }\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n <span class=\"deb-section-title\">{{ ui.text('dataSource') }}</span>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('optionsComeFrom') }}</mat-label>\n <mat-select\n data-testid=\"data-source\"\n [ngModel]=\"store.fieldDataSource(f)\"\n (ngModelChange)=\"store.setFieldDataSource(store.keyOf(f), $event)\"\n >\n <mat-option value=\"none\">{{ ui.text('optionsSourceNone') }}</mat-option>\n <mat-option value=\"manual\">{{ ui.text('optionsSourceInline') }}</mat-option>\n <mat-option value=\"lookup\">{{ ui.text('optionsSourceList') }}</mat-option>\n </mat-select>\n </mat-form-field>\n\n <!-- Named lookup list -->\n @if (store.fieldDataSource(f) === 'lookup') {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('listName') }}</mat-label>\n <input\n matInput\n data-testid=\"list-name\"\n [ngModel]=\"f.listName ?? ''\"\n (ngModelChange)=\"store.setListName(store.keyOf(f), $event)\"\n />\n </mat-form-field>\n <p class=\"deb-hint\">\n {{ ui.text('listNameHint') }}\n </p>\n }\n\n <!-- Inline options -->\n @if (store.fieldDataSource(f) !== 'lookup') {\n <div class=\"deb-row deb-row--split\">\n <span class=\"deb-section-title\">{{ ui.text('options') }}</span>\n <span class=\"deb-row__actions\">\n @if (store.hasUnkeyedOptions()) {\n <button\n mat-stroked-button\n type=\"button\"\n data-testid=\"assign-option-keys\"\n (click)=\"store.assignOptionKeys()\"\n [matTooltip]=\"ui.text('optionKeyHint')\"\n >\n <mat-icon>key</mat-icon> {{ ui.text('assignOptionKeys') }}\n </button>\n }\n <button\n mat-stroked-button\n type=\"button\"\n data-testid=\"add-option\"\n (click)=\"store.addOption(store.keyOf(f))\"\n >\n <mat-icon>add</mat-icon> {{ ui.text('option') }}\n </button>\n </span>\n </div>\n @for (opt of f.options ?? []; track $index) {\n <div class=\"deb-option-row\" data-testid=\"option-row\">\n <!-- One input: the displayed text is the stored value. -->\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('optionInLanguage', { language: lang() }) }}</mat-label>\n <input\n matInput\n [attr.data-testid]=\"'option-' + $index\"\n [ngModel]=\"optionLabel(opt)\"\n (ngModelChange)=\"store.setOptionLabel(store.keyOf(f), $index, lang(), $event)\"\n />\n </mat-form-field>\n <!--\n Not a control. A key is the option's identity and every record already\n holding it matches on it, so a text box here — even a read-only one —\n would be a data migration disguised as a field. It is shown because an\n author needs to be able to read it, and for no other reason.\n -->\n @if (store.optionKey(opt); as key) {\n <code\n class=\"deb-option-key\"\n [attr.data-testid]=\"'option-key-' + $index\"\n [attr.aria-label]=\"ui.text('optionKey')\"\n [matTooltip]=\"ui.text('optionKeyHint')\"\n >{{ key }}</code\n >\n }\n <button\n mat-icon-button\n type=\"button\"\n color=\"warn\"\n (click)=\"store.removeOption(store.keyOf(f), $index)\"\n [matTooltip]=\"ui.text('removeOption')\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n }\n @if (!(f.options ?? []).length) {\n <p class=\"deb-hint\">{{ ui.text('noOptionsYet') }}</p>\n }\n }\n </div>\n </details>\n }\n\n <!-- Flags -->\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionDisplay') }}\n @if (displayFlagCount(f); as count) {\n <span class=\"deb-inspector__count\" data-testid=\"display-count\">{{ count }}</span>\n }\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n <div class=\"deb-toggles\" role=\"group\" [attr.aria-label]=\"ui.text('display')\">\n <mat-slide-toggle\n color=\"primary\"\n [ngModel]=\"f.visibility ?? true\"\n (ngModelChange)=\"store.updateField(store.keyOf(f), { visibility: $event })\"\n >{{ ui.text('visible') }}</mat-slide-toggle\n >\n <mat-slide-toggle\n color=\"primary\"\n [ngModel]=\"f.table?.visible ?? false\"\n (ngModelChange)=\"store.updateField(store.keyOf(f), { table: { visible: $event } })\"\n >{{ ui.text('tableColumn') }}</mat-slide-toggle\n >\n <mat-slide-toggle\n color=\"primary\"\n [ngModel]=\"f.readonly ?? false\"\n (ngModelChange)=\"store.updateField(store.keyOf(f), { readonly: $event })\"\n >{{ ui.text('readOnly') }}</mat-slide-toggle\n >\n <mat-slide-toggle\n color=\"primary\"\n [ngModel]=\"f.disabled ?? false\"\n (ngModelChange)=\"store.updateField(store.keyOf(f), { disabled: $event })\"\n >{{ ui.text('disabled') }}</mat-slide-toggle\n >\n <mat-slide-toggle\n color=\"primary\"\n [ngModel]=\"f.maskData ?? false\"\n (ngModelChange)=\"store.updateField(store.keyOf(f), { maskData: $event })\"\n >{{ ui.text('maskData') }}</mat-slide-toggle\n >\n <mat-slide-toggle\n color=\"primary\"\n data-testid=\"toggle-critical\"\n [ngModel]=\"f.criticalField ?? false\"\n (ngModelChange)=\"store.updateField(store.keyOf(f), { criticalField: $event })\"\n [matTooltip]=\"ui.text('criticalFieldTooltip')\"\n >{{ ui.text('criticalField') }}</mat-slide-toggle\n >\n <mat-slide-toggle\n color=\"primary\"\n [ngModel]=\"f.showOnMinimize ?? false\"\n (ngModelChange)=\"store.updateField(store.keyOf(f), { showOnMinimize: $event })\"\n [matTooltip]=\"ui.text('showInSummaryTooltip')\"\n >{{ ui.text('showInSummary') }}</mat-slide-toggle\n >\n </div>\n </div>\n </details>\n\n <!-- Conditional visibility (static showWhen) -->\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionVisibility') }}\n @if (showWhenEntries(f).length; as count) {\n <span class=\"deb-inspector__count\" data-testid=\"visibility-count\">{{ count }}</span>\n }\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n <div class=\"deb-row deb-row--split\">\n <span class=\"deb-section-title\">{{ ui.text('showWhen') }}</span>\n <button mat-stroked-button type=\"button\" data-testid=\"add-show-when\" (click)=\"addShowWhen(f)\">\n <mat-icon>add</mat-icon> {{ ui.text('condition') }}\n </button>\n </div>\n @for (entry of showWhenEntries(f); track entry.key) {\n <div class=\"deb-option-row\" data-testid=\"option-row\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('watchedField') }}</mat-label>\n <mat-select\n data-testid=\"show-when-field\"\n [ngModel]=\"entry.key\"\n (ngModelChange)=\"renameShowWhen(f, entry.key, $event)\"\n >\n @for (option of optionsWith(entry.key); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }} <span class=\"deb-path-hint\">{{ option.path }}</span>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('equals') }}</mat-label>\n <input matInput [ngModel]=\"entry.display\" (ngModelChange)=\"setShowWhenValue(f, entry.key, $event)\" />\n </mat-form-field>\n <button\n mat-icon-button\n type=\"button\"\n color=\"warn\"\n [matTooltip]=\"ui.text('removeCondition')\"\n (click)=\"removeShowWhen(f, entry.key)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n }\n @if (!showWhenEntries(f).length) {\n <p class=\"deb-hint\">{{ ui.text('alwaysVisibleHint') }}</p>\n }\n </div>\n </details>\n\n <!-- Entity reference, cascade, autoPatch, and patchOnTrue -->\n @if (meta()?.isEntityRef || f.type === 'boolean' || f.type === 'checkbox') {\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionAutomation') }}\n @if ((f.patchOnTrue ?? []).length; as count) {\n <span class=\"deb-inspector__count\" data-testid=\"automation-count\">{{ count }}</span>\n }\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n @if (meta()?.isEntityRef) {\n <ngx-entity-reference-config />\n }\n\n <!-- patchOnTrue (boolean/checkbox only) -->\n @if (f.type === 'boolean' || f.type === 'checkbox') {\n <div class=\"deb-row deb-row--split\">\n <span class=\"deb-section-title\">{{ ui.text('copyOnTrue') }}</span>\n <button\n mat-stroked-button\n type=\"button\"\n data-testid=\"add-patch-on-true\"\n (click)=\"store.addPatchOnTrueMapping(store.keyOf(f))\"\n >\n <mat-icon>add</mat-icon> {{ ui.text('mapping') }}\n </button>\n </div>\n @for (mapping of f.patchOnTrue ?? []; track $index) {\n <div class=\"deb-option-row\" data-testid=\"option-row\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('fromField') }}</mat-label>\n <mat-select\n data-testid=\"patch-on-true-from\"\n [ngModel]=\"mapping.from\"\n (ngModelChange)=\"store.updatePatchOnTrueMapping(store.keyOf(f), $index, { from: $event })\"\n >\n @for (option of optionsWith(mapping.from); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }} <span class=\"deb-path-hint\">{{ option.path }}</span>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('toField') }}</mat-label>\n <mat-select\n data-testid=\"patch-on-true-to\"\n [ngModel]=\"mapping.to\"\n (ngModelChange)=\"store.updatePatchOnTrueMapping(store.keyOf(f), $index, { to: $event })\"\n >\n @for (option of optionsWith(mapping.to); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }} <span class=\"deb-path-hint\">{{ option.path }}</span>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <button\n mat-icon-button\n type=\"button\"\n color=\"warn\"\n [matTooltip]=\"ui.text('removeMapping')\"\n (click)=\"store.removePatchOnTrueMapping(store.keyOf(f), $index)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n }\n @if (!(f.patchOnTrue ?? []).length) {\n <p class=\"deb-hint\">{{ ui.text('copyOnTrueHint') }}</p>\n }\n }\n </div>\n </details>\n }\n\n <!-- Rules attached to this field -->\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionRules') }}\n @if (store.rulesForSelectedField().length; as count) {\n <span class=\"deb-inspector__count\" data-testid=\"rules-count\">{{ count }}</span>\n }\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n <ngx-field-rules-list />\n </div>\n </details>\n\n <!-- Field Dependencies Visualizer -->\n <details\n class=\"deb-inspector__section\"\n open\n data-testid=\"section-dependencies\"\n >\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionDependencies') }}\n @if (incomingDependencies().length + outgoingDependencies().length; as count) {\n <span class=\"deb-inspector__count\" data-testid=\"dependencies-count\">{{ count }}</span>\n }\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n @if (incomingDependencies().length) {\n <span class=\"deb-section-title\">{{ ui.text('dependsOn') }} ({{ incomingDependencies().length }})</span>\n <div class=\"deb-dep-list\" data-testid=\"incoming-dependencies\">\n @for (dep of incomingDependencies(); track dep.id) {\n <div class=\"deb-dep-row\">\n <div class=\"deb-dep-info\">\n <span class=\"deb-dep-name\">{{ dep.sourceLabel }}</span>\n <span class=\"deb-dep-detail\">{{ dep.description }}</span>\n </div>\n <button\n mat-stroked-button\n type=\"button\"\n [matTooltip]=\"ui.text('jumpToField', { field: dep.sourceLabel })\"\n (click)=\"selectField(dep.sourceKey)\"\n >\n <mat-icon>arrow_back</mat-icon> {{ ui.text('jumpToField', { field: dep.sourceLabel }) }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (outgoingDependencies().length) {\n <span class=\"deb-section-title\">{{ ui.text('affects') }} ({{ outgoingDependencies().length }})</span>\n <div class=\"deb-dep-list\" data-testid=\"outgoing-dependencies\">\n @for (dep of outgoingDependencies(); track dep.id) {\n <div class=\"deb-dep-row\">\n <div class=\"deb-dep-info\">\n <span class=\"deb-dep-name\">{{ dep.targetLabel }}</span>\n <span class=\"deb-dep-detail\">{{ dep.description }}</span>\n </div>\n <button\n mat-stroked-button\n type=\"button\"\n [matTooltip]=\"ui.text('jumpToField', { field: dep.targetLabel })\"\n (click)=\"selectField(dep.targetKey)\"\n >\n <mat-icon>arrow_forward</mat-icon> {{ ui.text('jumpToField', { field: dep.targetLabel }) }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (!incomingDependencies().length && !outgoingDependencies().length) {\n <p class=\"deb-hint\" data-testid=\"no-field-dependencies\">{{ ui.text('noDependencies') }}</p>\n }\n </div>\n </details>\n\n <!-- Cross-entity field reference & drift management -->\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionReference') }}\n @if (f.isReferenced) {\n <span class=\"deb-inspector__count\" data-testid=\"reference-count\">{{ f.referencedEntityKey }}</span>\n }\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n <ngx-referenced-field-config />\n </div>\n </details>\n </div>\n} @else {\n <div class=\"deb-inspector__empty\">\n <mat-icon>touch_app</mat-icon>\n <p>{{ ui.text('inspectorEmpty') }}</p>\n </div>\n}\n","import { ChangeDetectionStrategy, Component, EventEmitter, Output, computed, inject, signal } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport type { RichFieldType } from '@dynamic-entity/core';\nimport { FIELD_TYPE_CATALOG, type FieldTypeMeta } from '../field-catalog';\nimport { BuilderTextService } from '../builder-text';\n\n/**\n * Which drawer of the palette a field type belongs in.\n *\n * Kept here rather than on `FieldTypeMeta` in core: the catalogue is a data model shared with\n * the renderer, and how a picker arranges twenty-two buttons is a decision about this panel.\n * A type absent from the map — a consumer's custom type, or one added to core later — falls\n * into `other`, so the palette degrades to \"listed, just not filed\" rather than dropping it.\n */\nconst PALETTE_GROUPS = ['basic', 'choice', 'datetime', 'rich', 'structure', 'other'] as const;\ntype PaletteGroup = (typeof PALETTE_GROUPS)[number];\n\nconst GROUP_OF: Readonly<Record<string, PaletteGroup>> = {\n text: 'basic',\n textarea: 'basic',\n number: 'basic',\n currency: 'basic',\n email: 'basic',\n password: 'basic',\n\n dropdown: 'choice',\n radio: 'choice',\n multiSelect: 'choice',\n checkbox: 'choice',\n boolean: 'choice',\n 'entity-ref': 'choice',\n\n date: 'datetime',\n datetime: 'datetime',\n time: 'datetime',\n monthYear: 'datetime',\n\n markdown: 'rich',\n image: 'rich',\n file: 'rich',\n\n group: 'structure',\n array: 'structure',\n};\n\n/** The heading text key for each group, so the labels translate with the rest of the chrome. */\nconst GROUP_TEXT_KEY = {\n basic: 'paletteGroupBasic',\n choice: 'paletteGroupChoice',\n datetime: 'paletteGroupDateTime',\n rich: 'paletteGroupRich',\n structure: 'paletteGroupStructure',\n other: 'paletteGroupOther',\n} as const;\n\ninterface PaletteSection {\n group: PaletteGroup;\n heading: string;\n items: FieldTypeMeta[];\n}\n\n/**\n * FieldPaletteComponent — the list of buildable field types.\n *\n * Two things changed the day this stopped being a flat grid of twenty-two buttons. The labels\n * were clipped mid-word — \"Boolean Toggl\", \"Entity Referen\", \"File Attachmen\" — because the\n * grid forced two equal columns and the button refused to wrap, so a third of the palette\n * could not be read. And with no order to them, finding \"Month & Year\" meant scanning the\n * whole list: the grouping and the filter are what make a palette this size navigable.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-field-palette',\n standalone: true,\n imports: [MatButtonModule, MatIconModule, MatTooltipModule],\n template: `\n <div class=\"deb-palette\">\n <div class=\"deb-palette__search\">\n <mat-icon aria-hidden=\"true\">search</mat-icon>\n <input\n type=\"search\"\n data-testid=\"palette-search\"\n [value]=\"query()\"\n (input)=\"query.set($any($event.target).value)\"\n [attr.placeholder]=\"ui.text('paletteSearchPlaceholder')\"\n [attr.aria-label]=\"ui.text('paletteSearchLabel')\"\n />\n @if (query()) {\n <button\n type=\"button\"\n class=\"deb-palette__clear\"\n data-testid=\"palette-search-clear\"\n [attr.aria-label]=\"ui.text('paletteSearchClear')\"\n (click)=\"query.set('')\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n </div>\n\n @for (section of sections(); track section.group) {\n <div class=\"deb-palette__section\">\n <span class=\"deb-section-title\">{{ section.heading }}</span>\n <div class=\"deb-palette__grid\">\n @for (meta of section.items; track meta.type) {\n <button\n mat-stroked-button\n type=\"button\"\n class=\"deb-palette__item\"\n [attr.data-testid]=\"'palette-' + meta.type\"\n [matTooltip]=\"meta.description\"\n (click)=\"pick.emit(meta.type)\"\n >\n <mat-icon>{{ meta.icon }}</mat-icon>\n <span>{{ meta.label }}</span>\n </button>\n }\n </div>\n </div>\n } @empty {\n <p class=\"deb-hint\" data-testid=\"palette-no-match\">{{ ui.text('paletteNoMatch', { query: query() }) }}</p>\n }\n </div>\n `,\n styles: [\n `\n .deb-palette {\n display: flex;\n flex-direction: column;\n gap: 14px;\n }\n\n /*\n * A plain input rather than a mat-form-field: this sits inside a card that is already a\n * stack of outlined Material fields, and giving the filter the same chrome made it read\n * as one more property to fill in rather than a control over the list below it.\n */\n .deb-palette__search {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 0 10px;\n height: 36px;\n border: 1px solid var(--deb-border, #e2e8f0);\n border-radius: 8px;\n background: #f8fafc;\n }\n .deb-palette__search:focus-within {\n border-color: var(--deb-accent, #6366f1);\n background: #ffffff;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.16);\n }\n .deb-palette__search mat-icon {\n font-size: 17px;\n width: 17px;\n height: 17px;\n color: var(--deb-muted, #64748b);\n flex: none;\n }\n .deb-palette__search input {\n flex: 1;\n min-width: 0;\n border: 0;\n outline: 0;\n background: transparent;\n font: inherit;\n font-size: 13px;\n color: inherit;\n }\n /* The platform's own clear affordance, replaced by one that matches the rest. */\n .deb-palette__search input::-webkit-search-cancel-button {\n display: none;\n }\n .deb-palette__clear {\n appearance: none;\n border: 0;\n background: none;\n padding: 0;\n cursor: pointer;\n display: flex;\n color: var(--deb-muted, #64748b);\n }\n .deb-palette__clear:hover {\n color: #0f172a;\n }\n\n .deb-palette__section {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n .deb-palette__grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 6px;\n }\n\n /*\n * An auto height and a wrapping label are the fix for the clipped names. Material's\n * button locks a line height and hides the overflow, which is right for a toolbar and\n * wrong for a 140px-wide tile holding \"Entity Reference\".\n */\n .deb-palette__item {\n justify-content: flex-start !important;\n height: auto !important;\n min-height: 38px;\n line-height: 1.25 !important;\n border-radius: 8px !important;\n border: 1px solid var(--deb-border, #e2e8f0) !important;\n padding: 7px 10px !important;\n font-family: var(--font-heading, inherit) !important;\n font-weight: 600 !important;\n font-size: 12.5px !important;\n transition: all 0.18s cubic-bezier(0.16, 1, 0.3, 1) !important;\n background: #ffffff !important;\n text-align: left !important;\n }\n .deb-palette__item:hover {\n border-color: #6366f1 !important;\n background: #f5f3ff !important;\n color: #4f46e5 !important;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.15) !important;\n }\n .deb-palette__item mat-icon {\n color: #4338ca;\n margin-right: 7px;\n font-size: 17px;\n width: 17px;\n height: 17px;\n flex: none;\n }\n .deb-palette__item span {\n white-space: normal;\n overflow-wrap: anywhere;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .deb-palette__item {\n transition: none !important;\n }\n .deb-palette__item:hover {\n transform: none;\n }\n }\n `,\n ],\n})\nexport class FieldPaletteComponent {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n\n readonly catalog: readonly FieldTypeMeta[] = FIELD_TYPE_CATALOG;\n\n /** The filter text. Matched against the label, the type and the description. */\n protected readonly query = signal('');\n\n /**\n * The catalogue, filtered and filed.\n *\n * Matching the description as well as the label is what makes the filter worth having: a\n * person looking for a currency input types \"money\", which appears in no label but is\n * exactly the sort of word a description carries. An empty group is dropped rather than\n * rendered as a heading with nothing under it.\n */\n protected readonly sections = computed<PaletteSection[]>(() => {\n const needle = this.query().trim().toLowerCase();\n const matches = (meta: FieldTypeMeta) =>\n !needle ||\n meta.label.toLowerCase().includes(needle) ||\n meta.type.toLowerCase().includes(needle) ||\n meta.description.toLowerCase().includes(needle);\n\n return PALETTE_GROUPS.map(group => ({\n group,\n heading: this.ui.text(GROUP_TEXT_KEY[group]),\n items: this.catalog.filter(meta => (GROUP_OF[meta.type] ?? 'other') === group && matches(meta)),\n })).filter(section => section.items.length > 0);\n });\n\n @Output() pick = new EventEmitter<RichFieldType>();\n}\n","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatSlideToggleModule } from '@angular/material/slide-toggle';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport type { NestedTabConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { SYSTEM_DEFAULT_CAN_EDIT } from 'ngx-dynamic-entity';\nimport { BuilderStore } from '../builder-store.service';\nimport { BuilderTextService } from '../builder-text';\n\n/**\n * Re-exported so existing imports from this package keep working.\n *\n * This file used to declare its own `new InjectionToken('SYSTEM_DEFAULT_CAN_EDIT')` while\n * `ngx-dynamic-entity` exported another under the same name. InjectionToken identity is by\n * object reference, so a consumer providing the renderer's — the documented one — was\n * providing a token nothing injected, and the predicate silently never ran. One token now,\n * defined in the lower-level package that both depend on.\n */\nexport { SYSTEM_DEFAULT_CAN_EDIT };\n\n/**\n * TabManagerComponent — add / rename / reorder / remove tabs & sub-tabs with systemDefault protection.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-tab-manager',\n standalone: true,\n imports: [\n FormsModule,\n MatButtonModule,\n MatCheckboxModule,\n MatFormFieldModule,\n MatIconModule,\n MatInputModule,\n MatSlideToggleModule,\n MatTooltipModule,\n ],\n template: `\n <div class=\"deb-tabs\">\n <div class=\"deb-tabs__head\">\n <span class=\"deb-section-title\">{{ ui.text('tabsManager') }}</span>\n <button mat-stroked-button type=\"button\" (click)=\"store.addTab()\">\n <mat-icon>add</mat-icon> {{ ui.text('addTab') }}\n </button>\n </div>\n\n @if (store.tabs().length === 0) {\n <p class=\"deb-hint\">{{ ui.text('noTabs') }}</p>\n }\n\n @for (tab of store.tabs(); track tab.id; let i = $index, count = $count) {\n <div class=\"deb-tab-card\" [class.deb-tab-card--system]=\"tab.systemDefault\">\n <div class=\"deb-tabs__row\" [attr.data-testid]=\"'tab-row-' + tab.id\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-grow\">\n <mat-label>{{ tab.id }} {{ tab.systemDefault ? ui.text('systemTag') : '' }}</mat-label>\n <input\n matInput\n [disabled]=\"!canEditTab(tab)\"\n [ngModel]=\"tabLabel(tab)\"\n (ngModelChange)=\"store.setTabLabel(tab.id, lang(), $event)\"\n />\n </mat-form-field>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"i === 0 || !canEditTab(tab)\"\n (click)=\"store.moveTab(tab.id, -1)\"\n [matTooltip]=\"ui.text('moveUp')\"\n [attr.aria-label]=\"ui.text('moveTabUp')\"\n >\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"i === count - 1 || !canEditTab(tab)\"\n (click)=\"store.moveTab(tab.id, 1)\"\n [matTooltip]=\"ui.text('moveDown')\"\n [attr.aria-label]=\"ui.text('moveTabDown')\"\n >\n <mat-icon>arrow_downward</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n color=\"warn\"\n [disabled]=\"!canEditTab(tab)\"\n (click)=\"store.removeTab(tab.id)\"\n [matTooltip]=\"ui.text('removeTab')\"\n [attr.aria-label]=\"ui.text('removeTab')\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n\n <!-- Tab settings row -->\n <div class=\"deb-tab-settings\">\n <mat-checkbox\n color=\"primary\"\n [disabled]=\"!canEditTab(tab)\"\n [ngModel]=\"tab.flatData\"\n (ngModelChange)=\"store.updateTab(tab.id, { flatData: $event })\"\n >\n {{ ui.text('flatData') }}\n </mat-checkbox>\n <mat-checkbox\n color=\"primary\"\n [disabled]=\"!canEditTab(tab)\"\n [ngModel]=\"tab.isPrimaryTab\"\n (ngModelChange)=\"$event ? store.setPrimaryTab(tab.id) : store.updateTab(tab.id, { isPrimaryTab: false })\"\n >\n {{ ui.text('primaryTab') }}\n </mat-checkbox>\n <mat-checkbox\n color=\"primary\"\n [disabled]=\"!canEditTab(tab)\"\n [ngModel]=\"tab.maskData\"\n (ngModelChange)=\"store.updateTab(tab.id, { maskData: $event })\"\n >\n {{ ui.text('maskTabData') }}\n </mat-checkbox>\n <mat-checkbox\n color=\"primary\"\n [disabled]=\"!canEditTab(tab)\"\n [ngModel]=\"tab.systemDefault\"\n (ngModelChange)=\"store.updateTab(tab.id, { systemDefault: $event })\"\n >\n {{ ui.text('systemDefault') }}\n </mat-checkbox>\n <button mat-button type=\"button\" color=\"primary\" [disabled]=\"!canEditTab(tab)\" (click)=\"store.addSubTab(tab.id)\">\n {{ ui.text('addSubTab') }}\n </button>\n </div>\n\n <!-- Module tab configuration -->\n <div class=\"deb-tab-module\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-grow\">\n <mat-label>{{ ui.text('consumerModuleName') }}</mat-label>\n <input\n matInput\n [placeholder]=\"ui.text('consumerModulePlaceholder')\"\n [disabled]=\"!canEditTab(tab)\"\n [ngModel]=\"tab.moduleName\"\n (ngModelChange)=\"store.updateTab(tab.id, { moduleName: $event || undefined })\"\n />\n </mat-form-field>\n </div>\n\n <!-- Sub-tabs recursive render (Level 2) -->\n @if (tab.children && tab.children.length > 0) {\n <div class=\"deb-subtabs\">\n <span class=\"deb-subtabs__title\">{{ ui.text('subTabs') }}</span>\n @for (sub of tab.children; track sub.id) {\n <div class=\"deb-tabs__row deb-subtab-row\" [attr.data-testid]=\"'subtab-row-' + sub.id\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-grow\">\n <mat-label>{{ sub.id }}</mat-label>\n <input\n matInput\n [disabled]=\"!canEditTab(sub)\"\n [ngModel]=\"tabLabel(sub)\"\n (ngModelChange)=\"store.setTabLabel(sub.id, lang(), $event)\"\n />\n </mat-form-field>\n <button\n mat-icon-button\n type=\"button\"\n color=\"warn\"\n [disabled]=\"!canEditTab(sub)\"\n (click)=\"store.removeTab(sub.id)\"\n [matTooltip]=\"ui.text('removeSubTab')\"\n [attr.aria-label]=\"ui.text('removeSubTab')\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n `,\n styles: [\n `\n .deb-tabs__head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n }\n .deb-tab-card {\n border: 1px solid var(--deb-border, #e5e7eb);\n border-radius: 8px;\n padding: 10px;\n margin-bottom: 10px;\n background: var(--deb-bg-surface, #ffffff);\n }\n .deb-tab-card--system {\n border-left: 4px solid var(--deb-accent, #6366f1);\n }\n .deb-tabs__row {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n .deb-tab-settings {\n display: flex;\n flex-wrap: wrap;\n gap: 8px 16px;\n align-items: center;\n margin-top: 8px;\n font-size: 13px;\n }\n .deb-tab-module {\n margin-top: 8px;\n }\n .deb-subtabs {\n margin-top: 8px;\n padding-left: 16px;\n border-left: 2px dashed var(--deb-border, #e5e7eb);\n }\n .deb-subtabs__title {\n font-size: 12px;\n font-weight: 600;\n color: var(--deb-muted, #6b7280);\n }\n .deb-subtab-row {\n margin-top: 6px;\n }\n .deb-grow {\n flex: 1;\n }\n `,\n ],\n})\nexport class TabManagerComponent {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n private readonly canEditSystemDefaultsFn = inject<(roles: string[]) => boolean>(SYSTEM_DEFAULT_CAN_EDIT, {\n optional: true,\n });\n\n protected lang(): string {\n return this.store.activeLanguage();\n }\n\n protected tabLabel(tab: { label?: any }): string {\n return resolveLabel(tab.label, this.lang());\n }\n\n protected canEditTab(tab: NestedTabConfig): boolean {\n if (!tab.systemDefault) return true;\n if (this.canEditSystemDefaultsFn) {\n // The predicate's entire contract is (roles) => boolean. This passed a hardcoded []\n // regardless of who was using the builder, so any predicate that actually inspected\n // roles answered false for everyone and locked every system-default tab.\n return this.canEditSystemDefaultsFn(this.store.userRoles());\n }\n return true;\n }\n}\n","import { ChangeDetectionStrategy, Component, Input, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { DragDropModule } from '@angular/cdk/drag-drop';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { resolveLabel, type NestedFieldConfig } from '@dynamic-entity/core';\nimport { BuilderStore } from '../builder-store.service';\nimport { getFieldTypeMeta } from '../field-catalog';\nimport { BuilderTextService } from '../builder-text';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-entity-builder-tree-node',\n standalone: true,\n imports: [CommonModule, DragDropModule, MatButtonModule, MatIconModule, MatTooltipModule],\n template: `\n <div\n cdkDrag\n class=\"deb-field-row\"\n data-testid=\"builder-field-row\"\n [class.deb-field-row--active]=\"store.isSelected(field)\"\n (click)=\"store.selectField(store.keyOf(field))\"\n (keydown.enter)=\"store.selectField(store.keyOf(field))\"\n (keydown.space)=\"store.selectField(store.keyOf(field)); $event.preventDefault()\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-pressed]=\"store.isSelected(field)\"\n [attr.aria-label]=\"ui.text('selectField', { field: fieldLabel(field) })\"\n >\n <mat-icon class=\"deb-drag-handle\" cdkDragHandle aria-hidden=\"true\" [title]=\"ui.text('dragToReorder')\"\n >drag_indicator</mat-icon\n >\n <mat-icon class=\"deb-field-type\" [matTooltip]=\"fieldTypeLabel(field.type)\">{{ fieldTypeIcon(field.type) }}</mat-icon>\n <div class=\"deb-field-meta\">\n <div class=\"deb-row\" style=\"gap:6px\">\n <span class=\"deb-field-label\" [attr.data-testid]=\"'row-label-' + field.id\">{{ fieldLabel(field) }}</span>\n <span class=\"deb-type-badge\">{{ field.type }}</span>\n @if (field.isReferenced) {\n <mat-icon\n style=\"font-size: 16px; width: 16px; height: 16px; color: #1976d2;\"\n [matTooltip]=\"ui.text('referencedFieldTooltip', { entity: field.referencedEntityKey ?? '' })\"\n >link</mat-icon\n >\n }\n @if (field.hasDrift) {\n <mat-icon\n style=\"font-size: 16px; width: 16px; height: 16px; color: #d32f2f;\"\n data-testid=\"drift-warning-icon\"\n [matTooltip]=\"ui.text('driftDetected')\"\n >sync_problem</mat-icon\n >\n }\n </div>\n <span class=\"deb-field-id\" [attr.data-testid]=\"'row-id-' + field.id\">{{ field.id }}</span>\n </div>\n @if (field.validators?.required) {\n <span class=\"deb-req\" [title]=\"ui.text('required')\">*</span>\n }\n <!--\n The grid width this field was given, when it is not the default.\n Layout is now authored in the inspector, and a list that does not show it makes the\n author open every field in turn to find the one that is half a row wide.\n -->\n @if (field.colSpan && field.colSpan !== 12) {\n <span class=\"deb-span-badge\" [attr.data-testid]=\"'row-span-' + field.id\" [title]=\"ui.text('width')\"\n >{{ field.colSpan }}/12</span\n >\n }\n\n <!--\n Grouped so the row can reveal them together on hover, focus and selection. Four icon\n buttons on every row put more ink into the controls than into the field names.\n -->\n <div class=\"deb-field-row__actions\">\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"index === 0\"\n [attr.data-testid]=\"'row-up-' + field.id\"\n [attr.aria-label]=\"ui.text('moveFieldUp', { field: fieldLabel(field) })\"\n (click)=\"store.moveField(store.keyOf(field), -1); $event.stopPropagation()\"\n [matTooltip]=\"ui.text('moveUp')\"\n >\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"index === totalCount - 1\"\n [attr.data-testid]=\"'row-down-' + field.id\"\n [attr.aria-label]=\"ui.text('moveFieldDown', { field: fieldLabel(field) })\"\n (click)=\"store.moveField(store.keyOf(field), 1); $event.stopPropagation()\"\n [matTooltip]=\"ui.text('moveDown')\"\n >\n <mat-icon>arrow_downward</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n [attr.data-testid]=\"'row-duplicate-' + field.id\"\n [attr.aria-label]=\"ui.text('duplicateField', { field: fieldLabel(field) })\"\n (click)=\"store.duplicateField(store.keyOf(field)); $event.stopPropagation()\"\n [matTooltip]=\"ui.text('duplicate')\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n color=\"warn\"\n [attr.data-testid]=\"'row-delete-' + field.id\"\n (click)=\"store.removeField(store.keyOf(field)); $event.stopPropagation()\"\n [matTooltip]=\"ui.text('delete')\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n </div>\n\n @if (field.children && field.children.length > 0) {\n <div\n class=\"deb-tree-children\"\n style=\"padding-left: 20px; border-left: 2px solid rgba(0,0,0,0.08); margin-left: 12px; margin-top: 4px;\"\n >\n @for (child of field.children; track child.id; let ci = $index, cCount = $count) {\n <ngx-entity-builder-tree-node [field]=\"child\" [index]=\"ci\" [totalCount]=\"cCount\" />\n }\n </div>\n }\n `,\n})\nexport class EntityBuilderTreeNodeComponent {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n\n @Input({ required: true }) field!: NestedFieldConfig;\n @Input({ required: true }) index!: number;\n @Input({ required: true }) totalCount!: number;\n\n protected fieldTypeLabel(type: string): string {\n return getFieldTypeMeta(type)?.label ?? type;\n }\n\n protected fieldTypeIcon(type: string): string {\n return getFieldTypeMeta(type)?.icon ?? 'help_outline';\n }\n\n protected fieldLabel(field: { id: string; label?: any }): string {\n const lang = this.store.activeLanguage();\n return resolveLabel(field.label, lang) || field.id;\n }\n}\n","import { ChangeDetectionStrategy, Component, EventEmitter, Output, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { CdkDragDrop, DragDropModule } from '@angular/cdk/drag-drop';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatCardModule } from '@angular/material/card';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { BuilderStore, type BuilderFieldGroup } from '../builder-store.service';\nimport { EntityBuilderTreeNodeComponent } from './entity-builder-tree-node.component';\nimport { BuilderTextService } from '../builder-text';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-entity-builder-canvas',\n standalone: true,\n imports: [\n CommonModule,\n DragDropModule,\n MatButtonModule,\n MatCardModule,\n MatIconModule,\n MatTooltipModule,\n EntityBuilderTreeNodeComponent,\n ],\n template: `\n <mat-card class=\"deb-card deb-card--canvas\">\n <mat-card-header>\n <mat-card-title class=\"deb-card__title\">\n <mat-icon class=\"deb-card__icon\">format_list_bulleted</mat-icon>\n {{ ui.text('fieldsHeading', { count: store.fields().length }) }}\n </mat-card-title>\n <button\n mat-icon-button\n type=\"button\"\n class=\"deb-card__collapse-btn\"\n data-testid=\"collapse-fields\"\n aria-expanded=\"true\"\n aria-controls=\"deb-fields-section\"\n (click)=\"collapse.emit()\"\n [matTooltip]=\"ui.text('collapseFields')\"\n [attr.aria-label]=\"ui.text('collapseFields')\"\n >\n <mat-icon>keyboard_arrow_up</mat-icon>\n </button>\n </mat-card-header>\n <mat-card-content>\n @if (store.fields().length === 0) {\n <div class=\"deb-empty\">\n <!--\n Decoration, and marked as such. The sentence below says everything this glyph\n says, so a reader hearing \"widgets\" before it learns nothing; and a faint\n illustration cannot meet a text contrast ratio without ceasing to be faint.\n Hidden from the accessibility tree, it is neither announced nor measured.\n -->\n <mat-icon aria-hidden=\"true\">widgets</mat-icon>\n <p>{{ ui.text('canvasEmpty') }}</p>\n </div>\n }\n\n @for (group of store.fieldGroups(); track group.tabId) {\n <!--\n One drop list per tab. A single list spanning every tab would hand reorderField\n an index into the combined view, which is not the index of anything in the tab\n that actually owns the field.\n -->\n @if (showTabHeadings()) {\n <h4 class=\"deb-canvas__group\" [attr.data-testid]=\"'builder-group-' + group.tabId\">\n {{ groupLabel(group) }}\n </h4>\n }\n <div\n cdkDropList\n class=\"deb-field-list\"\n [attr.data-testid]=\"'builder-field-list-' + group.tabId\"\n (cdkDropListDropped)=\"onDrop(group.tabId, $event)\"\n >\n @for (f of group.fields; track f.id; let i = $index, count = $count) {\n <ngx-entity-builder-tree-node [field]=\"f\" [index]=\"i\" [totalCount]=\"count\" />\n }\n </div>\n }\n </mat-card-content>\n </mat-card>\n `,\n})\nexport class EntityBuilderCanvasComponent {\n @Output() collapse = new EventEmitter<void>();\n\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n\n /**\n * Headings only earn their space once the fields are actually split across tabs. A\n * single-tab config — the common case, and every existing spec — renders exactly as before.\n */\n protected showTabHeadings(): boolean {\n return this.store.fieldGroups().length > 1;\n }\n\n protected groupLabel(group: BuilderFieldGroup): string {\n return resolveLabel(group.label, this.store.activeLanguage()) || group.tabId;\n }\n\n protected onDrop(tabId: string, event: CdkDragDrop<unknown>): void {\n this.store.reorderField(event.previousIndex, event.currentIndex, tabId);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n EventEmitter,\n Output,\n computed,\n inject,\n signal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatChipsModule } from '@angular/material/chips';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { BuilderStore } from '../builder-store.service';\nimport { BuilderTextService } from '../builder-text';\nimport { computeRuleDependencies, type DependencyType, type RuleDependencyEdge } from '../rule-dependencies';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-rule-dependency-graph',\n standalone: true,\n imports: [\n FormsModule,\n MatButtonModule,\n MatChipsModule,\n MatFormFieldModule,\n MatIconModule,\n MatInputModule,\n MatTooltipModule,\n ],\n template: `\n <div class=\"deb-graph-backdrop\" (click)=\"onBackdropClick($event)\">\n <div class=\"deb-graph-dialog\" role=\"dialog\" aria-modal=\"true\" data-testid=\"rule-graph-dialog\">\n <div class=\"deb-graph-header\">\n <div class=\"deb-graph-header__titles\">\n <div class=\"deb-graph-header__title-row\">\n <mat-icon class=\"deb-graph-icon\">hub</mat-icon>\n <h2 class=\"deb-graph-title\">{{ ui.text('ruleGraphTitle') }}</h2>\n </div>\n <p class=\"deb-graph-subtitle\">{{ ui.text('ruleGraphSubtitle') }}</p>\n </div>\n <button\n mat-icon-button\n type=\"button\"\n data-testid=\"close-rule-graph\"\n [matTooltip]=\"ui.text('closeDialog')\"\n (click)=\"dismiss.emit()\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </div>\n\n <div class=\"deb-graph-metrics\">\n <span class=\"deb-metric-pill deb-metric-pill--rule\">\n <mat-icon>rule</mat-icon>\n {{ graphData().totalRules }} {{ ui.text('dependencyTypeRule') }}\n </span>\n <span class=\"deb-metric-pill deb-metric-pill--show-when\">\n <mat-icon>visibility</mat-icon>\n {{ graphData().totalShowWhen }} {{ ui.text('dependencyTypeShowWhen') }}\n </span>\n <span class=\"deb-metric-pill deb-metric-pill--cascade\">\n <mat-icon>account_tree</mat-icon>\n {{ graphData().totalCascades }} {{ ui.text('dependencyTypeCascade') }}\n </span>\n <span class=\"deb-metric-pill deb-metric-pill--patch\">\n <mat-icon>content_copy</mat-icon>\n {{ graphData().totalPatches }} {{ ui.text('dependencyTypePatch') }}\n </span>\n </div>\n\n <div class=\"deb-graph-controls\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-graph-search\">\n <mat-icon matPrefix>search</mat-icon>\n <input\n matInput\n data-testid=\"filter-dependencies-input\"\n [placeholder]=\"ui.text('filterDependencies')\"\n [ngModel]=\"filterQuery()\"\n (ngModelChange)=\"filterQuery.set($event)\"\n />\n @if (filterQuery()) {\n <button mat-icon-button matSuffix type=\"button\" (click)=\"filterQuery.set('')\">\n <mat-icon>clear</mat-icon>\n </button>\n }\n </mat-form-field>\n\n <div class=\"deb-graph-filter-types\">\n <button\n type=\"button\"\n class=\"deb-filter-btn\"\n [class.deb-filter-btn--active]=\"selectedType() === 'all'\"\n (click)=\"selectedType.set('all')\"\n >\n All ({{ graphData().edges.length }})\n </button>\n <button\n type=\"button\"\n class=\"deb-filter-btn\"\n [class.deb-filter-btn--active]=\"selectedType() === 'rule'\"\n (click)=\"selectedType.set('rule')\"\n >\n {{ ui.text('dependencyTypeRule') }}\n </button>\n <button\n type=\"button\"\n class=\"deb-filter-btn\"\n [class.deb-filter-btn--active]=\"selectedType() === 'showWhen'\"\n (click)=\"selectedType.set('showWhen')\"\n >\n {{ ui.text('dependencyTypeShowWhen') }}\n </button>\n <button\n type=\"button\"\n class=\"deb-filter-btn\"\n [class.deb-filter-btn--active]=\"selectedType() === 'cascade'\"\n (click)=\"selectedType.set('cascade')\"\n >\n {{ ui.text('dependencyTypeCascade') }}\n </button>\n <button\n type=\"button\"\n class=\"deb-filter-btn\"\n [class.deb-filter-btn--active]=\"selectedType() === 'patchOnTrue'\"\n (click)=\"selectedType.set('patchOnTrue')\"\n >\n {{ ui.text('dependencyTypePatch') }}\n </button>\n </div>\n </div>\n\n <div class=\"deb-graph-body\" data-testid=\"rule-graph-edges\">\n @if (filteredEdges().length === 0) {\n <div class=\"deb-graph-empty\" data-testid=\"no-dependencies-found\">\n <mat-icon>search_off</mat-icon>\n <p>{{ ui.text('noDependenciesFound') }}</p>\n </div>\n }\n\n @for (edge of filteredEdges(); track edge.id) {\n <div class=\"deb-edge-card\" [attr.data-testid]=\"'edge-card-' + edge.id\">\n <!-- Source -->\n <button\n type=\"button\"\n class=\"deb-node-chip deb-node-chip--source\"\n [matTooltip]=\"ui.text('jumpToField', { field: edge.sourceLabel })\"\n (click)=\"onNodeClick(edge.sourceKey)\"\n >\n <mat-icon class=\"deb-node-chip__icon\">tune</mat-icon>\n <span class=\"deb-node-chip__label\">{{ edge.sourceLabel }}</span>\n <span class=\"deb-node-chip__key\">{{ edge.sourceKey }}</span>\n </button>\n\n <!-- Connection details -->\n <div class=\"deb-edge-flow\">\n <span\n class=\"deb-edge-badge\"\n [class.deb-edge-badge--rule]=\"edge.type === 'rule'\"\n [class.deb-edge-badge--show-when]=\"edge.type === 'showWhen'\"\n [class.deb-edge-badge--cascade]=\"edge.type === 'cascade'\"\n [class.deb-edge-badge--patch]=\"edge.type === 'patchOnTrue' || edge.type === 'autoPatch'\"\n >\n {{ typeName(edge.type) }}\n </span>\n <span class=\"deb-edge-arrow\">\n <span class=\"deb-edge-summary\">{{ edge.actionSummary }}</span>\n <mat-icon class=\"deb-edge-arrow-icon\">arrow_forward</mat-icon>\n </span>\n <span class=\"deb-edge-desc\">{{ edge.description }}</span>\n </div>\n\n <!-- Target -->\n <button\n type=\"button\"\n class=\"deb-node-chip deb-node-chip--target\"\n [matTooltip]=\"ui.text('jumpToField', { field: edge.targetLabel })\"\n (click)=\"onNodeClick(edge.targetKey)\"\n >\n <mat-icon class=\"deb-node-chip__icon\">output</mat-icon>\n <span class=\"deb-node-chip__label\">{{ edge.targetLabel }}</span>\n <span class=\"deb-node-chip__key\">{{ edge.targetKey }}</span>\n </button>\n </div>\n }\n </div>\n\n <div class=\"deb-graph-footer\">\n <span class=\"deb-graph-count\">\n {{ ui.text('totalDependencies', { count: filteredEdges().length }) }}\n </span>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"dismiss.emit()\">\n {{ ui.text('closeDialog') }}\n </button>\n </div>\n </div>\n </div>\n `,\n styles: [\n `\n .deb-graph-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(15, 23, 42, 0.6);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 24px;\n animation: debFadeIn 0.15s ease-out;\n }\n @keyframes debFadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n .deb-graph-dialog {\n background: var(--deb-surface, #ffffff);\n border: 1px solid var(--deb-border, #e2e8f0);\n border-radius: 14px;\n width: 100%;\n max-width: 960px;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);\n overflow: hidden;\n }\n .deb-graph-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 20px 24px 16px;\n border-bottom: 1px solid var(--deb-border, #e2e8f0);\n }\n .deb-graph-header__title-row {\n display: flex;\n align-items: center;\n gap: 10px;\n }\n .deb-graph-icon {\n color: var(--deb-accent, #6366f1);\n font-size: 26px;\n width: 26px;\n height: 26px;\n }\n .deb-graph-title {\n font-size: 18px;\n font-weight: 700;\n color: #0f172a;\n margin: 0;\n }\n .deb-graph-subtitle {\n font-size: 13px;\n color: var(--deb-muted, #64748b);\n margin: 4px 0 0;\n }\n .deb-graph-metrics {\n display: flex;\n gap: 12px;\n padding: 12px 24px;\n background: #f8fafc;\n border-bottom: 1px solid var(--deb-border, #e2e8f0);\n flex-wrap: wrap;\n }\n .deb-metric-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n border-radius: 9999px;\n font-size: 12px;\n font-weight: 600;\n border: 1px solid transparent;\n }\n .deb-metric-pill mat-icon {\n font-size: 16px;\n width: 16px;\n height: 16px;\n }\n .deb-metric-pill--rule {\n background: #eef2ff;\n color: #4f46e5;\n border-color: #c7d2fe;\n }\n .deb-metric-pill--show-when {\n background: #f0fdf4;\n color: #16a34a;\n border-color: #bbf7d0;\n }\n .deb-metric-pill--cascade {\n background: #fefce8;\n color: #ca8a04;\n border-color: #fef08a;\n }\n .deb-metric-pill--patch {\n background: #fdf2f8;\n color: #db2777;\n border-color: #fbcfe8;\n }\n .deb-graph-controls {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 14px 24px;\n border-bottom: 1px solid var(--deb-border, #e2e8f0);\n flex-wrap: wrap;\n }\n .deb-graph-search {\n flex: 1;\n min-width: 240px;\n }\n .deb-graph-filter-types {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n }\n .deb-filter-btn {\n padding: 5px 12px;\n border-radius: 6px;\n border: 1px solid var(--deb-border, #e2e8f0);\n background: #ffffff;\n font-size: 12px;\n font-weight: 500;\n color: #475569;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n .deb-filter-btn:hover {\n background: #f1f5f9;\n color: #0f172a;\n }\n .deb-filter-btn--active {\n background: var(--deb-accent, #6366f1);\n color: #ffffff;\n border-color: var(--deb-accent, #6366f1);\n }\n .deb-filter-btn--active:hover {\n background: var(--deb-accent-hover, #4f46e5);\n }\n .deb-graph-body {\n flex: 1;\n overflow-y: auto;\n padding: 20px 24px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n .deb-graph-empty {\n text-align: center;\n padding: 48px 16px;\n color: var(--deb-muted, #64748b);\n }\n .deb-graph-empty mat-icon {\n font-size: 40px;\n width: 40px;\n height: 40px;\n margin-bottom: 8px;\n opacity: 0.5;\n }\n .deb-edge-card {\n display: grid;\n grid-template-columns: 220px 1fr 220px;\n align-items: center;\n gap: 16px;\n padding: 12px 16px;\n background: #ffffff;\n border: 1px solid var(--deb-border, #e2e8f0);\n border-radius: 10px;\n transition: box-shadow 0.15s ease, border-color 0.15s ease;\n }\n .deb-edge-card:hover {\n border-color: #cbd5e1;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);\n }\n .deb-node-chip {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n padding: 8px 12px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n cursor: pointer;\n text-align: left;\n width: 100%;\n transition: background 0.15s ease, border-color 0.15s ease;\n }\n .deb-node-chip:hover {\n background: #f1f5f9;\n border-color: var(--deb-accent, #6366f1);\n }\n .deb-node-chip__icon {\n font-size: 16px;\n width: 16px;\n height: 16px;\n color: var(--deb-accent, #6366f1);\n margin-bottom: 2px;\n }\n .deb-node-chip__label {\n font-size: 13px;\n font-weight: 600;\n color: #0f172a;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 190px;\n }\n .deb-node-chip__key {\n font-family: ui-monospace, SFMono-Regular, monospace;\n font-size: 11px;\n color: var(--deb-muted, #64748b);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 190px;\n }\n .deb-edge-flow {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 4px;\n text-align: center;\n }\n .deb-edge-badge {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n padding: 2px 8px;\n border-radius: 4px;\n }\n .deb-edge-badge--rule {\n background: #eef2ff;\n color: #4f46e5;\n }\n .deb-edge-badge--show-when {\n background: #f0fdf4;\n color: #16a34a;\n }\n .deb-edge-badge--cascade {\n background: #fefce8;\n color: #a16207;\n }\n .deb-edge-badge--patch {\n background: #fdf2f8;\n color: #be185d;\n }\n .deb-edge-arrow {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n color: #475569;\n }\n .deb-edge-summary {\n font-family: ui-monospace, SFMono-Regular, monospace;\n font-size: 12px;\n font-weight: 600;\n background: #f1f5f9;\n padding: 2px 8px;\n border-radius: 4px;\n }\n .deb-edge-arrow-icon {\n font-size: 16px;\n width: 16px;\n height: 16px;\n color: var(--deb-muted, #64748b);\n }\n .deb-edge-desc {\n font-size: 11px;\n color: var(--deb-muted, #64748b);\n }\n .deb-graph-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n border-top: 1px solid var(--deb-border, #e2e8f0);\n background: #f8fafc;\n }\n .deb-graph-count {\n font-size: 13px;\n color: var(--deb-muted, #64748b);\n }\n @media (max-width: 768px) {\n .deb-edge-card {\n grid-template-columns: 1fr;\n gap: 8px;\n }\n }\n `,\n ],\n})\nexport class RuleDependencyGraphComponent {\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n\n @Output() readonly dismiss = new EventEmitter<void>();\n @Output() readonly selectField = new EventEmitter<string>();\n\n protected readonly filterQuery = signal('');\n protected readonly selectedType = signal<DependencyType | 'all'>('all');\n\n protected readonly graphData = computed(() =>\n computeRuleDependencies(this.store.config(), this.store.rules(), this.ui.language()),\n );\n\n protected readonly filteredEdges = computed<RuleDependencyEdge[]>(() => {\n const q = this.filterQuery().trim().toLowerCase();\n const type = this.selectedType();\n return this.graphData().edges.filter(edge => {\n if (type !== 'all' && edge.type !== type) return false;\n if (!q) return true;\n return (\n edge.sourceLabel.toLowerCase().includes(q) ||\n edge.sourceKey.toLowerCase().includes(q) ||\n edge.targetLabel.toLowerCase().includes(q) ||\n edge.targetKey.toLowerCase().includes(q) ||\n edge.actionSummary.toLowerCase().includes(q) ||\n edge.description.toLowerCase().includes(q)\n );\n });\n });\n\n protected typeName(type: DependencyType): string {\n switch (type) {\n case 'rule':\n return this.ui.text('dependencyTypeRule');\n case 'showWhen':\n return this.ui.text('dependencyTypeShowWhen');\n case 'cascade':\n return this.ui.text('dependencyTypeCascade');\n case 'patchOnTrue':\n case 'autoPatch':\n return this.ui.text('dependencyTypePatch');\n }\n }\n\n protected onNodeClick(key: string): void {\n if (!key) return;\n this.selectField.emit(key);\n this.dismiss.emit();\n }\n\n protected onBackdropClick(event: MouseEvent): void {\n if ((event.target as HTMLElement).classList.contains('deb-graph-backdrop')) {\n this.dismiss.emit();\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n EventEmitter,\n HostListener,\n Input,\n OnChanges,\n Output,\n SimpleChanges,\n ViewEncapsulation,\n effect,\n inject,\n model,\n signal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatCardModule } from '@angular/material/card';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatExpansionModule } from '@angular/material/expansion';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatMenuModule } from '@angular/material/menu';\nimport { MatSelectModule } from '@angular/material/select';\nimport { MatSlideToggleModule } from '@angular/material/slide-toggle';\nimport { MatToolbarModule } from '@angular/material/toolbar';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport {\n COMMON_MODULES,\n type CommonModuleEntry,\n type EntityFormConfig,\n type FormRule,\n} from '@dynamic-entity/core';\nimport { ConfigSourceService } from 'ngx-dynamic-entity';\nimport { BuilderStore, type BuilderProblem } from './builder-store.service';\nimport { FieldInspectorComponent } from './components/field-inspector.component';\nimport { FieldPaletteComponent } from './components/field-palette.component';\nimport { TabManagerComponent } from './components/tab-manager.component';\nimport { EntityBuilderCanvasComponent } from './components/entity-builder-canvas.component';\nimport { RuleDependencyGraphComponent } from './components/rule-dependency-graph.component';\nimport { BuilderTextService } from './builder-text';\n\ntype RbacAction = 'view' | 'edit' | 'delete';\n\n/** RBAC actions surfaced in the settings panel. */\nconst RBAC_ACTIONS: readonly RbacAction[] = ['view', 'edit', 'delete'];\n\n/** Shared stable empty array — never allocate a fresh [] per change-detection (mat-select loops). */\nconst EMPTY_ROLES: readonly string[] = Object.freeze([]);\n\n/**\n * EntityBuilderComponent — the top-level visual builder for an EntityFormConfig.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-entity-builder',\n standalone: true,\n providers: [BuilderStore],\n imports: [\n FormsModule,\n MatButtonModule,\n MatCardModule,\n MatCheckboxModule,\n MatExpansionModule,\n MatFormFieldModule,\n MatIconModule,\n MatInputModule,\n MatMenuModule,\n MatSelectModule,\n MatSlideToggleModule,\n MatToolbarModule,\n MatTooltipModule,\n FieldPaletteComponent,\n TabManagerComponent,\n FieldInspectorComponent,\n EntityBuilderCanvasComponent,\n RuleDependencyGraphComponent,\n ],\n templateUrl: './entity-builder.component.html',\n styleUrl: './entity-builder.component.css',\n /*\n * This stylesheet is the builder's design system, not one component's styles.\n *\n * `.deb-field-row`, `.deb-section-title`, `.deb-hint`, `.deb-chip`, `.deb-empty` and the\n * rest are written in seven child components' templates and defined only here — and under\n * emulated encapsulation a parent's rules carry this component's `_ngcontent` attribute, so\n * none of them ever reached a child. The field rows, the inspector's section titles and the\n * canvas's empty state have been rendering unstyled since they were split out; the\n * duplicate `.deb-row` / `.deb-option-row` blocks inside `entity-reference-config` are\n * somebody working around the same thing one panel at a time.\n *\n * `.cdk-drag-preview` says the same thing from the other direction: the CDK attaches a drag\n * preview to `document.body`, outside this component entirely, so that rule could never\n * have applied while scoped.\n *\n * What makes lifting the scope safe is that every selector in the file is `deb-`-prefixed —\n * the CDK rules included, which are qualified with `.deb-field-row` so a host's own drop\n * list does not inherit the builder's drag styling. `:host` is spelled `ngx-entity-builder`\n * for the same reason: there is no host scope left to write it in.\n */\n encapsulation: ViewEncapsulation.None,\n})\nexport class EntityBuilderComponent implements OnChanges {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n /**\n * Optional: only apps that registered a CONFIG_SOURCE have one. Used to drop the cached\n * copy of a config the moment it is edited — see `doSave`.\n */\n private readonly configSource = inject(ConfigSourceService, { optional: true });\n /** Scopes the focus lookup below to this builder, not the first match in the document. */\n private readonly hostRef = inject(ElementRef);\n\n /** Existing config to edit. When omitted, the builder starts blank. */\n @Input() config?: EntityFormConfig;\n /**\n * The rules that belong with `config`.\n *\n * Rules live beside a config rather than inside it — that is the shape the renderer takes\n * them in, and the shape a host stores them in. Without this input, loading a config for\n * editing silently dropped every rule already authored against it: the builder opened on\n * the right fields with an empty rules list, and saving put that emptiness back.\n */\n @Input() rules?: FormRule[];\n /** Languages available for label/placeholder editing. First entry is the default. */\n @Input() languages: string[] = ['en'];\n /**\n * Language for the builder's **own** chrome, resolved through `BUILDER_TEXT`.\n *\n * Deliberately separate from `languages` and `store.activeLanguage()`, which choose the\n * `LocalizedText` entry being authored: switching the label language you are editing\n * should not translate the interface around it.\n */\n @Input() set uiLanguage(value: string) {\n this.ui.language.set(value || 'en');\n }\n /** Optional role list — enables multi-select role pickers for RBAC instead of free text. */\n @Input() availableRoles: string[] = [];\n /**\n * Roles of the person using the builder. Distinct from `availableRoles`, which is the\n * vocabulary a schema may reference. Passed to the `SYSTEM_DEFAULT_CAN_EDIT` predicate so\n * it can decide whether this user may edit system-default tabs.\n */\n @Input() userRoles: string[] = [];\n /** Optional common-module definitions for module tabs; defaults to the built-in list from core. */\n @Input() commonModules: readonly CommonModuleEntry[] = COMMON_MODULES;\n\n /** Emitted on every change to the working config. */\n @Output() configChange = new EventEmitter<EntityFormConfig>();\n /**\n * Emitted on every change to the working rules — the mirror of `configChange`.\n *\n * Without it a rule authored here could not leave this component. `BuilderStore` is\n * provided by the component, so its instance is private to this injector, and `save`\n * carries an `EntityFormConfig` alone. The builder could author a rule and hand it to\n * nobody: a host had no supported way to persist one, and therefore no way to pass it\n * back to the renderer as `[rules]`.\n *\n * A host that persists on Save keeps the latest emission and writes it alongside the\n * config `save` carries — the same pairing `configChange`/`save` already implies, and the\n * pairing the undo history has always stored, because undoing a field rename without the\n * rule that follows it would leave the rule pointing at a field that no longer exists.\n */\n @Output() rulesChange = new EventEmitter<FormRule[]>();\n /** Emitted when the user clicks Save. Carries a clean, deep-cloned config. */\n @Output() save = new EventEmitter<EntityFormConfig>();\n\n protected readonly rbacActions = RBAC_ACTIONS;\n\n /*\n * Two-way bindable, so the host decides whether a collapsed rail/bar survives a reload.\n *\n * `model()` rather than a plain signal: these stay ordinary writable signals to everything\n * inside the component, and gain `[(leftSidebarOpen)]`, `[(rightSidebarOpen)]`, `[(fieldsOpen)]`,\n * `[(previewOpen)]` for anyone outside it. The library deliberately persists nothing itself —\n * no package here touches `localStorage`, which is what keeps it safe to render on a server;\n * the demo wires these to storage to show how.\n */\n readonly leftSidebarOpen = model(true);\n readonly rightSidebarOpen = model(true);\n readonly fieldsOpen = model(true);\n readonly previewOpen = model(true);\n\n toggleLeftSidebar(): void {\n this.leftSidebarOpen.update(open => !open);\n }\n\n toggleRightSidebar(): void {\n this.rightSidebarOpen.update(open => !open);\n }\n\n toggleFields(): void {\n this.fieldsOpen.update(open => !open);\n }\n\n togglePreview(): void {\n this.previewOpen.update(open => !open);\n }\n\n readonly ruleGraphOpen = signal(false);\n\n openRuleGraph(): void {\n this.ruleGraphOpen.set(true);\n }\n\n closeRuleGraph(): void {\n this.ruleGraphOpen.set(false);\n }\n\n onSelectFieldFromGraph(key: string): void {\n this.store.selectField(key);\n this.ruleGraphOpen.set(false);\n }\n\n /*\n * Collapsing from inside a panel destroys the button that was just pressed, and expanding\n * from a rail destroys the rail. Either way the browser drops focus onto `<body>`, which\n * for a keyboard user means starting the tab sequence again from the top of the document.\n * Each of these hands focus to whichever control now stands in for the panel.\n *\n * The toolbar toggles need none of this: they stay put and keep their focus.\n */\n protected collapseLeft(): void {\n this.leftSidebarOpen.set(false);\n this.focusAfterRender('expand-left-sidebar');\n }\n\n protected expandLeft(): void {\n this.leftSidebarOpen.set(true);\n this.focusAfterRender('collapse-left-sidebar');\n }\n\n protected collapseRight(): void {\n this.rightSidebarOpen.set(false);\n this.focusAfterRender('expand-right-sidebar');\n }\n\n protected expandRight(): void {\n this.rightSidebarOpen.set(true);\n this.focusAfterRender('collapse-right-sidebar');\n }\n\n protected collapseFields(): void {\n this.fieldsOpen.set(false);\n this.focusAfterRender('expand-fields');\n }\n\n protected expandFields(): void {\n this.fieldsOpen.set(true);\n this.focusAfterRender('collapse-fields');\n }\n\n protected collapsePreview(): void {\n this.previewOpen.set(false);\n this.focusAfterRender('expand-preview');\n }\n\n protected expandPreview(): void {\n this.previewOpen.set(true);\n this.focusAfterRender('collapse-preview');\n }\n\n /** The replacement control does not exist until the template has caught up with the signal. */\n private focusAfterRender(testId: string): void {\n setTimeout(() => {\n const host = this.hostRef.nativeElement as HTMLElement;\n host.querySelector<HTMLElement>(`[data-testid=\"${testId}\"]`)?.focus();\n });\n }\n\n /**\n * Select the field an issue is about, so reading the message and acting on it are one step.\n *\n * A problem without a `fieldId` is about the entity itself — no tabs, a bad entity name —\n * and there is nothing to select; the template disables those entries rather than silently\n * doing nothing when one is clicked.\n */\n protected selectProblemField(problem: BuilderProblem): void {\n if (problem.fieldId) this.store.selectField(problem.fieldId);\n }\n\n constructor() {\n effect(() => this.configChange.emit(this.store.config()), { allowSignalWrites: true });\n effect(() => this.rulesChange.emit(this.store.rules()), { allowSignalWrites: true });\n }\n\n /**\n * Ctrl/Cmd+Z and Ctrl/Cmd+Shift+Z, but only when the user is not typing.\n *\n * A textarea or input has its own undo stack, and hijacking it would make Ctrl+Z revert a\n * whole structural edit when the author only wanted to take back a character.\n */\n @HostListener('document:keydown', ['$event'])\n protected onKeydown(event: KeyboardEvent): void {\n if (!(event.ctrlKey || event.metaKey) || event.key.toLowerCase() !== 'z') return;\n\n const target = event.target as HTMLElement | null;\n const tag = target?.tagName?.toLowerCase();\n if (tag === 'input' || tag === 'textarea' || target?.isContentEditable) return;\n\n event.preventDefault();\n if (event.shiftKey) this.store.redo();\n else this.store.undo();\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['config'] && changes['config'].currentValue !== changes['config'].previousValue) {\n // The rules go in with the config, as one snapshot: `load` seeds both before taking\n // the history baseline, so opening a builder is not itself an undoable step.\n if (this.config) this.store.load(this.config, this.rules ?? []);\n else if (changes['config'].isFirstChange()) this.store.reset();\n } else if (changes['rules'] && changes['rules'].currentValue !== changes['rules'].previousValue) {\n this.store.loadRules(this.rules ?? []);\n }\n if (changes['languages'] && this.languages.length) {\n const active = this.store.activeLanguage();\n if (!this.languages.includes(active)) this.store.setActiveLanguage(this.languages[0]);\n }\n if (changes['userRoles']) {\n this.store.setUserRoles(this.userRoles);\n }\n }\n\n // ─── Toolbar actions ──────────────────────────────────────────────────────\n\n protected doSave(): void {\n const config = this.store.exportConfig();\n\n // Saving is the moment this entity's config changes, so anything holding a cached copy is\n // now stale — most visibly a referenced field elsewhere resolving against the old schema.\n // ConfigSourceService caches per entity and exposed clearCache from the start, but nothing\n // ever called it, so a cache entry lived for the lifetime of the page.\n this.configSource?.clearCache(config.entity);\n\n this.save.emit(config);\n }\n\n protected get json(): string {\n return JSON.stringify(this.store.exportConfig(), null, 2);\n }\n\n protected copyJson(): void {\n if (typeof navigator !== 'undefined' && navigator.clipboard) {\n void navigator.clipboard.writeText(this.json);\n }\n }\n\n // ─── RBAC settings ────────────────────────────────────────────────────────\n\n protected rolesFor(action: RbacAction): readonly string[] {\n // Return the stored array (stable ref between mutations) or a shared empty — NOT a fresh [],\n // which would make the bound mat-select re-evaluate every CD and loop forever.\n return this.store.config().permissions?.[action] ?? EMPTY_ROLES;\n }\n\n protected setRoles(action: RbacAction, roles: string[]): void {\n this.store.setPermission(action, roles);\n }\n\n /** Parse a comma-separated role string into a trimmed, de-duplicated array. */\n protected setRolesFromText(action: RbacAction, text: string): void {\n const roles = Array.from(\n new Set(\n text\n .split(',')\n .map(r => r.trim())\n .filter(Boolean),\n ),\n );\n this.store.setPermission(action, roles);\n }\n}\n","<mat-toolbar class=\"deb-toolbar\">\n <button\n mat-icon-button\n type=\"button\"\n data-testid=\"toggle-left-sidebar\"\n class=\"deb-sidebar-toggle-btn\"\n [class.deb-sidebar-toggle-btn--active]=\"leftSidebarOpen()\"\n [attr.aria-expanded]=\"leftSidebarOpen()\"\n aria-controls=\"deb-left-sidebar\"\n (click)=\"toggleLeftSidebar()\"\n [matTooltip]=\"leftSidebarOpen() ? ui.text('collapsePalette') : ui.text('expandPalette')\"\n [attr.aria-label]=\"leftSidebarOpen() ? ui.text('collapsePalette') : ui.text('expandPalette')\"\n >\n <mat-icon>{{ leftSidebarOpen() ? 'menu_open' : 'menu' }}</mat-icon>\n </button>\n\n <mat-icon class=\"deb-toolbar__mark\">dashboard_customize</mat-icon>\n <span class=\"deb-toolbar__title\">{{ ui.text('builderTitle') }}</span>\n <span class=\"deb-toolbar__entity\" data-testid=\"builder-toolbar-entity\">{{ store.config().entity || '—' }}</span>\n <span class=\"deb-spacer\"></span>\n\n <!--\n The issue count, and the issues.\n It used to be a button labelled \"0 / 1\" whose tooltip said to hover the items in the list\n — a list that did not exist anywhere in the builder. The count now opens the problems\n themselves, and an entry that names a field selects it, which is the action the person\n reading the message wants to take next.\n -->\n @if (store.problems().length) {\n <button\n mat-button\n type=\"button\"\n class=\"deb-problems\"\n data-testid=\"builder-problems\"\n [class.deb-problems--error]=\"!store.isValid()\"\n [matMenuTriggerFor]=\"problemsMenu\"\n [matTooltip]=\"ui.text('issuesTooltip', { count: store.problems().length })\"\n >\n <mat-icon>{{ store.isValid() ? 'warning' : 'error' }}</mat-icon>\n {{ ui.text('issuesCount', { errors: store.errors().length, total: store.problems().length }) }}\n </button>\n <mat-menu #problemsMenu=\"matMenu\" class=\"deb-problems-menu\">\n @for (problem of store.problems(); track $index) {\n <button\n mat-menu-item\n type=\"button\"\n data-testid=\"builder-problem\"\n [disabled]=\"!problem.fieldId\"\n (click)=\"selectProblemField(problem)\"\n >\n <mat-icon [class.deb-problems--error]=\"problem.level === 'error'\">{{\n problem.level === 'error' ? 'error' : 'warning'\n }}</mat-icon>\n <span class=\"deb-problems-menu__text\">{{ problem.message }}</span>\n </button>\n }\n </mat-menu>\n }\n\n <button\n mat-icon-button\n type=\"button\"\n data-testid=\"builder-undo\"\n [disabled]=\"!store.canUndo()\"\n (click)=\"store.undo()\"\n [matTooltip]=\"ui.text('undoTooltip')\"\n [attr.aria-label]=\"ui.text('undo')\"\n >\n <mat-icon>undo</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n data-testid=\"builder-redo\"\n [disabled]=\"!store.canRedo()\"\n (click)=\"store.redo()\"\n [matTooltip]=\"ui.text('redoTooltip')\"\n [attr.aria-label]=\"ui.text('redo')\"\n >\n <mat-icon>redo</mat-icon>\n </button>\n\n <button\n mat-button\n type=\"button\"\n (click)=\"copyJson()\"\n [matTooltip]=\"ui.text('copyJson')\"\n [attr.aria-label]=\"ui.text('copyJson')\"\n >\n <mat-icon>content_copy</mat-icon>\n <!-- The label goes on a narrow screen; the tooltip and aria-label above carry the name. -->\n <span class=\"deb-toolbar__btn-label\">{{ ui.text('copyJson') }}</span>\n </button>\n\n <button\n mat-button\n type=\"button\"\n data-testid=\"builder-rule-graph\"\n (click)=\"openRuleGraph()\"\n [matTooltip]=\"ui.text('ruleGraph')\"\n [attr.aria-label]=\"ui.text('ruleGraph')\"\n >\n <mat-icon>hub</mat-icon>\n <span class=\"deb-toolbar__btn-label\">{{ ui.text('ruleGraph') }}</span>\n </button>\n\n <button\n mat-icon-button\n type=\"button\"\n data-testid=\"toggle-fields\"\n class=\"deb-sidebar-toggle-btn\"\n [class.deb-sidebar-toggle-btn--active]=\"fieldsOpen()\"\n [attr.aria-expanded]=\"fieldsOpen()\"\n aria-controls=\"deb-fields-section\"\n (click)=\"toggleFields()\"\n [matTooltip]=\"fieldsOpen() ? ui.text('collapseFields') : ui.text('expandFields')\"\n [attr.aria-label]=\"fieldsOpen() ? ui.text('collapseFields') : ui.text('expandFields')\"\n >\n <mat-icon>{{ fieldsOpen() ? 'view_agenda' : 'table_rows' }}</mat-icon>\n </button>\n\n <button\n mat-icon-button\n type=\"button\"\n data-testid=\"toggle-preview\"\n class=\"deb-sidebar-toggle-btn\"\n [class.deb-sidebar-toggle-btn--active]=\"previewOpen()\"\n [attr.aria-expanded]=\"previewOpen()\"\n aria-controls=\"deb-preview-section\"\n (click)=\"togglePreview()\"\n [matTooltip]=\"previewOpen() ? ui.text('collapsePreview') : ui.text('expandPreview')\"\n [attr.aria-label]=\"previewOpen() ? ui.text('collapsePreview') : ui.text('expandPreview')\"\n >\n <mat-icon>{{ previewOpen() ? 'visibility' : 'visibility_off' }}</mat-icon>\n </button>\n\n <button\n mat-icon-button\n type=\"button\"\n data-testid=\"toggle-right-sidebar\"\n class=\"deb-sidebar-toggle-btn\"\n [class.deb-sidebar-toggle-btn--active]=\"rightSidebarOpen()\"\n [attr.aria-expanded]=\"rightSidebarOpen()\"\n aria-controls=\"deb-right-sidebar\"\n (click)=\"toggleRightSidebar()\"\n [matTooltip]=\"rightSidebarOpen() ? ui.text('collapseInspector') : ui.text('expandInspector')\"\n [attr.aria-label]=\"rightSidebarOpen() ? ui.text('collapseInspector') : ui.text('expandInspector')\"\n >\n <mat-icon>{{ rightSidebarOpen() ? 'vertical_split' : 'tune' }}</mat-icon>\n </button>\n\n <!--\n The tooltip sits on a wrapper, not on the button.\n\n A disabled button receives no pointer events, so a tooltip bound to it never fires — which\n is the one state where the explanation is worth having. Saving stays disabled here (unlike\n the renderer's Save, which refuses instead): an invalid *schema* is not something the\n author can be shown their way out of one field at a time, and the issue list beside this\n button is where that conversation happens.\n -->\n <span [matTooltip]=\"store.isValid() ? '' : ui.text('saveBlockedTooltip')\" [matTooltipDisabled]=\"store.isValid()\">\n <!-- primary, not accent: white on Material's default pink accent is 3.33:1, below AA. -->\n <button mat-flat-button color=\"primary\" type=\"button\" [disabled]=\"!store.isValid()\" (click)=\"doSave()\">\n <mat-icon>save</mat-icon> {{ ui.text('save') }}\n </button>\n </span>\n</mat-toolbar>\n\n<div\n class=\"deb-body\"\n [class.deb-body--left-collapsed]=\"!leftSidebarOpen()\"\n [class.deb-body--right-collapsed]=\"!rightSidebarOpen()\"\n>\n <!-- Collapsed left sidebar: the rail that brings it back. -->\n @if (!leftSidebarOpen()) {\n <button\n type=\"button\"\n class=\"deb-dock-btn deb-dock-btn--left\"\n data-testid=\"expand-left-sidebar\"\n aria-expanded=\"false\"\n aria-controls=\"deb-left-sidebar\"\n (click)=\"expandLeft()\"\n [matTooltip]=\"ui.text('expandPalette')\"\n [attr.aria-label]=\"ui.text('expandPalette')\"\n >\n <!--\n The card's own icon, not its name turned on its side. A 44px rail can only hold a\n label by rotating it, and a rotated word is one you have to tilt your head to read —\n worse in German, where \"Eigenschaften\" is half a screen tall. The tooltip and the\n accessible name carry the words; the label below returns when the rail lies flat.\n -->\n <mat-icon class=\"deb-dock-btn__icon\">add_circle_outline</mat-icon>\n <span class=\"deb-dock-btn__label\">{{ ui.text('paletteRailLabel') }}</span>\n <mat-icon class=\"deb-dock-btn__chevron\">chevron_right</mat-icon>\n </button>\n }\n\n <!-- ─── Left: settings, palette, tabs ─── -->\n <div\n id=\"deb-left-sidebar\"\n class=\"deb-col deb-col--left\"\n data-testid=\"builder-left-sidebar\"\n [hidden]=\"!leftSidebarOpen()\"\n >\n <mat-card class=\"deb-card deb-card--palette\">\n <mat-card-header>\n <mat-card-title class=\"deb-card__title\">\n <mat-icon class=\"deb-card__icon\">add_circle_outline</mat-icon>\n {{ ui.text('addField') }}\n </mat-card-title>\n <button\n mat-icon-button\n type=\"button\"\n class=\"deb-card__collapse-btn\"\n data-testid=\"collapse-left-sidebar\"\n aria-expanded=\"true\"\n aria-controls=\"deb-left-sidebar\"\n (click)=\"collapseLeft()\"\n [matTooltip]=\"ui.text('collapsePalette')\"\n [attr.aria-label]=\"ui.text('collapsePalette')\"\n >\n <mat-icon>chevron_left</mat-icon>\n </button>\n </mat-card-header>\n <mat-card-content>\n <ngx-field-palette (pick)=\"store.addField($event)\"></ngx-field-palette>\n </mat-card-content>\n </mat-card>\n\n <mat-card class=\"deb-card deb-card--settings\">\n <mat-card-header>\n <mat-card-title class=\"deb-card__title\">\n <mat-icon class=\"deb-card__icon\">tune</mat-icon>\n {{ store.config().entity || ui.text('entityName') }}\n </mat-card-title>\n </mat-card-header>\n <mat-card-content>\n <div class=\"deb-settings-grid\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('entityName') }}</mat-label>\n <input\n matInput\n [ngModel]=\"store.config().entity\"\n (ngModelChange)=\"store.setEntityName($event)\"\n [placeholder]=\"ui.text('entityNamePlaceholder')\"\n />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('editingLanguage') }}</mat-label>\n <mat-select\n data-testid=\"builder-editing-language\"\n [ngModel]=\"store.activeLanguage()\"\n (ngModelChange)=\"store.setActiveLanguage($event)\"\n >\n @for (l of languages; track l) {\n <mat-option [value]=\"l\">{{ l }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n\n <div class=\"deb-mask-row\">\n <mat-slide-toggle\n color=\"primary\"\n [ngModel]=\"store.config().maskData ?? false\"\n (ngModelChange)=\"store.setMaskData($event)\"\n >{{ ui.text('maskEntity') }}</mat-slide-toggle\n >\n </div>\n\n <mat-expansion-panel class=\"deb-rbac\">\n <mat-expansion-panel-header>\n <mat-panel-title>{{ ui.text('permissions') }}</mat-panel-title>\n </mat-expansion-panel-header>\n @for (action of rbacActions; track action) {\n @if (availableRoles.length) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('actionRoles', { action }) }}</mat-label>\n <mat-select multiple [ngModel]=\"rolesFor(action)\" (ngModelChange)=\"setRoles(action, $event)\">\n @for (role of availableRoles; track role) {\n <mat-option [value]=\"role\">{{ role }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n } @else {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('actionRolesPlaceholder', { action }) }}</mat-label>\n <input matInput [ngModel]=\"rolesFor(action).join(', ')\" (ngModelChange)=\"setRolesFromText(action, $event)\" />\n </mat-form-field>\n }\n }\n <p class=\"deb-hint\">{{ ui.text('permissionsHint') }}</p>\n </mat-expansion-panel>\n </mat-card-content>\n </mat-card>\n\n <mat-card class=\"deb-card deb-card--tabs\">\n <mat-card-content>\n <ngx-tab-manager></ngx-tab-manager>\n </mat-card-content>\n </mat-card>\n </div>\n\n <!-- ─── Center: field canvas, then what it renders as ─── -->\n <div class=\"deb-col deb-col--center\" data-testid=\"builder-canvas-column\">\n <!-- Collapsed fields canvas dock bar -->\n <div\n class=\"deb-dock-pane deb-dock-pane--fields\"\n [class.deb-dock-pane--open]=\"!fieldsOpen()\"\n [attr.aria-hidden]=\"fieldsOpen()\"\n >\n <div class=\"deb-dock-pane__inner\">\n <button\n type=\"button\"\n class=\"deb-dock-btn deb-dock-btn--horizontal deb-dock-btn--fields\"\n data-testid=\"expand-fields\"\n aria-expanded=\"false\"\n aria-controls=\"deb-fields-section\"\n (click)=\"expandFields()\"\n [matTooltip]=\"ui.text('expandFields')\"\n [attr.aria-label]=\"ui.text('expandFields')\"\n >\n <mat-icon class=\"deb-dock-btn__icon\">format_list_bulleted</mat-icon>\n <span class=\"deb-dock-btn__label\">{{ ui.text('fieldsRailLabel') }} ({{ store.fields().length }})</span>\n <mat-icon class=\"deb-dock-btn__chevron\">keyboard_arrow_down</mat-icon>\n </button>\n </div>\n </div>\n\n <!-- Fields canvas section -->\n <div\n id=\"deb-fields-section\"\n class=\"deb-toggle-pane deb-section--fields\"\n [class.deb-toggle-pane--collapsed]=\"!fieldsOpen()\"\n data-testid=\"builder-fields-section\"\n [attr.aria-hidden]=\"!fieldsOpen()\"\n >\n <div class=\"deb-toggle-pane__inner\">\n <ngx-entity-builder-canvas (collapse)=\"collapseFields()\" />\n </div>\n </div>\n\n <!-- Collapsed preview dock bar -->\n <div\n class=\"deb-dock-pane deb-dock-pane--preview\"\n [class.deb-dock-pane--open]=\"!previewOpen()\"\n [attr.aria-hidden]=\"previewOpen()\"\n >\n <div class=\"deb-dock-pane__inner\">\n <button\n type=\"button\"\n class=\"deb-dock-btn deb-dock-btn--horizontal deb-dock-btn--preview\"\n data-testid=\"expand-preview\"\n aria-expanded=\"false\"\n aria-controls=\"deb-preview-section\"\n (click)=\"expandPreview()\"\n [matTooltip]=\"ui.text('expandPreview')\"\n [attr.aria-label]=\"ui.text('expandPreview')\"\n >\n <mat-icon class=\"deb-dock-btn__icon\">visibility</mat-icon>\n <span class=\"deb-dock-btn__label\">{{ ui.text('previewRailLabel') }}</span>\n <mat-icon class=\"deb-dock-btn__chevron\">keyboard_arrow_up</mat-icon>\n </button>\n </div>\n </div>\n\n <!--\n The live preview, moved up from the footer.\n Directly under the field list is where a change and its effect can be seen in the same glance.\n -->\n <div\n id=\"deb-preview-section\"\n class=\"deb-toggle-pane deb-preview-slot\"\n [class.deb-toggle-pane--collapsed]=\"!previewOpen()\"\n data-testid=\"builder-preview-section\"\n [attr.aria-hidden]=\"!previewOpen()\"\n >\n <div class=\"deb-toggle-pane__inner\">\n <mat-card class=\"deb-card deb-card--preview\">\n <mat-card-header>\n <mat-card-title class=\"deb-card__title\">\n <mat-icon class=\"deb-card__icon\">visibility</mat-icon>\n {{ ui.text('previewHeading') }}\n </mat-card-title>\n <button\n mat-icon-button\n type=\"button\"\n class=\"deb-card__collapse-btn\"\n data-testid=\"collapse-preview\"\n aria-expanded=\"true\"\n aria-controls=\"deb-preview-section\"\n (click)=\"collapsePreview()\"\n [matTooltip]=\"ui.text('collapsePreview')\"\n [attr.aria-label]=\"ui.text('collapsePreview')\"\n >\n <mat-icon>keyboard_arrow_down</mat-icon>\n </button>\n </mat-card-header>\n <mat-card-content>\n <ng-content select=\"[ngxBuilderPreview]\"></ng-content>\n </mat-card-content>\n </mat-card>\n </div>\n </div>\n </div>\n\n <!-- Collapsed right sidebar: the rail that brings it back. -->\n @if (!rightSidebarOpen()) {\n <button\n type=\"button\"\n class=\"deb-dock-btn deb-dock-btn--right\"\n data-testid=\"expand-right-sidebar\"\n aria-expanded=\"false\"\n aria-controls=\"deb-right-sidebar\"\n (click)=\"expandRight()\"\n [matTooltip]=\"ui.text('expandInspector')\"\n [attr.aria-label]=\"ui.text('expandInspector')\"\n >\n <mat-icon class=\"deb-dock-btn__icon\">tune</mat-icon>\n <span class=\"deb-dock-btn__label\">{{ ui.text('inspectorRailLabel') }}</span>\n <mat-icon class=\"deb-dock-btn__chevron\">chevron_left</mat-icon>\n </button>\n }\n\n <!-- ─── Right: inspector ─── -->\n <div\n id=\"deb-right-sidebar\"\n class=\"deb-col deb-col--right\"\n data-testid=\"builder-right-sidebar\"\n [hidden]=\"!rightSidebarOpen()\"\n >\n <mat-card class=\"deb-card deb-card--inspector\">\n <mat-card-header>\n <mat-card-title class=\"deb-card__title\">\n <mat-icon class=\"deb-card__icon\">tune</mat-icon>\n {{ ui.text('fieldProperties') }}\n </mat-card-title>\n <button\n mat-icon-button\n type=\"button\"\n class=\"deb-card__collapse-btn\"\n data-testid=\"collapse-right-sidebar\"\n aria-expanded=\"true\"\n aria-controls=\"deb-right-sidebar\"\n (click)=\"collapseRight()\"\n [matTooltip]=\"ui.text('collapseInspector')\"\n [attr.aria-label]=\"ui.text('collapseInspector')\"\n >\n <mat-icon>chevron_right</mat-icon>\n </button>\n </mat-card-header>\n <mat-card-content>\n <ngx-field-inspector></ngx-field-inspector>\n </mat-card-content>\n </mat-card>\n </div>\n</div>\n\n<!-- ─── Footer: the exported JSON ─── -->\n<div class=\"deb-footer\">\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title><mat-icon>data_object</mat-icon>&nbsp;{{ ui.text('configJson') }}</mat-panel-title>\n </mat-expansion-panel-header>\n <pre class=\"deb-json\">{{ json }}</pre>\n </mat-expansion-panel>\n</div>\n\n@if (ruleGraphOpen()) {\n <ngx-rule-dependency-graph\n (dismiss)=\"closeRuleGraph()\"\n (selectField)=\"onSelectFieldFromGraph($event)\"\n />\n}\n","// Main component\nexport * from './lib/entity-builder.component';\n\n// Sub-components (individually importable — reusability rule, mirrors ngx-dynamic-entity)\nexport * from './lib/components/field-palette.component';\nexport * from './lib/components/field-inspector.component';\nexport * from './lib/components/tab-manager.component';\nexport * from './lib/components/rule-form.component';\nexport * from './lib/components/field-rules-list.component';\nexport * from './lib/components/entity-reference-config.component';\nexport * from './lib/components/entity-builder-canvas.component';\nexport * from './lib/components/entity-builder-tree-node.component';\nexport * from './lib/components/rule-dependency-graph.component';\n\n// UI text for the builder's own chrome\nexport * from './lib/builder-text';\n\n// Store (provided per builder instance)\nexport * from './lib/builder-store.service';\n\n// Catalog + helpers\nexport * from './lib/field-catalog';\nexport * from './lib/field-path-options';\nexport * from './lib/rule-dependencies';\n\n// Re-export the core types a consumer of the builder needs\nexport type {\n EntityFormConfig,\n NestedTabConfig,\n NestedFieldConfig,\n RichFieldType,\n DropdownOption,\n EntityPermissions,\n EntityReferenceConfig,\n AutoPatchConfig,\n AutoPatchMapping,\n PatchOnTrueMapping,\n FormRule,\n RuleCondition,\n RuleAction,\n RuleOperator,\n} from '@dynamic-entity/core';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i5","i8","i3","i4","i6","i2","i9","i1","i7","i12"],"mappings":"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"}
1
+ {"version":3,"file":"ngx-dynamic-entity-builder.mjs","sources":["../../src/lib/field-catalog.ts","../../src/lib/clone.ts","../../src/lib/builder-history.ts","../../src/lib/builder-store.service.ts","../../src/lib/field-path-options.ts","../../src/lib/rule-dependencies.ts","../../src/lib/builder-text.ts","../../src/lib/components/entity-reference-config.component.ts","../../src/lib/components/rule-form.component.ts","../../src/lib/components/field-rules-list.component.ts","../../src/lib/components/referenced-field-config.component.ts","../../src/lib/components/field-inspector.component.ts","../../src/lib/components/field-inspector.component.html","../../src/lib/components/field-palette.component.ts","../../src/lib/components/tab-manager.component.ts","../../src/lib/components/entity-builder-tree-node.component.ts","../../src/lib/components/entity-builder-canvas.component.ts","../../src/lib/components/rule-dependency-graph.component.ts","../../src/lib/entity-builder.component.ts","../../src/lib/entity-builder.component.html","../../src/public-api.ts","../../src/ngx-dynamic-entity-builder.ts"],"sourcesContent":["/**\n * field-catalog.ts — re-exports shared field catalog from @dynamic-entity/core.\n * Single source of truth shared by both visual builder and renderer.\n */\nexport {\n FIELD_TYPE_CATALOG,\n getFieldTypeMeta,\n humanizeId,\n createFieldConfig,\n type FieldTypeMeta,\n type FlagValidator,\n type ParamValidator,\n} from '@dynamic-entity/core';\n","/**\n * Deep clone with a JSON fallback.\n *\n * `structuredClone` is not universally available (older browsers, and jsdom before v22),\n * so it must never be called unguarded — an unguarded call throws a ReferenceError and the\n * caller silently does nothing. Config and rule objects are JSON-safe, so the fallback is\n * lossless here.\n */\nexport function deepClone<T>(value: T): T {\n if (typeof structuredClone === 'function') return structuredClone(value);\n return JSON.parse(JSON.stringify(value)) as T;\n}\n","import { computed, signal } from '@angular/core';\n\n/**\n * Bounded undo/redo over immutable states, with keystroke coalescing.\n *\n * Entries hold **references, not clones**. The store builds a new state on every edit and\n * shares unchanged subtrees, so every entry already refers to immutable objects. Undo puts\n * the stored object back, so a `record` that follows sees the reference already sitting at\n * the cursor and skips it — no suppression flag to get out of step.\n *\n * Deliberately free of Angular DI: signals need no injection context, so `new BuilderStore()`\n * keeps working and a test can assert straight after an edit without flushing effects.\n */\nexport class BuilderHistory<S> {\n private readonly entries: { state: S; shape: string }[] = [];\n private readonly cursor = signal(-1);\n private readonly length = signal(0);\n private lastEditAt = 0;\n\n readonly canUndo = computed(() => this.cursor() > 0);\n readonly canRedo = computed(() => this.cursor() < this.length() - 1);\n\n /**\n * @param shapeOf Counts that distinguish a structural edit from a value edit. Two\n * consecutive edits merge only when their shapes match.\n * @param same Whether two states are the same state (reference identity, in practice).\n */\n constructor(\n private readonly shapeOf: (state: S) => string,\n private readonly same: (a: S, b: S) => boolean,\n private readonly maxEntries = 200,\n private readonly coalesceMs = 400,\n ) {}\n\n /**\n * Fold a state into history.\n *\n * Recording the same state twice is harmless. A label bound to a keystroke would otherwise\n * make undo walk back one character at a time, so two consecutive edits merge when they\n * land inside `coalesceMs` *and* the shape is unchanged — a rename coalesces, while adding,\n * removing or moving anything always earns its own step however fast it is clicked.\n */\n record(state: S): void {\n const at = this.cursor();\n const top = at >= 0 ? this.entries[at] : undefined;\n if (top && this.same(top.state, state)) return;\n\n const now = Date.now();\n const entry = { state, shape: this.shapeOf(state) };\n\n if (top && now - this.lastEditAt < this.coalesceMs && top.shape === entry.shape && at === this.entries.length - 1) {\n this.entries[at] = entry;\n this.lastEditAt = now;\n return;\n }\n\n // A new edit after an undo discards the redo branch, which is what every editor does.\n this.entries.length = at + 1;\n this.entries.push(entry);\n // Bounded: a builder session is long, and the oldest steps are the ones nobody walks back to.\n if (this.entries.length > this.maxEntries) {\n this.entries.splice(0, this.entries.length - this.maxEntries);\n }\n\n this.cursor.set(this.entries.length - 1);\n this.length.set(this.entries.length);\n this.lastEditAt = now;\n }\n\n /** Start again from `state`. Nothing before it is undoable. */\n reset(state: S): void {\n this.entries.length = 0;\n this.entries.push({ state, shape: this.shapeOf(state) });\n this.cursor.set(0);\n this.length.set(1);\n this.lastEditAt = 0;\n }\n\n /** Step back, returning the state to restore, or `null` when there is none. */\n undo(): S | null {\n return this.canUndo() ? this.moveTo(this.cursor() - 1) : null;\n }\n\n /** Step forward, returning the state to restore, or `null` when there is none. */\n redo(): S | null {\n return this.canRedo() ? this.moveTo(this.cursor() + 1) : null;\n }\n\n private moveTo(index: number): S | null {\n const entry = this.entries[index];\n if (!entry) return null;\n this.cursor.set(index);\n return entry.state;\n }\n}\n","import { Injectable, computed, signal } from '@angular/core';\nimport type {\n AutoPatchMapping,\n DropdownOption,\n EntityFormConfig,\n EntityPermissions,\n EntityReferenceConfig,\n FormRule,\n NestedFieldConfig,\n NestedTabConfig,\n PatchOnTrueMapping,\n RichFieldType,\n} from '@dynamic-entity/core';\nimport {\n OPTION_KEY,\n computeFieldDrift,\n createFieldSnapshot,\n findTab,\n labelToId,\n normalizeConfigOptions,\n optionKeyOf,\n resolveLabel,\n} from '@dynamic-entity/core';\nimport { assignFieldRefs, collectFieldScopes, fieldRefFor, parseFieldRef, toRefToken } from '@dynamic-entity/core';\nimport { createFieldConfig, getFieldTypeMeta, humanizeId, type FlagValidator, type ParamValidator } from './field-catalog';\nimport { deepClone } from './clone';\nimport { BuilderHistory } from './builder-history';\n\nexport interface BuilderProblem {\n level: 'error' | 'warning';\n message: string;\n fieldId?: string;\n}\n\n/** One tab's own fields, for a canvas that has to reorder within the right tab. */\nexport interface BuilderFieldGroup {\n tabId: string;\n label: NestedTabConfig['label'];\n fields: NestedFieldConfig[];\n}\n\nconst clone = deepClone;\n\nconst ID_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/**\n * The regex the builder used to write into `pattern` to mean \"email\".\n *\n * Retained only to recognise configs authored before `FieldValidators.email` existed, so\n * they still show Email as ticked and do not leave a stray pattern behind when it is\n * un-ticked. Nothing writes it any more.\n */\nconst LEGACY_EMAIL_PATTERN = '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}$';\n\n/** One undoable state of the builder: the config and the rules that belong with it. */\ninterface BuilderSnapshot {\n readonly config: EntityFormConfig;\n readonly rules: FormRule[];\n}\n\n/** Counts that distinguish a structural edit from a value edit. */\nfunction shapeOf({ config, rules }: BuilderSnapshot): string {\n let fields = 0;\n let tabs = 0;\n const walkFields = (list: NestedFieldConfig[] | undefined): void => {\n for (const f of list ?? []) {\n fields += 1;\n walkFields(f.children);\n }\n };\n const walkTabs = (list: NestedTabConfig[] | undefined): void => {\n for (const t of list ?? []) {\n tabs += 1;\n walkFields(t.fields);\n walkTabs(t.children);\n }\n };\n walkTabs(config.tabs);\n return `${tabs}:${fields}:${rules.length}`;\n}\n\n/**\n * Follow a field rename through a rule reference, in either spelling.\n *\n * This matched the bare id alone, while the builder authors rules by **path** —\n * `[personal.address.city]`, because a bare id cannot name one of two fields that share\n * one. So renaming a field silently orphaned every rule the builder itself had written: the\n * rule kept pointing at a path nothing resolved to, and nothing said so.\n *\n * A path's last segment is the field id, which is what makes this exact rather than a\n * substring replace — `[work.status]` must not be rewritten by renaming `statusCode`, and\n * `[status.city]` must not be rewritten by renaming `status`.\n */\nfunction repointRef(reference: string, oldId: string, newId: string): string {\n const parsed = parseFieldRef(reference);\n if (parsed.kind === 'id') return parsed.value === oldId ? newId : reference;\n\n const segments = parsed.value.split('.');\n if (segments[segments.length - 1] !== oldId) return reference;\n segments[segments.length - 1] = newId;\n return toRefToken(segments.join('.'));\n}\n\n@Injectable()\nexport class BuilderStore {\n private readonly _config = signal<EntityFormConfig>(this.emptyConfig());\n private readonly _selectedFieldId = signal<string | null>(null);\n private readonly _activeLanguage = signal<string>('en');\n /** Rules live beside the config: they are persisted per form, not inside `EntityFormConfig`. */\n private readonly _rules = signal<FormRule[]>([]);\n /**\n * Field ids the author owns — set by an explicit rename, or by loading a saved config\n * whose ids are already live data keys. Ids outside this set are still derived from the\n * field's label. Builder-session state, deliberately not part of the exported config.\n */\n private readonly manualIds = new Set<string>();\n /**\n * Fields whose `refererField` the config declared, rather than the builder stamping it.\n *\n * A declared path is a deliberate binding override and must survive a structural edit. A\n * stamped one is just the field's address, so it has to be rewritten when the field moves.\n * Without the distinction, restamping would destroy the override and not restamping would\n * leave a moved field pointing at where it used to be.\n */\n private readonly authoredRefs = new Set<string>();\n\n private readonly _isDirty = signal<boolean>(false);\n\n /**\n * Roles of the person using the builder — distinct from `availableRoles`, which is the\n * vocabulary a schema may reference. Needed so the SYSTEM_DEFAULT_CAN_EDIT predicate can\n * be asked a real question rather than answering for an empty role list.\n */\n private readonly _userRoles = signal<string[]>([]);\n\n // ─── Undo / redo ────────────────────────────────────────────────────────────\n //\n // History stores {config, rules} pairs, because the builder's state is two signals and\n // undoing one without the other would leave a rule pointing at a field that no longer\n // exists. Write paths call `record()` explicitly rather than from an `effect`, which would\n // need an injection context and break `new BuilderStore()`.\n private readonly history = new BuilderHistory<BuilderSnapshot>(\n shapeOf,\n (a, b) => a.config === b.config && a.rules === b.rules,\n );\n\n readonly canUndo = this.history.canUndo;\n readonly canRedo = this.history.canRedo;\n\n private record(): void {\n this.history.record({ config: this._config(), rules: this._rules() });\n }\n\n /** Start history again from the state just loaded. Nothing before it is undoable. */\n private resetHistory(): void {\n this.history.reset({ config: this._config(), rules: this._rules() });\n }\n\n undo(): void {\n this.restore(this.history.undo());\n }\n\n redo(): void {\n this.restore(this.history.redo());\n }\n\n private restore(snapshot: BuilderSnapshot | null): void {\n if (!snapshot) return;\n this._config.set(snapshot.config);\n this._rules.set(snapshot.rules);\n this._isDirty.set(true);\n\n // The selected field may not exist in the state being restored.\n const selected = this._selectedFieldId();\n if (selected && !this.findFieldInTabs(snapshot.config.tabs, selected)) {\n this._selectedFieldId.set(null);\n }\n }\n\n readonly config = this._config.asReadonly();\n readonly selectedFieldId = this._selectedFieldId.asReadonly();\n readonly activeLanguage = this._activeLanguage.asReadonly();\n readonly rules = this._rules.asReadonly();\n readonly isDirty = this._isDirty.asReadonly();\n readonly userRoles = this._userRoles.asReadonly();\n\n readonly tabs = computed<NestedTabConfig[]>(() => this._config().tabs ?? []);\n\n /**\n * Every field the config declares, sub-tabs included.\n *\n * The canvas, the entity-reference source picker and the drift check all read this, so it\n * has to reach nested tabs just as the store's structural operations do.\n *\n * It deliberately does not descend into a field's own `children`: `group` and `array`\n * children are rendered by the row that owns them, not as rows of their own.\n */\n readonly fields = computed<NestedFieldConfig[]>(() => this.getAllFields(this._config().tabs ?? []));\n\n /**\n * The same fields, kept in their owning tab.\n *\n * Drag-and-drop reorders by index, so the canvas needs to know which tab an index belongs\n * to — `reorderField` has always taken a `tabId` for exactly this, and the canvas simply\n * never passed one. Without the grouping a drag on any config with more than one tab\n * reordered `tabs[0]` regardless of what was actually dragged.\n */\n readonly fieldGroups = computed<BuilderFieldGroup[]>(() =>\n this.flattenTabs(this._config().tabs ?? [])\n .filter(tab => (tab.fields ?? []).length > 0)\n .map(tab => ({ tabId: tab.id, label: tab.label, fields: tab.fields ?? [] })),\n );\n\n readonly selectedField = computed<NestedFieldConfig | null>(() => {\n const id = this._selectedFieldId();\n if (!id) return null;\n return this.findFieldInTabs(this._config().tabs, id);\n });\n\n readonly problems = computed<BuilderProblem[]>(() => this.validate(this._config()));\n readonly errors = computed<BuilderProblem[]>(() => this.problems().filter(p => p.level === 'error'));\n readonly isValid = computed<boolean>(() => this.errors().length === 0);\n\n // ─── Initialisation ─────────────────────────────────────────────────────────\n\n load(config: EntityFormConfig, rules: readonly FormRule[] = []): void {\n // Remember the paths the config declared before filling in the rest, so a deliberate\n // binding override is never mistaken for one of ours and rewritten.\n this.authoredRefs.clear();\n for (const entry of collectFieldScopes(config)) {\n if (entry.field?.id && entry.field.refererField) this.authoredRefs.add(entry.field.id);\n }\n assignFieldRefs(config);\n // Check if any fields carry both inline options and listName before normalizing options\n const fieldsWithBoth = this.getAllFields(config.tabs ?? []).filter(\n f => Array.isArray(f.options) && f.options.length > 0 && typeof f.listName === 'string' && f.listName.trim() !== '',\n );\n for (const f of fieldsWithBoth) {\n console.warn(\n `[BuilderStore] Field \"${f.id}\" carries both inline options and listName \"${f.listName}\". ` +\n `Inline options win; listName was dropped.`,\n );\n }\n\n // The other boundary where a config enters the library (the renderer's ngOnChanges is\n // the first). Authoring must start from the canonical option shape, or the builder\n // would round-trip a legacy config straight back out unchanged.\n const next = clone(normalizeConfigOptions(config));\n next.tabs = next.tabs ?? [];\n if (next.tabs.length === 0) {\n next.tabs = [{ id: 'default', label: { en: 'Default' }, fields: [] }];\n }\n this._config.set(next);\n const firstField = this.getAllFields(next.tabs)[0];\n this._selectedFieldId.set(firstField?.id ?? null);\n this._activeLanguage.set(next.defaultLanguage ?? 'en');\n\n // Ids in a saved config are live data keys — records are already stored under them.\n // Editing a label must never rewrite one, so freeze every id the config arrived with.\n this.manualIds.clear();\n for (const field of this.getAllFields(next.tabs)) this.manualIds.add(field.id);\n // Set before the baseline is taken, not after. A snapshot is a `{config, rules}` pair —\n // that is why history stores them together — so seeding them as two recorded operations\n // would put a step on the stack for a load nobody performed, and leave a fresh builder\n // offering to undo the act of opening it.\n this._rules.set(clone(rules as FormRule[]));\n this._isDirty.set(false);\n this.resetHistory();\n }\n\n reset(entity = ''): void {\n this._config.set(this.emptyConfig(entity));\n this._selectedFieldId.set(null);\n this._rules.set([]);\n this.manualIds.clear();\n this._isDirty.set(false);\n this.resetHistory();\n }\n\n resetDirty(): void {\n this._isDirty.set(false);\n }\n\n private emptyConfig(entity = ''): EntityFormConfig {\n return {\n entity,\n version: 1,\n defaultLanguage: 'en',\n tabs: [],\n };\n }\n\n // ─── Entity-level settings ──────────────────────────────────────────────────\n\n setEntityName(entity: string): void {\n this.mutate(draft => {\n draft.entity = entity.trim();\n });\n }\n\n setDefaultLanguage(language: string): void {\n this.mutate(draft => {\n draft.defaultLanguage = language;\n });\n }\n\n setMaskData(mask: boolean): void {\n this.mutate(draft => {\n draft.maskData = mask;\n });\n }\n\n setPermission(action: keyof EntityPermissions, roles: string[]): void {\n this.mutate(draft => {\n const permissions: EntityPermissions = { ...(draft.permissions ?? {}) };\n permissions[action] = roles;\n draft.permissions = permissions;\n });\n }\n\n setActiveLanguage(language: string): void {\n this._activeLanguage.set(language);\n }\n\n /** Roles of the person using the builder, for SYSTEM_DEFAULT_CAN_EDIT. */\n setUserRoles(roles: string[]): void {\n this._userRoles.set(roles ?? []);\n }\n\n // ─── Helper Traversal ───────────────────────────────────────────────────────\n\n private getAllFields(tabs: NestedTabConfig[] = []): NestedFieldConfig[] {\n const list: NestedFieldConfig[] = [];\n for (const t of tabs) {\n if (t.fields) list.push(...t.fields);\n if (t.children) list.push(...this.getAllFields(t.children));\n }\n return list;\n }\n\n /**\n * Every tab in the tree, flattened.\n *\n * The structural operations below go through this rather than `draft.tabs`, which is only\n * the top level — otherwise a field on a sub-tab could be edited but never removed,\n * duplicated, moved or reordered.\n */\n private flattenTabs(tabs: NestedTabConfig[] = []): NestedTabConfig[] {\n const list: NestedTabConfig[] = [];\n for (const t of tabs) {\n list.push(t);\n if (t.children) list.push(...this.flattenTabs(t.children));\n }\n return list;\n }\n\n /**\n * Every field id in the config, including `group`/`array` children.\n *\n * Id uniqueness is a whole-config invariant, not a per-tab one: rules, `showWhen`\n * conditions and `autoPatch` mappings all address fields by bare id, so two fields\n * sharing an id anywhere in the tree interfere with each other. Uniqueness checks must\n * therefore see deeper than `fields()`, which stops at a tab's own fields.\n */\n private allFieldIds(tabs: NestedTabConfig[] = []): Set<string> {\n const ids = new Set<string>();\n const walkFields = (fields: NestedFieldConfig[] | undefined) => {\n for (const f of fields ?? []) {\n ids.add(f.id);\n if (f.children?.length) walkFields(f.children);\n }\n };\n for (const tab of this.flattenTabs(tabs)) walkFields(tab.fields);\n return ids;\n }\n\n /**\n * Resolve a field by key, where a key is either its `refererField` path or a bare id.\n *\n * Every resolution in this store funnels through here, which is why a bare id was enough\n * to edit the wrong field: with `personal.address` and `work.address` both present, the\n * first match won, so selecting or editing the second one silently addressed the first.\n *\n * The path is tried across the whole tree before any bare id is, so an exact key never\n * loses to a nearer-but-wrong match. Bare ids still resolve — every existing caller and\n * spec passes one, and for an unambiguous id it is the same field either way.\n */\n private findFieldInTabs(tabs: NestedTabConfig[] = [], key: string): NestedFieldConfig | null {\n return this.findFieldBy(tabs, f => f.refererField === key) ?? this.findFieldBy(tabs, f => f.id === key);\n }\n\n private findFieldBy(tabs: NestedTabConfig[] = [], match: (f: NestedFieldConfig) => boolean): NestedFieldConfig | null {\n for (const t of tabs) {\n const found = t.fields?.find(match);\n if (found) return found;\n if (t.children) {\n const nested = this.findFieldBy(t.children, match);\n if (nested) return nested;\n }\n }\n return null;\n }\n\n /**\n * The key a caller should hand back to address this exact field. Templates use it so a\n * click on the second of two same-named fields selects that one.\n */\n keyOf(field: { id: string; refererField?: string }): string {\n return field.refererField || field.id;\n }\n\n /**\n * Whether this exact field is the selected one.\n *\n * Not `selectedFieldId() === field.id`: selection may hold a bare id or a path depending\n * on who set it, and with two fields sharing an id a bare comparison lights up both rows\n * — or neither, once the click starts storing a path. Resolving both sides answers for\n * the field itself.\n */\n isSelected(field: NestedFieldConfig): boolean {\n const key = this._selectedFieldId();\n if (!key) return false;\n // Same key, same field — and this is the path a row click takes, so it is the common\n // case. It also covers a field handed in as an @Input that the store's own config has\n // no object for, which identity alone cannot.\n if (key === this.keyOf(field)) return true;\n // Otherwise the selection is in the other form (a bare id against a field that carries a\n // path, or vice versa), so let it resolve and compare the field it names.\n const resolved = this.findFieldInTabs(this._config().tabs, key);\n return !!resolved && resolved === field;\n }\n\n // ─── Field CRUD ─────────────────────────────────────────────────────────────\n\n addField(type: RichFieldType, targetTabId?: string): string {\n const meta = getFieldTypeMeta(type);\n const prefix = meta?.idPrefix ?? 'field';\n const id = this.uniqueId(prefix, this.allFieldIds(this._config().tabs));\n\n this.mutate(draft => {\n const field = createFieldConfig(type, id, draft.defaultLanguage ?? 'en');\n const targetTab = targetTabId ? this.flattenTabs(draft.tabs).find(t => t.id === targetTabId) : draft.tabs[0];\n if (targetTab) {\n targetTab.fields = targetTab.fields ?? [];\n targetTab.fields.push(field);\n } else {\n draft.tabs.push({ id: 'main', label: { en: 'Main' }, fields: [field] });\n }\n });\n this._selectedFieldId.set(id);\n return id;\n }\n\n updateField(id: string, patch: Partial<NestedFieldConfig>): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, id);\n if (field) Object.assign(field, patch);\n });\n }\n\n /**\n * Rename a field explicitly, pinning the id so it is no longer derived from the label.\n *\n * Not reachable from the inspector — the id input is read-only by design. This exists for\n * programmatic callers that must match an id to an existing data key.\n */\n renameField(oldId: string, newId: string): void {\n const trimmed = newId.trim();\n if (!trimmed || trimmed === oldId) return;\n if (this.allFieldIds(this._config().tabs).has(trimmed)) return;\n if (!this.findFieldInTabs(this._config().tabs, oldId)) return;\n\n this.applyRename(oldId, oldId, trimmed);\n this.manualIds.delete(oldId);\n this.manualIds.add(trimmed);\n }\n\n /** Whether this field's id is pinned (loaded from storage or explicitly renamed). */\n hasManualId(id: string): boolean {\n return this.manualIds.has(id);\n }\n\n /**\n * Move a field to a new id and repoint every id-based reference in the config at it.\n *\n * Ids are the wiring between fields — rules, cascades, patches and `showWhen` all address\n * fields by id — so a rename that only touches `field.id` silently breaks that wiring.\n * Label-derived ids make renaming routine, so the references move with it.\n *\n * `key` addresses the field to rename; `oldId` is the bare id every *reference* to it\n * carries. They are separate because resolving needs the path, while `showWhen`,\n * `parentField`, `autoPatch` targets and rules are all keyed by bare id.\n */\n private applyRename(key: string, oldId: string, newId: string): void {\n // Selection is held as whatever the caller passed — `addField` stores a bare id while a\n // canvas click stores a path — so compare the fields the two keys resolve to, not the\n // strings.\n const selectedKey = this._selectedFieldId();\n const tabsNow = this._config().tabs;\n const wasSelected = !!selectedKey && this.findFieldInTabs(tabsNow, selectedKey) === this.findFieldInTabs(tabsNow, key);\n\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, key);\n if (!field) return;\n field.id = newId;\n\n const walkFields = (fields: NestedFieldConfig[] | undefined) => {\n for (const f of fields ?? []) {\n if (f.showWhen && oldId in f.showWhen) {\n const next: Record<string, unknown> = {};\n // Rebuild in place so condition order survives the rename.\n for (const [key, value] of Object.entries(f.showWhen)) {\n next[key === oldId ? newId : key] = value;\n }\n f.showWhen = next;\n }\n if (f.entityReference?.parentField === oldId) {\n f.entityReference = { ...f.entityReference, parentField: newId };\n }\n if (f.autoPatch) {\n // `source` names a field on the *linked* record, not this config — leave it.\n f.autoPatch = {\n ...f.autoPatch,\n mappings: f.autoPatch.mappings.map(m => (m.target === oldId ? { ...m, target: newId } : m)),\n };\n }\n if (f.patchOnTrue) {\n f.patchOnTrue = f.patchOnTrue.map(m => ({\n from: m.from === oldId ? newId : m.from,\n to: m.to === oldId ? newId : m.to,\n }));\n }\n if (f.children?.length) walkFields(f.children);\n }\n };\n const walkTabs = (tabs: NestedTabConfig[] | undefined) => {\n for (const tab of tabs ?? []) {\n walkFields(tab.fields);\n walkTabs(tab.children);\n }\n };\n walkTabs(draft.tabs);\n });\n\n this._rules.update(rules =>\n rules.map(rule => ({\n ...rule,\n fieldId: repointRef(rule.fieldId, oldId, newId),\n conditions: rule.conditions?.map(c =>\n c?.compareToField\n ? { ...c, compareToField: repointRef(c.compareToField, oldId, newId) }\n : c,\n ),\n targets: rule.targets.map(t =>\n t.type === 'field' ? { ...t, id: repointRef(t.id, oldId, newId) } : t,\n ),\n })),\n );\n\n // `mutate` restamps `refererField`, so the key's last segment moves with the id. Without\n // this the selection points at a path nothing resolves to any more, and the inspector\n // empties itself mid-keystroke as soon as a typed label derives a new id.\n this.record();\n\n if (wasSelected) {\n // Keep the shape the selection already had: a bare id stays bare, a path keeps its\n // scope and moves only its last segment.\n const cut = selectedKey!.lastIndexOf('.');\n this._selectedFieldId.set(cut === -1 ? newId : `${selectedKey!.slice(0, cut + 1)}${newId}`);\n }\n }\n\n removeField(key: string): void {\n let removedId: string | null = null;\n this.mutate(draft => {\n // Resolve inside the draft, then remove that one by identity. Filtering on\n // `f.id !== id` deleted every field sharing the id, so removing `work.address` took\n // `personal.address` with it.\n const target = this.findFieldInTabs(draft.tabs, key);\n if (!target) return;\n removedId = target.id;\n for (const tab of this.flattenTabs(draft.tabs)) {\n if (tab.fields) {\n tab.fields = tab.fields.filter(f => f !== target);\n }\n }\n });\n if (removedId === null) return;\n // `manualIds` is keyed by bare id and shared by every field carrying it, so it is only\n // safe to forget once no field uses that id any more.\n if (!this.getAllFields(this._config().tabs ?? []).some(f => f.id === removedId)) {\n this.manualIds.delete(removedId);\n }\n if (this._selectedFieldId() === key) this._selectedFieldId.set(null);\n }\n\n duplicateField(id: string): string | null {\n // Look the source up by id — not by current selection. The insert below searches by id\n // too, so falling back to the selected field could report a new id while inserting\n // nothing, or duplicate a field the caller never named.\n const source = this.findFieldInTabs(this._config().tabs, id);\n if (!source) return null;\n const meta = getFieldTypeMeta(source.type);\n const prefix = meta?.idPrefix ?? 'field';\n const newId = this.uniqueId(prefix, this.allFieldIds(this._config().tabs));\n\n this.mutate(draft => {\n for (const tab of this.flattenTabs(draft.tabs)) {\n const index = (tab.fields ?? []).findIndex(f => f.id === id);\n if (index !== -1) {\n const copy = clone(source);\n copy.id = newId;\n tab.fields!.splice(index + 1, 0, copy);\n break;\n }\n }\n });\n this._selectedFieldId.set(newId);\n return newId;\n }\n\n moveField(key: string, direction: -1 | 1): void {\n this.mutate(draft => {\n // Resolve by key, then locate that object — `f.id === id` moved whichever same-named\n // field the walk reached first, which for two `address` fields was never the one the\n // arrow button belonged to.\n const wanted = this.findFieldInTabs(draft.tabs, key);\n if (!wanted) return;\n\n for (const tab of this.flattenTabs(draft.tabs)) {\n const fields = tab.fields ?? [];\n const from = fields.findIndex(f => f === wanted);\n if (from !== -1) {\n const to = from + direction;\n if (to < 0 || to >= fields.length) return;\n const [item] = fields.splice(from, 1);\n fields.splice(to, 0, item);\n return;\n }\n }\n });\n }\n\n /**\n * Moves a field to another tab, keeping its id.\n *\n * The builder could add, remove, duplicate and reorder a field but never relocate one, so\n * a field authored on the wrong tab had to be deleted and rebuilt — losing its validators,\n * options and any rule that pointed at it.\n *\n * The field's `refererField` changes, because it is an address and the field now has a new one.\n * `mutate` restamps it and repoints the rules that named it, so a move does not silently\n * strand them.\n */\n moveFieldToTab(id: string, targetTabId: string): boolean {\n const target = this.flattenTabs(this._config().tabs).find(t => t.id === targetTabId);\n if (!target) return false;\n\n let moved = false;\n this.mutate(draft => {\n const targetTab = this.flattenTabs(draft.tabs).find(t => t.id === targetTabId);\n if (!targetTab) return;\n\n // Resolve by key first so a path names one field, then locate that object. Matching\n // `f.id === id` moved whichever same-named field came first in the walk.\n const wanted = this.findFieldInTabs(draft.tabs, id);\n if (!wanted) return;\n\n for (const tab of this.flattenTabs(draft.tabs)) {\n const index = (tab.fields ?? []).findIndex(f => f === wanted);\n if (index === -1) continue;\n if (tab.id === targetTabId) return; // already there; nothing to do\n\n const [field] = tab.fields!.splice(index, 1);\n targetTab.fields = targetTab.fields ?? [];\n targetTab.fields.push(field);\n moved = true;\n return;\n }\n });\n return moved;\n }\n\n /** Safe reorder for drag & drop within active tab or flat list */\n reorderField(fromIndex: number, toIndex: number, tabId?: string): void {\n this.mutate(draft => {\n const targetTab = tabId ? this.flattenTabs(draft.tabs).find(t => t.id === tabId) : draft.tabs[0];\n const fields = targetTab?.fields ?? [];\n if (fromIndex < 0 || toIndex < 0 || fromIndex >= fields.length || toIndex >= fields.length) {\n return;\n }\n const [item] = fields.splice(fromIndex, 1);\n fields.splice(toIndex, 0, item);\n });\n }\n\n selectField(id: string | null): void {\n this._selectedFieldId.set(id);\n }\n\n // ─── Localised text ─────────────────────────────────────────────────────────\n\n /**\n * Set a field's label, and derive the field's id from it: type \"Employee Count\", get\n * `employeeCount`. The inspector renders the id read-only, so this is the only way a\n * new field's id is set.\n *\n * Two things stop derivation: a config loaded from storage (its ids are live data keys\n * that records are already stored under — see `load`), and an explicit `renameField`\n * call, which remains available to programmatic callers.\n *\n * Only the config's default language drives the id; translating a label must not rename\n * anything.\n */\n setFieldLabel(key: string, language: string, value: string): void {\n // Bound to a keystroke event, so this uses the structural-sharing path.\n this.mutateField(key, field => ({ ...field, label: { ...field.label, [language]: value } }));\n\n if (language !== (this._config().defaultLanguage ?? 'en')) return;\n\n // The mutation is addressed by key, but everything below is about the *id*: `manualIds`\n // records bare ids, `availableId` compares bare ids, and a rename replaces one. Reading\n // the field's own id keeps the two straight — passing the path into `manualIds.has`\n // would never match, so a pinned id would silently start following the label again.\n const field = this.findFieldInTabs(this._config().tabs, key);\n if (!field) return;\n const currentId = field.id;\n if (this.manualIds.has(currentId)) return;\n\n const derived = labelToId(value);\n if (!derived || derived === currentId) return;\n\n this.applyRename(this.keyOf(field), currentId, this.availableId(derived, currentId));\n }\n\n /** `derived`, or `derived_2`, `derived_3`… if another field already holds it. */\n private availableId(derived: string, currentId: string): string {\n const taken = new Set([...this.allFieldIds(this._config().tabs)].filter(fid => fid !== currentId));\n if (!taken.has(derived)) return derived;\n\n let n = 2;\n while (taken.has(`${derived}_${n}`)) n += 1;\n return `${derived}_${n}`;\n }\n\n setFieldPlaceholder(id: string, language: string, value: string): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, id);\n if (!field) return;\n field.placeholder = { ...(field.placeholder ?? {}), [language]: value };\n });\n }\n\n /**\n * Help text shown under the control, per language.\n *\n * Separate from the placeholder for the reason the schema keeps them separate: a\n * placeholder vanishes the moment the user types, so anything they need *while* filling the\n * field in cannot live there. An author with only a placeholder box to write in tends to\n * put it there anyway.\n */\n setFieldHint(id: string, language: string, value: string): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, id);\n if (!field) return;\n field.hint = { ...(field.hint ?? {}), [language]: value };\n });\n }\n\n // ─── Validators ─────────────────────────────────────────────────────────────\n\n toggleFlagValidator(id: string, validator: FlagValidator, on: boolean): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, id);\n if (!field) return;\n field.validators = field.validators ?? {};\n if (validator === 'required') {\n if (on) field.validators.required = true;\n else delete field.validators.required;\n } else if (validator === 'email') {\n // Writes its own flag, not `pattern`. Sharing `pattern` meant a field could not have\n // both an email check and a custom regex, setting a custom pattern made the Email box\n // appear ticked, and un-ticking Email deleted whatever pattern the author had written.\n if (on) field.validators.email = true;\n else delete field.validators.email;\n // Clear the legacy encoding either way, so a config touched here stops carrying both.\n if (field.validators.pattern === LEGACY_EMAIL_PATTERN) delete field.validators.pattern;\n } else if (validator === 'url' || validator === 'phone') {\n if (on) field.validators[validator] = true;\n else delete field.validators[validator];\n }\n });\n }\n\n setParamValidator(id: string, validator: ParamValidator, value: number | null): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, id);\n if (!field) return;\n field.validators = field.validators ?? {};\n if (value === null || value === undefined || Number.isNaN(value)) {\n delete field.validators[validator];\n } else {\n field.validators[validator] = value;\n }\n });\n }\n\n setPatternValidator(id: string, pattern: string | null): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, id);\n if (!field) return;\n field.validators = field.validators ?? {};\n const trimmed = pattern?.trim();\n if (!trimmed) {\n delete field.validators.pattern;\n } else {\n field.validators.pattern = trimmed;\n }\n });\n }\n\n getParamValidator(field: NestedFieldConfig, validator: ParamValidator): number | null {\n const val = field.validators?.[validator];\n return typeof val === 'number' ? val : null;\n }\n\n hasFlagValidator(field: NestedFieldConfig, validator: FlagValidator): boolean {\n if (validator === 'required') return !!field.validators?.required;\n if (validator === 'email') {\n // Only the legacy email regex counts, never any pattern: a custom regex must not tick\n // the box. Recognising it keeps older configs showing Email as ticked.\n return !!field.validators?.email || field.validators?.pattern === LEGACY_EMAIL_PATTERN;\n }\n if (validator === 'url' || validator === 'phone') return !!field.validators?.[validator];\n return false;\n }\n\n // ─── Options (dropdown / multiSelect / radio) ────────────────────────────────\n\n /**\n * Where a choice field's options come from.\n *\n * `entity` is absent on purpose: in this model an entity reference is a field *type*\n * (`entity-ref`), not a data source a dropdown can switch to, so offering it here would mean\n * mutating the field's type — and rebuilding its control — from a source picker. The\n * exclusion that matters within a choice field is inline `options` vs `listName`.\n */\n fieldDataSource(field: NestedFieldConfig | undefined): 'none' | 'manual' | 'lookup' {\n if (!field) return 'none';\n // Presence, not emptiness: a source the author has picked but not filled in yet — no\n // options authored, no list name typed — must still read as that source, or the editor\n // for it disappears the moment they select it.\n if (Array.isArray(field.options)) return 'manual';\n if (typeof field.listName === 'string') return 'lookup';\n return 'none';\n }\n\n /**\n * Switch a choice field's data source, clearing the one it is leaving.\n *\n * The reference makes these mutually exclusive (doc §4.4) and it has to stay that way here:\n * `optionsFor` resolves inline options first, so a field left holding both would silently\n * ignore its list.\n */\n setFieldDataSource(fieldId: string, source: 'none' | 'manual' | 'lookup'): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n if (source === 'manual') {\n delete field.listName;\n field.options = field.options?.length ? field.options : [];\n } else if (source === 'lookup') {\n delete field.options;\n field.listName = field.listName ?? '';\n } else {\n delete field.options;\n delete field.listName;\n }\n });\n }\n\n /** Set the named list a choice field reads its options from. */\n setListName(fieldId: string, listName: string): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n const trimmed = listName.trim();\n if (trimmed) {\n field.listName = trimmed;\n // Belt and braces: inline options would win over the list at render time.\n delete field.options;\n } else {\n field.listName = '';\n }\n });\n }\n\n /** Link a field to a field defined in another entity configuration */\n linkReferencedField(fieldId: string, sourceEntityKey: string, sourceField: NestedFieldConfig): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n field.isReferenced = true;\n field.referencedEntityKey = sourceEntityKey;\n field.referencedFieldId = sourceField.id;\n field.referencedSnapshot = createFieldSnapshot(sourceField);\n field.hasDrift = false;\n // Copy label, type, validators, options from source\n if (sourceField.label) field.label = clone(sourceField.label);\n if (sourceField.type) field.type = sourceField.type;\n if (sourceField.validators) field.validators = clone(sourceField.validators);\n if (sourceField.options) field.options = clone(sourceField.options);\n });\n }\n\n /** Unlink a referenced field back to an independent field. */\n unlinkReferencedField(fieldId: string): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n delete field.isReferenced;\n delete field.referencedEntityKey;\n delete field.referencedFieldId;\n delete field.referencedSnapshot;\n delete field.hasDrift;\n });\n }\n\n /** Sync a drifted referenced field with the updated source field definition. */\n syncReferencedField(fieldId: string, currentSourceField: NestedFieldConfig): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field || !field.isReferenced) return;\n field.referencedSnapshot = createFieldSnapshot(currentSourceField);\n field.hasDrift = false;\n if (currentSourceField.label) field.label = clone(currentSourceField.label);\n if (currentSourceField.type) field.type = currentSourceField.type;\n if (currentSourceField.validators) field.validators = clone(currentSourceField.validators);\n if (currentSourceField.options) field.options = clone(currentSourceField.options);\n });\n }\n\n /** Scan all referenced fields in the config and update their hasDrift state against current source configs. */\n checkDrift(sourceConfigs: Record<string, EntityFormConfig>): void {\n this.mutate(draft => {\n const scanFields = (fields: NestedFieldConfig[]) => {\n for (const f of fields) {\n if (f.isReferenced && f.referencedEntityKey && f.referencedFieldId) {\n const sourceConfig = sourceConfigs[f.referencedEntityKey];\n const sourceField = sourceConfig\n ? this.findFieldInTabs(sourceConfig.tabs ?? [], f.referencedFieldId)\n : undefined;\n f.hasDrift = computeFieldDrift(f, sourceField ?? undefined);\n }\n if (f.children?.length) scanFields(f.children);\n }\n };\n\n for (const tab of draft.tabs ?? []) {\n if (tab.fields?.length) scanFields(tab.fields);\n }\n });\n }\n\n addOption(fieldId: string): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n const options = field.options ?? [];\n const n = options.length + 1;\n const lang = draft.defaultLanguage ?? 'en';\n const label = `Option ${n}`;\n // The key is minted here, at creation, from the label the option starts with — and\n // then never rewritten, which is the entire point. Renaming an option afterwards\n // changes what it *reads*; the key is what it *is*, so every record already holding it\n // keeps matching. See `DropdownOption`.\n options.push({ [OPTION_KEY]: this.mintOptionKey(options, label), [lang]: label });\n field.options = options;\n // Authoring an inline option makes this a manual field — see `setFieldDataSource`.\n delete field.listName;\n });\n }\n\n /**\n * A key for a new option: the label slugified, made unique within its own field.\n *\n * Unique within the field and nowhere wider, because that is the scope the key has to\n * distinguish within — two fields may both offer \"Active\" and they are the same value.\n * A label that slugifies to nothing (punctuation, a script `labelToId` strips) falls back\n * to a positional name rather than an empty key, which `optionKeyOf` would ignore.\n */\n private mintOptionKey(existing: readonly DropdownOption[], label: string): string {\n const taken = new Set(existing.map(optionKeyOf).filter(Boolean) as string[]);\n const base = labelToId(label) || `option${existing.length + 1}`;\n if (!taken.has(base)) return base;\n let n = 2;\n while (taken.has(`${base}${n}`)) n += 1;\n return `${base}${n}`;\n }\n\n /**\n * Give every option in the config a key, leaving the ones that already have one alone.\n *\n * The counterpart to `optionKeyMigration` in core: that one keys stored *records* against\n * a keyed config, this one keys the config. Run this first, then ship the migration — the\n * other order leaves the migration with no keys to attach.\n *\n * Existing keys are never rewritten, so this is safe to run again on a config that is\n * already half-keyed, which is what happens as options are added to an older schema.\n */\n assignOptionKeys(): void {\n this.mutate(draft => {\n const visitFields = (fields: NestedFieldConfig[] | undefined): void => {\n for (const field of fields ?? []) {\n if (Array.isArray(field.options)) {\n const keyed: DropdownOption[] = [];\n for (const option of field.options) {\n if (!option || typeof option !== 'object' || optionKeyOf(option) !== undefined) {\n keyed.push(option);\n continue;\n }\n const label = resolveLabel(option, draft.defaultLanguage ?? 'en');\n keyed.push({ [OPTION_KEY]: this.mintOptionKey(keyed, label), ...option });\n }\n field.options = keyed;\n }\n visitFields(field.children);\n }\n };\n const visitTabs = (tabs: NestedTabConfig[] | undefined): void => {\n for (const tab of tabs ?? []) {\n visitFields(tab.fields);\n visitTabs(tab.children);\n }\n };\n visitTabs(draft.tabs);\n });\n }\n\n /** Whether any option in the config is still without a key — gates the action in the UI. */\n readonly hasUnkeyedOptions = computed(() => {\n let found = false;\n const visitFields = (fields: NestedFieldConfig[] | undefined): void => {\n for (const field of fields ?? []) {\n if (Array.isArray(field.options) && field.options.some(o => optionKeyOf(o) === undefined)) {\n found = true;\n }\n visitFields(field.children);\n }\n };\n const visitTabs = (tabs: NestedTabConfig[] | undefined): void => {\n for (const tab of tabs ?? []) {\n visitFields(tab.fields);\n visitTabs(tab.children);\n }\n };\n visitTabs(this._config().tabs);\n return found;\n });\n\n /** An option's stable key, for the inspector to show read-only. */\n optionKey(option: DropdownOption): string {\n return optionKeyOf(option) ?? '';\n }\n\n /** Merge language keys into an option. `setOptionLabel` is the usual single-language path. */\n updateOption(fieldId: string, index: number, patch: DropdownOption): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n const option = field?.options?.[index];\n if (!option) return;\n // A patch may add translations; it may not change what the option *is*. Letting one\n // rewrite an established key would orphan every record holding it, which is exactly\n // the failure the key exists to prevent.\n const existing = optionKeyOf(option);\n const merged: DropdownOption = { ...option, ...patch };\n if (existing !== undefined) merged[OPTION_KEY] = existing;\n field.options![index] = merged;\n });\n }\n\n /**\n * Set an option's text for one language.\n *\n * An option is a language-keyed object and the displayed text **is** the stored value,\n * so this is the only way to edit one — there is no separate value to set.\n */\n setOptionLabel(fieldId: string, index: number, language: string, value: string): void {\n // Also keystroke-bound.\n this.mutateField(fieldId, field => {\n const option = field.options?.[index];\n if (!option) return field;\n const options = field.options!.map((o, i) => (i === index ? { ...o, [language]: value } : o));\n return { ...field, options };\n });\n }\n\n removeOption(fieldId: string, index: number): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field?.options) return;\n field.options = field.options.filter((_, i) => i !== index);\n });\n }\n\n // ─── Entity reference / cascade ─────────────────────────────────────────────\n\n /** Merge a patch into a field's `entityReference` block, keeping it enabled. */\n updateEntityReference(fieldId: string, patch: Partial<EntityReferenceConfig>): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n const next: EntityReferenceConfig = {\n ...(field.entityReference ?? { enabled: true }),\n ...patch,\n enabled: true,\n };\n // Drop keys explicitly cleared to `undefined` so exported configs stay clean.\n for (const key of Object.keys(patch) as (keyof EntityReferenceConfig)[]) {\n if (patch[key] === undefined) delete next[key];\n }\n field.entityReference = next;\n });\n }\n\n // ─── autoPatch ──────────────────────────────────────────────────────────────\n\n addAutoPatchMapping(fieldId: string): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n const targetTab = field.autoPatch?.targetTab ?? draft.tabs[0]?.id ?? '';\n const mappings = [...(field.autoPatch?.mappings ?? []), { source: '', target: '' }];\n field.autoPatch = { targetTab, mappings };\n });\n }\n\n setAutoPatchTargetTab(fieldId: string, targetTab: string): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field?.autoPatch) return;\n field.autoPatch = { ...field.autoPatch, targetTab };\n });\n }\n\n updateAutoPatchMapping(fieldId: string, index: number, patch: Partial<AutoPatchMapping>): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field?.autoPatch?.mappings?.[index]) return;\n field.autoPatch = {\n ...field.autoPatch,\n mappings: field.autoPatch.mappings.map((m, i) => (i === index ? { ...m, ...patch } : m)),\n };\n });\n }\n\n /** Removing the last mapping drops `autoPatch` entirely — no empty config in the export. */\n removeAutoPatchMapping(fieldId: string, index: number): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field?.autoPatch) return;\n const mappings = field.autoPatch.mappings.filter((_, i) => i !== index);\n if (mappings.length === 0) delete field.autoPatch;\n else field.autoPatch = { ...field.autoPatch, mappings };\n });\n }\n\n // ─── patchOnTrue ────────────────────────────────────────────────────────────\n\n addPatchOnTrueMapping(fieldId: string): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n field.patchOnTrue = [...(field.patchOnTrue ?? []), { from: '', to: '' }];\n });\n }\n\n updatePatchOnTrueMapping(fieldId: string, index: number, patch: Partial<PatchOnTrueMapping>): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field?.patchOnTrue?.[index]) return;\n field.patchOnTrue = field.patchOnTrue.map((m, i) => (i === index ? { ...m, ...patch } : m));\n });\n }\n\n removePatchOnTrueMapping(fieldId: string, index: number): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field?.patchOnTrue) return;\n const mappings = field.patchOnTrue.filter((_, i) => i !== index);\n if (mappings.length === 0) delete field.patchOnTrue;\n else field.patchOnTrue = mappings;\n });\n }\n\n // ─── showWhen (static conditional visibility) ───────────────────────────────\n\n /** Replace a field's `showWhen` map; an empty map removes the condition. */\n setShowWhen(fieldId: string, showWhen: Record<string, unknown> | undefined): void {\n this.mutate(draft => {\n const field = this.findFieldInTabs(draft.tabs, fieldId);\n if (!field) return;\n if (!showWhen || Object.keys(showWhen).length === 0) delete field.showWhen;\n else field.showWhen = showWhen;\n });\n }\n\n // ─── Rules ──────────────────────────────────────────────────────────────────\n\n /** Rules for the field currently selected in the inspector. */\n /**\n * Rules attached to the selected field, whichever way they name it.\n *\n * New rules are authored with the field's path — `[work.address]` — because a bare id\n * cannot distinguish two fields that share one. Rules written before paths existed name it\n * by id, and those must keep showing up here or editing an older config would look like it\n * had lost its rules.\n */\n readonly rulesForSelectedField = computed<FormRule[]>(() => {\n const id = this._selectedFieldId();\n if (!id) return [];\n const names = new Set<string>([id]);\n const ref = this.selectedField()?.refererField;\n if (ref) names.add(toRefToken(ref));\n return this._rules().filter(r => names.has(r.fieldId) || r.targets.some(t => names.has(t.id)));\n });\n\n /**\n * Replace the rules without touching the config — for a host whose rules changed on their\n * own. It records a step, because from the author's side it is an edit. Loading a config\n * passes its rules to `load` instead, so the pair arrives as one snapshot.\n */\n loadRules(rules: FormRule[]): void {\n this._rules.set(clone(rules));\n this.record();\n }\n\n addRule(rule: FormRule): string {\n const id = rule.id?.trim() || this.uniqueId('rule', new Set(this._rules().map(r => r.id ?? '')));\n this._rules.update(rules => [...rules, { ...clone(rule), id }]);\n this.record();\n return id;\n }\n\n updateRule(id: string, patch: Partial<FormRule>): void {\n this._rules.update(rules => rules.map(r => (r.id === id ? { ...r, ...clone(patch), id } : r)));\n this.record();\n }\n\n removeRule(id: string): void {\n this._rules.update(rules => rules.filter(r => r.id !== id));\n this.record();\n }\n\n toggleRule(id: string, enabled: boolean): void {\n this.updateRule(id, { enabled });\n }\n\n /** Move a rule in priority order. Priorities are renumbered 1..n so they stay contiguous. */\n moveRule(id: string, direction: -1 | 1): void {\n this._rules.update(rules => {\n const next = [...rules];\n const from = next.findIndex(r => r.id === id);\n if (from === -1) return rules;\n const to = from + direction;\n if (to < 0 || to >= next.length) return rules;\n const [item] = next.splice(from, 1);\n next.splice(to, 0, item);\n return next.map((r, i) => ({ ...r, priority: i + 1 }));\n });\n }\n\n exportRules(): FormRule[] {\n return clone(this._rules());\n }\n\n // ─── Tabs ───────────────────────────────────────────────────────────────────\n\n addTab(): string {\n // Must be unique across the whole tree, not just the top level: a tab id is the record\n // storage path, so a new top-level tab colliding with an existing sub-tab would make two\n // tabs write to the same key and break findTab/getTabPath.\n const id = this.uniqueId('tab', new Set(this.allTabIds()));\n this.mutate(draft => {\n const tabs = draft.tabs ?? (draft.tabs = []);\n const lang = draft.defaultLanguage ?? 'en';\n tabs.push({ id, label: { [lang]: humanizeId(id) }, fields: [] });\n });\n return id;\n }\n\n /** Every tab id in the tree, at any depth. Tab ids must be globally unique — they are paths. */\n private allTabIds(): string[] {\n const ids: string[] = [];\n const collect = (tabs: NestedTabConfig[] | undefined) => {\n for (const t of tabs ?? []) {\n ids.push(t.id);\n collect(t.children);\n }\n };\n collect(this._config().tabs);\n return ids;\n }\n\n addSubTab(parentId: string): string {\n const id = this.uniqueId('tab', new Set(this.allTabIds()));\n this.mutate(draft => {\n const parent = findTab(draft.tabs, parentId);\n if (parent) {\n parent.children = parent.children ?? [];\n const lang = draft.defaultLanguage ?? 'en';\n parent.children.push({ id, label: { [lang]: humanizeId(id) }, fields: [] });\n }\n });\n return id;\n }\n\n setPrimaryTab(tabId: string): void {\n this.mutate(draft => {\n const markPrimary = (tabs: NestedTabConfig[]) => {\n for (const t of tabs) {\n t.isPrimaryTab = t.id === tabId;\n if (t.children) markPrimary(t.children);\n }\n };\n markPrimary(draft.tabs ?? []);\n });\n }\n\n updateTab(id: string, patch: Partial<NestedTabConfig>): void {\n this.mutate(draft => {\n const tab = findTab(draft.tabs, id);\n if (tab) Object.assign(tab, patch);\n });\n }\n\n setTabLabel(id: string, language: string, value: string): void {\n this.mutate(draft => {\n const tab = findTab(draft.tabs, id);\n if (tab) tab.label = { ...tab.label, [language]: value };\n });\n }\n\n removeTab(id: string): void {\n this.mutate(draft => {\n const removeRecursive = (tabs: NestedTabConfig[]): NestedTabConfig[] => {\n return tabs\n .filter(t => t.id !== id)\n .map(t => ({\n ...t,\n children: t.children ? removeRecursive(t.children) : undefined,\n }));\n };\n draft.tabs = removeRecursive(draft.tabs ?? []);\n });\n }\n\n moveTab(id: string, direction: -1 | 1): void {\n this.mutate(draft => {\n const tabs = draft.tabs ?? [];\n const from = tabs.findIndex(t => t.id === id);\n if (from === -1) return;\n const to = from + direction;\n if (to < 0 || to >= tabs.length) return;\n const [item] = tabs.splice(from, 1);\n tabs.splice(to, 0, item);\n });\n }\n\n // ─── Export ─────────────────────────────────────────────────────────────────\n\n exportConfig(): EntityFormConfig {\n return clone(this._config());\n }\n\n // ─── Internals ──────────────────────────────────────────────────────────────\n\n /**\n * The single choke point for a structural edit, and therefore the one place refs are kept\n * true.\n *\n * `refererField` is a field's address, so it changes whenever the structure around it does —\n * moving a field to another tab, or into a group, gives it a new one. Rules address fields\n * by ref, so a move that only restamped the field would leave every rule pointing at an\n * address nothing occupies. Both happen here, together, or the config is inconsistent\n * between them.\n */\n private mutate(fn: (draft: EntityFormConfig) => void): void {\n const before = this.refsById(this._config());\n const draft = clone(this._config());\n draft.tabs = draft.tabs ?? [];\n fn(draft);\n this.restampFieldPaths(draft);\n this.repointRulesForMovedFields(before, this.refsById(draft));\n this._config.set(draft);\n this._isDirty.set(true);\n this.record();\n }\n\n /**\n * Rewrites the address of every field the builder owns, leaving declared overrides alone.\n *\n * `assignFieldRefs` only fills in a missing path, which is right when a config arrives and\n * wrong after a move: the field already has a path, and it is now the wrong one.\n */\n private restampFieldPaths(config: EntityFormConfig): void {\n for (const entry of collectFieldScopes(config)) {\n const field = entry.field;\n if (!field?.id || this.authoredRefs.has(field.id)) continue;\n field.refererField = fieldRefFor(entry.scope, field.id);\n }\n }\n\n /** Field id → the refs it currently has. A duplicated id has more than one. */\n private refsById(config: EntityFormConfig): Map<string, string[]> {\n const map = new Map<string, string[]>();\n for (const entry of collectFieldScopes(config)) {\n if (!entry.field?.id) continue;\n const refs = map.get(entry.field.id) ?? [];\n refs.push(fieldRefFor(entry.scope, entry.field.id));\n map.set(entry.field.id, refs);\n }\n return map;\n }\n\n /**\n * Rewrites rules that pointed at a ref a move has just changed.\n *\n * A field is matched by its id: if exactly one ref for that id disappeared and exactly one\n * appeared, that is the move and the rules follow it. Anything less clear-cut — two fields\n * sharing an id where one moved — is left alone rather than guessed at, because rewriting\n * the wrong rule is worse than leaving one to be repointed by hand.\n */\n private repointRulesForMovedFields(before: Map<string, string[]>, after: Map<string, string[]>): void {\n const moves = new Map<string, string>();\n for (const [id, oldRefs] of before) {\n const newRefs = after.get(id) ?? [];\n const gone = oldRefs.filter(r => !newRefs.includes(r));\n const added = newRefs.filter(r => !oldRefs.includes(r));\n if (gone.length === 1 && added.length === 1) moves.set(gone[0], added[0]);\n }\n if (moves.size === 0) return;\n\n const repoint = (reference: string | undefined): string | undefined => {\n if (!reference) return reference;\n const parsed = parseFieldRef(reference);\n if (parsed.kind !== 'ref') return reference;\n const moved = moves.get(parsed.value);\n return moved ? toRefToken(moved) : reference;\n };\n\n this._rules.update(rules =>\n rules.map(rule => ({\n ...rule,\n fieldId: repoint(rule.fieldId) ?? rule.fieldId,\n conditions: rule.conditions.map(c => (c.compareToField ? { ...c, compareToField: repoint(c.compareToField) } : c)),\n targets: rule.targets.map(t => ({ ...t, id: repoint(t.id) ?? t.id })),\n })),\n );\n }\n\n /**\n * Replace one field, copying only the objects on the path to it.\n *\n * `mutate` deep-clones the entire config, which is right for a structural edit but wrong\n * for the two setters bound to keystroke events: typing a label allocated a full copy of\n * the config per character. Here every tab and field outside the target's chain is reused\n * by reference, so the cost is proportional to nesting depth rather than config size —\n * while the parts that did change are still fresh objects, so change detection and the\n * signal both see a new identity.\n *\n * Returns without touching anything when the field is not found.\n */\n private mutateField(key: string, update: (field: NestedFieldConfig) => NestedFieldConfig): void {\n let found = false;\n\n // Resolve once, then match on object identity. Matching on `field.id === id` inside the\n // walk updated *every* field carrying that id, so renaming `work.address` also rewrote\n // `personal.address` — both rows changed, and the second write was silent. Identity\n // cannot be ambiguous the way a bare id can.\n const target = this.findFieldInTabs(this._config().tabs, key);\n if (!target) return;\n\n const visitFields = (fields: NestedFieldConfig[] | undefined): NestedFieldConfig[] | undefined => {\n if (!fields) return fields;\n let changed = false;\n const next = fields.map(field => {\n if (field === target) {\n found = true;\n changed = true;\n return update(field);\n }\n const children = visitFields(field.children);\n if (children !== field.children) {\n changed = true;\n return { ...field, children };\n }\n return field;\n });\n return changed ? next : fields;\n };\n\n const visitTabs = (tabs: NestedTabConfig[] | undefined): NestedTabConfig[] | undefined => {\n if (!tabs) return tabs;\n let changed = false;\n const next = tabs.map(tab => {\n const fields = visitFields(tab.fields);\n const children = visitTabs(tab.children);\n if (fields !== tab.fields || children !== tab.children) {\n changed = true;\n return { ...tab, fields, children };\n }\n return tab;\n });\n return changed ? next : tabs;\n };\n\n const current = this._config();\n const tabs = visitTabs(current.tabs);\n // `found` implies current.tabs existed and was walked, so tabs is defined here — the\n // fallback below is for the type checker, not a reachable state.\n if (!found || tabs === current.tabs) return;\n\n this._config.set({ ...current, tabs: tabs ?? [] });\n this._isDirty.set(true);\n this.record();\n }\n\n private uniqueId(prefix: string, taken: Set<string>): string {\n let n = 1;\n let candidate = `${prefix}_${n}`;\n while (taken.has(candidate)) {\n n += 1;\n candidate = `${prefix}_${n}`;\n }\n return candidate;\n }\n\n private validate(config: EntityFormConfig): BuilderProblem[] {\n const problems: BuilderProblem[] = [];\n\n // Core calls a config with no tabs an error — nothing can render — and the builder used\n // to report only a warning and leave Save enabled. That let the builder save a config\n // `dynamic-entity validate` then rejected in CI: the mirror of the bug where it refused\n // one core accepted. The builder defers to core here, as it already does for the scope\n // rule, and the message is core's so the two read the same in both places.\n if (!config.tabs?.length) {\n problems.push({ level: 'error', message: 'At least one tab is required.' });\n }\n\n if (!config.entity || !config.entity.trim()) {\n problems.push({ level: 'error', message: 'Entity name is required.' });\n } else if (!ID_PATTERN.test(config.entity)) {\n problems.push({\n level: 'error',\n message: 'Entity name must start with a letter or underscore and contain only letters, digits, and underscores.',\n });\n }\n\n const allFields = this.getAllFields(config.tabs);\n if (allFields.length === 0) {\n problems.push({ level: 'warning', message: 'This entity has no fields yet.' });\n }\n\n for (const field of allFields) {\n if (!field.id || !ID_PATTERN.test(field.id)) {\n problems.push({\n level: 'error',\n message: `Field id \"${field.id}\" is not a valid identifier.`,\n fieldId: field.id,\n });\n }\n\n const labels = field.label ?? {};\n const hasLabel = Object.values(labels).some(v => typeof v === 'string' && v.trim());\n if (!hasLabel) {\n problems.push({\n level: 'warning',\n message: `Field \"${field.id}\" has no label.`,\n fieldId: field.id,\n });\n }\n\n const meta = getFieldTypeMeta(field.type);\n // A field on the lookup source has no inline options by design — its options arrive from\n // the registry at runtime. Warn only about the missing list name.\n if (meta?.hasOptions && typeof field.listName === 'string') {\n if (!field.listName.trim()) {\n problems.push({\n level: 'warning',\n message: `Field \"${field.id}\" reads options from a named list but has no list name.`,\n fieldId: field.id,\n });\n }\n } else if (meta?.hasOptions && (!field.options || field.options.length === 0)) {\n problems.push({\n level: 'warning',\n message: `Field \"${field.id}\" is a ${field.type} but has no options.`,\n fieldId: field.id,\n });\n }\n }\n\n // Id uniqueness is a *per-scope* invariant, not a whole-config one — this counted into\n // one flat map keyed by bare id, so it rejected `personal.address` alongside\n // `work.address` and made every such config unopenable: Save is disabled while an error\n // stands, so unrelated edits could not be saved either. The runtime, the record shape\n // and `validateConfig` have all accepted per-scope ids since 1.4.0; this was the last\n // component still enforcing the old rule, and it enforced it against configs the rest\n // of the stack calls valid.\n //\n // The scope rule itself comes from core rather than being reimplemented here, so the\n // builder and the validator cannot drift apart on what \"same scope\" means.\n const scopeCounts = new Map<string, { id: string; count: number }>();\n for (const entry of collectFieldScopes(config)) {\n if (!entry.field.id) continue;\n const key = `${entry.scope}::${entry.field.id}`;\n const seen = scopeCounts.get(key);\n if (seen) seen.count += 1;\n else scopeCounts.set(key, { id: entry.field.id, count: 1 });\n }\n\n for (const [key, { id, count }] of scopeCounts) {\n if (count > 1) {\n // Still an error, and it must stay one: two fields in the same scope share a single\n // control and a single record key, so the second silently overwrites the first.\n const scope = key.slice(0, key.lastIndexOf('::'));\n problems.push({\n level: 'error',\n message: `Duplicate field id \"${id}\" (${count}×) in ${scope}. Two fields in one scope share a control and a record key.`,\n fieldId: id,\n });\n }\n }\n\n return problems;\n }\n}\n","import type { EntityFormConfig } from '@dynamic-entity/core';\nimport { collectFieldScopes, refOf, resolveLabel, toRefToken } from '@dynamic-entity/core';\n\n/** One choosable field: the reference stored, the label shown, and the path behind it. */\nexport interface FieldPathOption {\n value: string;\n label: string;\n path: string;\n}\n\n/**\n * Every field in the config, offered by path.\n *\n * Four places in the builder name a field — `showWhen` keys, `patchOnTrue` mappings,\n * `autoPatch` targets and rule triggers/targets — and each was a free-text box. Typing an id\n * is the one way left to author an ambiguous reference: ids are unique per scope, so\n * `address` names nothing in particular once two tabs have one. Choosing from this list\n * always yields a path.\n *\n * `collectFieldScopes` rather than the tab-level view, so a field nested inside a `group` is\n * offered too, and every entry carries the scope `refOf` needs.\n */\nexport function fieldPathOptions(\n config: EntityFormConfig | null | undefined,\n language: string,\n): FieldPathOption[] {\n return collectFieldScopes(config).map(entry => {\n const path = refOf(entry.field, entry.scope);\n return {\n value: toRefToken(path),\n label: resolveLabel(entry.field.label, language) || entry.field.id,\n path,\n };\n });\n}\n\n/**\n * The options plus whatever is already selected.\n *\n * A reference written before paths existed is a bare id, and one written against a field\n * since deleted is a path nothing answers to. Neither appears in the list, and a `mat-select`\n * silently drops a value it has no option for — so opening such a config and saving it would\n * quietly erase the reference. They are kept, and shown as they are.\n */\nexport function withExistingOptions(\n options: readonly FieldPathOption[],\n current: readonly (string | undefined)[],\n): FieldPathOption[] {\n const known = new Set(options.map(o => o.value));\n const extra = current\n .filter((value): value is string => !!value && !known.has(value))\n .map(value => ({ value, label: value, path: 'not in this config' }));\n return [...options, ...extra];\n}\n","import type { EntityFormConfig, FormRule, NestedFieldConfig } from '@dynamic-entity/core';\nimport {\n collectFieldScopes,\n parseFieldRef,\n refOf,\n resolveLabel,\n toRefToken,\n} from '@dynamic-entity/core';\n\nexport type DependencyType = 'rule' | 'showWhen' | 'cascade' | 'patchOnTrue' | 'autoPatch';\n\nexport interface RuleDependencyEdge {\n id: string;\n sourceKey: string;\n sourceLabel: string;\n targetKey: string;\n targetLabel: string;\n type: DependencyType;\n actionSummary: string;\n description: string;\n sourceValid: boolean;\n targetValid: boolean;\n}\n\nexport interface RuleDependencyGraphData {\n edges: RuleDependencyEdge[];\n totalRules: number;\n totalShowWhen: number;\n totalCascades: number;\n totalPatches: number;\n}\n\ninterface FieldMeta {\n key: string;\n id: string;\n label: string;\n field: NestedFieldConfig;\n}\n\n/**\n * Computes all dependency edges (rules, showWhen, cascades, patchOnTrue, autoPatch)\n * across an EntityFormConfig and its rules.\n */\nexport function computeRuleDependencies(\n config: EntityFormConfig | null | undefined,\n rules: readonly FormRule[] = [],\n language = 'en',\n): RuleDependencyGraphData {\n const edges: RuleDependencyEdge[] = [];\n let edgeIdSeq = 0;\n\n const scopes = collectFieldScopes(config);\n const byKey = new Map<string, FieldMeta>();\n const byId = new Map<string, FieldMeta>();\n const byToken = new Map<string, FieldMeta>();\n\n for (const entry of scopes) {\n const key = refOf(entry.field, entry.scope);\n const token = toRefToken(key);\n const label = resolveLabel(entry.field.label, language) || entry.field.id;\n const meta: FieldMeta = { key, id: entry.field.id, label, field: entry.field };\n\n byKey.set(key, meta);\n byId.set(entry.field.id, meta);\n byToken.set(token, meta);\n }\n\n function resolveRef(refStr: string): { key: string; label: string; valid: boolean } {\n if (!refStr) return { key: '', label: '—', valid: false };\n const parsed = parseFieldRef(refStr);\n const val = parsed.value;\n const meta =\n byKey.get(refStr) ??\n byKey.get(val) ??\n byId.get(val) ??\n byToken.get(refStr) ??\n byToken.get(toRefToken(val));\n\n if (meta) {\n return { key: meta.key, label: meta.label, valid: true };\n }\n return { key: val || refStr, label: val || refStr, valid: false };\n }\n\n let totalRules = 0;\n let totalShowWhen = 0;\n let totalCascades = 0;\n let totalPatches = 0;\n\n // 1. Form Rules\n for (const rule of rules) {\n if (!rule.fieldId) continue;\n totalRules++;\n const source = resolveRef(rule.fieldId);\n const targets = rule.targets ?? [];\n\n const actionType: string = rule.action?.type ?? 'action';\n let actionSummary = actionType;\n if (actionType === 'visibility') {\n actionSummary = rule.action?.value === false || rule.action?.value === 'false' ? 'hide' : 'show';\n } else if (actionType === 'validation' || actionType === 'validationMessage') {\n actionSummary = 'validate';\n } else if (actionType === 'info' || actionType === 'infoBanner') {\n actionSummary = 'info';\n }\n\n const conditionsText =\n rule.conditions && rule.conditions.length > 0\n ? rule.conditions.map(c => `${c.operator ?? 'EQUAL'} ${c.value ?? ''}`.trim()).join(' & ')\n : 'always';\n\n for (const target of targets) {\n const targetResolved = resolveRef(target.id);\n edges.push({\n id: `rule-${++edgeIdSeq}`,\n sourceKey: source.key,\n sourceLabel: source.label,\n targetKey: targetResolved.key,\n targetLabel: targetResolved.label,\n type: 'rule',\n actionSummary,\n description: `${actionSummary.toUpperCase()} when ${conditionsText}`,\n sourceValid: source.valid,\n targetValid: targetResolved.valid,\n });\n }\n }\n\n // 2. Field-level features: showWhen, cascade, patchOnTrue, autoPatch\n for (const entry of scopes) {\n const field = entry.field;\n const fieldKey = refOf(field, entry.scope);\n const fieldResolved = resolveRef(fieldKey);\n\n // showWhen\n if (field.showWhen && typeof field.showWhen === 'object') {\n for (const [watchedRef, expectedVal] of Object.entries(field.showWhen)) {\n totalShowWhen++;\n const source = resolveRef(watchedRef);\n const valStr = typeof expectedVal === 'object' ? JSON.stringify(expectedVal) : String(expectedVal);\n edges.push({\n id: `showWhen-${++edgeIdSeq}`,\n sourceKey: source.key,\n sourceLabel: source.label,\n targetKey: fieldResolved.key,\n targetLabel: fieldResolved.label,\n type: 'showWhen',\n actionSummary: `= ${valStr}`,\n description: `Visible when ${source.label} = ${valStr}`,\n sourceValid: source.valid,\n targetValid: fieldResolved.valid,\n });\n }\n }\n\n // cascade parentField\n if (field.entityReference?.parentField) {\n totalCascades++;\n const source = resolveRef(field.entityReference.parentField);\n edges.push({\n id: `cascade-${++edgeIdSeq}`,\n sourceKey: source.key,\n sourceLabel: source.label,\n targetKey: fieldResolved.key,\n targetLabel: fieldResolved.label,\n type: 'cascade',\n actionSummary: 'filters options',\n description: `Reloads options when ${source.label} changes`,\n sourceValid: source.valid,\n targetValid: fieldResolved.valid,\n });\n }\n\n // patchOnTrue\n if (Array.isArray(field.patchOnTrue)) {\n for (const mapping of field.patchOnTrue) {\n if (!mapping.to) continue;\n totalPatches++;\n const toResolved = resolveRef(mapping.to);\n const fromResolved = resolveRef(mapping.from);\n edges.push({\n id: `patch-${++edgeIdSeq}`,\n sourceKey: fieldResolved.key,\n sourceLabel: fieldResolved.label,\n targetKey: toResolved.key,\n targetLabel: toResolved.label,\n type: 'patchOnTrue',\n actionSummary: `copy ${fromResolved.label} → ${toResolved.label}`,\n description: `When true, copies ${fromResolved.label} to ${toResolved.label}`,\n sourceValid: fieldResolved.valid,\n targetValid: toResolved.valid,\n });\n }\n }\n\n // autoPatch\n if (field.autoPatch && Array.isArray(field.autoPatch.mappings)) {\n for (const mapping of field.autoPatch.mappings) {\n if (!mapping.target) continue;\n totalPatches++;\n const targetResolved = resolveRef(mapping.target);\n edges.push({\n id: `autopatch-${++edgeIdSeq}`,\n sourceKey: fieldResolved.key,\n sourceLabel: fieldResolved.label,\n targetKey: targetResolved.key,\n targetLabel: targetResolved.label,\n type: 'autoPatch',\n actionSummary: `patch → ${targetResolved.label}`,\n description: `Selection copies ${mapping.source} to ${targetResolved.label}`,\n sourceValid: fieldResolved.valid,\n targetValid: targetResolved.valid,\n });\n }\n }\n }\n\n return {\n edges,\n totalRules,\n totalShowWhen,\n totalCascades,\n totalPatches,\n };\n}\n","import { Injectable, InjectionToken, inject, signal } from '@angular/core';\nimport { resolveUiText, type UiTextOverridesFor, type UiTextParams } from 'ngx-dynamic-entity';\n\n/**\n * Every word the builder puts on screen that is not part of the config being authored.\n *\n * The renderer has its own list (`DEFAULT_UI_TEXT`) and the two are deliberately separate:\n * an application that ships only the renderer should not see a hundred and fifty builder\n * keys in completion, and the two vocabularies share no strings worth deduplicating. What\n * they do share is the resolution rule, which comes from `resolveUiText`.\n *\n * Keys are grouped by panel, because a translator works screen by screen.\n */\nexport const DEFAULT_BUILDER_TEXT = {\n // Toolbar and page chrome\n builderTitle: 'Entity Builder',\n undo: 'Undo',\n undoTooltip: 'Undo (Ctrl+Z)',\n redo: 'Redo',\n redoTooltip: 'Redo (Ctrl+Shift+Z)',\n issuesTooltip: '{count} issue(s) — open the list to see them',\n issuesCount: '{errors} / {total}',\n copyJson: 'Copy JSON',\n save: 'Save',\n saveBlockedTooltip: 'Fix the errors in the issue list before saving.',\n\n /*\n * The panels collapse, so each control is named in both directions — and a collapsed\n * panel leaves a rail or dock bar whose label is the only word left standing for it.\n */\n collapsePalette: 'Collapse the palette',\n expandPalette: 'Expand the palette',\n collapseInspector: 'Collapse the inspector',\n expandInspector: 'Expand the inspector',\n paletteRailLabel: 'Add fields',\n inspectorRailLabel: 'Properties',\n collapseFields: 'Collapse fields',\n expandFields: 'Expand fields',\n fieldsRailLabel: 'Fields',\n collapsePreview: 'Collapse live preview',\n expandPreview: 'Expand live preview',\n previewRailLabel: 'Live preview',\n previewHeading: 'Live preview',\n\n // Entity settings panel\n entityName: 'Entity name',\n entityNamePlaceholder: 'e.g. clients',\n editingLanguage: 'Editing language',\n maskEntity: 'Mask this entity (RBAC)',\n permissions: 'Permissions',\n actionRoles: '{action} roles',\n actionRolesPlaceholder: '{action} roles (comma-separated)',\n permissionsHint: 'Empty = no restriction for that action.',\n addField: 'Add field',\n fieldProperties: 'Field properties',\n configJson: 'Config JSON',\n\n // Field palette\n paletteSearchPlaceholder: 'Filter field types…',\n paletteSearchLabel: 'Filter field types',\n paletteSearchClear: 'Clear the filter',\n paletteNoMatch: 'No field type matches \"{query}\".',\n paletteGroupBasic: 'Basic',\n paletteGroupChoice: 'Choice',\n paletteGroupDateTime: 'Date & time',\n paletteGroupRich: 'Rich & files',\n paletteGroupStructure: 'Structure',\n paletteGroupOther: 'Other',\n\n // Canvas\n fieldsHeading: 'Fields ({count})',\n canvasEmpty: 'No fields yet. Pick a type from Add field to get started.',\n\n // Field rows in the tree\n selectField: 'Select field {field}',\n dragToReorder: 'Drag to reorder (or use the move buttons)',\n referencedFieldTooltip: 'Referenced field (linked to {entity})',\n driftDetected: 'Drift detected: source field has evolved',\n required: 'Required',\n moveUp: 'Move up',\n moveDown: 'Move down',\n duplicate: 'Duplicate',\n delete: 'Delete',\n moveFieldUp: 'Move {field} up',\n moveFieldDown: 'Move {field} down',\n duplicateField: 'Duplicate {field}',\n\n // Field inspector — identity\n inspectorEmpty: 'Select a field to edit its properties.',\n fieldId: 'Field id',\n fieldIdFixedHint: 'The stored data key for this saved field — fixed.',\n fieldIdDerivedHint: 'Derived from the label. Used as the data key.',\n tab: 'Tab',\n tabMoveHint: 'Moving the field rewrites its path and repoints the rules that named it.',\n labelInLanguage: 'Label ({language})',\n placeholderInLanguage: 'Placeholder ({language})',\n hintInLanguage: 'Help text ({language})',\n hintHint: 'An info icon beside the label, shown on hover and while the field has focus. Read out with the field.',\n defaultValue: 'Default value',\n sliderStep: 'Step',\n sliderStepHint: 'How far one notch moves the slider. Leave empty for 1.',\n\n // Field inspector — section headings and the layout control.\n sectionBasics: 'Basics',\n sectionLayout: 'Layout',\n sectionValidation: 'Validation',\n sectionOptions: 'Options',\n sectionDisplay: 'Display',\n sectionVisibility: 'Visibility',\n sectionAutomation: 'Automation',\n sectionRules: 'Rules',\n sectionReference: 'Reference',\n sectionDependencies: 'Dependencies',\n width: 'Width',\n widthQuarter: '¼',\n widthThird: '⅓',\n widthHalf: '½',\n widthTwoThirds: '⅔',\n widthFull: 'Full',\n widthHint: 'How much of the 12-column row this field takes. Fields sharing a row sit side by side.',\n widthOf: '{span} of 12 columns',\n\n // Field inspector — options\n dataSource: 'Data source',\n optionsComeFrom: 'Options come from',\n optionsSourceNone: 'Nothing yet',\n optionsSourceInline: 'Options authored here',\n optionsSourceList: 'A named list',\n listName: 'List name',\n listNameHint: 'The consuming app resolves this name through its lookup registry. Options are not authored here.',\n options: 'Options',\n option: 'Option',\n optionInLanguage: 'Option ({language})',\n removeOption: 'Remove option',\n noOptionsYet: 'No options yet — add at least one.',\n optionKey: 'Key',\n optionKeyHint: 'Set once, when the option was created. Records store it, so renaming the text above is safe.',\n assignOptionKeys: 'Assign stable keys',\n\n // Field inspector — display flags\n display: 'Display',\n visible: 'Visible',\n tableColumn: 'Table column',\n readOnly: 'Read-only',\n disabled: 'Disabled',\n maskData: 'Mask data (RBAC)',\n criticalField: 'Critical field',\n criticalFieldTooltip: 'Renders locked; editing it announces a change against the session baseline.',\n showInSummary: 'Show in summary',\n showInSummaryTooltip: \"Shown in the record editor's summary panel.\",\n\n // Field inspector — conditional visibility\n showWhen: 'Show when',\n condition: 'Condition',\n watchedField: 'Watched field',\n equals: 'Equals',\n removeCondition: 'Remove condition',\n alwaysVisibleHint: 'Always visible. Add a condition to show this field only for certain values.',\n\n // Field inspector — copy on true\n copyOnTrue: 'Copy on true',\n mapping: 'Mapping',\n fromField: 'From field',\n toField: 'To field',\n removeMapping: 'Remove mapping',\n copyOnTrueHint: \"When this flips to true, copy one field's value into another.\",\n\n // Rules list\n rules: 'Rules',\n rule: 'Rule',\n noRulesOnField: 'No rules on this field.',\n rulePriority: 'priority {priority} · {targets} target(s)',\n toggleRule: 'Enable / disable',\n moveRuleUp: 'Move rule up',\n moveRuleDown: 'Move rule down',\n editRule: 'Edit rule',\n deleteRule: 'Delete rule',\n\n // Rule form\n newRuleTitle: 'New Form Rule',\n editRuleTitle: 'Edit Rule',\n triggerField: 'Trigger Field',\n applyToFields: 'Apply to fields',\n conditions: 'Conditions',\n operator: 'Operator',\n value: 'Value',\n conditionValuePlaceholder: 'Condition value',\n addCondition: 'Add Condition',\n action: 'Action',\n actionType: 'Action Type',\n actionVisibility: 'Visibility (Show/Hide)',\n actionValidationMessage: 'Validation Message',\n actionInfoBanner: 'Info Banner',\n valueOrMessage: 'Value / Message',\n valueOrMessagePlaceholder: 'false to hide, or message text',\n cancel: 'Cancel',\n saveRule: 'Save Rule',\n\n // Tab manager\n tabsManager: 'Tabs Manager',\n systemTag: '(System)',\n addTab: 'Add Tab',\n noTabs: 'No tabs — all fields render in a single section.',\n flatData: 'Flat Data',\n primaryTab: 'Primary Tab',\n maskTabData: 'Mask Tab Data',\n systemDefault: 'System Default',\n addSubTab: '+ Sub-tab',\n consumerModuleName: 'Consumer Module Name (Optional)',\n consumerModulePlaceholder: 'e.g. documents-view',\n subTabs: 'Sub-tabs:',\n moveTabUp: 'Move tab up',\n moveTabDown: 'Move tab down',\n removeTab: 'Remove tab',\n removeSubTab: 'Remove sub-tab',\n\n // Entity reference panel\n entityReference: 'Entity reference',\n registryKey: 'Registry key',\n registryKeyHint: 'Key the consumer registered a loader under. Defaults to the field id.',\n displayFields: 'Display fields',\n displayFieldsHint: 'Comma-separated record paths used to build each option label.',\n staticFilters: 'Static filters (JSON)',\n staticFiltersHint: 'Passed to the loader, e.g. &#123;\"isEmployee\": false&#125;.',\n cascade: 'Cascade',\n parentField: 'Parent field',\n parentFieldNone: 'None — load all options',\n cascadeHint: \"This field's options reload whenever the parent changes.\",\n lookupFilterPath: 'Lookup filter path',\n lookupFilterPathHint: 'Keep options whose record matches the parent value at this path.',\n lookupPath: 'Lookup path (nested options)',\n lookupPathHint: \"Take options from this array on the selected parent's record instead.\",\n autoPatchOnSelect: 'Auto-patch on select',\n targetTab: 'Target tab',\n sourceLinkedRecord: 'Source (linked record)',\n targetField: 'Target field',\n noAutoPatch: 'No auto-patch configured — selecting a reference will not copy any values.',\n\n // Referenced-field panel\n referencedField: 'Referenced Field',\n link: 'Link',\n sourceEntityKey: 'Source Entity Key',\n sourceEntityKeyPlaceholder: 'e.g. individuals',\n sourceFieldId: 'Source Field ID',\n sourceFieldIdPlaceholder: 'e.g. firstName',\n driftHeading: 'Source field definition has drifted!',\n driftBody: 'The upstream field configuration in \"{entity}\" has evolved.',\n syncWithSource: 'Sync with Source',\n\n // Validation pattern playground\n pattern: 'Validation Pattern (Regex)',\n patternHint: 'Regular expression for format validation.',\n testPattern: 'Test Pattern',\n testPatternPlaceholder: 'Type sample input to test…',\n patternMatch: 'Pattern matches',\n patternNoMatch: 'Pattern does not match',\n patternInvalid: 'Invalid regex syntax',\n patternEmptyPrompt: 'Enter regex above to test sample input',\n quickPresets: 'Presets',\n\n // Field dependencies\n dependsOn: 'Depends on',\n affects: 'Affects',\n noDependencies: 'No active rule or field dependencies for this field.',\n\n // Rule graph\n ruleGraph: 'Rule Graph',\n ruleGraphTitle: 'Rule & Dependency Graph',\n ruleGraphSubtitle: 'Schema-wide rule triggers, conditional visibility, and cascades',\n filterDependencies: 'Filter dependencies…',\n noDependenciesFound: 'No dependencies matching current filter.',\n jumpToField: 'Select {field}',\n closeDialog: 'Close',\n dependencyTypeRule: 'Rule',\n dependencyTypeShowWhen: 'Show When',\n dependencyTypeCascade: 'Cascade',\n dependencyTypePatch: 'Copy on True',\n totalDependencies: '{count} dependencies',\n};\n\n/** The keys above, as a union — checked in templates, completed in a host's overrides. */\nexport type BuilderTextKey = keyof typeof DEFAULT_BUILDER_TEXT;\n\n/** Same contract as the renderer's `UI_TEXT`, over the builder's vocabulary. */\nexport type BuilderTextOverrides = UiTextOverridesFor<BuilderTextKey>;\n\n/**\n * Overrides for the builder's own chrome.\n *\n * Accepts what `UI_TEXT` accepts: a partial map whose values are strings or `LocalizedText`\n * (`{ en, de }`), or a resolver `(key, defaultText, language) => string` for a host with an\n * existing i18n layer. `DEFAULT_BUILDER_TEXT` is the full key list with its English source\n * strings; anything left out keeps its default.\n *\n * @example\n * { provide: BUILDER_TEXT, useValue: { save: { en: 'Save', de: 'Speichern' } } }\n */\nexport const BUILDER_TEXT = new InjectionToken<BuilderTextOverrides>('BUILDER_TEXT');\n\n/**\n * Resolves the builder's own UI text.\n *\n * The language lives on the service rather than travelling through every template call,\n * because the builder already has a *different* language on screen: `activeLanguage()`\n * selects the `LocalizedText` entry being **authored**. Passing that one to the chrome\n * would flip the builder's own interface every time an author switched the label language\n * they were editing, which is the opposite of what it means.\n *\n * Root-provided and therefore shared: two builders mounted at once show one chrome\n * language. `EntityBuilderComponent`'s `uiLanguage` input is what sets it.\n */\n@Injectable({ providedIn: 'root' })\nexport class BuilderTextService {\n private readonly overrides = inject(BUILDER_TEXT, { optional: true });\n\n /** The chrome language. Not the authoring language — see the class comment. */\n readonly language = signal('en');\n\n /** One label by key. `params` fill the `{placeholder}` slots. */\n text(key: BuilderTextKey, params?: UiTextParams): string {\n return resolveUiText(this.overrides, DEFAULT_BUILDER_TEXT, key, this.language(), params);\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatDividerModule } from '@angular/material/divider';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatSelectModule } from '@angular/material/select';\nimport { MatSlideToggleModule } from '@angular/material/slide-toggle';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel, toRefToken } from '@dynamic-entity/core';\nimport { fieldPathOptions, withExistingOptions, type FieldPathOption } from '../field-path-options';\nimport { BuilderStore } from '../builder-store.service';\nimport { BuilderTextService } from '../builder-text';\n\n/**\n * EntityReferenceConfigComponent — authors the `entityReference` block of an entity-ref field:\n * registry key, display fields, static filters, and the parent→child cascade.\n *\n * Also authors `autoPatch`, since the mappings only make sense against the record the\n * selected reference returns.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-entity-reference-config',\n standalone: true,\n imports: [\n FormsModule,\n MatButtonModule,\n MatDividerModule,\n MatFormFieldModule,\n MatIconModule,\n MatInputModule,\n MatSelectModule,\n MatSlideToggleModule,\n MatTooltipModule,\n ],\n template: `\n @if (field(); as f) {\n <div class=\"deb-entity-ref\">\n <span class=\"deb-section-title\">{{ ui.text('entityReference') }}</span>\n\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('registryKey') }}</mat-label>\n <input\n matInput\n data-testid=\"entity-ref-key\"\n [ngModel]=\"ref(f).linkedEntityKey ?? ''\"\n (ngModelChange)=\"patchRef(f, { linkedEntityKey: $event || undefined })\"\n />\n <mat-hint>{{ ui.text('registryKeyHint') }}</mat-hint>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('displayFields') }}</mat-label>\n <input\n matInput\n data-testid=\"entity-ref-display-fields\"\n [ngModel]=\"displayFieldsText(f)\"\n (ngModelChange)=\"setDisplayFields(f, $event)\"\n />\n <mat-hint>{{ ui.text('displayFieldsHint') }}</mat-hint>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('staticFilters') }}</mat-label>\n <input\n matInput\n data-testid=\"entity-ref-filters\"\n [ngModel]=\"filtersText(f)\"\n (ngModelChange)=\"setFilters(f, $event)\"\n />\n @if (filtersError()) {\n <mat-hint class=\"deb-error-hint\">{{ filtersError() }}</mat-hint>\n } @else {\n <mat-hint>{{ ui.text('staticFiltersHint') }}</mat-hint>\n }\n </mat-form-field>\n\n <mat-divider></mat-divider>\n\n <!-- Cascade -->\n <span class=\"deb-section-title\">{{ ui.text('cascade') }}</span>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('parentField') }}</mat-label>\n <mat-select\n data-testid=\"entity-ref-parent\"\n [ngModel]=\"ref(f).parentField ?? ''\"\n (ngModelChange)=\"patchRef(f, { parentField: $event || undefined })\"\n >\n <mat-option value=\"\">{{ ui.text('parentFieldNone') }}</mat-option>\n @for (option of parentOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }} <span class=\"deb-path-hint\">{{ option.path }}</span>\n </mat-option>\n }\n </mat-select>\n <mat-hint>{{ ui.text('cascadeHint') }}</mat-hint>\n </mat-form-field>\n\n @if (ref(f).parentField) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('lookupFilterPath') }}</mat-label>\n <input\n matInput\n data-testid=\"entity-ref-lookup-filter\"\n [ngModel]=\"ref(f).lookupFilter ?? ''\"\n (ngModelChange)=\"patchRef(f, { lookupFilter: $event || undefined })\"\n />\n <mat-hint>{{ ui.text('lookupFilterPathHint') }}</mat-hint>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('lookupPath') }}</mat-label>\n <input\n matInput\n data-testid=\"entity-ref-lookup-path\"\n [ngModel]=\"ref(f).lookupPath ?? ''\"\n (ngModelChange)=\"patchRef(f, { lookupPath: $event || undefined })\"\n />\n <mat-hint>{{ ui.text('lookupPathHint') }}</mat-hint>\n </mat-form-field>\n }\n\n <mat-divider></mat-divider>\n\n <!-- autoPatch -->\n <div class=\"deb-row deb-row--split\">\n <span class=\"deb-section-title\">{{ ui.text('autoPatchOnSelect') }}</span>\n <button\n mat-stroked-button\n type=\"button\"\n data-testid=\"add-auto-patch\"\n (click)=\"store.addAutoPatchMapping(store.keyOf(f))\"\n >\n <mat-icon>add</mat-icon> {{ ui.text('mapping') }}\n </button>\n </div>\n\n @if (f.autoPatch) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('targetTab') }}</mat-label>\n <mat-select\n data-testid=\"auto-patch-tab\"\n [ngModel]=\"f.autoPatch.targetTab\"\n (ngModelChange)=\"store.setAutoPatchTargetTab(store.keyOf(f), $event)\"\n >\n @for (tab of store.tabs(); track tab.id) {\n <mat-option [value]=\"tab.id\">{{ tabLabel(tab.id) }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n @for (mapping of f.autoPatch.mappings; track $index) {\n <div class=\"deb-option-row\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('sourceLinkedRecord') }}</mat-label>\n <input\n matInput\n [ngModel]=\"mapping.source\"\n (ngModelChange)=\"store.updateAutoPatchMapping(store.keyOf(f), $index, { source: $event })\"\n />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('targetField') }}</mat-label>\n <mat-select\n data-testid=\"auto-patch-target\"\n [ngModel]=\"mapping.target\"\n (ngModelChange)=\"store.updateAutoPatchMapping(store.keyOf(f), $index, { target: $event })\"\n >\n @for (option of optionsWith(mapping.target); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }} <span class=\"deb-path-hint\">{{ option.path }}</span>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <button\n mat-icon-button\n type=\"button\"\n color=\"warn\"\n [matTooltip]=\"ui.text('removeMapping')\"\n (click)=\"store.removeAutoPatchMapping(store.keyOf(f), $index)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n }\n } @else {\n <p class=\"deb-hint\">\n {{ ui.text('noAutoPatch') }}\n </p>\n }\n </div>\n }\n `,\n styles: [\n `\n /*\n * .deb-row, .deb-row--split, .deb-option-row and .deb-full come from the builder's\n * unscoped stylesheet; do not copy them here.\n */\n .deb-entity-ref {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n .deb-option-row > mat-form-field {\n flex: 1;\n }\n .deb-error-hint {\n color: #b91c1c;\n }\n `,\n ],\n})\nexport class EntityReferenceConfigComponent {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n\n protected readonly field = this.store.selectedField;\n\n /** Sibling fields that can drive a cascade — anything but this field itself. */\n protected readonly parentCandidates = computed<NestedFieldConfig[]>(() => {\n const current = this.field();\n return this.store.fields().filter(f => f.id !== current?.id);\n });\n\n private readonly fieldOptions = computed<FieldPathOption[]>(() =>\n fieldPathOptions(this.store.config(), this.store.activeLanguage()),\n );\n\n /**\n * Cascade parents, offered by path.\n *\n * The picker existed but its values were bare ids, which name a field only while no second\n * scope reuses the id — so the one control that was already a list could still produce an\n * ambiguous reference.\n */\n protected parentOptions(): FieldPathOption[] {\n const self = this.field();\n const selfValue = self ? toRefToken(self.refererField ?? self.id) : null;\n const options = this.fieldOptions().filter(o => o.value !== selfValue);\n return withExistingOptions(options, [this.field() ? this.ref(this.field()!).parentField : undefined]);\n }\n\n /** Options plus whatever is already selected, so an unknown reference is never dropped. */\n protected optionsWith(...current: (string | undefined)[]): FieldPathOption[] {\n return withExistingOptions(this.fieldOptions(), current);\n }\n\n private readonly filtersParseError = signal<string | null>(null);\n protected readonly filtersError = this.filtersParseError.asReadonly();\n\n protected ref(field: NestedFieldConfig) {\n return field.entityReference ?? { enabled: true };\n }\n\n protected patchRef(field: NestedFieldConfig, patch: Record<string, unknown>): void {\n this.store.updateEntityReference(this.store.keyOf(field), patch);\n }\n\n protected fieldLabel(field: NestedFieldConfig): string {\n return resolveLabel(field.label, this.store.activeLanguage());\n }\n\n protected tabLabel(tabId: string): string {\n const tab = this.store.tabs().find(t => t.id === tabId);\n return tab ? resolveLabel(tab.label, this.store.activeLanguage()) : tabId;\n }\n\n protected displayFieldsText(field: NestedFieldConfig): string {\n return (this.ref(field).displayFields ?? []).join(', ');\n }\n\n protected setDisplayFields(field: NestedFieldConfig, value: string): void {\n const parts = value\n .split(',')\n .map(s => s.trim())\n .filter(Boolean);\n this.patchRef(field, { displayFields: parts.length ? parts : undefined });\n }\n\n protected filtersText(field: NestedFieldConfig): string {\n const filters = this.ref(field).filters;\n return filters ? JSON.stringify(filters) : '';\n }\n\n /** Invalid JSON is reported inline and left unapplied rather than silently dropped. */\n protected setFilters(field: NestedFieldConfig, value: string): void {\n const trimmed = value.trim();\n if (!trimmed) {\n this.filtersParseError.set(null);\n this.patchRef(field, { filters: undefined });\n return;\n }\n try {\n const parsed = JSON.parse(trimmed);\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n this.filtersParseError.set('Filters must be a JSON object.');\n return;\n }\n this.filtersParseError.set(null);\n this.patchRef(field, { filters: parsed as Record<string, unknown> });\n } catch {\n this.filtersParseError.set('Invalid JSON.');\n }\n }\n}\n","import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, computed, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatSelectModule } from '@angular/material/select';\n\nimport type { FormRule, RuleOperator } from '@dynamic-entity/core';\nimport { BuilderStore } from '../builder-store.service';\nimport { fieldPathOptions, withExistingOptions, type FieldPathOption } from '../field-path-options';\nimport { BuilderTextService } from '../builder-text';\n\n/**\n * RuleFormComponent — dialog/panel form for creating or editing a FormRule.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-rule-form',\n standalone: true,\n imports: [CommonModule, FormsModule, MatButtonModule, MatFormFieldModule, MatIconModule, MatInputModule, MatSelectModule],\n template: `\n <div class=\"deb-rule-form\">\n <h3 class=\"deb-rule-form__title\">{{ ui.text(rule.id ? 'editRuleTitle' : 'newRuleTitle') }}</h3>\n\n <!-- Trigger Field -->\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('triggerField') }}</mat-label>\n <mat-select [(ngModel)]=\"rule.fieldId\" data-testid=\"rule-trigger\">\n @for (option of triggerOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }} <span class=\"deb-rule-path\">{{ option.path }}</span>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n <!-- Targets: the fields this rule acts on -->\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('applyToFields') }}</mat-label>\n <mat-select multiple data-testid=\"rule-targets\" [ngModel]=\"targetValues()\" (ngModelChange)=\"setTargets($event)\">\n @for (option of targetOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }} <span class=\"deb-rule-path\">{{ option.path }}</span>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n <!-- Conditions -->\n <div class=\"deb-rule-section\">\n <h4>{{ ui.text('conditions') }}</h4>\n @for (cond of rule.conditions; track $index) {\n <div class=\"deb-rule-row\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('operator') }}</mat-label>\n <mat-select [(ngModel)]=\"cond.operator\">\n @for (op of operators; track op) {\n <mat-option [value]=\"op\">{{ op }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('value') }}</mat-label>\n <input matInput [(ngModel)]=\"cond.value\" [placeholder]=\"ui.text('conditionValuePlaceholder')\" />\n </mat-form-field>\n <button mat-icon-button color=\"warn\" type=\"button\" (click)=\"removeCondition($index)\">\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n }\n <button mat-stroked-button type=\"button\" (click)=\"addCondition()\">\n <mat-icon>add</mat-icon> {{ ui.text('addCondition') }}\n </button>\n </div>\n\n <!-- Action -->\n <div class=\"deb-rule-section\">\n <h4>{{ ui.text('action') }}</h4>\n <div class=\"deb-rule-row\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('actionType') }}</mat-label>\n <mat-select [(ngModel)]=\"rule.action.type\">\n <mat-option value=\"visibility\">{{ ui.text('actionVisibility') }}</mat-option>\n <mat-option value=\"validation\">{{ ui.text('actionValidationMessage') }}</mat-option>\n <mat-option value=\"info\">{{ ui.text('actionInfoBanner') }}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('valueOrMessage') }}</mat-label>\n <input matInput [(ngModel)]=\"rule.action.value\" [placeholder]=\"ui.text('valueOrMessagePlaceholder')\" />\n </mat-form-field>\n </div>\n </div>\n\n <div class=\"deb-rule-form__actions\">\n <button mat-button type=\"button\" (click)=\"cancel.emit()\">{{ ui.text('cancel') }}</button>\n <button mat-raised-button color=\"primary\" type=\"button\" (click)=\"save.emit(rule)\">{{ ui.text('saveRule') }}</button>\n </div>\n </div>\n `,\n styles: [\n `\n .deb-rule-form {\n display: flex;\n flex-direction: column;\n gap: 12px;\n background: #fafafa;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n padding: 16px;\n }\n .deb-rule-form__title {\n margin: 0 0 8px 0;\n font-size: 16px;\n font-weight: 600;\n }\n .deb-full {\n width: 100%;\n }\n .deb-rule-path {\n color: #888;\n font-size: 11px;\n margin-left: 6px;\n }\n .deb-rule-section {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n .deb-rule-section h4 {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: #555;\n }\n .deb-rule-row {\n display: flex;\n gap: 8px;\n align-items: center;\n }\n .deb-rule-row > * {\n flex: 1;\n }\n .deb-rule-form__actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n margin-top: 8px;\n }\n `,\n ],\n})\nexport class RuleFormComponent {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n private readonly store = inject(BuilderStore);\n\n @Input() rule: FormRule = {\n formConfigId: 'form-1',\n fieldId: '',\n conditions: [{ operator: 'EQUAL', compareType: 'value', value: '' }],\n action: { type: 'visibility', value: false },\n targets: [],\n enabled: true,\n priority: 1,\n };\n\n @Output() save = new EventEmitter<FormRule>();\n // Published API since 1.x: renaming it would break every host bound to `(cancel)`.\n // eslint-disable-next-line @angular-eslint/no-output-native\n @Output() cancel = new EventEmitter<void>();\n\n readonly operators: RuleOperator[] = [\n 'EQUAL',\n 'NOT_EQUAL',\n 'CONTAINS',\n 'NOT_CONTAINS',\n 'STARTS_WITH',\n 'ENDS_WITH',\n 'IS_EMPTY',\n 'IS_NOT_EMPTY',\n 'LESS_THAN',\n 'MORE_THAN',\n 'LESS_THAN_EQUAL',\n 'MORE_THAN_EQUAL',\n 'DATE_BEFORE',\n 'DATE_AFTER',\n 'IN',\n 'NOT_IN',\n 'HAS_ITEMS',\n 'VALUE_CHANGED',\n ];\n\n protected readonly fieldOptions = computed<FieldPathOption[]>(() =>\n fieldPathOptions(this.store.config(), this.store.activeLanguage()),\n );\n\n /**\n * Methods, not `computed`. Both read `rule`, which is a plain `@Input` object mutated in\n * place rather than a signal — a computed would cache the first evaluation and never see a\n * different rule being edited.\n */\n protected triggerOptions(): FieldPathOption[] {\n return withExistingOptions(this.fieldOptions(), [this.rule.fieldId]);\n }\n\n protected targetOptions(): FieldPathOption[] {\n return withExistingOptions(this.fieldOptions(), this.targetValues());\n }\n\n private cachedTargets: string[] = [];\n\n /**\n * Field targets only — a rule may also target a tab, which this picker does not manage.\n *\n * The array identity is held stable while the contents are unchanged. This is bound through\n * `[ngModel]` on a multi-select, and a fresh array on each call made `ngModel` see a new\n * value on every change-detection pass: it wrote, which scheduled another pass, which built\n * another array. Opening the rule editor locked the browser outright.\n */\n protected targetValues(): string[] {\n const ids = this.rule.targets.filter(t => t.type === 'field').map(t => t.id);\n const unchanged = ids.length === this.cachedTargets.length && ids.every((id, i) => id === this.cachedTargets[i]);\n if (!unchanged) this.cachedTargets = ids;\n return this.cachedTargets;\n }\n\n /**\n * Replaces the field targets, leaving any tab target untouched.\n *\n * Rebuilding `targets` wholesale from this picker would drop tab targets, which it never\n * offered and so cannot know about.\n */\n protected setTargets(ids: string[]): void {\n const others = this.rule.targets.filter(t => t.type !== 'field');\n this.rule.targets = [...others, ...ids.map(id => ({ id, type: 'field' as const }))];\n }\n\n addCondition(): void {\n this.rule.conditions.push({ operator: 'EQUAL', compareType: 'value', value: '' });\n }\n\n removeCondition(index: number): void {\n this.rule.conditions.splice(index, 1);\n }\n}\n","import { ChangeDetectionStrategy, Component, inject, signal } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatSlideToggleModule } from '@angular/material/slide-toggle';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport type { FormRule } from '@dynamic-entity/core';\nimport { toRefToken } from '@dynamic-entity/core';\nimport { BuilderStore } from '../builder-store.service';\nimport { deepClone } from '../clone';\nimport { RuleFormComponent } from './rule-form.component';\nimport { BuilderTextService } from '../builder-text';\n\n/**\n * FieldRulesListComponent — the rules attached to the selected field: view, reorder,\n * enable/disable, edit, delete. `RuleFormComponent` authors one rule; this owns the set.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-field-rules-list',\n standalone: true,\n imports: [MatButtonModule, MatIconModule, MatSlideToggleModule, MatTooltipModule, RuleFormComponent],\n template: `\n <div class=\"deb-rules\">\n <div class=\"deb-rules__head\">\n <span class=\"deb-section-title\">{{ ui.text('rules') }}</span>\n <button\n mat-stroked-button\n type=\"button\"\n data-testid=\"add-rule\"\n [disabled]=\"!store.selectedFieldId()\"\n (click)=\"startCreate()\"\n >\n <mat-icon>add</mat-icon> {{ ui.text('rule') }}\n </button>\n </div>\n\n @if (editing(); as draft) {\n <ngx-rule-form [rule]=\"draft\" (save)=\"commit($event)\" (cancel)=\"editing.set(null)\" />\n }\n\n @if (store.rulesForSelectedField().length === 0 && !editing()) {\n <p class=\"deb-hint\" data-testid=\"rules-empty\">{{ ui.text('noRulesOnField') }}</p>\n }\n\n @for (rule of store.rulesForSelectedField(); track rule.id) {\n <div class=\"deb-rule-item\" [class.deb-rule-item--off]=\"!rule.enabled\" data-testid=\"rule-item\">\n <div class=\"deb-rule-item__body\">\n <span class=\"deb-rule-item__summary\">{{ summarize(rule) }}</span>\n <span class=\"deb-rule-item__meta\">\n {{ ui.text('rulePriority', { priority: rule.priority, targets: rule.targets.length }) }}\n </span>\n </div>\n <div class=\"deb-rule-item__actions\">\n <mat-slide-toggle\n color=\"primary\"\n [checked]=\"rule.enabled\"\n [matTooltip]=\"ui.text('toggleRule')\"\n (change)=\"store.toggleRule(rule.id!, $event.checked)\"\n />\n <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"ui.text('moveUp')\"\n [attr.aria-label]=\"ui.text('moveRuleUp')\"\n [attr.data-testid]=\"'rule-up-' + rule.id\"\n (click)=\"store.moveRule(rule.id!, -1)\"\n >\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"ui.text('moveDown')\"\n [attr.aria-label]=\"ui.text('moveRuleDown')\"\n [attr.data-testid]=\"'rule-down-' + rule.id\"\n (click)=\"store.moveRule(rule.id!, 1)\"\n >\n <mat-icon>arrow_downward</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"ui.text('editRule')\"\n [attr.data-testid]=\"'rule-edit-' + rule.id\"\n (click)=\"startEdit(rule)\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n color=\"warn\"\n [matTooltip]=\"ui.text('deleteRule')\"\n [attr.data-testid]=\"'rule-delete-' + rule.id\"\n (click)=\"store.removeRule(rule.id!)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n </div>\n }\n </div>\n `,\n styles: [\n `\n .deb-rules {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n .deb-rules__head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n .deb-rule-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n padding: 8px 10px;\n }\n .deb-rule-item--off {\n opacity: 0.55;\n }\n .deb-rule-item__body {\n display: flex;\n flex-direction: column;\n min-width: 0;\n }\n .deb-rule-item__summary {\n font-size: 13px;\n font-weight: 600;\n overflow-wrap: anywhere;\n }\n .deb-rule-item__meta {\n font-size: 11px;\n color: #6b7280;\n }\n .deb-rule-item__actions {\n display: flex;\n align-items: center;\n flex: 0 0 auto;\n }\n `,\n ],\n})\nexport class FieldRulesListComponent {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n\n /** The rule currently open in the editor — a new draft or a copy of an existing rule. */\n protected readonly editing = signal<FormRule | null>(null);\n\n protected startCreate(): void {\n const fieldId = this.store.selectedFieldId();\n if (!fieldId) return;\n // Author the field's path, not its id. Ids are unique per scope, so `address` may exist\n // on two tabs and a bare id cannot say which one the rule is about; `[work.address]` can.\n // A rule written by hand may still use a bare id, and both resolve at runtime.\n const ref = this.store.selectedField()?.refererField;\n const name = ref ? toRefToken(ref) : fieldId;\n this.editing.set({\n formConfigId: this.store.config().entity || 'form-1',\n fieldId: name,\n conditions: [{ operator: 'EQUAL', compareType: 'value', value: '' }],\n action: { type: 'visibility', value: false },\n targets: [{ id: name, type: 'field' }],\n enabled: true,\n priority: this.store.rules().length + 1,\n });\n }\n\n protected startEdit(rule: FormRule): void {\n this.editing.set(deepClone(rule));\n }\n\n protected commit(rule: FormRule): void {\n if (rule.id) this.store.updateRule(rule.id, rule);\n else this.store.addRule(rule);\n this.editing.set(null);\n }\n\n /** One-line human summary: `status EQUAL \"archived\" → hide`. */\n protected summarize(rule: FormRule): string {\n const cond = rule.conditions\n .map(c => {\n const rhs = c.compareType === 'field' ? c.compareToField : JSON.stringify(c.value ?? '');\n return `${c.operator} ${rhs ?? ''}`.trim();\n })\n .join(' AND ');\n\n const action =\n rule.action.type === 'visibility'\n ? rule.action.value === false || rule.action.value === 'false'\n ? 'hide'\n : 'show'\n : `${rule.action.type}: ${rule.action.value}`;\n\n return `${rule.fieldId} ${cond} → ${action}`;\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, isDevMode } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatDividerModule } from '@angular/material/divider';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatSlideToggleModule } from '@angular/material/slide-toggle';\nimport { ConfigSourceService } from 'ngx-dynamic-entity';\nimport type { NestedFieldConfig } from '@dynamic-entity/core';\nimport { BuilderStore } from '../builder-store.service';\nimport { BuilderTextService } from '../builder-text';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-referenced-field-config',\n standalone: true,\n imports: [\n CommonModule,\n FormsModule,\n MatButtonModule,\n MatDividerModule,\n MatFormFieldModule,\n MatIconModule,\n MatInputModule,\n MatSlideToggleModule,\n ],\n template: `\n @if (field(); as f) {\n <div class=\"deb-referenced-field\" style=\"margin-top: 16px;\">\n <div class=\"deb-row\" style=\"justify-content: space-between; align-items: center; margin-bottom: 8px;\">\n <span class=\"deb-section-title\" style=\"margin:0;\">{{ ui.text('referencedField') }}</span>\n <mat-slide-toggle\n color=\"primary\"\n data-testid=\"toggle-referenced\"\n [ngModel]=\"f.isReferenced ?? false\"\n (ngModelChange)=\"toggleReferenced(f, $event)\"\n >\n {{ ui.text('link') }}\n </mat-slide-toggle>\n </div>\n\n @if (f.isReferenced) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\" style=\"margin-bottom: 8px;\">\n <mat-label>{{ ui.text('sourceEntityKey') }}</mat-label>\n <input\n matInput\n data-testid=\"referenced-entity-key\"\n [ngModel]=\"f.referencedEntityKey ?? ''\"\n (ngModelChange)=\"updateEntityKey(f, $event)\"\n [placeholder]=\"ui.text('sourceEntityKeyPlaceholder')\"\n />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\" style=\"margin-bottom: 8px;\">\n <mat-label>{{ ui.text('sourceFieldId') }}</mat-label>\n <input\n matInput\n data-testid=\"referenced-field-id\"\n [ngModel]=\"f.referencedFieldId ?? ''\"\n (ngModelChange)=\"updateFieldId(f, $event)\"\n [placeholder]=\"ui.text('sourceFieldIdPlaceholder')\"\n />\n </mat-form-field>\n\n @if (f.hasDrift) {\n <div\n class=\"deb-drift-banner\"\n data-testid=\"drift-banner\"\n style=\"background: #fff3e0; border: 1px solid #ffe0b2; padding: 8px 12px; border-radius: 4px; margin-top: 8px;\"\n >\n <div class=\"deb-row\" style=\"gap: 8px; align-items: center; color: #e65100; font-weight: 500;\">\n <mat-icon style=\"font-size: 18px; width:18px; height:18px;\">warning</mat-icon>\n <span>{{ ui.text('driftHeading') }}</span>\n </div>\n <p style=\"margin: 4px 0 8px 0; font-size: 12px; color: #666;\">\n {{ ui.text('driftBody', { entity: f.referencedEntityKey ?? '' }) }}\n </p>\n <button mat-flat-button color=\"warn\" type=\"button\" data-testid=\"sync-source-btn\" (click)=\"syncWithSource(f)\">\n {{ ui.text('syncWithSource') }}\n </button>\n </div>\n }\n }\n </div>\n }\n `,\n})\nexport class ReferencedFieldConfigComponent {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n protected readonly configSource = inject(ConfigSourceService, { optional: true }) as ConfigSourceService | null;\n protected readonly field = computed(() => this.store.selectedField());\n\n protected toggleReferenced(field: NestedFieldConfig, enabled: boolean): void {\n if (enabled) {\n this.store.updateField(this.store.keyOf(field), { isReferenced: true });\n } else {\n this.store.unlinkReferencedField(this.store.keyOf(field));\n }\n }\n\n protected updateEntityKey(field: NestedFieldConfig, key: string): void {\n const trimmed = key.trim();\n this.store.updateField(this.store.keyOf(field), { referencedEntityKey: trimmed || undefined });\n // Fire-and-forget on purpose: the edit has already landed, and the drift check is a\n // decoration on top of it. `void` says so, and `checkDriftForField` swallows its own\n // failures — a source config that cannot be fetched must not reject out of a keystroke\n // handler, where nothing would catch it.\n void this.checkDriftForField(field.id);\n }\n\n protected updateFieldId(field: NestedFieldConfig, fieldId: string): void {\n const trimmed = fieldId.trim();\n this.store.updateField(this.store.keyOf(field), { referencedFieldId: trimmed || undefined });\n void this.checkDriftForField(field.id);\n }\n\n protected async syncWithSource(field: NestedFieldConfig): Promise<void> {\n if (!field.referencedEntityKey || !field.referencedFieldId || !this.configSource) return;\n const sourceConfig = await this.configSource.getConfig(field.referencedEntityKey);\n if (!sourceConfig) return;\n\n const sourceField = this.findField(sourceConfig.tabs ?? [], field.referencedFieldId);\n if (sourceField) {\n this.store.syncReferencedField(this.store.keyOf(field), sourceField);\n }\n }\n\n /**\n * Takes the id of the field just edited rather than reading `store.selectedField()`, which\n * need not be the same field — or any field at all.\n */\n private async checkDriftForField(fieldId: string): Promise<void> {\n const f = this.store.fields().find(field => field.id === fieldId);\n if (!f || !f.isReferenced || !f.referencedEntityKey || !f.referencedFieldId || !this.configSource) return;\n\n // The callers are keystroke handlers that cannot await this, so a rejection here has\n // nowhere to go but the console as an unhandled promise. `getConfig` is consumer code\n // reaching for a source entity that may not load; failing to *check* drift is not a\n // reason to interrupt the edit that was already applied.\n try {\n const sourceConfig = await this.configSource.getConfig(f.referencedEntityKey);\n if (sourceConfig) {\n this.store.checkDrift({ [f.referencedEntityKey]: sourceConfig });\n }\n } catch (err) {\n if (isDevMode()) {\n console.warn(\n `[ngx-dynamic-entity-builder] Could not load \"${f.referencedEntityKey}\" to check ` +\n `drift on \"${fieldId}\". The field's link is saved; the drift flag is stale.`,\n err,\n );\n }\n }\n }\n\n private findField(tabs: any[], id: string): NestedFieldConfig | undefined {\n for (const t of tabs) {\n for (const f of t.fields ?? []) {\n if (f.id === id) return f;\n if (f.children?.length) {\n const res = this.findFieldInList(f.children, id);\n if (res) return res;\n }\n }\n }\n return undefined;\n }\n\n private findFieldInList(fields: NestedFieldConfig[], id: string): NestedFieldConfig | undefined {\n for (const f of fields) {\n if (f.id === id) return f;\n if (f.children?.length) {\n const res = this.findFieldInList(f.children, id);\n if (res) return res;\n }\n }\n return undefined;\n }\n}\n","import { Component, computed, inject, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatDividerModule } from '@angular/material/divider';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatSelectModule } from '@angular/material/select';\nimport { MatSlideToggleModule } from '@angular/material/slide-toggle';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport type { DropdownOption, NestedFieldConfig } from '@dynamic-entity/core';\nimport { resolveLabel, resolveOptionLabel, toRefToken } from '@dynamic-entity/core';\nimport { fieldPathOptions, withExistingOptions, type FieldPathOption } from '../field-path-options';\nimport { BuilderStore } from '../builder-store.service';\nimport { getFieldTypeMeta, type FieldTypeMeta } from '../field-catalog';\nimport { computeRuleDependencies, type RuleDependencyEdge } from '../rule-dependencies';\nimport { EntityReferenceConfigComponent } from './entity-reference-config.component';\nimport { FieldRulesListComponent } from './field-rules-list.component';\nimport { ReferencedFieldConfigComponent } from './referenced-field-config.component';\nimport { BuilderTextService } from '../builder-text';\n\n/**\n * FieldInspectorComponent — edits every property of the currently selected field.\n */\n@Component({\n selector: 'ngx-field-inspector',\n standalone: true,\n imports: [\n FormsModule,\n MatButtonModule,\n MatCheckboxModule,\n MatDividerModule,\n MatFormFieldModule,\n MatIconModule,\n MatInputModule,\n MatSelectModule,\n MatSlideToggleModule,\n MatTooltipModule,\n EntityReferenceConfigComponent,\n FieldRulesListComponent,\n ReferencedFieldConfigComponent,\n ],\n templateUrl: './field-inspector.component.html',\n styles: [\n `\n .deb-inspector {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n .deb-inspector__empty {\n color: var(--deb-muted, #6b7280);\n text-align: center;\n padding: 24px 8px;\n }\n .deb-full {\n width: 100%;\n }\n .deb-row > * {\n flex: 1;\n }\n /*\n * The type chip is a label, not a field.\n *\n * The rule above gave it an equal share of the identity row, so the chip took half the\n * inspector's width and squeezed the field id into a column narrow enough to wrap its\n * hint over three lines.\n */\n .deb-row > .deb-chip {\n flex: 0 0 auto;\n }\n .deb-row--split > * {\n flex: 0 0 auto;\n }\n .deb-toggles {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 8px 12px;\n }\n .deb-option-row {\n display: flex;\n gap: 6px;\n align-items: center;\n }\n .deb-pattern-box {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 8px;\n padding: 12px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n }\n .deb-pattern-status {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 600;\n }\n .deb-pattern-status--match {\n background: #dcfce7;\n color: #166534;\n }\n .deb-pattern-status--no-match {\n background: #fee2e2;\n color: #991b1b;\n }\n .deb-pattern-status--invalid {\n background: #fef3c7;\n color: #92400e;\n }\n .deb-pattern-status--idle,\n .deb-pattern-status--empty {\n background: #f1f5f9;\n color: #334155;\n }\n .deb-pattern-presets {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n align-items: center;\n }\n .deb-preset-btn {\n padding: 2px 8px;\n border-radius: 4px;\n border: 1px solid #cbd5e1;\n background: #ffffff;\n font-size: 11px;\n color: #334155;\n cursor: pointer;\n transition: background 0.1s ease;\n }\n .deb-preset-btn:hover {\n background: #e2e8f0;\n }\n .deb-dep-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-top: 4px;\n margin-bottom: 12px;\n }\n .deb-dep-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 6px 10px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 6px;\n }\n .deb-dep-info {\n display: flex;\n flex-direction: column;\n min-width: 0;\n }\n .deb-dep-name {\n font-size: 12px;\n font-weight: 600;\n color: #0f172a;\n }\n .deb-dep-detail {\n font-size: 11px;\n color: #64748b;\n }\n `,\n ],\n})\nexport class FieldInspectorComponent {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n\n protected readonly field = this.store.selectedField;\n protected readonly meta = computed<FieldTypeMeta | undefined>(() => {\n const f = this.field();\n return f ? getFieldTypeMeta(f.type) : undefined;\n });\n\n /**\n * The offered widths, as fractions of the 12-column row.\n *\n * Five steps rather than all twelve: a free 1–12 spinner is a layout system, and what an\n * author actually wants is \"these two side by side\" or \"this one across the row\". The\n * fractions that divide twelve evenly cover that, and anything finer stays authorable in\n * the JSON for the rare case that needs it.\n */\n protected readonly spanChoices = [\n { span: 3, textKey: 'widthQuarter' },\n { span: 4, textKey: 'widthThird' },\n { span: 6, textKey: 'widthHalf' },\n { span: 8, textKey: 'widthTwoThirds' },\n { span: 12, textKey: 'widthFull' },\n ] as const;\n\n protected lang(): string {\n return this.store.activeLanguage();\n }\n\n /**\n * How many validators this field actually has, for the section's badge.\n *\n * `false` and an empty `custom: []` are both \"not set\" written the long way — a toggle\n * switched off leaves the key behind — so neither counts. `0` does: `minLength: 0` is a\n * value somebody typed.\n */\n protected validatorCount(field: NestedFieldConfig): number {\n return Object.values(field.validators ?? {}).filter(value => {\n if (value === undefined || value === null || value === false) return false;\n return Array.isArray(value) ? value.length > 0 : true;\n }).length;\n }\n\n /**\n * How many display flags are set away from their default.\n *\n * `visibility` counts when it is *false* and the rest when they are true, because the badge\n * is meant to say \"something here is not the default\" — counting `visibility: true` would\n * put a 1 on every field in the config and tell the author nothing.\n */\n protected displayFlagCount(field: NestedFieldConfig): number {\n const flags = [\n field.visibility === false,\n field.table?.visible === true,\n field.readonly === true,\n field.disabled === true,\n field.maskData === true,\n field.criticalField === true,\n field.showOnMinimize === true,\n ];\n return flags.filter(Boolean).length;\n }\n\n /** A step must be above zero; anything else clears it, and the slider uses 1. */\n protected positiveOrUnset(value: unknown): number | undefined {\n const n = this.toNum(value);\n return n !== null && n > 0 ? n : undefined;\n }\n\n protected toNum(value: unknown): number | null {\n if (value === '' || value === null || value === undefined) return null;\n const n = Number(value);\n return Number.isNaN(n) ? null : n;\n }\n\n protected labelValue(field: NestedFieldConfig): string {\n return resolveLabel(field.label, this.lang());\n }\n\n protected placeholderValue(field: NestedFieldConfig): string {\n return resolveLabel(field.placeholder, this.lang());\n }\n\n protected hintValue(field: NestedFieldConfig): string {\n return resolveLabel(field.hint, this.lang());\n }\n\n protected optionLabel(option: DropdownOption): string {\n return resolveOptionLabel(option, this.lang());\n }\n\n /**\n * Every tab a field can live on, sub-tabs included.\n *\n * `moveFieldToTab` existed on the store with nothing calling it, so a field authored on the\n * wrong tab had to be deleted and rebuilt — losing its validators, options and every rule\n * aimed at it.\n */\n protected readonly tabOptions = computed<{ id: string; label: string }[]>(() =>\n this.store\n .fieldGroups()\n .map(group => ({ id: group.tabId, label: resolveLabel(group.label, this.lang()) || group.tabId }))\n .concat(\n this.store\n .tabs()\n .flatMap(tab => [tab, ...(tab.children ?? [])])\n .map(tab => ({ id: tab.id, label: resolveLabel(tab.label, this.lang()) || tab.id })),\n )\n .filter((tab, i, all) => all.findIndex(t => t.id === tab.id) === i),\n );\n\n /**\n * The tab the selected field currently sits on.\n *\n * Looked up by identity rather than parsed out of the path: the scope of\n * `incident.incidentDetails.incidentTime` is two segments and the field belongs to the\n * *last* of them, while a field inside a group has the group id in that position and\n * belongs to no tab of that name at all.\n */\n protected currentTabId(field: NestedFieldConfig): string {\n return this.store.fieldGroups().find(group => group.fields.includes(field))?.tabId ?? '';\n }\n\n protected moveToTab(field: NestedFieldConfig, tabId: string): void {\n if (tabId && tabId !== this.currentTabId(field)) this.store.moveFieldToTab(this.store.keyOf(field), tabId);\n }\n\n /**\n * Fields offered wherever this inspector names one — the `showWhen` key and both ends of a\n * `patchOnTrue` mapping. All three were free text, which is the one way left to write a\n * reference that names two fields at once.\n */\n protected readonly fieldOptions = computed<FieldPathOption[]>(() =>\n fieldPathOptions(this.store.config(), this.store.activeLanguage()),\n );\n\n /** Options plus whatever is already selected, so an unknown reference is never dropped. */\n protected optionsWith(...current: (string | undefined)[]): FieldPathOption[] {\n return withExistingOptions(this.fieldOptions(), current);\n }\n\n // ─── showWhen editing ───────────────────────────────────────────────────────\n\n protected showWhenEntries(field: NestedFieldConfig): { key: string; display: string }[] {\n return Object.entries(field.showWhen ?? {}).map(([key, value]) => ({\n key,\n display: this.stringifyShowWhen(value),\n }));\n }\n\n /**\n * Seeds a new condition with the first field not already watched.\n * A seed that names no real field would silently hide this one until edited.\n */\n protected addShowWhen(field: NestedFieldConfig): void {\n const next = { ...(field.showWhen ?? {}) };\n const self = toRefToken(field.refererField ?? field.id);\n const candidate = this.fieldOptions().find(o => o.value !== self && !(o.value in next));\n\n // Falls back to the old placeholder only when there is genuinely nothing else to watch —\n // a config with one field. Otherwise a new condition starts on a real field instead of\n // the literal string `field`, which is not an id at all and hid the field until edited.\n let key = candidate?.value ?? 'field';\n let n = 1;\n while (key in next) key = `field_${++n}`;\n next[key] = true;\n this.store.setShowWhen(this.store.keyOf(field), next);\n }\n\n protected renameShowWhen(field: NestedFieldConfig, oldKey: string, newKey: string): void {\n const trimmed = newKey.trim();\n if (!trimmed || trimmed === oldKey) return;\n const current = field.showWhen ?? {};\n if (trimmed in current) return;\n const next: Record<string, unknown> = {};\n // Rebuild in order so the row does not jump while the user is typing.\n for (const [k, v] of Object.entries(current)) next[k === oldKey ? trimmed : k] = v;\n this.store.setShowWhen(this.store.keyOf(field), next);\n }\n\n protected setShowWhenValue(field: NestedFieldConfig, key: string, raw: string): void {\n this.store.setShowWhen(this.store.keyOf(field), { ...(field.showWhen ?? {}), [key]: this.parseShowWhen(raw) });\n }\n\n protected removeShowWhen(field: NestedFieldConfig, key: string): void {\n const next = { ...(field.showWhen ?? {}) };\n delete next[key];\n this.store.setShowWhen(this.store.keyOf(field), next);\n }\n\n /**\n * `showWhen` compares with `!==`, so the authored type has to survive the round trip:\n * \"true\"/\"false\" become booleans and numeric text becomes a number.\n */\n private parseShowWhen(raw: string): unknown {\n const trimmed = raw.trim();\n if (trimmed === 'true') return true;\n if (trimmed === 'false') return false;\n if (trimmed === 'null') return null;\n if (trimmed !== '' && !Number.isNaN(Number(trimmed))) return Number(trimmed);\n return raw;\n }\n\n private stringifyShowWhen(value: unknown): string {\n if (value === null) return 'null';\n if (typeof value === 'object') return JSON.stringify(value);\n return String(value);\n }\n\n // ─── Pattern Playground ────────────────────────────────────────────────────\n\n protected readonly testSample = signal<string>('');\n\n protected readonly regexEvaluation = computed<{\n status: 'empty' | 'idle' | 'match' | 'no-match' | 'invalid';\n error?: string;\n }>(() => {\n const f = this.field();\n const pattern = f?.validators?.pattern?.trim();\n if (!pattern) return { status: 'empty' };\n\n let regex: RegExp;\n try {\n regex = new RegExp(pattern);\n } catch (e) {\n return { status: 'invalid', error: (e as Error).message };\n }\n\n const sample = this.testSample();\n if (!sample) return { status: 'idle' };\n\n return { status: regex.test(sample) ? 'match' : 'no-match' };\n });\n\n protected readonly patternPresets = [\n { label: 'Alpha', pattern: '^[a-zA-Z]+$' },\n { label: 'Alphanumeric', pattern: '^[a-zA-Z0-9]+$' },\n { label: 'Digits', pattern: '^\\\\d+$' },\n { label: 'Postal Code', pattern: '^\\\\d{5}(-\\\\d{4})?$' },\n { label: 'Phone', pattern: '^\\\\+?[1-9]\\\\d{1,14}$' },\n { label: 'Slug', pattern: '^[a-z0-9]+(?:-[a-z0-9]+)*$' },\n ];\n\n protected supportsPattern(type: string): boolean {\n return ['text', 'textarea', 'markdown', 'email', 'password', 'url', 'phone'].includes(type);\n }\n\n protected applyPreset(field: NestedFieldConfig, pattern: string): void {\n this.store.setPatternValidator(this.store.keyOf(field), pattern);\n }\n\n // ─── Dependencies ──────────────────────────────────────────────────────────\n\n protected readonly allDependencies = computed(() =>\n computeRuleDependencies(this.store.config(), this.store.rules(), this.lang()),\n );\n\n protected readonly incomingDependencies = computed<RuleDependencyEdge[]>(() => {\n const f = this.field();\n if (!f) return [];\n const key = this.store.keyOf(f);\n const id = f.id;\n return this.allDependencies().edges.filter(\n e => e.targetKey === key || e.targetKey === id,\n );\n });\n\n protected readonly outgoingDependencies = computed<RuleDependencyEdge[]>(() => {\n const f = this.field();\n if (!f) return [];\n const key = this.store.keyOf(f);\n const id = f.id;\n return this.allDependencies().edges.filter(\n e => e.sourceKey === key || e.sourceKey === id,\n );\n });\n\n protected selectField(key: string): void {\n if (key) this.store.selectField(key);\n }\n}\n","@if (field(); as f) {\n <!--\n The inspector, in collapsible sections.\n\n It used to be one flat scroll of fifteen divider-separated blocks, so renaming a field\n meant scrolling past every advanced setting a field has, and finding the rules list meant\n scrolling past all of them.\n\n All inspector sections start expanded by default so authors have immediate access to\n validation, automation, visibility conditions, rules, dependencies, and reference settings\n without needing to manually unfold each section. Sections can still be collapsed as desired.\n\n `<details>` rather than mat-expansion-panel: the inspector already sits inside a card in a\n scrolling rail, and a third level of Material elevation inside that read as noise.\n -->\n <div class=\"deb-inspector\">\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionBasics') }}\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n <!-- Identity -->\n <div class=\"deb-row\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('fieldId') }}</mat-label>\n <input matInput data-testid=\"field-id\" [value]=\"f.id\" disabled />\n @if (store.hasManualId(f.id)) {\n <mat-hint>{{ ui.text('fieldIdFixedHint') }}</mat-hint>\n } @else {\n <mat-hint>{{ ui.text('fieldIdDerivedHint') }}</mat-hint>\n }\n </mat-form-field>\n <span class=\"deb-chip\">{{ meta()?.label || f.type }}</span>\n </div>\n\n @if (tabOptions().length > 1) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('tab') }}</mat-label>\n <mat-select data-testid=\"field-tab\" [ngModel]=\"currentTabId(f)\" (ngModelChange)=\"moveToTab(f, $event)\">\n @for (tab of tabOptions(); track tab.id) {\n <mat-option [value]=\"tab.id\">{{ tab.label }}</mat-option>\n }\n </mat-select>\n <mat-hint>{{ ui.text('tabMoveHint') }}</mat-hint>\n </mat-form-field>\n }\n\n <!-- Localised text (active language) -->\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('labelInLanguage', { language: lang() }) }}</mat-label>\n <input\n matInput\n data-testid=\"field-label\"\n [ngModel]=\"labelValue(f)\"\n (ngModelChange)=\"store.setFieldLabel(store.keyOf(f), lang(), $event)\"\n />\n </mat-form-field>\n\n @if (meta()?.supportsPlaceholder) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('placeholderInLanguage', { language: lang() }) }}</mat-label>\n <input\n matInput\n [ngModel]=\"placeholderValue(f)\"\n (ngModelChange)=\"store.setFieldPlaceholder(store.keyOf(f), lang(), $event)\"\n />\n </mat-form-field>\n }\n\n <!--\n Help text, offered on every field type — including the ones with no placeholder,\n which are exactly the ones most likely to need explaining. Its hint says what it is\n *for*, because the box above it is the one authors reach for by habit and a\n placeholder is gone the moment somebody types.\n -->\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('hintInLanguage', { language: lang() }) }}</mat-label>\n <input\n matInput\n data-testid=\"field-hint\"\n [ngModel]=\"hintValue(f)\"\n (ngModelChange)=\"store.setFieldHint(store.keyOf(f), lang(), $event)\"\n />\n <mat-hint>{{ ui.text('hintHint') }}</mat-hint>\n </mat-form-field>\n\n @if (meta()?.supportsDefaultValue) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('defaultValue') }}</mat-label>\n <input\n matInput\n [ngModel]=\"f.defaultValue ?? ''\"\n (ngModelChange)=\"store.updateField(store.keyOf(f), { defaultValue: $event })\"\n />\n </mat-form-field>\n }\n </div>\n </details>\n\n <!--\n Width.\n\n `colSpan` has been in the schema and honoured by the renderer since the 12-column grid\n existed, and the builder had no control for it — so every form authored here came out a\n single-column ladder, and the only way to put two fields on one row was to hand-edit the\n JSON. This is that control.\n -->\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionLayout') }}\n <span class=\"deb-inspector__count\" data-testid=\"layout-count\">{{ f.colSpan ?? 12 }}/12</span>\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n <div class=\"deb-span-picker\" role=\"group\" [attr.aria-label]=\"ui.text('width')\">\n @for (choice of spanChoices; track choice.span) {\n <button\n type=\"button\"\n class=\"deb-span-picker__btn\"\n [class.deb-span-picker__btn--active]=\"(f.colSpan ?? 12) === choice.span\"\n [attr.data-testid]=\"'field-span-' + choice.span\"\n [attr.aria-pressed]=\"(f.colSpan ?? 12) === choice.span\"\n [matTooltip]=\"ui.text('widthOf', { span: choice.span })\"\n (click)=\"store.updateField(store.keyOf(f), { colSpan: choice.span })\"\n >\n {{ ui.text(choice.textKey) }}\n </button>\n }\n </div>\n <p class=\"deb-hint\">{{ ui.text('widthHint') }}</p>\n </div>\n </details>\n\n <!-- Validators -->\n <!-- Validators -->\n @if (meta(); as m) {\n @if (m.flagValidators.length || m.paramValidators.length || supportsPattern(f.type) || f.validators?.pattern) {\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionValidation') }}\n @if (validatorCount(f); as count) {\n <span class=\"deb-inspector__count\" data-testid=\"validation-count\">{{ count }}</span>\n }\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n @if (m.flagValidators.length) {\n <div class=\"deb-flags-row\">\n @for (v of m.flagValidators; track v) {\n <mat-checkbox\n color=\"primary\"\n [ngModel]=\"store.hasFlagValidator(f, v)\"\n (ngModelChange)=\"store.toggleFlagValidator(store.keyOf(f), v, $event)\"\n >{{ v }}</mat-checkbox\n >\n }\n </div>\n }\n @if (m.paramValidators.length) {\n <div class=\"deb-param-validators-grid\">\n @for (v of m.paramValidators; track v) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ v }}</mat-label>\n <input\n matInput\n type=\"number\"\n [ngModel]=\"store.getParamValidator(f, v)\"\n (ngModelChange)=\"store.setParamValidator(store.keyOf(f), v, toNum($event))\"\n />\n </mat-form-field>\n }\n </div>\n }\n @if (f.type === 'slider') {\n <!-- The slider's range is min and max above; its increment is the one number left. -->\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('sliderStep') }}</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n data-testid=\"field-step\"\n [ngModel]=\"f.step ?? null\"\n (ngModelChange)=\"store.updateField(store.keyOf(f), { step: positiveOrUnset($event) })\"\n />\n <mat-hint>{{ ui.text('sliderStepHint') }}</mat-hint>\n </mat-form-field>\n }\n\n @if (supportsPattern(f.type) || f.validators?.pattern) {\n <div class=\"deb-pattern-box\" data-testid=\"pattern-playground\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('pattern') }}</mat-label>\n <input\n matInput\n data-testid=\"field-pattern-input\"\n [ngModel]=\"f.validators?.pattern ?? ''\"\n (ngModelChange)=\"store.setPatternValidator(store.keyOf(f), $event)\"\n />\n <mat-hint>{{ ui.text('patternHint') }}</mat-hint>\n </mat-form-field>\n\n <div class=\"deb-pattern-presets\">\n <span class=\"deb-section-title\">{{ ui.text('quickPresets') }}:</span>\n @for (preset of patternPresets; track preset.label) {\n <button\n type=\"button\"\n class=\"deb-preset-btn\"\n [attr.data-testid]=\"'preset-' + preset.label.toLowerCase()\"\n (click)=\"applyPreset(f, preset.pattern)\"\n >\n {{ preset.label }}\n </button>\n }\n </div>\n\n <div class=\"deb-row deb-row--split\">\n <span class=\"deb-section-title\">{{ ui.text('testPattern') }}</span>\n <div\n class=\"deb-pattern-status\"\n [class.deb-pattern-status--match]=\"regexEvaluation().status === 'match'\"\n [class.deb-pattern-status--no-match]=\"regexEvaluation().status === 'no-match'\"\n [class.deb-pattern-status--invalid]=\"regexEvaluation().status === 'invalid'\"\n [class.deb-pattern-status--idle]=\"regexEvaluation().status === 'idle'\"\n [class.deb-pattern-status--empty]=\"regexEvaluation().status === 'empty'\"\n data-testid=\"regex-test-status\"\n >\n @switch (regexEvaluation().status) {\n @case ('match') {\n <mat-icon>check_circle</mat-icon> {{ ui.text('patternMatch') }}\n }\n @case ('no-match') {\n <mat-icon>cancel</mat-icon> {{ ui.text('patternNoMatch') }}\n }\n @case ('invalid') {\n <mat-icon>error</mat-icon> {{ ui.text('patternInvalid') }}\n }\n @case ('idle') {\n <mat-icon>edit_note</mat-icon> {{ ui.text('testPatternPlaceholder') }}\n }\n @case ('empty') {\n <mat-icon>info</mat-icon> {{ ui.text('patternEmptyPrompt') }}\n }\n }\n </div>\n </div>\n\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <input\n matInput\n data-testid=\"regex-test-input\"\n [placeholder]=\"ui.text('testPatternPlaceholder')\"\n [ngModel]=\"testSample()\"\n (ngModelChange)=\"testSample.set($event)\"\n />\n </mat-form-field>\n </div>\n }\n </div>\n </details>\n }\n }\n\n <!-- Options (dropdown / radio / multiSelect) -->\n @if (meta()?.hasOptions) {\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionOptions') }}\n @if ((f.options ?? []).length; as count) {\n <span class=\"deb-inspector__count\" data-testid=\"options-count\">{{ count }}</span>\n }\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n <span class=\"deb-section-title\">{{ ui.text('dataSource') }}</span>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('optionsComeFrom') }}</mat-label>\n <mat-select\n data-testid=\"data-source\"\n [ngModel]=\"store.fieldDataSource(f)\"\n (ngModelChange)=\"store.setFieldDataSource(store.keyOf(f), $event)\"\n >\n <mat-option value=\"none\">{{ ui.text('optionsSourceNone') }}</mat-option>\n <mat-option value=\"manual\">{{ ui.text('optionsSourceInline') }}</mat-option>\n <mat-option value=\"lookup\">{{ ui.text('optionsSourceList') }}</mat-option>\n </mat-select>\n </mat-form-field>\n\n <!-- Named lookup list -->\n @if (store.fieldDataSource(f) === 'lookup') {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('listName') }}</mat-label>\n <input\n matInput\n data-testid=\"list-name\"\n [ngModel]=\"f.listName ?? ''\"\n (ngModelChange)=\"store.setListName(store.keyOf(f), $event)\"\n />\n </mat-form-field>\n <p class=\"deb-hint\">\n {{ ui.text('listNameHint') }}\n </p>\n }\n\n <!-- Inline options -->\n @if (store.fieldDataSource(f) !== 'lookup') {\n <div class=\"deb-row deb-row--split\">\n <span class=\"deb-section-title\">{{ ui.text('options') }}</span>\n <span class=\"deb-row__actions\">\n @if (store.hasUnkeyedOptions()) {\n <button\n mat-stroked-button\n type=\"button\"\n data-testid=\"assign-option-keys\"\n (click)=\"store.assignOptionKeys()\"\n [matTooltip]=\"ui.text('optionKeyHint')\"\n >\n <mat-icon>key</mat-icon> {{ ui.text('assignOptionKeys') }}\n </button>\n }\n <button\n mat-stroked-button\n type=\"button\"\n data-testid=\"add-option\"\n (click)=\"store.addOption(store.keyOf(f))\"\n >\n <mat-icon>add</mat-icon> {{ ui.text('option') }}\n </button>\n </span>\n </div>\n @for (opt of f.options ?? []; track $index) {\n <div class=\"deb-option-row\" data-testid=\"option-row\">\n <!-- One input: the displayed text is the stored value. -->\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('optionInLanguage', { language: lang() }) }}</mat-label>\n <input\n matInput\n [attr.data-testid]=\"'option-' + $index\"\n [ngModel]=\"optionLabel(opt)\"\n (ngModelChange)=\"store.setOptionLabel(store.keyOf(f), $index, lang(), $event)\"\n />\n </mat-form-field>\n <!--\n Not a control. A key is the option's identity and every record already\n holding it matches on it, so a text box here — even a read-only one —\n would be a data migration disguised as a field. It is shown because an\n author needs to be able to read it, and for no other reason.\n -->\n @if (store.optionKey(opt); as key) {\n <code\n class=\"deb-option-key\"\n [attr.data-testid]=\"'option-key-' + $index\"\n [attr.aria-label]=\"ui.text('optionKey')\"\n [matTooltip]=\"ui.text('optionKeyHint')\"\n >{{ key }}</code\n >\n }\n <button\n mat-icon-button\n type=\"button\"\n color=\"warn\"\n (click)=\"store.removeOption(store.keyOf(f), $index)\"\n [matTooltip]=\"ui.text('removeOption')\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n }\n @if (!(f.options ?? []).length) {\n <p class=\"deb-hint\">{{ ui.text('noOptionsYet') }}</p>\n }\n }\n </div>\n </details>\n }\n\n <!-- Flags -->\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionDisplay') }}\n @if (displayFlagCount(f); as count) {\n <span class=\"deb-inspector__count\" data-testid=\"display-count\">{{ count }}</span>\n }\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n <div class=\"deb-toggles\" role=\"group\" [attr.aria-label]=\"ui.text('display')\">\n <mat-slide-toggle\n color=\"primary\"\n [ngModel]=\"f.visibility ?? true\"\n (ngModelChange)=\"store.updateField(store.keyOf(f), { visibility: $event })\"\n >{{ ui.text('visible') }}</mat-slide-toggle\n >\n <mat-slide-toggle\n color=\"primary\"\n [ngModel]=\"f.table?.visible ?? false\"\n (ngModelChange)=\"store.updateField(store.keyOf(f), { table: { visible: $event } })\"\n >{{ ui.text('tableColumn') }}</mat-slide-toggle\n >\n <mat-slide-toggle\n color=\"primary\"\n [ngModel]=\"f.readonly ?? false\"\n (ngModelChange)=\"store.updateField(store.keyOf(f), { readonly: $event })\"\n >{{ ui.text('readOnly') }}</mat-slide-toggle\n >\n <mat-slide-toggle\n color=\"primary\"\n [ngModel]=\"f.disabled ?? false\"\n (ngModelChange)=\"store.updateField(store.keyOf(f), { disabled: $event })\"\n >{{ ui.text('disabled') }}</mat-slide-toggle\n >\n <mat-slide-toggle\n color=\"primary\"\n [ngModel]=\"f.maskData ?? false\"\n (ngModelChange)=\"store.updateField(store.keyOf(f), { maskData: $event })\"\n >{{ ui.text('maskData') }}</mat-slide-toggle\n >\n <mat-slide-toggle\n color=\"primary\"\n data-testid=\"toggle-critical\"\n [ngModel]=\"f.criticalField ?? false\"\n (ngModelChange)=\"store.updateField(store.keyOf(f), { criticalField: $event })\"\n [matTooltip]=\"ui.text('criticalFieldTooltip')\"\n >{{ ui.text('criticalField') }}</mat-slide-toggle\n >\n <mat-slide-toggle\n color=\"primary\"\n [ngModel]=\"f.showOnMinimize ?? false\"\n (ngModelChange)=\"store.updateField(store.keyOf(f), { showOnMinimize: $event })\"\n [matTooltip]=\"ui.text('showInSummaryTooltip')\"\n >{{ ui.text('showInSummary') }}</mat-slide-toggle\n >\n </div>\n </div>\n </details>\n\n <!-- Conditional visibility (static showWhen) -->\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionVisibility') }}\n @if (showWhenEntries(f).length; as count) {\n <span class=\"deb-inspector__count\" data-testid=\"visibility-count\">{{ count }}</span>\n }\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n <div class=\"deb-row deb-row--split\">\n <span class=\"deb-section-title\">{{ ui.text('showWhen') }}</span>\n <button mat-stroked-button type=\"button\" data-testid=\"add-show-when\" (click)=\"addShowWhen(f)\">\n <mat-icon>add</mat-icon> {{ ui.text('condition') }}\n </button>\n </div>\n @for (entry of showWhenEntries(f); track entry.key) {\n <div class=\"deb-option-row\" data-testid=\"option-row\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('watchedField') }}</mat-label>\n <mat-select\n data-testid=\"show-when-field\"\n [ngModel]=\"entry.key\"\n (ngModelChange)=\"renameShowWhen(f, entry.key, $event)\"\n >\n @for (option of optionsWith(entry.key); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }} <span class=\"deb-path-hint\">{{ option.path }}</span>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('equals') }}</mat-label>\n <input matInput [ngModel]=\"entry.display\" (ngModelChange)=\"setShowWhenValue(f, entry.key, $event)\" />\n </mat-form-field>\n <button\n mat-icon-button\n type=\"button\"\n color=\"warn\"\n [matTooltip]=\"ui.text('removeCondition')\"\n (click)=\"removeShowWhen(f, entry.key)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n }\n @if (!showWhenEntries(f).length) {\n <p class=\"deb-hint\">{{ ui.text('alwaysVisibleHint') }}</p>\n }\n </div>\n </details>\n\n <!-- Entity reference, cascade, autoPatch, and patchOnTrue -->\n @if (meta()?.isEntityRef || f.type === 'boolean' || f.type === 'checkbox') {\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionAutomation') }}\n @if ((f.patchOnTrue ?? []).length; as count) {\n <span class=\"deb-inspector__count\" data-testid=\"automation-count\">{{ count }}</span>\n }\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n @if (meta()?.isEntityRef) {\n <ngx-entity-reference-config />\n }\n\n <!-- patchOnTrue (boolean/checkbox only) -->\n @if (f.type === 'boolean' || f.type === 'checkbox') {\n <div class=\"deb-row deb-row--split\">\n <span class=\"deb-section-title\">{{ ui.text('copyOnTrue') }}</span>\n <button\n mat-stroked-button\n type=\"button\"\n data-testid=\"add-patch-on-true\"\n (click)=\"store.addPatchOnTrueMapping(store.keyOf(f))\"\n >\n <mat-icon>add</mat-icon> {{ ui.text('mapping') }}\n </button>\n </div>\n @for (mapping of f.patchOnTrue ?? []; track $index) {\n <div class=\"deb-option-row\" data-testid=\"option-row\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('fromField') }}</mat-label>\n <mat-select\n data-testid=\"patch-on-true-from\"\n [ngModel]=\"mapping.from\"\n (ngModelChange)=\"store.updatePatchOnTrueMapping(store.keyOf(f), $index, { from: $event })\"\n >\n @for (option of optionsWith(mapping.from); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }} <span class=\"deb-path-hint\">{{ option.path }}</span>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <mat-label>{{ ui.text('toField') }}</mat-label>\n <mat-select\n data-testid=\"patch-on-true-to\"\n [ngModel]=\"mapping.to\"\n (ngModelChange)=\"store.updatePatchOnTrueMapping(store.keyOf(f), $index, { to: $event })\"\n >\n @for (option of optionsWith(mapping.to); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }} <span class=\"deb-path-hint\">{{ option.path }}</span>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <button\n mat-icon-button\n type=\"button\"\n color=\"warn\"\n [matTooltip]=\"ui.text('removeMapping')\"\n (click)=\"store.removePatchOnTrueMapping(store.keyOf(f), $index)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n }\n @if (!(f.patchOnTrue ?? []).length) {\n <p class=\"deb-hint\">{{ ui.text('copyOnTrueHint') }}</p>\n }\n }\n </div>\n </details>\n }\n\n <!-- Rules attached to this field -->\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionRules') }}\n @if (store.rulesForSelectedField().length; as count) {\n <span class=\"deb-inspector__count\" data-testid=\"rules-count\">{{ count }}</span>\n }\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n <ngx-field-rules-list />\n </div>\n </details>\n\n <!-- Field Dependencies Visualizer -->\n <details\n class=\"deb-inspector__section\"\n open\n data-testid=\"section-dependencies\"\n >\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionDependencies') }}\n @if (incomingDependencies().length + outgoingDependencies().length; as count) {\n <span class=\"deb-inspector__count\" data-testid=\"dependencies-count\">{{ count }}</span>\n }\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n @if (incomingDependencies().length) {\n <span class=\"deb-section-title\">{{ ui.text('dependsOn') }} ({{ incomingDependencies().length }})</span>\n <div class=\"deb-dep-list\" data-testid=\"incoming-dependencies\">\n @for (dep of incomingDependencies(); track dep.id) {\n <div class=\"deb-dep-row\">\n <div class=\"deb-dep-info\">\n <span class=\"deb-dep-name\">{{ dep.sourceLabel }}</span>\n <span class=\"deb-dep-detail\">{{ dep.description }}</span>\n </div>\n <button\n mat-stroked-button\n type=\"button\"\n [matTooltip]=\"ui.text('jumpToField', { field: dep.sourceLabel })\"\n (click)=\"selectField(dep.sourceKey)\"\n >\n <mat-icon>arrow_back</mat-icon> {{ ui.text('jumpToField', { field: dep.sourceLabel }) }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (outgoingDependencies().length) {\n <span class=\"deb-section-title\">{{ ui.text('affects') }} ({{ outgoingDependencies().length }})</span>\n <div class=\"deb-dep-list\" data-testid=\"outgoing-dependencies\">\n @for (dep of outgoingDependencies(); track dep.id) {\n <div class=\"deb-dep-row\">\n <div class=\"deb-dep-info\">\n <span class=\"deb-dep-name\">{{ dep.targetLabel }}</span>\n <span class=\"deb-dep-detail\">{{ dep.description }}</span>\n </div>\n <button\n mat-stroked-button\n type=\"button\"\n [matTooltip]=\"ui.text('jumpToField', { field: dep.targetLabel })\"\n (click)=\"selectField(dep.targetKey)\"\n >\n <mat-icon>arrow_forward</mat-icon> {{ ui.text('jumpToField', { field: dep.targetLabel }) }}\n </button>\n </div>\n }\n </div>\n }\n\n @if (!incomingDependencies().length && !outgoingDependencies().length) {\n <p class=\"deb-hint\" data-testid=\"no-field-dependencies\">{{ ui.text('noDependencies') }}</p>\n }\n </div>\n </details>\n\n <!-- Cross-entity field reference & drift management -->\n <details class=\"deb-inspector__section\" open>\n <summary class=\"deb-inspector__summary\">\n {{ ui.text('sectionReference') }}\n @if (f.isReferenced) {\n <span class=\"deb-inspector__count\" data-testid=\"reference-count\">{{ f.referencedEntityKey }}</span>\n }\n <mat-icon class=\"deb-inspector__chevron\">expand_more</mat-icon>\n </summary>\n <div class=\"deb-inspector__body\">\n <ngx-referenced-field-config />\n </div>\n </details>\n </div>\n} @else {\n <div class=\"deb-inspector__empty\">\n <mat-icon>touch_app</mat-icon>\n <p>{{ ui.text('inspectorEmpty') }}</p>\n </div>\n}\n","import { ChangeDetectionStrategy, Component, EventEmitter, Output, computed, inject, signal } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport type { RichFieldType } from '@dynamic-entity/core';\nimport { FIELD_TYPE_CATALOG, type FieldTypeMeta } from '../field-catalog';\nimport { BuilderTextService } from '../builder-text';\n\n/**\n * Which drawer of the palette a field type belongs in.\n *\n * Kept here rather than on `FieldTypeMeta` in core: the catalogue is a data model shared with\n * the renderer, and how a picker arranges twenty-two buttons is a decision about this panel.\n * A type absent from the map — a consumer's custom type, or one added to core later — falls\n * into `other`, so the palette degrades to \"listed, just not filed\" rather than dropping it.\n */\nconst PALETTE_GROUPS = ['basic', 'choice', 'datetime', 'rich', 'structure', 'other'] as const;\ntype PaletteGroup = (typeof PALETTE_GROUPS)[number];\n\nconst GROUP_OF: Readonly<Record<string, PaletteGroup>> = {\n text: 'basic',\n textarea: 'basic',\n number: 'basic',\n currency: 'basic',\n email: 'basic',\n password: 'basic',\n url: 'basic',\n phone: 'basic',\n slider: 'basic',\n color: 'basic',\n\n dropdown: 'choice',\n radio: 'choice',\n multiSelect: 'choice',\n checkbox: 'choice',\n boolean: 'choice',\n 'entity-ref': 'choice',\n rating: 'choice',\n tags: 'choice',\n\n date: 'datetime',\n datetime: 'datetime',\n time: 'datetime',\n monthYear: 'datetime',\n\n markdown: 'rich',\n image: 'rich',\n file: 'rich',\n\n group: 'structure',\n array: 'structure',\n};\n\n/** The heading text key for each group, so the labels translate with the rest of the chrome. */\nconst GROUP_TEXT_KEY = {\n basic: 'paletteGroupBasic',\n choice: 'paletteGroupChoice',\n datetime: 'paletteGroupDateTime',\n rich: 'paletteGroupRich',\n structure: 'paletteGroupStructure',\n other: 'paletteGroupOther',\n} as const;\n\ninterface PaletteSection {\n group: PaletteGroup;\n heading: string;\n items: FieldTypeMeta[];\n}\n\n/**\n * FieldPaletteComponent — the list of buildable field types.\n *\n * Grouped and filterable, because a flat list of twenty-two types is not navigable, and\n * tiles wrap their labels so names like \"Entity Reference\" are never clipped.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-field-palette',\n standalone: true,\n imports: [MatButtonModule, MatIconModule, MatTooltipModule],\n template: `\n <div class=\"deb-palette\">\n <div class=\"deb-palette__search\">\n <mat-icon aria-hidden=\"true\">search</mat-icon>\n <input\n type=\"search\"\n data-testid=\"palette-search\"\n [value]=\"query()\"\n (input)=\"query.set($any($event.target).value)\"\n [attr.placeholder]=\"ui.text('paletteSearchPlaceholder')\"\n [attr.aria-label]=\"ui.text('paletteSearchLabel')\"\n />\n @if (query()) {\n <button\n type=\"button\"\n class=\"deb-palette__clear\"\n data-testid=\"palette-search-clear\"\n [attr.aria-label]=\"ui.text('paletteSearchClear')\"\n (click)=\"query.set('')\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n </div>\n\n @for (section of sections(); track section.group) {\n <div class=\"deb-palette__section\">\n <span class=\"deb-section-title\">{{ section.heading }}</span>\n <div class=\"deb-palette__grid\">\n @for (meta of section.items; track meta.type) {\n <button\n mat-stroked-button\n type=\"button\"\n class=\"deb-palette__item\"\n [attr.data-testid]=\"'palette-' + meta.type\"\n [matTooltip]=\"meta.description\"\n (click)=\"pick.emit(meta.type)\"\n >\n <mat-icon>{{ meta.icon }}</mat-icon>\n <span>{{ meta.label }}</span>\n </button>\n }\n </div>\n </div>\n } @empty {\n <p class=\"deb-hint\" data-testid=\"palette-no-match\">{{ ui.text('paletteNoMatch', { query: query() }) }}</p>\n }\n </div>\n `,\n styles: [\n `\n .deb-palette {\n display: flex;\n flex-direction: column;\n gap: 14px;\n }\n\n /*\n * A plain input rather than a mat-form-field: this sits inside a card that is already a\n * stack of outlined Material fields, and giving the filter the same chrome made it read\n * as one more property to fill in rather than a control over the list below it.\n */\n .deb-palette__search {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 0 10px;\n height: 36px;\n border: 1px solid var(--deb-border, #e2e8f0);\n border-radius: 8px;\n background: #f8fafc;\n }\n .deb-palette__search:focus-within {\n border-color: var(--deb-accent, #6366f1);\n background: #ffffff;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.16);\n }\n .deb-palette__search mat-icon {\n font-size: 17px;\n width: 17px;\n height: 17px;\n color: var(--deb-muted, #64748b);\n flex: none;\n }\n .deb-palette__search input {\n flex: 1;\n min-width: 0;\n border: 0;\n outline: 0;\n background: transparent;\n font: inherit;\n font-size: 13px;\n color: inherit;\n }\n /* The platform's own clear affordance, replaced by one that matches the rest. */\n .deb-palette__search input::-webkit-search-cancel-button {\n display: none;\n }\n .deb-palette__clear {\n appearance: none;\n border: 0;\n background: none;\n padding: 0;\n cursor: pointer;\n display: flex;\n color: var(--deb-muted, #64748b);\n }\n .deb-palette__clear:hover {\n color: #0f172a;\n }\n\n .deb-palette__section {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n .deb-palette__grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 6px;\n }\n\n /*\n * An auto height and a wrapping label keep long names readable. Material's\n * button locks a line height and hides the overflow, which is right for a toolbar and\n * wrong for a 140px-wide tile holding \"Entity Reference\".\n */\n .deb-palette__item {\n justify-content: flex-start !important;\n height: auto !important;\n min-height: 38px;\n line-height: 1.25 !important;\n border-radius: 8px !important;\n border: 1px solid var(--deb-border, #e2e8f0) !important;\n padding: 7px 10px !important;\n font-family: var(--font-heading, inherit) !important;\n font-weight: 600 !important;\n font-size: 12.5px !important;\n transition: all 0.18s cubic-bezier(0.16, 1, 0.3, 1) !important;\n background: #ffffff !important;\n text-align: left !important;\n }\n .deb-palette__item:hover {\n border-color: #6366f1 !important;\n background: #f5f3ff !important;\n color: #4f46e5 !important;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.15) !important;\n }\n .deb-palette__item mat-icon {\n color: #4338ca;\n margin-right: 7px;\n font-size: 17px;\n width: 17px;\n height: 17px;\n flex: none;\n }\n .deb-palette__item span {\n white-space: normal;\n overflow-wrap: anywhere;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .deb-palette__item {\n transition: none !important;\n }\n .deb-palette__item:hover {\n transform: none;\n }\n }\n `,\n ],\n})\nexport class FieldPaletteComponent {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n\n readonly catalog: readonly FieldTypeMeta[] = FIELD_TYPE_CATALOG;\n\n /** The filter text. Matched against the label, the type and the description. */\n protected readonly query = signal('');\n\n /**\n * The catalogue, filtered and filed.\n *\n * Matching the description as well as the label is what makes the filter worth having: a\n * person looking for a currency input types \"money\", which appears in no label but is\n * exactly the sort of word a description carries. An empty group is dropped rather than\n * rendered as a heading with nothing under it.\n */\n protected readonly sections = computed<PaletteSection[]>(() => {\n const needle = this.query().trim().toLowerCase();\n const matches = (meta: FieldTypeMeta) =>\n !needle ||\n meta.label.toLowerCase().includes(needle) ||\n meta.type.toLowerCase().includes(needle) ||\n meta.description.toLowerCase().includes(needle);\n\n return PALETTE_GROUPS.map(group => ({\n group,\n heading: this.ui.text(GROUP_TEXT_KEY[group]),\n items: this.catalog.filter(meta => (GROUP_OF[meta.type] ?? 'other') === group && matches(meta)),\n })).filter(section => section.items.length > 0);\n });\n\n @Output() pick = new EventEmitter<RichFieldType>();\n}\n","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatSlideToggleModule } from '@angular/material/slide-toggle';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport type { NestedTabConfig } from '@dynamic-entity/core';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { SYSTEM_DEFAULT_CAN_EDIT } from 'ngx-dynamic-entity';\nimport { BuilderStore } from '../builder-store.service';\nimport { BuilderTextService } from '../builder-text';\n\n/**\n * Re-exported so existing imports from this package keep working.\n *\n * Never declare a second `new InjectionToken('SYSTEM_DEFAULT_CAN_EDIT')` here: token identity\n * is by object reference, so a consumer providing the renderer's would provide a token nothing\n * injects. There is one token, in the lower-level package both depend on.\n */\nexport { SYSTEM_DEFAULT_CAN_EDIT };\n\n/**\n * TabManagerComponent — add / rename / reorder / remove tabs & sub-tabs with systemDefault protection.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-tab-manager',\n standalone: true,\n imports: [\n FormsModule,\n MatButtonModule,\n MatCheckboxModule,\n MatFormFieldModule,\n MatIconModule,\n MatInputModule,\n MatSlideToggleModule,\n MatTooltipModule,\n ],\n template: `\n <div class=\"deb-tabs\">\n <div class=\"deb-tabs__head\">\n <span class=\"deb-section-title\">{{ ui.text('tabsManager') }}</span>\n <button mat-stroked-button type=\"button\" (click)=\"store.addTab()\">\n <mat-icon>add</mat-icon> {{ ui.text('addTab') }}\n </button>\n </div>\n\n @if (store.tabs().length === 0) {\n <p class=\"deb-hint\">{{ ui.text('noTabs') }}</p>\n }\n\n @for (tab of store.tabs(); track tab.id; let i = $index, count = $count) {\n <div class=\"deb-tab-card\" [class.deb-tab-card--system]=\"tab.systemDefault\">\n <div class=\"deb-tabs__row\" [attr.data-testid]=\"'tab-row-' + tab.id\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-grow\">\n <mat-label>{{ tab.id }} {{ tab.systemDefault ? ui.text('systemTag') : '' }}</mat-label>\n <input\n matInput\n [disabled]=\"!canEditTab(tab)\"\n [ngModel]=\"tabLabel(tab)\"\n (ngModelChange)=\"store.setTabLabel(tab.id, lang(), $event)\"\n />\n </mat-form-field>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"i === 0 || !canEditTab(tab)\"\n (click)=\"store.moveTab(tab.id, -1)\"\n [matTooltip]=\"ui.text('moveUp')\"\n [attr.aria-label]=\"ui.text('moveTabUp')\"\n >\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"i === count - 1 || !canEditTab(tab)\"\n (click)=\"store.moveTab(tab.id, 1)\"\n [matTooltip]=\"ui.text('moveDown')\"\n [attr.aria-label]=\"ui.text('moveTabDown')\"\n >\n <mat-icon>arrow_downward</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n color=\"warn\"\n [disabled]=\"!canEditTab(tab)\"\n (click)=\"store.removeTab(tab.id)\"\n [matTooltip]=\"ui.text('removeTab')\"\n [attr.aria-label]=\"ui.text('removeTab')\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n\n <!-- Tab settings row -->\n <div class=\"deb-tab-settings\">\n <mat-checkbox\n color=\"primary\"\n [disabled]=\"!canEditTab(tab)\"\n [ngModel]=\"tab.flatData\"\n (ngModelChange)=\"store.updateTab(tab.id, { flatData: $event })\"\n >\n {{ ui.text('flatData') }}\n </mat-checkbox>\n <mat-checkbox\n color=\"primary\"\n [disabled]=\"!canEditTab(tab)\"\n [ngModel]=\"tab.isPrimaryTab\"\n (ngModelChange)=\"$event ? store.setPrimaryTab(tab.id) : store.updateTab(tab.id, { isPrimaryTab: false })\"\n >\n {{ ui.text('primaryTab') }}\n </mat-checkbox>\n <mat-checkbox\n color=\"primary\"\n [disabled]=\"!canEditTab(tab)\"\n [ngModel]=\"tab.maskData\"\n (ngModelChange)=\"store.updateTab(tab.id, { maskData: $event })\"\n >\n {{ ui.text('maskTabData') }}\n </mat-checkbox>\n <mat-checkbox\n color=\"primary\"\n [disabled]=\"!canEditTab(tab)\"\n [ngModel]=\"tab.systemDefault\"\n (ngModelChange)=\"store.updateTab(tab.id, { systemDefault: $event })\"\n >\n {{ ui.text('systemDefault') }}\n </mat-checkbox>\n <button mat-button type=\"button\" color=\"primary\" [disabled]=\"!canEditTab(tab)\" (click)=\"store.addSubTab(tab.id)\">\n {{ ui.text('addSubTab') }}\n </button>\n </div>\n\n <!-- Module tab configuration -->\n <div class=\"deb-tab-module\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-grow\">\n <mat-label>{{ ui.text('consumerModuleName') }}</mat-label>\n <input\n matInput\n [placeholder]=\"ui.text('consumerModulePlaceholder')\"\n [disabled]=\"!canEditTab(tab)\"\n [ngModel]=\"tab.moduleName\"\n (ngModelChange)=\"store.updateTab(tab.id, { moduleName: $event || undefined })\"\n />\n </mat-form-field>\n </div>\n\n <!-- Sub-tabs recursive render (Level 2) -->\n @if (tab.children && tab.children.length > 0) {\n <div class=\"deb-subtabs\">\n <span class=\"deb-subtabs__title\">{{ ui.text('subTabs') }}</span>\n @for (sub of tab.children; track sub.id) {\n <div class=\"deb-tabs__row deb-subtab-row\" [attr.data-testid]=\"'subtab-row-' + sub.id\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-grow\">\n <mat-label>{{ sub.id }}</mat-label>\n <input\n matInput\n [disabled]=\"!canEditTab(sub)\"\n [ngModel]=\"tabLabel(sub)\"\n (ngModelChange)=\"store.setTabLabel(sub.id, lang(), $event)\"\n />\n </mat-form-field>\n <button\n mat-icon-button\n type=\"button\"\n color=\"warn\"\n [disabled]=\"!canEditTab(sub)\"\n (click)=\"store.removeTab(sub.id)\"\n [matTooltip]=\"ui.text('removeSubTab')\"\n [attr.aria-label]=\"ui.text('removeSubTab')\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n `,\n styles: [\n `\n .deb-tabs__head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n }\n .deb-tab-card {\n border: 1px solid var(--deb-border, #e5e7eb);\n border-radius: 8px;\n padding: 10px;\n margin-bottom: 10px;\n background: var(--deb-bg-surface, #ffffff);\n }\n .deb-tab-card--system {\n border-left: 4px solid var(--deb-accent, #6366f1);\n }\n .deb-tabs__row {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n .deb-tab-settings {\n display: flex;\n flex-wrap: wrap;\n gap: 8px 16px;\n align-items: center;\n margin-top: 8px;\n font-size: 13px;\n }\n .deb-tab-module {\n margin-top: 8px;\n }\n .deb-subtabs {\n margin-top: 8px;\n padding-left: 16px;\n border-left: 2px dashed var(--deb-border, #e5e7eb);\n }\n .deb-subtabs__title {\n font-size: 12px;\n font-weight: 600;\n color: var(--deb-muted, #6b7280);\n }\n .deb-subtab-row {\n margin-top: 6px;\n }\n .deb-grow {\n flex: 1;\n }\n `,\n ],\n})\nexport class TabManagerComponent {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n private readonly canEditSystemDefaultsFn = inject<(roles: string[]) => boolean>(SYSTEM_DEFAULT_CAN_EDIT, {\n optional: true,\n });\n\n protected lang(): string {\n return this.store.activeLanguage();\n }\n\n protected tabLabel(tab: { label?: any }): string {\n return resolveLabel(tab.label, this.lang());\n }\n\n protected canEditTab(tab: NestedTabConfig): boolean {\n if (!tab.systemDefault) return true;\n if (this.canEditSystemDefaultsFn) {\n // The predicate's entire contract is (roles) => boolean. This passed a hardcoded []\n // regardless of who was using the builder, so any predicate that actually inspected\n // roles answered false for everyone and locked every system-default tab.\n return this.canEditSystemDefaultsFn(this.store.userRoles());\n }\n return true;\n }\n}\n","import { ChangeDetectionStrategy, Component, Input, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { DragDropModule } from '@angular/cdk/drag-drop';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { resolveLabel, type NestedFieldConfig } from '@dynamic-entity/core';\nimport { BuilderStore } from '../builder-store.service';\nimport { getFieldTypeMeta } from '../field-catalog';\nimport { BuilderTextService } from '../builder-text';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-entity-builder-tree-node',\n standalone: true,\n imports: [CommonModule, DragDropModule, MatButtonModule, MatIconModule, MatTooltipModule],\n template: `\n <div\n cdkDrag\n class=\"deb-field-row\"\n data-testid=\"builder-field-row\"\n [class.deb-field-row--active]=\"store.isSelected(field)\"\n (click)=\"store.selectField(store.keyOf(field))\"\n (keydown.enter)=\"store.selectField(store.keyOf(field))\"\n (keydown.space)=\"store.selectField(store.keyOf(field)); $event.preventDefault()\"\n role=\"button\"\n tabindex=\"0\"\n [attr.aria-pressed]=\"store.isSelected(field)\"\n [attr.aria-label]=\"ui.text('selectField', { field: fieldLabel(field) })\"\n >\n <mat-icon class=\"deb-drag-handle\" cdkDragHandle aria-hidden=\"true\" [title]=\"ui.text('dragToReorder')\"\n >drag_indicator</mat-icon\n >\n <mat-icon class=\"deb-field-type\" [matTooltip]=\"fieldTypeLabel(field.type)\">{{ fieldTypeIcon(field.type) }}</mat-icon>\n <div class=\"deb-field-meta\">\n <div class=\"deb-row\" style=\"gap:6px\">\n <span class=\"deb-field-label\" [attr.data-testid]=\"'row-label-' + field.id\">{{ fieldLabel(field) }}</span>\n <span class=\"deb-type-badge\">{{ field.type }}</span>\n @if (field.isReferenced) {\n <mat-icon\n style=\"font-size: 16px; width: 16px; height: 16px; color: #1976d2;\"\n [matTooltip]=\"ui.text('referencedFieldTooltip', { entity: field.referencedEntityKey ?? '' })\"\n >link</mat-icon\n >\n }\n @if (field.hasDrift) {\n <mat-icon\n style=\"font-size: 16px; width: 16px; height: 16px; color: #d32f2f;\"\n data-testid=\"drift-warning-icon\"\n [matTooltip]=\"ui.text('driftDetected')\"\n >sync_problem</mat-icon\n >\n }\n </div>\n <span class=\"deb-field-id\" [attr.data-testid]=\"'row-id-' + field.id\">{{ field.id }}</span>\n </div>\n @if (field.validators?.required) {\n <span class=\"deb-req\" [title]=\"ui.text('required')\">*</span>\n }\n <!--\n The grid width this field was given, when it is not the default.\n Layout is now authored in the inspector, and a list that does not show it makes the\n author open every field in turn to find the one that is half a row wide.\n -->\n @if (field.colSpan && field.colSpan !== 12) {\n <span class=\"deb-span-badge\" [attr.data-testid]=\"'row-span-' + field.id\" [title]=\"ui.text('width')\"\n >{{ field.colSpan }}/12</span\n >\n }\n\n <!--\n Grouped so the row can reveal them together on hover, focus and selection. Four icon\n buttons on every row put more ink into the controls than into the field names.\n -->\n <div class=\"deb-field-row__actions\">\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"index === 0\"\n [attr.data-testid]=\"'row-up-' + field.id\"\n [attr.aria-label]=\"ui.text('moveFieldUp', { field: fieldLabel(field) })\"\n (click)=\"store.moveField(store.keyOf(field), -1); $event.stopPropagation()\"\n [matTooltip]=\"ui.text('moveUp')\"\n >\n <mat-icon>arrow_upward</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n [disabled]=\"index === totalCount - 1\"\n [attr.data-testid]=\"'row-down-' + field.id\"\n [attr.aria-label]=\"ui.text('moveFieldDown', { field: fieldLabel(field) })\"\n (click)=\"store.moveField(store.keyOf(field), 1); $event.stopPropagation()\"\n [matTooltip]=\"ui.text('moveDown')\"\n >\n <mat-icon>arrow_downward</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n [attr.data-testid]=\"'row-duplicate-' + field.id\"\n [attr.aria-label]=\"ui.text('duplicateField', { field: fieldLabel(field) })\"\n (click)=\"store.duplicateField(store.keyOf(field)); $event.stopPropagation()\"\n [matTooltip]=\"ui.text('duplicate')\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n color=\"warn\"\n [attr.data-testid]=\"'row-delete-' + field.id\"\n (click)=\"store.removeField(store.keyOf(field)); $event.stopPropagation()\"\n [matTooltip]=\"ui.text('delete')\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n </div>\n\n @if (field.children && field.children.length > 0) {\n <div\n class=\"deb-tree-children\"\n style=\"padding-left: 20px; border-left: 2px solid rgba(0,0,0,0.08); margin-left: 12px; margin-top: 4px;\"\n >\n @for (child of field.children; track child.id; let ci = $index, cCount = $count) {\n <ngx-entity-builder-tree-node [field]=\"child\" [index]=\"ci\" [totalCount]=\"cCount\" />\n }\n </div>\n }\n `,\n})\nexport class EntityBuilderTreeNodeComponent {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n\n @Input({ required: true }) field!: NestedFieldConfig;\n @Input({ required: true }) index!: number;\n @Input({ required: true }) totalCount!: number;\n\n protected fieldTypeLabel(type: string): string {\n return getFieldTypeMeta(type)?.label ?? type;\n }\n\n protected fieldTypeIcon(type: string): string {\n return getFieldTypeMeta(type)?.icon ?? 'help_outline';\n }\n\n protected fieldLabel(field: { id: string; label?: any }): string {\n const lang = this.store.activeLanguage();\n return resolveLabel(field.label, lang) || field.id;\n }\n}\n","import { ChangeDetectionStrategy, Component, EventEmitter, Output, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { CdkDragDrop, DragDropModule } from '@angular/cdk/drag-drop';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatCardModule } from '@angular/material/card';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { resolveLabel } from '@dynamic-entity/core';\nimport { BuilderStore, type BuilderFieldGroup } from '../builder-store.service';\nimport { EntityBuilderTreeNodeComponent } from './entity-builder-tree-node.component';\nimport { BuilderTextService } from '../builder-text';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-entity-builder-canvas',\n standalone: true,\n imports: [\n CommonModule,\n DragDropModule,\n MatButtonModule,\n MatCardModule,\n MatIconModule,\n MatTooltipModule,\n EntityBuilderTreeNodeComponent,\n ],\n template: `\n <mat-card class=\"deb-card deb-card--canvas\">\n <mat-card-header>\n <mat-card-title class=\"deb-card__title\">\n <mat-icon class=\"deb-card__icon\">format_list_bulleted</mat-icon>\n {{ ui.text('fieldsHeading', { count: store.fields().length }) }}\n </mat-card-title>\n <button\n mat-icon-button\n type=\"button\"\n class=\"deb-card__collapse-btn\"\n data-testid=\"collapse-fields\"\n aria-expanded=\"true\"\n aria-controls=\"deb-fields-section\"\n (click)=\"collapse.emit()\"\n [matTooltip]=\"ui.text('collapseFields')\"\n [attr.aria-label]=\"ui.text('collapseFields')\"\n >\n <mat-icon>keyboard_arrow_up</mat-icon>\n </button>\n </mat-card-header>\n <mat-card-content>\n @if (store.fields().length === 0) {\n <div class=\"deb-empty\">\n <!--\n Decoration, and marked as such: the sentence below says everything this glyph\n says, so it is hidden from the accessibility tree. axe still measures its\n contrast, so its colour passes AA like any other text.\n -->\n <mat-icon aria-hidden=\"true\">widgets</mat-icon>\n <p>{{ ui.text('canvasEmpty') }}</p>\n </div>\n }\n\n @for (group of store.fieldGroups(); track group.tabId) {\n <!--\n One drop list per tab. A single list spanning every tab would hand reorderField\n an index into the combined view, which is not the index of anything in the tab\n that actually owns the field.\n -->\n @if (showTabHeadings()) {\n <h4 class=\"deb-canvas__group\" [attr.data-testid]=\"'builder-group-' + group.tabId\">\n {{ groupLabel(group) }}\n </h4>\n }\n <div\n cdkDropList\n class=\"deb-field-list\"\n [attr.data-testid]=\"'builder-field-list-' + group.tabId\"\n (cdkDropListDropped)=\"onDrop(group.tabId, $event)\"\n >\n @for (f of group.fields; track f.id; let i = $index, count = $count) {\n <ngx-entity-builder-tree-node [field]=\"f\" [index]=\"i\" [totalCount]=\"count\" />\n }\n </div>\n }\n </mat-card-content>\n </mat-card>\n `,\n})\nexport class EntityBuilderCanvasComponent {\n @Output() collapse = new EventEmitter<void>();\n\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n\n /**\n * Headings only earn their space once the fields are actually split across tabs. A\n * single-tab config — the common case, and every existing spec — renders exactly as before.\n */\n protected showTabHeadings(): boolean {\n return this.store.fieldGroups().length > 1;\n }\n\n protected groupLabel(group: BuilderFieldGroup): string {\n return resolveLabel(group.label, this.store.activeLanguage()) || group.tabId;\n }\n\n protected onDrop(tabId: string, event: CdkDragDrop<unknown>): void {\n this.store.reorderField(event.previousIndex, event.currentIndex, tabId);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n EventEmitter,\n Output,\n computed,\n inject,\n signal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatChipsModule } from '@angular/material/chips';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { BuilderStore } from '../builder-store.service';\nimport { BuilderTextService } from '../builder-text';\nimport { computeRuleDependencies, type DependencyType, type RuleDependencyEdge } from '../rule-dependencies';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-rule-dependency-graph',\n standalone: true,\n imports: [\n FormsModule,\n MatButtonModule,\n MatChipsModule,\n MatFormFieldModule,\n MatIconModule,\n MatInputModule,\n MatTooltipModule,\n ],\n template: `\n <div class=\"deb-graph-backdrop\" (click)=\"onBackdropClick($event)\">\n <div class=\"deb-graph-dialog\" role=\"dialog\" aria-modal=\"true\" data-testid=\"rule-graph-dialog\">\n <div class=\"deb-graph-header\">\n <div class=\"deb-graph-header__titles\">\n <div class=\"deb-graph-header__title-row\">\n <mat-icon class=\"deb-graph-icon\">hub</mat-icon>\n <h2 class=\"deb-graph-title\">{{ ui.text('ruleGraphTitle') }}</h2>\n </div>\n <p class=\"deb-graph-subtitle\">{{ ui.text('ruleGraphSubtitle') }}</p>\n </div>\n <button\n mat-icon-button\n type=\"button\"\n data-testid=\"close-rule-graph\"\n [matTooltip]=\"ui.text('closeDialog')\"\n (click)=\"dismiss.emit()\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </div>\n\n <div class=\"deb-graph-metrics\">\n <span class=\"deb-metric-pill deb-metric-pill--rule\">\n <mat-icon>rule</mat-icon>\n {{ graphData().totalRules }} {{ ui.text('dependencyTypeRule') }}\n </span>\n <span class=\"deb-metric-pill deb-metric-pill--show-when\">\n <mat-icon>visibility</mat-icon>\n {{ graphData().totalShowWhen }} {{ ui.text('dependencyTypeShowWhen') }}\n </span>\n <span class=\"deb-metric-pill deb-metric-pill--cascade\">\n <mat-icon>account_tree</mat-icon>\n {{ graphData().totalCascades }} {{ ui.text('dependencyTypeCascade') }}\n </span>\n <span class=\"deb-metric-pill deb-metric-pill--patch\">\n <mat-icon>content_copy</mat-icon>\n {{ graphData().totalPatches }} {{ ui.text('dependencyTypePatch') }}\n </span>\n </div>\n\n <div class=\"deb-graph-controls\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-graph-search\">\n <mat-icon matPrefix>search</mat-icon>\n <input\n matInput\n data-testid=\"filter-dependencies-input\"\n [placeholder]=\"ui.text('filterDependencies')\"\n [ngModel]=\"filterQuery()\"\n (ngModelChange)=\"filterQuery.set($event)\"\n />\n @if (filterQuery()) {\n <button mat-icon-button matSuffix type=\"button\" (click)=\"filterQuery.set('')\">\n <mat-icon>clear</mat-icon>\n </button>\n }\n </mat-form-field>\n\n <div class=\"deb-graph-filter-types\">\n <button\n type=\"button\"\n class=\"deb-filter-btn\"\n [class.deb-filter-btn--active]=\"selectedType() === 'all'\"\n (click)=\"selectedType.set('all')\"\n >\n All ({{ graphData().edges.length }})\n </button>\n <button\n type=\"button\"\n class=\"deb-filter-btn\"\n [class.deb-filter-btn--active]=\"selectedType() === 'rule'\"\n (click)=\"selectedType.set('rule')\"\n >\n {{ ui.text('dependencyTypeRule') }}\n </button>\n <button\n type=\"button\"\n class=\"deb-filter-btn\"\n [class.deb-filter-btn--active]=\"selectedType() === 'showWhen'\"\n (click)=\"selectedType.set('showWhen')\"\n >\n {{ ui.text('dependencyTypeShowWhen') }}\n </button>\n <button\n type=\"button\"\n class=\"deb-filter-btn\"\n [class.deb-filter-btn--active]=\"selectedType() === 'cascade'\"\n (click)=\"selectedType.set('cascade')\"\n >\n {{ ui.text('dependencyTypeCascade') }}\n </button>\n <button\n type=\"button\"\n class=\"deb-filter-btn\"\n [class.deb-filter-btn--active]=\"selectedType() === 'patchOnTrue'\"\n (click)=\"selectedType.set('patchOnTrue')\"\n >\n {{ ui.text('dependencyTypePatch') }}\n </button>\n </div>\n </div>\n\n <div class=\"deb-graph-body\" data-testid=\"rule-graph-edges\">\n @if (filteredEdges().length === 0) {\n <div class=\"deb-graph-empty\" data-testid=\"no-dependencies-found\">\n <mat-icon>search_off</mat-icon>\n <p>{{ ui.text('noDependenciesFound') }}</p>\n </div>\n }\n\n @for (edge of filteredEdges(); track edge.id) {\n <div class=\"deb-edge-card\" [attr.data-testid]=\"'edge-card-' + edge.id\">\n <!-- Source -->\n <button\n type=\"button\"\n class=\"deb-node-chip deb-node-chip--source\"\n [matTooltip]=\"ui.text('jumpToField', { field: edge.sourceLabel })\"\n (click)=\"onNodeClick(edge.sourceKey)\"\n >\n <mat-icon class=\"deb-node-chip__icon\">tune</mat-icon>\n <span class=\"deb-node-chip__label\">{{ edge.sourceLabel }}</span>\n <span class=\"deb-node-chip__key\">{{ edge.sourceKey }}</span>\n </button>\n\n <!-- Connection details -->\n <div class=\"deb-edge-flow\">\n <span\n class=\"deb-edge-badge\"\n [class.deb-edge-badge--rule]=\"edge.type === 'rule'\"\n [class.deb-edge-badge--show-when]=\"edge.type === 'showWhen'\"\n [class.deb-edge-badge--cascade]=\"edge.type === 'cascade'\"\n [class.deb-edge-badge--patch]=\"edge.type === 'patchOnTrue' || edge.type === 'autoPatch'\"\n >\n {{ typeName(edge.type) }}\n </span>\n <span class=\"deb-edge-arrow\">\n <span class=\"deb-edge-summary\">{{ edge.actionSummary }}</span>\n <mat-icon class=\"deb-edge-arrow-icon\">arrow_forward</mat-icon>\n </span>\n <span class=\"deb-edge-desc\">{{ edge.description }}</span>\n </div>\n\n <!-- Target -->\n <button\n type=\"button\"\n class=\"deb-node-chip deb-node-chip--target\"\n [matTooltip]=\"ui.text('jumpToField', { field: edge.targetLabel })\"\n (click)=\"onNodeClick(edge.targetKey)\"\n >\n <mat-icon class=\"deb-node-chip__icon\">output</mat-icon>\n <span class=\"deb-node-chip__label\">{{ edge.targetLabel }}</span>\n <span class=\"deb-node-chip__key\">{{ edge.targetKey }}</span>\n </button>\n </div>\n }\n </div>\n\n <div class=\"deb-graph-footer\">\n <span class=\"deb-graph-count\">\n {{ ui.text('totalDependencies', { count: filteredEdges().length }) }}\n </span>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"dismiss.emit()\">\n {{ ui.text('closeDialog') }}\n </button>\n </div>\n </div>\n </div>\n `,\n styles: [\n `\n .deb-graph-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(15, 23, 42, 0.6);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 24px;\n animation: debFadeIn 0.15s ease-out;\n }\n @keyframes debFadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n .deb-graph-dialog {\n background: var(--deb-surface, #ffffff);\n border: 1px solid var(--deb-border, #e2e8f0);\n border-radius: 14px;\n width: 100%;\n max-width: 960px;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);\n overflow: hidden;\n }\n .deb-graph-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 20px 24px 16px;\n border-bottom: 1px solid var(--deb-border, #e2e8f0);\n }\n .deb-graph-header__title-row {\n display: flex;\n align-items: center;\n gap: 10px;\n }\n .deb-graph-icon {\n color: var(--deb-accent, #6366f1);\n font-size: 26px;\n width: 26px;\n height: 26px;\n }\n .deb-graph-title {\n font-size: 18px;\n font-weight: 700;\n color: #0f172a;\n margin: 0;\n }\n .deb-graph-subtitle {\n font-size: 13px;\n color: var(--deb-muted, #64748b);\n margin: 4px 0 0;\n }\n .deb-graph-metrics {\n display: flex;\n gap: 12px;\n padding: 12px 24px;\n background: #f8fafc;\n border-bottom: 1px solid var(--deb-border, #e2e8f0);\n flex-wrap: wrap;\n }\n .deb-metric-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n border-radius: 9999px;\n font-size: 12px;\n font-weight: 600;\n border: 1px solid transparent;\n }\n .deb-metric-pill mat-icon {\n font-size: 16px;\n width: 16px;\n height: 16px;\n }\n .deb-metric-pill--rule {\n background: #eef2ff;\n color: #4f46e5;\n border-color: #c7d2fe;\n }\n .deb-metric-pill--show-when {\n background: #f0fdf4;\n color: #16a34a;\n border-color: #bbf7d0;\n }\n .deb-metric-pill--cascade {\n background: #fefce8;\n color: #ca8a04;\n border-color: #fef08a;\n }\n .deb-metric-pill--patch {\n background: #fdf2f8;\n color: #db2777;\n border-color: #fbcfe8;\n }\n .deb-graph-controls {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 14px 24px;\n border-bottom: 1px solid var(--deb-border, #e2e8f0);\n flex-wrap: wrap;\n }\n .deb-graph-search {\n flex: 1;\n min-width: 240px;\n }\n .deb-graph-filter-types {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n }\n .deb-filter-btn {\n padding: 5px 12px;\n border-radius: 6px;\n border: 1px solid var(--deb-border, #e2e8f0);\n background: #ffffff;\n font-size: 12px;\n font-weight: 500;\n color: #475569;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n .deb-filter-btn:hover {\n background: #f1f5f9;\n color: #0f172a;\n }\n .deb-filter-btn--active {\n background: var(--deb-accent, #6366f1);\n color: #ffffff;\n border-color: var(--deb-accent, #6366f1);\n }\n .deb-filter-btn--active:hover {\n background: var(--deb-accent-hover, #4f46e5);\n }\n .deb-graph-body {\n flex: 1;\n overflow-y: auto;\n padding: 20px 24px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n .deb-graph-empty {\n text-align: center;\n padding: 48px 16px;\n color: var(--deb-muted, #64748b);\n }\n .deb-graph-empty mat-icon {\n font-size: 40px;\n width: 40px;\n height: 40px;\n margin-bottom: 8px;\n opacity: 0.5;\n }\n .deb-edge-card {\n display: grid;\n grid-template-columns: 220px 1fr 220px;\n align-items: center;\n gap: 16px;\n padding: 12px 16px;\n background: #ffffff;\n border: 1px solid var(--deb-border, #e2e8f0);\n border-radius: 10px;\n transition: box-shadow 0.15s ease, border-color 0.15s ease;\n }\n .deb-edge-card:hover {\n border-color: #cbd5e1;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);\n }\n .deb-node-chip {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n padding: 8px 12px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n cursor: pointer;\n text-align: left;\n width: 100%;\n transition: background 0.15s ease, border-color 0.15s ease;\n }\n .deb-node-chip:hover {\n background: #f1f5f9;\n border-color: var(--deb-accent, #6366f1);\n }\n .deb-node-chip__icon {\n font-size: 16px;\n width: 16px;\n height: 16px;\n color: var(--deb-accent, #6366f1);\n margin-bottom: 2px;\n }\n .deb-node-chip__label {\n font-size: 13px;\n font-weight: 600;\n color: #0f172a;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 190px;\n }\n .deb-node-chip__key {\n font-family: ui-monospace, SFMono-Regular, monospace;\n font-size: 11px;\n color: var(--deb-muted, #64748b);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 190px;\n }\n .deb-edge-flow {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 4px;\n text-align: center;\n }\n .deb-edge-badge {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n padding: 2px 8px;\n border-radius: 4px;\n }\n .deb-edge-badge--rule {\n background: #eef2ff;\n color: #4f46e5;\n }\n .deb-edge-badge--show-when {\n background: #f0fdf4;\n color: #16a34a;\n }\n .deb-edge-badge--cascade {\n background: #fefce8;\n color: #a16207;\n }\n .deb-edge-badge--patch {\n background: #fdf2f8;\n color: #be185d;\n }\n .deb-edge-arrow {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n color: #475569;\n }\n .deb-edge-summary {\n font-family: ui-monospace, SFMono-Regular, monospace;\n font-size: 12px;\n font-weight: 600;\n background: #f1f5f9;\n padding: 2px 8px;\n border-radius: 4px;\n }\n .deb-edge-arrow-icon {\n font-size: 16px;\n width: 16px;\n height: 16px;\n color: var(--deb-muted, #64748b);\n }\n .deb-edge-desc {\n font-size: 11px;\n color: var(--deb-muted, #64748b);\n }\n .deb-graph-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n border-top: 1px solid var(--deb-border, #e2e8f0);\n background: #f8fafc;\n }\n .deb-graph-count {\n font-size: 13px;\n color: var(--deb-muted, #64748b);\n }\n @media (max-width: 768px) {\n .deb-edge-card {\n grid-template-columns: 1fr;\n gap: 8px;\n }\n }\n `,\n ],\n})\nexport class RuleDependencyGraphComponent {\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n\n @Output() readonly dismiss = new EventEmitter<void>();\n @Output() readonly selectField = new EventEmitter<string>();\n\n protected readonly filterQuery = signal('');\n protected readonly selectedType = signal<DependencyType | 'all'>('all');\n\n protected readonly graphData = computed(() =>\n computeRuleDependencies(this.store.config(), this.store.rules(), this.ui.language()),\n );\n\n protected readonly filteredEdges = computed<RuleDependencyEdge[]>(() => {\n const q = this.filterQuery().trim().toLowerCase();\n const type = this.selectedType();\n return this.graphData().edges.filter(edge => {\n if (type !== 'all' && edge.type !== type) return false;\n if (!q) return true;\n return (\n edge.sourceLabel.toLowerCase().includes(q) ||\n edge.sourceKey.toLowerCase().includes(q) ||\n edge.targetLabel.toLowerCase().includes(q) ||\n edge.targetKey.toLowerCase().includes(q) ||\n edge.actionSummary.toLowerCase().includes(q) ||\n edge.description.toLowerCase().includes(q)\n );\n });\n });\n\n protected typeName(type: DependencyType): string {\n switch (type) {\n case 'rule':\n return this.ui.text('dependencyTypeRule');\n case 'showWhen':\n return this.ui.text('dependencyTypeShowWhen');\n case 'cascade':\n return this.ui.text('dependencyTypeCascade');\n case 'patchOnTrue':\n case 'autoPatch':\n return this.ui.text('dependencyTypePatch');\n }\n }\n\n protected onNodeClick(key: string): void {\n if (!key) return;\n this.selectField.emit(key);\n this.dismiss.emit();\n }\n\n protected onBackdropClick(event: MouseEvent): void {\n if ((event.target as HTMLElement).classList.contains('deb-graph-backdrop')) {\n this.dismiss.emit();\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n EventEmitter,\n HostListener,\n Input,\n OnChanges,\n Output,\n SimpleChanges,\n ViewEncapsulation,\n effect,\n inject,\n model,\n signal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatCardModule } from '@angular/material/card';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatExpansionModule } from '@angular/material/expansion';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatMenuModule } from '@angular/material/menu';\nimport { MatSelectModule } from '@angular/material/select';\nimport { MatSlideToggleModule } from '@angular/material/slide-toggle';\nimport { MatToolbarModule } from '@angular/material/toolbar';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport {\n COMMON_MODULES,\n type CommonModuleEntry,\n type EntityFormConfig,\n type FormRule,\n} from '@dynamic-entity/core';\nimport { ConfigSourceService } from 'ngx-dynamic-entity';\nimport { BuilderStore, type BuilderProblem } from './builder-store.service';\nimport { FieldInspectorComponent } from './components/field-inspector.component';\nimport { FieldPaletteComponent } from './components/field-palette.component';\nimport { TabManagerComponent } from './components/tab-manager.component';\nimport { EntityBuilderCanvasComponent } from './components/entity-builder-canvas.component';\nimport { RuleDependencyGraphComponent } from './components/rule-dependency-graph.component';\nimport { BuilderTextService } from './builder-text';\n\ntype RbacAction = 'view' | 'edit' | 'delete';\n\n/** RBAC actions surfaced in the settings panel. */\nconst RBAC_ACTIONS: readonly RbacAction[] = ['view', 'edit', 'delete'];\n\n/** Shared stable empty array — never allocate a fresh [] per change-detection (mat-select loops). */\nconst EMPTY_ROLES: readonly string[] = Object.freeze([]);\n\n/**\n * EntityBuilderComponent — the top-level visual builder for an EntityFormConfig.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ngx-entity-builder',\n standalone: true,\n providers: [BuilderStore],\n imports: [\n FormsModule,\n MatButtonModule,\n MatCardModule,\n MatCheckboxModule,\n MatExpansionModule,\n MatFormFieldModule,\n MatIconModule,\n MatInputModule,\n MatMenuModule,\n MatSelectModule,\n MatSlideToggleModule,\n MatToolbarModule,\n MatTooltipModule,\n FieldPaletteComponent,\n TabManagerComponent,\n FieldInspectorComponent,\n EntityBuilderCanvasComponent,\n RuleDependencyGraphComponent,\n ],\n templateUrl: './entity-builder.component.html',\n styleUrl: './entity-builder.component.css',\n /*\n * This stylesheet is the builder's design system, not one component's styles.\n *\n * `.deb-field-row`, `.deb-section-title`, `.deb-hint`, `.deb-chip`, `.deb-empty` and the\n * rest are written in seven child components' templates and defined only here — and under\n * emulated encapsulation a parent's rules carry this component's `_ngcontent` attribute, so\n * none of them ever reached a child. The field rows, the inspector's section titles and the\n * canvas's empty state have been rendering unstyled since they were split out; the\n * duplicate `.deb-row` / `.deb-option-row` blocks inside `entity-reference-config` are\n * somebody working around the same thing one panel at a time.\n *\n * `.cdk-drag-preview` says the same thing from the other direction: the CDK attaches a drag\n * preview to `document.body`, outside this component entirely, so that rule could never\n * have applied while scoped.\n *\n * What makes lifting the scope safe is that every selector in the file is `deb-`-prefixed —\n * the CDK rules included, which are qualified with `.deb-field-row` so a host's own drop\n * list does not inherit the builder's drag styling. `:host` is spelled `ngx-entity-builder`\n * for the same reason: there is no host scope left to write it in.\n */\n encapsulation: ViewEncapsulation.None,\n})\nexport class EntityBuilderComponent implements OnChanges {\n /** Builder chrome, overridable via BUILDER_TEXT. */\n protected readonly ui = inject(BuilderTextService);\n protected readonly store = inject(BuilderStore);\n /**\n * Optional: only apps that registered a CONFIG_SOURCE have one. Used to drop the cached\n * copy of a config the moment it is edited — see `doSave`.\n */\n private readonly configSource = inject(ConfigSourceService, { optional: true });\n /** Scopes the focus lookup below to this builder, not the first match in the document. */\n private readonly hostRef = inject(ElementRef);\n\n /** Existing config to edit. When omitted, the builder starts blank. */\n @Input() config?: EntityFormConfig;\n /**\n * The rules that belong with `config`.\n *\n * Rules live beside a config rather than inside it — that is the shape the renderer takes\n * them in, and the shape a host stores them in. Without this input, loading a config for\n * editing silently dropped every rule already authored against it: the builder opened on\n * the right fields with an empty rules list, and saving put that emptiness back.\n */\n @Input() rules?: FormRule[];\n /** Languages available for label/placeholder editing. First entry is the default. */\n @Input() languages: string[] = ['en'];\n /**\n * Language for the builder's **own** chrome, resolved through `BUILDER_TEXT`.\n *\n * Deliberately separate from `languages` and `store.activeLanguage()`, which choose the\n * `LocalizedText` entry being authored: switching the label language you are editing\n * should not translate the interface around it.\n */\n @Input() set uiLanguage(value: string) {\n this.ui.language.set(value || 'en');\n }\n /** Optional role list — enables multi-select role pickers for RBAC instead of free text. */\n @Input() availableRoles: string[] = [];\n /**\n * Roles of the person using the builder. Distinct from `availableRoles`, which is the\n * vocabulary a schema may reference. Passed to the `SYSTEM_DEFAULT_CAN_EDIT` predicate so\n * it can decide whether this user may edit system-default tabs.\n */\n @Input() userRoles: string[] = [];\n /** Optional common-module definitions for module tabs; defaults to the built-in list from core. */\n @Input() commonModules: readonly CommonModuleEntry[] = COMMON_MODULES;\n\n /** Emitted on every change to the working config. */\n @Output() configChange = new EventEmitter<EntityFormConfig>();\n /**\n * Emitted on every change to the working rules — the mirror of `configChange`.\n *\n * Without it a rule authored here could not leave this component. `BuilderStore` is\n * provided by the component, so its instance is private to this injector, and `save`\n * carries an `EntityFormConfig` alone. The builder could author a rule and hand it to\n * nobody: a host had no supported way to persist one, and therefore no way to pass it\n * back to the renderer as `[rules]`.\n *\n * A host that persists on Save keeps the latest emission and writes it alongside the\n * config `save` carries — the same pairing `configChange`/`save` already implies, and the\n * pairing the undo history has always stored, because undoing a field rename without the\n * rule that follows it would leave the rule pointing at a field that no longer exists.\n */\n @Output() rulesChange = new EventEmitter<FormRule[]>();\n /** Emitted when the user clicks Save. Carries a clean, deep-cloned config. */\n @Output() save = new EventEmitter<EntityFormConfig>();\n\n protected readonly rbacActions = RBAC_ACTIONS;\n\n /*\n * Two-way bindable, so the host decides whether a collapsed rail/bar survives a reload.\n *\n * `model()` rather than a plain signal: these stay ordinary writable signals to everything\n * inside the component, and gain `[(leftSidebarOpen)]`, `[(rightSidebarOpen)]`, `[(fieldsOpen)]`,\n * `[(previewOpen)]` for anyone outside it. The library deliberately persists nothing itself —\n * no package here touches `localStorage`, which is what keeps it safe to render on a server;\n * the demo wires these to storage to show how.\n */\n readonly leftSidebarOpen = model(true);\n readonly rightSidebarOpen = model(true);\n readonly fieldsOpen = model(true);\n readonly previewOpen = model(true);\n\n toggleLeftSidebar(): void {\n this.leftSidebarOpen.update(open => !open);\n }\n\n toggleRightSidebar(): void {\n this.rightSidebarOpen.update(open => !open);\n }\n\n toggleFields(): void {\n this.fieldsOpen.update(open => !open);\n }\n\n togglePreview(): void {\n this.previewOpen.update(open => !open);\n }\n\n readonly ruleGraphOpen = signal(false);\n\n openRuleGraph(): void {\n this.ruleGraphOpen.set(true);\n }\n\n closeRuleGraph(): void {\n this.ruleGraphOpen.set(false);\n }\n\n onSelectFieldFromGraph(key: string): void {\n this.store.selectField(key);\n this.ruleGraphOpen.set(false);\n }\n\n /*\n * Collapsing from inside a panel destroys the button that was just pressed, and expanding\n * from a rail destroys the rail. Either way the browser drops focus onto `<body>`, which\n * for a keyboard user means starting the tab sequence again from the top of the document.\n * Each of these hands focus to whichever control now stands in for the panel.\n *\n * The toolbar toggles need none of this: they stay put and keep their focus.\n */\n protected collapseLeft(): void {\n this.leftSidebarOpen.set(false);\n this.focusAfterRender('expand-left-sidebar');\n }\n\n protected expandLeft(): void {\n this.leftSidebarOpen.set(true);\n this.focusAfterRender('collapse-left-sidebar');\n }\n\n protected collapseRight(): void {\n this.rightSidebarOpen.set(false);\n this.focusAfterRender('expand-right-sidebar');\n }\n\n protected expandRight(): void {\n this.rightSidebarOpen.set(true);\n this.focusAfterRender('collapse-right-sidebar');\n }\n\n protected collapseFields(): void {\n this.fieldsOpen.set(false);\n this.focusAfterRender('expand-fields');\n }\n\n protected expandFields(): void {\n this.fieldsOpen.set(true);\n this.focusAfterRender('collapse-fields');\n }\n\n protected collapsePreview(): void {\n this.previewOpen.set(false);\n this.focusAfterRender('expand-preview');\n }\n\n protected expandPreview(): void {\n this.previewOpen.set(true);\n this.focusAfterRender('collapse-preview');\n }\n\n /** The replacement control does not exist until the template has caught up with the signal. */\n private focusAfterRender(testId: string): void {\n setTimeout(() => {\n const host = this.hostRef.nativeElement as HTMLElement;\n host.querySelector<HTMLElement>(`[data-testid=\"${testId}\"]`)?.focus();\n });\n }\n\n /**\n * Select the field an issue is about, so reading the message and acting on it are one step.\n *\n * A problem without a `fieldId` is about the entity itself — no tabs, a bad entity name —\n * and there is nothing to select; the template disables those entries rather than silently\n * doing nothing when one is clicked.\n */\n protected selectProblemField(problem: BuilderProblem): void {\n if (problem.fieldId) this.store.selectField(problem.fieldId);\n }\n\n constructor() {\n effect(() => this.configChange.emit(this.store.config()), { allowSignalWrites: true });\n effect(() => this.rulesChange.emit(this.store.rules()), { allowSignalWrites: true });\n }\n\n /**\n * Ctrl/Cmd+Z and Ctrl/Cmd+Shift+Z, but only when the user is not typing.\n *\n * A textarea or input has its own undo stack, and hijacking it would make Ctrl+Z revert a\n * whole structural edit when the author only wanted to take back a character.\n */\n @HostListener('document:keydown', ['$event'])\n protected onKeydown(event: KeyboardEvent): void {\n if (!(event.ctrlKey || event.metaKey) || event.key.toLowerCase() !== 'z') return;\n\n const target = event.target as HTMLElement | null;\n const tag = target?.tagName?.toLowerCase();\n if (tag === 'input' || tag === 'textarea' || target?.isContentEditable) return;\n\n event.preventDefault();\n if (event.shiftKey) this.store.redo();\n else this.store.undo();\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['config'] && changes['config'].currentValue !== changes['config'].previousValue) {\n // The rules go in with the config, as one snapshot: `load` seeds both before taking\n // the history baseline, so opening a builder is not itself an undoable step.\n if (this.config) this.store.load(this.config, this.rules ?? []);\n else if (changes['config'].isFirstChange()) this.store.reset();\n } else if (changes['rules'] && changes['rules'].currentValue !== changes['rules'].previousValue) {\n this.store.loadRules(this.rules ?? []);\n }\n if (changes['languages'] && this.languages.length) {\n const active = this.store.activeLanguage();\n if (!this.languages.includes(active)) this.store.setActiveLanguage(this.languages[0]);\n }\n if (changes['userRoles']) {\n this.store.setUserRoles(this.userRoles);\n }\n }\n\n // ─── Toolbar actions ──────────────────────────────────────────────────────\n\n protected doSave(): void {\n const config = this.store.exportConfig();\n\n // Saving is the moment this entity's config changes, so anything holding a cached copy is\n // now stale — most visibly a referenced field elsewhere resolving against the old schema.\n // ConfigSourceService caches per entity and exposed clearCache from the start, but nothing\n // ever called it, so a cache entry lived for the lifetime of the page.\n this.configSource?.clearCache(config.entity);\n\n this.save.emit(config);\n }\n\n protected get json(): string {\n return JSON.stringify(this.store.exportConfig(), null, 2);\n }\n\n protected copyJson(): void {\n if (typeof navigator !== 'undefined' && navigator.clipboard) {\n void navigator.clipboard.writeText(this.json);\n }\n }\n\n // ─── RBAC settings ────────────────────────────────────────────────────────\n\n protected rolesFor(action: RbacAction): readonly string[] {\n // Return the stored array (stable ref between mutations) or a shared empty — NOT a fresh [],\n // which would make the bound mat-select re-evaluate every CD and loop forever.\n return this.store.config().permissions?.[action] ?? EMPTY_ROLES;\n }\n\n protected setRoles(action: RbacAction, roles: string[]): void {\n this.store.setPermission(action, roles);\n }\n\n /** Parse a comma-separated role string into a trimmed, de-duplicated array. */\n protected setRolesFromText(action: RbacAction, text: string): void {\n const roles = Array.from(\n new Set(\n text\n .split(',')\n .map(r => r.trim())\n .filter(Boolean),\n ),\n );\n this.store.setPermission(action, roles);\n }\n}\n","<mat-toolbar class=\"deb-toolbar\">\n <button\n mat-icon-button\n type=\"button\"\n data-testid=\"toggle-left-sidebar\"\n class=\"deb-sidebar-toggle-btn\"\n [class.deb-sidebar-toggle-btn--active]=\"leftSidebarOpen()\"\n [attr.aria-expanded]=\"leftSidebarOpen()\"\n aria-controls=\"deb-left-sidebar\"\n (click)=\"toggleLeftSidebar()\"\n [matTooltip]=\"leftSidebarOpen() ? ui.text('collapsePalette') : ui.text('expandPalette')\"\n [attr.aria-label]=\"leftSidebarOpen() ? ui.text('collapsePalette') : ui.text('expandPalette')\"\n >\n <mat-icon>{{ leftSidebarOpen() ? 'menu_open' : 'menu' }}</mat-icon>\n </button>\n\n <mat-icon class=\"deb-toolbar__mark\">dashboard_customize</mat-icon>\n <span class=\"deb-toolbar__title\">{{ ui.text('builderTitle') }}</span>\n <span class=\"deb-toolbar__entity\" data-testid=\"builder-toolbar-entity\">{{ store.config().entity || '—' }}</span>\n <span class=\"deb-spacer\"></span>\n\n <!--\n The issue count, and the issues.\n It used to be a button labelled \"0 / 1\" whose tooltip said to hover the items in the list\n — a list that did not exist anywhere in the builder. The count now opens the problems\n themselves, and an entry that names a field selects it, which is the action the person\n reading the message wants to take next.\n -->\n @if (store.problems().length) {\n <button\n mat-button\n type=\"button\"\n class=\"deb-problems\"\n data-testid=\"builder-problems\"\n [class.deb-problems--error]=\"!store.isValid()\"\n [matMenuTriggerFor]=\"problemsMenu\"\n [matTooltip]=\"ui.text('issuesTooltip', { count: store.problems().length })\"\n >\n <mat-icon>{{ store.isValid() ? 'warning' : 'error' }}</mat-icon>\n {{ ui.text('issuesCount', { errors: store.errors().length, total: store.problems().length }) }}\n </button>\n <mat-menu #problemsMenu=\"matMenu\" class=\"deb-problems-menu\">\n @for (problem of store.problems(); track $index) {\n <button\n mat-menu-item\n type=\"button\"\n data-testid=\"builder-problem\"\n [disabled]=\"!problem.fieldId\"\n (click)=\"selectProblemField(problem)\"\n >\n <mat-icon [class.deb-problems--error]=\"problem.level === 'error'\">{{\n problem.level === 'error' ? 'error' : 'warning'\n }}</mat-icon>\n <span class=\"deb-problems-menu__text\">{{ problem.message }}</span>\n </button>\n }\n </mat-menu>\n }\n\n <button\n mat-icon-button\n type=\"button\"\n data-testid=\"builder-undo\"\n [disabled]=\"!store.canUndo()\"\n (click)=\"store.undo()\"\n [matTooltip]=\"ui.text('undoTooltip')\"\n [attr.aria-label]=\"ui.text('undo')\"\n >\n <mat-icon>undo</mat-icon>\n </button>\n <button\n mat-icon-button\n type=\"button\"\n data-testid=\"builder-redo\"\n [disabled]=\"!store.canRedo()\"\n (click)=\"store.redo()\"\n [matTooltip]=\"ui.text('redoTooltip')\"\n [attr.aria-label]=\"ui.text('redo')\"\n >\n <mat-icon>redo</mat-icon>\n </button>\n\n <button\n mat-button\n type=\"button\"\n (click)=\"copyJson()\"\n [matTooltip]=\"ui.text('copyJson')\"\n [attr.aria-label]=\"ui.text('copyJson')\"\n >\n <mat-icon>content_copy</mat-icon>\n <!-- The label goes on a narrow screen; the tooltip and aria-label above carry the name. -->\n <span class=\"deb-toolbar__btn-label\">{{ ui.text('copyJson') }}</span>\n </button>\n\n <button\n mat-button\n type=\"button\"\n data-testid=\"builder-rule-graph\"\n (click)=\"openRuleGraph()\"\n [matTooltip]=\"ui.text('ruleGraph')\"\n [attr.aria-label]=\"ui.text('ruleGraph')\"\n >\n <mat-icon>hub</mat-icon>\n <span class=\"deb-toolbar__btn-label\">{{ ui.text('ruleGraph') }}</span>\n </button>\n\n <button\n mat-icon-button\n type=\"button\"\n data-testid=\"toggle-fields\"\n class=\"deb-sidebar-toggle-btn\"\n [class.deb-sidebar-toggle-btn--active]=\"fieldsOpen()\"\n [attr.aria-expanded]=\"fieldsOpen()\"\n aria-controls=\"deb-fields-section\"\n (click)=\"toggleFields()\"\n [matTooltip]=\"fieldsOpen() ? ui.text('collapseFields') : ui.text('expandFields')\"\n [attr.aria-label]=\"fieldsOpen() ? ui.text('collapseFields') : ui.text('expandFields')\"\n >\n <mat-icon>{{ fieldsOpen() ? 'view_agenda' : 'table_rows' }}</mat-icon>\n </button>\n\n <button\n mat-icon-button\n type=\"button\"\n data-testid=\"toggle-preview\"\n class=\"deb-sidebar-toggle-btn\"\n [class.deb-sidebar-toggle-btn--active]=\"previewOpen()\"\n [attr.aria-expanded]=\"previewOpen()\"\n aria-controls=\"deb-preview-section\"\n (click)=\"togglePreview()\"\n [matTooltip]=\"previewOpen() ? ui.text('collapsePreview') : ui.text('expandPreview')\"\n [attr.aria-label]=\"previewOpen() ? ui.text('collapsePreview') : ui.text('expandPreview')\"\n >\n <mat-icon>{{ previewOpen() ? 'visibility' : 'visibility_off' }}</mat-icon>\n </button>\n\n <button\n mat-icon-button\n type=\"button\"\n data-testid=\"toggle-right-sidebar\"\n class=\"deb-sidebar-toggle-btn\"\n [class.deb-sidebar-toggle-btn--active]=\"rightSidebarOpen()\"\n [attr.aria-expanded]=\"rightSidebarOpen()\"\n aria-controls=\"deb-right-sidebar\"\n (click)=\"toggleRightSidebar()\"\n [matTooltip]=\"rightSidebarOpen() ? ui.text('collapseInspector') : ui.text('expandInspector')\"\n [attr.aria-label]=\"rightSidebarOpen() ? ui.text('collapseInspector') : ui.text('expandInspector')\"\n >\n <mat-icon>{{ rightSidebarOpen() ? 'vertical_split' : 'tune' }}</mat-icon>\n </button>\n\n <!--\n The tooltip sits on a wrapper, not on the button.\n\n A disabled button receives no pointer events, so a tooltip bound to it never fires — which\n is the one state where the explanation is worth having. Saving stays disabled here (unlike\n the renderer's Save, which refuses instead): an invalid *schema* is not something the\n author can be shown their way out of one field at a time, and the issue list beside this\n button is where that conversation happens.\n -->\n <span [matTooltip]=\"store.isValid() ? '' : ui.text('saveBlockedTooltip')\" [matTooltipDisabled]=\"store.isValid()\">\n <!-- primary, not accent: white on Material's default pink accent is 3.33:1, below AA. -->\n <button mat-flat-button color=\"primary\" type=\"button\" [disabled]=\"!store.isValid()\" (click)=\"doSave()\">\n <mat-icon>save</mat-icon> {{ ui.text('save') }}\n </button>\n </span>\n</mat-toolbar>\n\n<div\n class=\"deb-body\"\n [class.deb-body--left-collapsed]=\"!leftSidebarOpen()\"\n [class.deb-body--right-collapsed]=\"!rightSidebarOpen()\"\n>\n <!-- Collapsed left sidebar: the rail that brings it back. -->\n @if (!leftSidebarOpen()) {\n <button\n type=\"button\"\n class=\"deb-dock-btn deb-dock-btn--left\"\n data-testid=\"expand-left-sidebar\"\n aria-expanded=\"false\"\n aria-controls=\"deb-left-sidebar\"\n (click)=\"expandLeft()\"\n [matTooltip]=\"ui.text('expandPalette')\"\n [attr.aria-label]=\"ui.text('expandPalette')\"\n >\n <!--\n The card's own icon, not its name turned on its side. A 44px rail can only hold a\n label by rotating it, and a rotated word is one you have to tilt your head to read —\n worse in German, where \"Eigenschaften\" is half a screen tall. The tooltip and the\n accessible name carry the words; the label below returns when the rail lies flat.\n -->\n <mat-icon class=\"deb-dock-btn__icon\">add_circle_outline</mat-icon>\n <span class=\"deb-dock-btn__label\">{{ ui.text('paletteRailLabel') }}</span>\n <mat-icon class=\"deb-dock-btn__chevron\">chevron_right</mat-icon>\n </button>\n }\n\n <!-- ─── Left: settings, palette, tabs ─── -->\n <div\n id=\"deb-left-sidebar\"\n class=\"deb-col deb-col--left\"\n data-testid=\"builder-left-sidebar\"\n [hidden]=\"!leftSidebarOpen()\"\n >\n <mat-card class=\"deb-card deb-card--palette\">\n <mat-card-header>\n <mat-card-title class=\"deb-card__title\">\n <mat-icon class=\"deb-card__icon\">add_circle_outline</mat-icon>\n {{ ui.text('addField') }}\n </mat-card-title>\n <button\n mat-icon-button\n type=\"button\"\n class=\"deb-card__collapse-btn\"\n data-testid=\"collapse-left-sidebar\"\n aria-expanded=\"true\"\n aria-controls=\"deb-left-sidebar\"\n (click)=\"collapseLeft()\"\n [matTooltip]=\"ui.text('collapsePalette')\"\n [attr.aria-label]=\"ui.text('collapsePalette')\"\n >\n <mat-icon>chevron_left</mat-icon>\n </button>\n </mat-card-header>\n <mat-card-content>\n <ngx-field-palette (pick)=\"store.addField($event)\"></ngx-field-palette>\n </mat-card-content>\n </mat-card>\n\n <mat-card class=\"deb-card deb-card--settings\">\n <mat-card-header>\n <mat-card-title class=\"deb-card__title\">\n <mat-icon class=\"deb-card__icon\">tune</mat-icon>\n {{ store.config().entity || ui.text('entityName') }}\n </mat-card-title>\n </mat-card-header>\n <mat-card-content>\n <div class=\"deb-settings-grid\">\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('entityName') }}</mat-label>\n <input\n matInput\n [ngModel]=\"store.config().entity\"\n (ngModelChange)=\"store.setEntityName($event)\"\n [placeholder]=\"ui.text('entityNamePlaceholder')\"\n />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('editingLanguage') }}</mat-label>\n <mat-select\n data-testid=\"builder-editing-language\"\n [ngModel]=\"store.activeLanguage()\"\n (ngModelChange)=\"store.setActiveLanguage($event)\"\n >\n @for (l of languages; track l) {\n <mat-option [value]=\"l\">{{ l }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n\n <div class=\"deb-mask-row\">\n <mat-slide-toggle\n color=\"primary\"\n [ngModel]=\"store.config().maskData ?? false\"\n (ngModelChange)=\"store.setMaskData($event)\"\n >{{ ui.text('maskEntity') }}</mat-slide-toggle\n >\n </div>\n\n <mat-expansion-panel class=\"deb-rbac\">\n <mat-expansion-panel-header>\n <mat-panel-title>{{ ui.text('permissions') }}</mat-panel-title>\n </mat-expansion-panel-header>\n @for (action of rbacActions; track action) {\n @if (availableRoles.length) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('actionRoles', { action }) }}</mat-label>\n <mat-select multiple [ngModel]=\"rolesFor(action)\" (ngModelChange)=\"setRoles(action, $event)\">\n @for (role of availableRoles; track role) {\n <mat-option [value]=\"role\">{{ role }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n } @else {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" class=\"deb-full\">\n <mat-label>{{ ui.text('actionRolesPlaceholder', { action }) }}</mat-label>\n <input matInput [ngModel]=\"rolesFor(action).join(', ')\" (ngModelChange)=\"setRolesFromText(action, $event)\" />\n </mat-form-field>\n }\n }\n <p class=\"deb-hint\">{{ ui.text('permissionsHint') }}</p>\n </mat-expansion-panel>\n </mat-card-content>\n </mat-card>\n\n <mat-card class=\"deb-card deb-card--tabs\">\n <mat-card-content>\n <ngx-tab-manager></ngx-tab-manager>\n </mat-card-content>\n </mat-card>\n </div>\n\n <!-- ─── Center: field canvas, then what it renders as ─── -->\n <div class=\"deb-col deb-col--center\" data-testid=\"builder-canvas-column\">\n <!-- Collapsed fields canvas dock bar -->\n <div\n class=\"deb-dock-pane deb-dock-pane--fields\"\n [class.deb-dock-pane--open]=\"!fieldsOpen()\"\n [attr.aria-hidden]=\"fieldsOpen()\"\n >\n <div class=\"deb-dock-pane__inner\">\n <button\n type=\"button\"\n class=\"deb-dock-btn deb-dock-btn--horizontal deb-dock-btn--fields\"\n data-testid=\"expand-fields\"\n aria-expanded=\"false\"\n aria-controls=\"deb-fields-section\"\n (click)=\"expandFields()\"\n [matTooltip]=\"ui.text('expandFields')\"\n [attr.aria-label]=\"ui.text('expandFields')\"\n >\n <mat-icon class=\"deb-dock-btn__icon\">format_list_bulleted</mat-icon>\n <span class=\"deb-dock-btn__label\">{{ ui.text('fieldsRailLabel') }} ({{ store.fields().length }})</span>\n <mat-icon class=\"deb-dock-btn__chevron\">keyboard_arrow_down</mat-icon>\n </button>\n </div>\n </div>\n\n <!-- Fields canvas section -->\n <div\n id=\"deb-fields-section\"\n class=\"deb-toggle-pane deb-section--fields\"\n [class.deb-toggle-pane--collapsed]=\"!fieldsOpen()\"\n data-testid=\"builder-fields-section\"\n [attr.aria-hidden]=\"!fieldsOpen()\"\n >\n <div class=\"deb-toggle-pane__inner\">\n <ngx-entity-builder-canvas (collapse)=\"collapseFields()\" />\n </div>\n </div>\n\n <!-- Collapsed preview dock bar -->\n <div\n class=\"deb-dock-pane deb-dock-pane--preview\"\n [class.deb-dock-pane--open]=\"!previewOpen()\"\n [attr.aria-hidden]=\"previewOpen()\"\n >\n <div class=\"deb-dock-pane__inner\">\n <button\n type=\"button\"\n class=\"deb-dock-btn deb-dock-btn--horizontal deb-dock-btn--preview\"\n data-testid=\"expand-preview\"\n aria-expanded=\"false\"\n aria-controls=\"deb-preview-section\"\n (click)=\"expandPreview()\"\n [matTooltip]=\"ui.text('expandPreview')\"\n [attr.aria-label]=\"ui.text('expandPreview')\"\n >\n <mat-icon class=\"deb-dock-btn__icon\">visibility</mat-icon>\n <span class=\"deb-dock-btn__label\">{{ ui.text('previewRailLabel') }}</span>\n <mat-icon class=\"deb-dock-btn__chevron\">keyboard_arrow_up</mat-icon>\n </button>\n </div>\n </div>\n\n <!--\n The live preview, moved up from the footer.\n Directly under the field list is where a change and its effect can be seen in the same glance.\n -->\n <div\n id=\"deb-preview-section\"\n class=\"deb-toggle-pane deb-preview-slot\"\n [class.deb-toggle-pane--collapsed]=\"!previewOpen()\"\n data-testid=\"builder-preview-section\"\n [attr.aria-hidden]=\"!previewOpen()\"\n >\n <div class=\"deb-toggle-pane__inner\">\n <mat-card class=\"deb-card deb-card--preview\">\n <mat-card-header>\n <mat-card-title class=\"deb-card__title\">\n <mat-icon class=\"deb-card__icon\">visibility</mat-icon>\n {{ ui.text('previewHeading') }}\n </mat-card-title>\n <button\n mat-icon-button\n type=\"button\"\n class=\"deb-card__collapse-btn\"\n data-testid=\"collapse-preview\"\n aria-expanded=\"true\"\n aria-controls=\"deb-preview-section\"\n (click)=\"collapsePreview()\"\n [matTooltip]=\"ui.text('collapsePreview')\"\n [attr.aria-label]=\"ui.text('collapsePreview')\"\n >\n <mat-icon>keyboard_arrow_down</mat-icon>\n </button>\n </mat-card-header>\n <mat-card-content>\n <ng-content select=\"[ngxBuilderPreview]\"></ng-content>\n </mat-card-content>\n </mat-card>\n </div>\n </div>\n </div>\n\n <!-- Collapsed right sidebar: the rail that brings it back. -->\n @if (!rightSidebarOpen()) {\n <button\n type=\"button\"\n class=\"deb-dock-btn deb-dock-btn--right\"\n data-testid=\"expand-right-sidebar\"\n aria-expanded=\"false\"\n aria-controls=\"deb-right-sidebar\"\n (click)=\"expandRight()\"\n [matTooltip]=\"ui.text('expandInspector')\"\n [attr.aria-label]=\"ui.text('expandInspector')\"\n >\n <mat-icon class=\"deb-dock-btn__icon\">tune</mat-icon>\n <span class=\"deb-dock-btn__label\">{{ ui.text('inspectorRailLabel') }}</span>\n <mat-icon class=\"deb-dock-btn__chevron\">chevron_left</mat-icon>\n </button>\n }\n\n <!-- ─── Right: inspector ─── -->\n <div\n id=\"deb-right-sidebar\"\n class=\"deb-col deb-col--right\"\n data-testid=\"builder-right-sidebar\"\n [hidden]=\"!rightSidebarOpen()\"\n >\n <mat-card class=\"deb-card deb-card--inspector\">\n <mat-card-header>\n <mat-card-title class=\"deb-card__title\">\n <mat-icon class=\"deb-card__icon\">tune</mat-icon>\n {{ ui.text('fieldProperties') }}\n </mat-card-title>\n <button\n mat-icon-button\n type=\"button\"\n class=\"deb-card__collapse-btn\"\n data-testid=\"collapse-right-sidebar\"\n aria-expanded=\"true\"\n aria-controls=\"deb-right-sidebar\"\n (click)=\"collapseRight()\"\n [matTooltip]=\"ui.text('collapseInspector')\"\n [attr.aria-label]=\"ui.text('collapseInspector')\"\n >\n <mat-icon>chevron_right</mat-icon>\n </button>\n </mat-card-header>\n <mat-card-content>\n <ngx-field-inspector></ngx-field-inspector>\n </mat-card-content>\n </mat-card>\n </div>\n</div>\n\n<!-- ─── Footer: the exported JSON ─── -->\n<div class=\"deb-footer\">\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title><mat-icon>data_object</mat-icon>&nbsp;{{ ui.text('configJson') }}</mat-panel-title>\n </mat-expansion-panel-header>\n <pre class=\"deb-json\">{{ json }}</pre>\n </mat-expansion-panel>\n</div>\n\n@if (ruleGraphOpen()) {\n <ngx-rule-dependency-graph\n (dismiss)=\"closeRuleGraph()\"\n (selectField)=\"onSelectFieldFromGraph($event)\"\n />\n}\n","// Main component\nexport * from './lib/entity-builder.component';\n\n// Sub-components (individually importable — reusability rule, mirrors ngx-dynamic-entity)\nexport * from './lib/components/field-palette.component';\nexport * from './lib/components/field-inspector.component';\nexport * from './lib/components/tab-manager.component';\nexport * from './lib/components/rule-form.component';\nexport * from './lib/components/field-rules-list.component';\nexport * from './lib/components/entity-reference-config.component';\nexport * from './lib/components/entity-builder-canvas.component';\nexport * from './lib/components/entity-builder-tree-node.component';\nexport * from './lib/components/rule-dependency-graph.component';\n\n// UI text for the builder's own chrome\nexport * from './lib/builder-text';\n\n// Store (provided per builder instance)\nexport * from './lib/builder-store.service';\n\n// Catalog + helpers\nexport * from './lib/field-catalog';\nexport * from './lib/field-path-options';\nexport * from './lib/rule-dependencies';\n\n// Re-export the core types a consumer of the builder needs\nexport type {\n EntityFormConfig,\n NestedTabConfig,\n NestedFieldConfig,\n RichFieldType,\n DropdownOption,\n EntityPermissions,\n EntityReferenceConfig,\n AutoPatchConfig,\n AutoPatchMapping,\n PatchOnTrueMapping,\n FormRule,\n RuleCondition,\n RuleAction,\n RuleOperator,\n} from '@dynamic-entity/core';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i5","i8","i3","i4","i6","i2","i9","i1","i7","i12"],"mappings":"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"}