ngx-dynamic-entity-builder 1.0.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.
Files changed (36) hide show
  1. package/README.md +54 -0
  2. package/esm2022/lib/builder-store.service.mjs +923 -0
  3. package/esm2022/lib/clone.mjs +14 -0
  4. package/esm2022/lib/components/connection-source-config.component.mjs +121 -0
  5. package/esm2022/lib/components/entity-builder-canvas.component.mjs +83 -0
  6. package/esm2022/lib/components/entity-builder-tree-node.component.mjs +173 -0
  7. package/esm2022/lib/components/entity-reference-config.component.mjs +405 -0
  8. package/esm2022/lib/components/field-inspector.component.mjs +139 -0
  9. package/esm2022/lib/components/field-palette.component.mjs +57 -0
  10. package/esm2022/lib/components/field-rules-list.component.mjs +224 -0
  11. package/esm2022/lib/components/referenced-field-config.component.mjs +228 -0
  12. package/esm2022/lib/components/rule-form.component.mjs +201 -0
  13. package/esm2022/lib/components/tab-manager.component.mjs +341 -0
  14. package/esm2022/lib/entity-builder.component.mjs +153 -0
  15. package/esm2022/lib/field-catalog.mjs +6 -0
  16. package/esm2022/ngx-dynamic-entity-builder.mjs +5 -0
  17. package/esm2022/public-api.mjs +17 -0
  18. package/fesm2022/ngx-dynamic-entity-builder.mjs +2910 -0
  19. package/fesm2022/ngx-dynamic-entity-builder.mjs.map +1 -0
  20. package/index.d.ts +5 -0
  21. package/lib/builder-store.service.d.ts +165 -0
  22. package/lib/clone.d.ts +9 -0
  23. package/lib/components/connection-source-config.component.d.ts +16 -0
  24. package/lib/components/entity-builder-canvas.component.d.ts +9 -0
  25. package/lib/components/entity-builder-tree-node.component.d.ts +17 -0
  26. package/lib/components/entity-reference-config.component.d.ts +29 -0
  27. package/lib/components/field-inspector.component.d.ts +33 -0
  28. package/lib/components/field-palette.component.d.ts +13 -0
  29. package/lib/components/field-rules-list.component.d.ts +19 -0
  30. package/lib/components/referenced-field-config.component.d.ts +18 -0
  31. package/lib/components/rule-form.component.d.ts +16 -0
  32. package/lib/components/tab-manager.component.d.ts +19 -0
  33. package/lib/entity-builder.component.d.ts +42 -0
  34. package/lib/field-catalog.d.ts +5 -0
  35. package/package.json +42 -0
  36. package/public-api.d.ts +13 -0
