ngx-dynamic-entity-builder 1.14.0 → 2.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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ngx-dynamic-entity-builder",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Angular standalone visual builder for authoring dynamic-entity EntityConfig (fields, tabs, validators, RBAC).",
|
|
5
5
|
"//typings": "Local workspace resolution only: ng-packagr 21 writes types/ngx-dynamic-entity-builder.d.ts into dist/package.json. Do NOT add a 'main' field here — ng-packagr does not generate one, so it would be copied verbatim and resolve wrongly in the published package.",
|
|
6
6
|
"typings": "types/ngx-dynamic-entity-builder.d.ts",
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"@angular/core": "^17.2.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
|
|
11
11
|
"@angular/forms": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
|
|
12
12
|
"@angular/material": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
|
|
13
|
-
"@dynamic-entity/core": "^
|
|
14
|
-
"ngx-dynamic-entity": "^
|
|
13
|
+
"@dynamic-entity/core": "^2.0.0",
|
|
14
|
+
"ngx-dynamic-entity": "^2.0.0",
|
|
15
15
|
"rxjs": "^7.0.0"
|
|
16
16
|
},
|
|
17
17
|
"keywords": [
|
|
@@ -73,6 +73,8 @@ declare class BuilderStore {
|
|
|
73
73
|
* removing or moving anything always earns its own step however fast it is clicked.
|
|
74
74
|
*/
|
|
75
75
|
private record;
|
|
76
|
+
/** How many undo steps are kept. */
|
|
77
|
+
private static readonly MAX_HISTORY;
|
|
76
78
|
/** Counts that distinguish a structural edit from a value edit. */
|
|
77
79
|
private shapeOf;
|
|
78
80
|
/** Start history again from the state just loaded. Nothing before it is undoable. */
|
|
@@ -113,7 +115,7 @@ declare class BuilderStore {
|
|
|
113
115
|
readonly problems: _angular_core.Signal<BuilderProblem[]>;
|
|
114
116
|
readonly errors: _angular_core.Signal<BuilderProblem[]>;
|
|
115
117
|
readonly isValid: _angular_core.Signal<boolean>;
|
|
116
|
-
load(config: EntityFormConfig): void;
|
|
118
|
+
load(config: EntityFormConfig, rules?: readonly FormRule[]): void;
|
|
117
119
|
reset(entity?: string): void;
|
|
118
120
|
resetDirty(): void;
|
|
119
121
|
private emptyConfig;
|
|
@@ -274,6 +276,30 @@ declare class BuilderStore {
|
|
|
274
276
|
/** Scan all referenced fields in the config and update their hasDrift state against current source configs. */
|
|
275
277
|
checkDrift(sourceConfigs: Record<string, EntityFormConfig>): void;
|
|
276
278
|
addOption(fieldId: string): void;
|
|
279
|
+
/**
|
|
280
|
+
* A key for a new option: the label slugified, made unique within its own field.
|
|
281
|
+
*
|
|
282
|
+
* Unique within the field and nowhere wider, because that is the scope the key has to
|
|
283
|
+
* distinguish within — two fields may both offer "Active" and they are the same value.
|
|
284
|
+
* A label that slugifies to nothing (punctuation, a script `labelToId` strips) falls back
|
|
285
|
+
* to a positional name rather than an empty key, which `optionKeyOf` would ignore.
|
|
286
|
+
*/
|
|
287
|
+
private mintOptionKey;
|
|
288
|
+
/**
|
|
289
|
+
* Give every option in the config a key, leaving the ones that already have one alone.
|
|
290
|
+
*
|
|
291
|
+
* The counterpart to `optionKeyMigration` in core: that one keys stored *records* against
|
|
292
|
+
* a keyed config, this one keys the config. Run this first, then ship the migration — the
|
|
293
|
+
* other order leaves the migration with no keys to attach.
|
|
294
|
+
*
|
|
295
|
+
* Existing keys are never rewritten, so this is safe to run again on a config that is
|
|
296
|
+
* already half-keyed, which is what happens as options are added to an older schema.
|
|
297
|
+
*/
|
|
298
|
+
assignOptionKeys(): void;
|
|
299
|
+
/** Whether any option in the config is still without a key — gates the action in the UI. */
|
|
300
|
+
readonly hasUnkeyedOptions: _angular_core.Signal<boolean>;
|
|
301
|
+
/** An option's stable key, for the inspector to show read-only. */
|
|
302
|
+
optionKey(option: DropdownOption): string;
|
|
277
303
|
/** Merge language keys into an option. `setOptionLabel` is the usual single-language path. */
|
|
278
304
|
updateOption(fieldId: string, index: number, patch: DropdownOption): void;
|
|
279
305
|
/**
|
|
@@ -306,6 +332,11 @@ declare class BuilderStore {
|
|
|
306
332
|
* had lost its rules.
|
|
307
333
|
*/
|
|
308
334
|
readonly rulesForSelectedField: _angular_core.Signal<FormRule[]>;
|
|
335
|
+
/**
|
|
336
|
+
* Replace the rules without touching the config — for a host whose rules changed on their
|
|
337
|
+
* own. It records a step, because from the author's side it is an edit. Loading a config
|
|
338
|
+
* passes its rules to `load` instead, so the pair arrives as one snapshot.
|
|
339
|
+
*/
|
|
309
340
|
loadRules(rules: FormRule[]): void;
|
|
310
341
|
addRule(rule: FormRule): string;
|
|
311
342
|
updateRule(id: string, patch: Partial<FormRule>): void;
|
|
@@ -481,6 +512,9 @@ declare const DEFAULT_BUILDER_TEXT: {
|
|
|
481
512
|
optionInLanguage: string;
|
|
482
513
|
removeOption: string;
|
|
483
514
|
noOptionsYet: string;
|
|
515
|
+
optionKey: string;
|
|
516
|
+
optionKeyHint: string;
|
|
517
|
+
assignOptionKeys: string;
|
|
484
518
|
display: string;
|
|
485
519
|
visible: string;
|
|
486
520
|
tableColumn: string;
|
|
@@ -631,6 +665,15 @@ declare class EntityBuilderComponent implements OnChanges {
|
|
|
631
665
|
private readonly hostRef;
|
|
632
666
|
/** Existing config to edit. When omitted, the builder starts blank. */
|
|
633
667
|
config?: EntityFormConfig;
|
|
668
|
+
/**
|
|
669
|
+
* The rules that belong with `config`.
|
|
670
|
+
*
|
|
671
|
+
* Rules live beside a config rather than inside it — that is the shape the renderer takes
|
|
672
|
+
* them in, and the shape a host stores them in. Without this input, loading a config for
|
|
673
|
+
* editing silently dropped every rule already authored against it: the builder opened on
|
|
674
|
+
* the right fields with an empty rules list, and saving put that emptiness back.
|
|
675
|
+
*/
|
|
676
|
+
rules?: FormRule[];
|
|
634
677
|
/** Languages available for label/placeholder editing. First entry is the default. */
|
|
635
678
|
languages: string[];
|
|
636
679
|
/**
|
|
@@ -653,6 +696,21 @@ declare class EntityBuilderComponent implements OnChanges {
|
|
|
653
696
|
commonModules: readonly CommonModuleEntry[];
|
|
654
697
|
/** Emitted on every change to the working config. */
|
|
655
698
|
configChange: EventEmitter<EntityFormConfig>;
|
|
699
|
+
/**
|
|
700
|
+
* Emitted on every change to the working rules — the mirror of `configChange`.
|
|
701
|
+
*
|
|
702
|
+
* Without it a rule authored here could not leave this component. `BuilderStore` is
|
|
703
|
+
* provided by the component, so its instance is private to this injector, and `save`
|
|
704
|
+
* carries an `EntityFormConfig` alone. The builder could author a rule and hand it to
|
|
705
|
+
* nobody: a host had no supported way to persist one, and therefore no way to pass it
|
|
706
|
+
* back to the renderer as `[rules]`.
|
|
707
|
+
*
|
|
708
|
+
* A host that persists on Save keeps the latest emission and writes it alongside the
|
|
709
|
+
* config `save` carries — the same pairing `configChange`/`save` already implies, and the
|
|
710
|
+
* pairing the undo history has always stored, because undoing a field rename without the
|
|
711
|
+
* rule that follows it would leave the rule pointing at a field that no longer exists.
|
|
712
|
+
*/
|
|
713
|
+
rulesChange: EventEmitter<FormRule[]>;
|
|
656
714
|
/** Emitted when the user clicks Save. Carries a clean, deep-cloned config. */
|
|
657
715
|
save: EventEmitter<EntityFormConfig>;
|
|
658
716
|
protected readonly rbacActions: readonly RbacAction[];
|
|
@@ -699,7 +757,7 @@ declare class EntityBuilderComponent implements OnChanges {
|
|
|
699
757
|
/** Parse a comma-separated role string into a trimmed, de-duplicated array. */
|
|
700
758
|
protected setRolesFromText(action: RbacAction, text: string): void;
|
|
701
759
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<EntityBuilderComponent, never>;
|
|
702
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<EntityBuilderComponent, "ngx-entity-builder", never, { "config": { "alias": "config"; "required": false; }; "languages": { "alias": "languages"; "required": false; }; "uiLanguage": { "alias": "uiLanguage"; "required": false; }; "availableRoles": { "alias": "availableRoles"; "required": false; }; "userRoles": { "alias": "userRoles"; "required": false; }; "commonModules": { "alias": "commonModules"; "required": false; }; "leftSidebarOpen": { "alias": "leftSidebarOpen"; "required": false; "isSignal": true; }; "rightSidebarOpen": { "alias": "rightSidebarOpen"; "required": false; "isSignal": true; }; "fieldsOpen": { "alias": "fieldsOpen"; "required": false; "isSignal": true; }; "previewOpen": { "alias": "previewOpen"; "required": false; "isSignal": true; }; }, { "configChange": "configChange"; "save": "save"; "leftSidebarOpen": "leftSidebarOpenChange"; "rightSidebarOpen": "rightSidebarOpenChange"; "fieldsOpen": "fieldsOpenChange"; "previewOpen": "previewOpenChange"; }, never, ["[ngxBuilderPreview]"], true, never>;
|
|
760
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<EntityBuilderComponent, "ngx-entity-builder", never, { "config": { "alias": "config"; "required": false; }; "rules": { "alias": "rules"; "required": false; }; "languages": { "alias": "languages"; "required": false; }; "uiLanguage": { "alias": "uiLanguage"; "required": false; }; "availableRoles": { "alias": "availableRoles"; "required": false; }; "userRoles": { "alias": "userRoles"; "required": false; }; "commonModules": { "alias": "commonModules"; "required": false; }; "leftSidebarOpen": { "alias": "leftSidebarOpen"; "required": false; "isSignal": true; }; "rightSidebarOpen": { "alias": "rightSidebarOpen"; "required": false; "isSignal": true; }; "fieldsOpen": { "alias": "fieldsOpen"; "required": false; "isSignal": true; }; "previewOpen": { "alias": "previewOpen"; "required": false; "isSignal": true; }; }, { "configChange": "configChange"; "rulesChange": "rulesChange"; "save": "save"; "leftSidebarOpen": "leftSidebarOpenChange"; "rightSidebarOpen": "rightSidebarOpenChange"; "fieldsOpen": "fieldsOpenChange"; "previewOpen": "previewOpenChange"; }, never, ["[ngxBuilderPreview]"], true, never>;
|
|
703
761
|
}
|
|
704
762
|
|
|
705
763
|
/**
|