@@ -0,0 +1,165 @@
1
+ import type { AutoPatchMapping, DropdownOption, EntityFormConfig, EntityPermissions, EntityReferenceConfig, FormRule, NestedFieldConfig, NestedTabConfig, PatchOnTrueMapping, RichFieldType } from '@dynamic-entity/core';
2
+ import { type FlagValidator, type ParamValidator } from './field-catalog';
3
+ import * as i0 from "@angular/core";
4
+ export interface BuilderProblem {
5
+ level: 'error' | 'warning';
6
+ message: string;
7
+ fieldId?: string;
8
+ }
9
+ export declare class BuilderStore {
10
+ private readonly _config;
11
+ private readonly _selectedFieldId;
12
+ private readonly _activeLanguage;
13
+ /** Rules live beside the config: they are persisted per form, not inside `EntityFormConfig`. */
14
+ private readonly _rules;
15
+ /**
16
+ * Field ids the author owns — set by an explicit rename, or by loading a saved config
17
+ * whose ids are already live data keys. Ids outside this set are still derived from the
18
+ * field's label. Builder-session state, deliberately not part of the exported config.
19
+ */
20
+ private readonly manualIds;
21
+ private readonly _isDirty;
22
+ readonly config: import("@angular/core").Signal<EntityFormConfig>;
23
+ readonly selectedFieldId: import("@angular/core").Signal<string>;
24
+ readonly activeLanguage: import("@angular/core").Signal<string>;
25
+ readonly rules: import("@angular/core").Signal<FormRule[]>;
26
+ readonly isDirty: import("@angular/core").Signal<boolean>;
27
+ readonly tabs: import("@angular/core").Signal<NestedTabConfig[]>;
28
+ readonly fields: import("@angular/core").Signal<NestedFieldConfig[]>;
29
+ readonly selectedField: import("@angular/core").Signal<NestedFieldConfig>;
30
+ readonly problems: import("@angular/core").Signal<BuilderProblem[]>;
31
+ readonly errors: import("@angular/core").Signal<BuilderProblem[]>;
32
+ readonly isValid: import("@angular/core").Signal<boolean>;
33
+ load(config: EntityFormConfig): void;
34
+ reset(entity?: string): void;
35
+ resetDirty(): void;
36
+ private emptyConfig;
37
+ setEntityName(entity: string): void;
38
+ setDefaultLanguage(language: string): void;
39
+ setMaskData(mask: boolean): void;
40
+ setPermission(action: keyof EntityPermissions, roles: string[]): void;
41
+ setActiveLanguage(language: string): void;
42
+ private getAllFields;
43
+ private findFieldInTabs;
44
+ addField(type: RichFieldType, targetTabId?: string): string;
45
+ updateField(id: string, patch: Partial<NestedFieldConfig>): void;
46
+ /**
47
+ * Rename a field explicitly, pinning the id so it is no longer derived from the label.
48
+ *
49
+ * Not reachable from the inspector — the id input is read-only by design. This exists for
50
+ * programmatic callers that must match an id to an existing data key.
51
+ */
52
+ renameField(oldId: string, newId: string): void;
53
+ /** Whether this field's id is pinned (loaded from storage or explicitly renamed). */
54
+ hasManualId(id: string): boolean;
55
+ /**
56
+ * Move a field to a new id and repoint every id-based reference in the config at it.
57
+ *
58
+ * Ids are the wiring between fields — rules, cascades, patches and `showWhen` all address
59
+ * fields by id — so a rename that only touches `field.id` silently breaks that wiring.
60
+ * That was survivable while renaming was a rare manual act; label-derived ids make it
61
+ * routine, so the references move with it.
62
+ */
63
+ private applyRename;
64
+ removeField(id: string): void;
65
+ duplicateField(id: string): string | null;
66
+ moveField(id: string, direction: -1 | 1): void;
67
+ /** Safe reorder for drag & drop within active tab or flat list */
68
+ reorderField(fromIndex: number, toIndex: number, tabId?: string): void;
69
+ selectField(id: string | null): void;
70
+ /**
71
+ * Set a field's label, and derive the field's id from it: type "Employee Count", get
72
+ * `employeeCount`. The inspector renders the id read-only, so this is the only way a
73
+ * new field's id is set.
74
+ *
75
+ * Two things stop derivation: a config loaded from storage (its ids are live data keys
76
+ * that records are already stored under — see `load`), and an explicit `renameField`
77
+ * call, which remains available to programmatic callers.
78
+ *
79
+ * Only the config's default language drives the id; translating a label must not rename
80
+ * anything.
81
+ */
82
+ setFieldLabel(id: string, language: string, value: string): void;
83
+ /** `derived`, or `derived_2`, `derived_3`… if another field already holds it. */
84
+ private availableId;
85
+ setFieldPlaceholder(id: string, language: string, value: string): void;
86
+ toggleFlagValidator(id: string, validator: FlagValidator, on: boolean): void;
87
+ setParamValidator(id: string, validator: ParamValidator, value: number | null): void;
88
+ getParamValidator(field: NestedFieldConfig, validator: ParamValidator): number | null;
89
+ hasFlagValidator(field: NestedFieldConfig, validator: FlagValidator): boolean;
90
+ /**
91
+ * Where a choice field's options come from.
92
+ *
93
+ * `entity` is absent on purpose: in this model an entity reference is a field *type*
94
+ * (`entity-ref`), not a data source a dropdown can switch to, so offering it here would mean
95
+ * mutating the field's type — and rebuilding its control — from a source picker. The
96
+ * exclusion that matters within a choice field is inline `options` vs `listName`.
97
+ */
98
+ fieldDataSource(field: NestedFieldConfig | undefined): 'none' | 'manual' | 'lookup';
99
+ /**
100
+ * Switch a choice field's data source, clearing the one it is leaving.
101
+ *
102
+ * The reference makes these mutually exclusive (doc §4.4) and it has to stay that way here:
103
+ * `optionsFor` resolves inline options first, so a field left holding both would silently
104
+ * ignore its list.
105
+ */
106
+ setFieldDataSource(fieldId: string, source: 'none' | 'manual' | 'lookup'): void;
107
+ /** Set the named list a choice field reads its options from. */
108
+ setListName(fieldId: string, listName: string): void;
109
+ /** Link a field to a field defined in another entity configuration (Phase 8). */
110
+ linkReferencedField(fieldId: string, sourceEntityKey: string, sourceField: NestedFieldConfig): void;
111
+ /** Unlink a referenced field back to an independent field. */
112
+ unlinkReferencedField(fieldId: string): void;
113
+ /** Sync a drifted referenced field with the updated source field definition. */
114
+ syncReferencedField(fieldId: string, currentSourceField: NestedFieldConfig): void;
115
+ /** Scan all referenced fields in the config and update their hasDrift state against current source configs. */
116
+ checkDrift(sourceConfigs: Record<string, EntityFormConfig>): void;
117
+ addOption(fieldId: string): void;
118
+ /** Merge language keys into an option. `setOptionLabel` is the usual single-language path. */
119
+ updateOption(fieldId: string, index: number, patch: DropdownOption): void;
120
+ /**
121
+ * Set an option's text for one language.
122
+ *
123
+ * An option is a language-keyed object and the displayed text **is** the stored value,
124
+ * so this is the only way to edit one — there is no separate value to set.
125
+ */
126
+ setOptionLabel(fieldId: string, index: number, language: string, value: string): void;
127
+ removeOption(fieldId: string, index: number): void;
128
+ /** Merge a patch into a field's `entityReference` block, keeping it enabled. */
129
+ updateEntityReference(fieldId: string, patch: Partial<EntityReferenceConfig>): void;
130
+ addAutoPatchMapping(fieldId: string): void;
131
+ setAutoPatchTargetTab(fieldId: string, targetTab: string): void;
132
+ updateAutoPatchMapping(fieldId: string, index: number, patch: Partial<AutoPatchMapping>): void;
133
+ /** Removing the last mapping drops `autoPatch` entirely — no empty config in the export. */
134
+ removeAutoPatchMapping(fieldId: string, index: number): void;
135
+ addPatchOnTrueMapping(fieldId: string): void;
136
+ updatePatchOnTrueMapping(fieldId: string, index: number, patch: Partial<PatchOnTrueMapping>): void;
137
+ removePatchOnTrueMapping(fieldId: string, index: number): void;
138
+ /** Replace a field's `showWhen` map; an empty map removes the condition. */
139
+ setShowWhen(fieldId: string, showWhen: Record<string, unknown> | undefined): void;
140
+ /** Rules for the field currently selected in the inspector. */
141
+ readonly rulesForSelectedField: import("@angular/core").Signal<FormRule[]>;
142
+ loadRules(rules: FormRule[]): void;
143
+ addRule(rule: FormRule): string;
144
+ updateRule(id: string, patch: Partial<FormRule>): void;
145
+ removeRule(id: string): void;
146
+ toggleRule(id: string, enabled: boolean): void;
147
+ /** Move a rule in priority order. Priorities are renumbered 1..n so they stay contiguous. */
148
+ moveRule(id: string, direction: -1 | 1): void;
149
+ exportRules(): FormRule[];
150
+ addTab(): string;
151
+ /** Every tab id in the tree, at any depth. Tab ids must be globally unique — they are paths. */
152
+ private allTabIds;
153
+ addSubTab(parentId: string): string;
154
+ setPrimaryTab(tabId: string): void;
155
+ updateTab(id: string, patch: Partial<NestedTabConfig>): void;
156
+ setTabLabel(id: string, language: string, value: string): void;
157
+ removeTab(id: string): void;
158
+ moveTab(id: string, direction: -1 | 1): void;
159
+ exportConfig(): EntityFormConfig;
160
+ private mutate;
161
+ private uniqueId;
162
+ private validate;
163
+ static ɵfac: i0.ɵɵFactoryDeclaration<BuilderStore, never>;
164
+ static ɵprov: i0.ɵɵInjectableDeclaration<BuilderStore>;
165
+ }
package/lib/clone.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Deep clone with a JSON fallback.
3
+ *
4
+ * `structuredClone` is not universally available (older browsers, and jsdom before v22),
5
+ * so it must never be called unguarded — an unguarded call throws a ReferenceError and the
6
+ * caller silently does nothing. Config and rule objects are JSON-safe, so the fallback is
7
+ * lossless here.
8
+ */
9
+ export declare function deepClone<T>(value: T): T;
@@ -0,0 +1,16 @@
1
+ import { BuilderStore } from '../builder-store.service';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * ConnectionSourceConfigComponent — allows configuring connection source settings
5
+ * for an entity or field (Phase 7.2).
6
+ */
7
+ export declare class ConnectionSourceConfigComponent {
8
+ protected readonly store: BuilderStore;
9
+ protected readonly field: import("@angular/core").Signal<import("ngx-dynamic-entity").NestedFieldConfig>;
10
+ protected connectionSourceEntity(field: any): string;
11
+ protected setConnectionSourceEntity(field: any, entity: string): void;
12
+ protected connectionTargetField(field: any): string;
13
+ protected setConnectionTargetField(field: any, targetField: string): void;
14
+ static ɵfac: i0.ɵɵFactoryDeclaration<ConnectionSourceConfigComponent, never>;
15
+ static ɵcmp: i0.ɵɵComponentDeclaration<ConnectionSourceConfigComponent, "ngx-connection-source-config", never, {}, {}, never, never, true, never>;
16
+ }
@@ -0,0 +1,9 @@
1
+ import { CdkDragDrop } from '@angular/cdk/drag-drop';
2
+ import { BuilderStore } from '../builder-store.service';
3
+ import * as i0 from "@angular/core";
4
+ export declare class EntityBuilderCanvasComponent {
5
+ protected readonly store: BuilderStore;
6
+ protected onDrop(event: CdkDragDrop<unknown>): void;
7
+ static ɵfac: i0.ɵɵFactoryDeclaration<EntityBuilderCanvasComponent, never>;
8
+ static ɵcmp: i0.ɵɵComponentDeclaration<EntityBuilderCanvasComponent, "ngx-entity-builder-canvas", never, {}, {}, never, never, true, never>;
9
+ }
@@ -0,0 +1,17 @@
1
+ import { type NestedFieldConfig } from '@dynamic-entity/core';
2
+ import { BuilderStore } from '../builder-store.service';
3
+ import * as i0 from "@angular/core";
4
+ export declare class EntityBuilderTreeNodeComponent {
5
+ protected readonly store: BuilderStore;
6
+ field: NestedFieldConfig;
7
+ index: number;
8
+ totalCount: number;
9
+ protected fieldTypeLabel(type: string): string;
10
+ protected fieldTypeIcon(type: string): string;
11
+ protected fieldLabel(field: {
12
+ id: string;
13
+ label?: any;
14
+ }): string;
15
+ static ɵfac: i0.ɵɵFactoryDeclaration<EntityBuilderTreeNodeComponent, never>;
16
+ static ɵcmp: i0.ɵɵComponentDeclaration<EntityBuilderTreeNodeComponent, "ngx-entity-builder-tree-node", never, { "field": { "alias": "field"; "required": true; }; "index": { "alias": "index"; "required": true; }; "totalCount": { "alias": "totalCount"; "required": true; }; }, {}, never, never, true, never>;
17
+ }
@@ -0,0 +1,29 @@
1
+ import type { NestedFieldConfig } from '@dynamic-entity/core';
2
+ import { BuilderStore } from '../builder-store.service';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * EntityReferenceConfigComponent — authors the `entityReference` block of an entity-ref field:
6
+ * registry key, display fields, static filters, and the parent→child cascade.
7
+ *
8
+ * Also authors `autoPatch`, since the mappings only make sense against the record the
9
+ * selected reference returns.
10
+ */
11
+ export declare class EntityReferenceConfigComponent {
12
+ protected readonly store: BuilderStore;
13
+ protected readonly field: import("@angular/core").Signal<NestedFieldConfig>;
14
+ /** Sibling fields that can drive a cascade — anything but this field itself. */
15
+ protected readonly parentCandidates: import("@angular/core").Signal<NestedFieldConfig[]>;
16
+ private readonly filtersParseError;
17
+ protected readonly filtersError: import("@angular/core").Signal<string>;
18
+ protected ref(field: NestedFieldConfig): import("@dynamic-entity/core").EntityReferenceConfig;
19
+ protected patchRef(field: NestedFieldConfig, patch: Record<string, unknown>): void;
20
+ protected fieldLabel(field: NestedFieldConfig): string;
21
+ protected tabLabel(tabId: string): string;
22
+ protected displayFieldsText(field: NestedFieldConfig): string;
23
+ protected setDisplayFields(field: NestedFieldConfig, value: string): void;
24
+ protected filtersText(field: NestedFieldConfig): string;
25
+ /** Invalid JSON is reported inline and left unapplied rather than silently dropped. */
26
+ protected setFilters(field: NestedFieldConfig, value: string): void;
27
+ static ɵfac: i0.ɵɵFactoryDeclaration<EntityReferenceConfigComponent, never>;
28
+ static ɵcmp: i0.ɵɵComponentDeclaration<EntityReferenceConfigComponent, "ngx-entity-reference-config", never, {}, {}, never, never, true, never>;
29
+ }
@@ -0,0 +1,33 @@
1
+ import type { DropdownOption, NestedFieldConfig } from '@dynamic-entity/core';
2
+ import { BuilderStore } from '../builder-store.service';
3
+ import { type FieldTypeMeta } from '../field-catalog';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * FieldInspectorComponent — edits every property of the currently selected field.
7
+ */
8
+ export declare class FieldInspectorComponent {
9
+ protected readonly store: BuilderStore;
10
+ protected readonly field: import("@angular/core").Signal<NestedFieldConfig>;
11
+ protected readonly meta: import("@angular/core").Signal<FieldTypeMeta>;
12
+ protected lang(): string;
13
+ protected toNum(value: unknown): number | null;
14
+ protected labelValue(field: NestedFieldConfig): string;
15
+ protected placeholderValue(field: NestedFieldConfig): string;
16
+ protected optionLabel(option: DropdownOption): string;
17
+ protected showWhenEntries(field: NestedFieldConfig): {
18
+ key: string;
19
+ display: string;
20
+ }[];
21
+ protected addShowWhen(field: NestedFieldConfig): void;
22
+ protected renameShowWhen(field: NestedFieldConfig, oldKey: string, newKey: string): void;
23
+ protected setShowWhenValue(field: NestedFieldConfig, key: string, raw: string): void;
24
+ protected removeShowWhen(field: NestedFieldConfig, key: string): void;
25
+ /**
26
+ * `showWhen` compares with `!==`, so the authored type has to survive the round trip:
27
+ * "true"/"false" become booleans and numeric text becomes a number.
28
+ */
29
+ private parseShowWhen;
30
+ private stringifyShowWhen;
31
+ static ɵfac: i0.ɵɵFactoryDeclaration<FieldInspectorComponent, never>;
32
+ static ɵcmp: i0.ɵɵComponentDeclaration<FieldInspectorComponent, "ngx-field-inspector", never, {}, {}, never, never, true, never>;
33
+ }
@@ -0,0 +1,13 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import type { RichFieldType } from '@dynamic-entity/core';
3
+ import { type FieldTypeMeta } from '../field-catalog';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * FieldPaletteComponent — the list of buildable field types (Angular Material).
7
+ */
8
+ export declare class FieldPaletteComponent {
9
+ readonly catalog: readonly FieldTypeMeta[];
10
+ pick: EventEmitter<RichFieldType>;
11
+ static ɵfac: i0.ɵɵFactoryDeclaration<FieldPaletteComponent, never>;
12
+ static ɵcmp: i0.ɵɵComponentDeclaration<FieldPaletteComponent, "ngx-field-palette", never, {}, { "pick": "pick"; }, never, never, true, never>;
13
+ }
@@ -0,0 +1,19 @@
1
+ import type { FormRule } from '@dynamic-entity/core';
2
+ import { BuilderStore } from '../builder-store.service';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * FieldRulesListComponent — the rules attached to the selected field: view, reorder,
6
+ * enable/disable, edit, delete. `RuleFormComponent` authors one rule; this owns the set.
7
+ */
8
+ export declare class FieldRulesListComponent {
9
+ protected readonly store: BuilderStore;
10
+ /** The rule currently open in the editor — a new draft or a copy of an existing rule. */
11
+ protected readonly editing: import("@angular/core").WritableSignal<FormRule>;
12
+ protected startCreate(): void;
13
+ protected startEdit(rule: FormRule): void;
14
+ protected commit(rule: FormRule): void;
15
+ /** One-line human summary: `status EQUAL "archived" → hide`. */
16
+ protected summarize(rule: FormRule): string;
17
+ static ɵfac: i0.ɵɵFactoryDeclaration<FieldRulesListComponent, never>;
18
+ static ɵcmp: i0.ɵɵComponentDeclaration<FieldRulesListComponent, "ngx-field-rules-list", never, {}, {}, never, never, true, never>;
19
+ }
@@ -0,0 +1,18 @@
1
+ import { ConfigSourceService } from 'ngx-dynamic-entity';
2
+ import type { NestedFieldConfig } from '@dynamic-entity/core';
3
+ import { BuilderStore } from '../builder-store.service';
4
+ import * as i0 from "@angular/core";
5
+ export declare class ReferencedFieldConfigComponent {
6
+ protected readonly store: BuilderStore;
7
+ protected readonly configSource: ConfigSourceService;
8
+ protected readonly field: import("@angular/core").Signal<NestedFieldConfig>;
9
+ protected toggleReferenced(field: NestedFieldConfig, enabled: boolean): void;
10
+ protected updateEntityKey(field: NestedFieldConfig, key: string): void;
11
+ protected updateFieldId(field: NestedFieldConfig, fieldId: string): void;
12
+ protected syncWithSource(field: NestedFieldConfig): Promise<void>;
13
+ private checkDriftForField;
14
+ private findField;
15
+ private findFieldInList;
16
+ static ɵfac: i0.ɵɵFactoryDeclaration<ReferencedFieldConfigComponent, never>;
17
+ static ɵcmp: i0.ɵɵComponentDeclaration<ReferencedFieldConfigComponent, "ngx-referenced-field-config", never, {}, {}, never, never, true, never>;
18
+ }
@@ -0,0 +1,16 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import type { FormRule, RuleOperator } from '@dynamic-entity/core';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * RuleFormComponent — dialog/panel form for creating or editing a FormRule.
6
+ */
7
+ export declare class RuleFormComponent {
8
+ rule: FormRule;
9
+ save: EventEmitter<FormRule>;
10
+ cancel: EventEmitter<void>;
11
+ readonly operators: RuleOperator[];
12
+ addCondition(): void;
13
+ removeCondition(index: number): void;
14
+ static ɵfac: i0.ɵɵFactoryDeclaration<RuleFormComponent, never>;
15
+ static ɵcmp: i0.ɵɵComponentDeclaration<RuleFormComponent, "ngx-rule-form", never, { "rule": { "alias": "rule"; "required": false; }; }, { "save": "save"; "cancel": "cancel"; }, never, never, true, never>;
16
+ }
@@ -0,0 +1,19 @@
1
+ import { InjectionToken } from '@angular/core';
2
+ import type { NestedTabConfig } from '@dynamic-entity/core';
3
+ import { BuilderStore } from '../builder-store.service';
4
+ import * as i0 from "@angular/core";
5
+ export declare const SYSTEM_DEFAULT_CAN_EDIT: InjectionToken<(roles: string[]) => boolean>;
6
+ /**
7
+ * TabManagerComponent — add / rename / reorder / remove tabs & sub-tabs with systemDefault protection.
8
+ */
9
+ export declare class TabManagerComponent {
10
+ protected readonly store: BuilderStore;
11
+ private readonly canEditSystemDefaultsFn;
12
+ protected lang(): string;
13
+ protected tabLabel(tab: {
14
+ label?: any;
15
+ }): string;
16
+ protected canEditTab(tab: NestedTabConfig): boolean;
17
+ static ɵfac: i0.ɵɵFactoryDeclaration<TabManagerComponent, never>;
18
+ static ɵcmp: i0.ɵɵComponentDeclaration<TabManagerComponent, "ngx-tab-manager", never, {}, {}, never, never, true, never>;
19
+ }
@@ -0,0 +1,42 @@
1
+ import { EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
2
+ import { CdkDragDrop } from '@angular/cdk/drag-drop';
3
+ import { type CommonModuleEntry, type EntityFormConfig, type EntityPermissions } from '@dynamic-entity/core';
4
+ import { BuilderStore } from './builder-store.service';
5
+ import * as i0 from "@angular/core";
6
+ /**
7
+ * EntityBuilderComponent — the top-level visual builder for an EntityFormConfig.
8
+ */
9
+ export declare class EntityBuilderComponent implements OnChanges {
10
+ protected readonly store: BuilderStore;
11
+ /** Existing config to edit. When omitted, the builder starts blank. */
12
+ config?: EntityFormConfig;
13
+ /** Languages available for label/placeholder editing. First entry is the default. */
14
+ languages: string[];
15
+ /** Optional role list — enables multi-select role pickers for RBAC instead of free text. */
16
+ availableRoles: string[];
17
+ /** Optional common-module definitions for module tabs; defaults to the built-in list from core. */
18
+ commonModules: readonly CommonModuleEntry[];
19
+ /** Emitted on every change to the working config. */
20
+ configChange: EventEmitter<EntityFormConfig>;
21
+ /** Emitted when the user clicks Save. Carries a clean, deep-cloned config. */
22
+ save: EventEmitter<EntityFormConfig>;
23
+ protected readonly rbacActions: (keyof EntityPermissions)[];
24
+ constructor();
25
+ ngOnChanges(changes: SimpleChanges): void;
26
+ protected onDrop(event: CdkDragDrop<unknown>): void;
27
+ protected fieldTypeLabel(type: string): string;
28
+ protected fieldTypeIcon(type: string): string;
29
+ protected fieldLabel(field: {
30
+ id: string;
31
+ label?: any;
32
+ }): string;
33
+ protected doSave(): void;
34
+ protected get json(): string;
35
+ protected copyJson(): void;
36
+ protected rolesFor(action: keyof EntityPermissions): readonly string[];
37
+ protected setRoles(action: keyof EntityPermissions, roles: string[]): void;
38
+ /** Parse a comma-separated role string into a trimmed, de-duplicated array. */
39
+ protected setRolesFromText(action: keyof EntityPermissions, text: string): void;
40
+ static ɵfac: i0.ɵɵFactoryDeclaration<EntityBuilderComponent, never>;
41
+ static ɵcmp: i0.ɵɵComponentDeclaration<EntityBuilderComponent, "ngx-entity-builder", never, { "config": { "alias": "config"; "required": false; }; "languages": { "alias": "languages"; "required": false; }; "availableRoles": { "alias": "availableRoles"; "required": false; }; "commonModules": { "alias": "commonModules"; "required": false; }; }, { "configChange": "configChange"; "save": "save"; }, never, ["[ngxBuilderPreview]"], true, never>;
42
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * field-catalog.ts — re-exports shared field catalog from @dynamic-entity/core.
3
+ * Single source of truth shared by both visual builder and renderer.
4
+ */
5
+ export { FIELD_TYPE_CATALOG, getFieldTypeMeta, humanizeId, createFieldConfig, type FieldTypeMeta, type FlagValidator, type ParamValidator, } from '@dynamic-entity/core';
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "ngx-dynamic-entity-builder",
3
+ "version": "1.0.0",
4
+ "description": "Angular 17 standalone visual builder for authoring dynamic-entity EntityConfig (fields, tabs, validators, RBAC).",
5
+ "dependencies": {
6
+ "ngx-dynamic-entity": "*",
7
+ "tslib": "^2.3.0"
8
+ },
9
+ "peerDependencies": {
10
+ "@angular/cdk": "^17.0.0",
11
+ "@angular/common": "^17.0.0",
12
+ "@angular/core": "^17.0.0",
13
+ "@angular/forms": "^17.0.0",
14
+ "@angular/material": "^17.0.0",
15
+ "@dynamic-entity/core": "^1.0.0",
16
+ "ngx-dynamic-entity": "^1.0.0",
17
+ "rxjs": "^7.0.0"
18
+ },
19
+ "keywords": [
20
+ "angular",
21
+ "dynamic-entity",
22
+ "form-builder",
23
+ "config-builder",
24
+ "dynamic-forms",
25
+ "low-code"
26
+ ],
27
+ "license": "MIT",
28
+ "sideEffects": false,
29
+ "module": "fesm2022/ngx-dynamic-entity-builder.mjs",
30
+ "typings": "index.d.ts",
31
+ "exports": {
32
+ "./package.json": {
33
+ "default": "./package.json"
34
+ },
35
+ ".": {
36
+ "types": "./index.d.ts",
37
+ "esm2022": "./esm2022/ngx-dynamic-entity-builder.mjs",
38
+ "esm": "./esm2022/ngx-dynamic-entity-builder.mjs",
39
+ "default": "./fesm2022/ngx-dynamic-entity-builder.mjs"
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,13 @@
1
+ export * from './lib/entity-builder.component';
2
+ export * from './lib/components/field-palette.component';
3
+ export * from './lib/components/field-inspector.component';
4
+ export * from './lib/components/tab-manager.component';
5
+ export * from './lib/components/rule-form.component';
6
+ export * from './lib/components/field-rules-list.component';
7
+ export * from './lib/components/entity-reference-config.component';
8
+ export * from './lib/components/connection-source-config.component';
9
+ export * from './lib/components/entity-builder-canvas.component';
10
+ export * from './lib/components/entity-builder-tree-node.component';
11
+ export * from './lib/builder-store.service';
12
+ export * from './lib/field-catalog';
13
+ export type { EntityFormConfig, NestedTabConfig, NestedFieldConfig, RichFieldType, DropdownOption, EntityPermissions, EntityReferenceConfig, AutoPatchConfig, AutoPatchMapping, PatchOnTrueMapping, FormRule, RuleCondition, RuleAction, RuleOperator, } from '@dynamic-entity/core';