ngx-dynamic-entity 1.0.0 → 1.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.
- package/README.md +129 -139
- package/esm2022/lib/field-types/array-field.component.mjs +112 -104
- package/esm2022/lib/field-types/boolean-field.component.mjs +62 -61
- package/esm2022/lib/field-types/checkbox-field.component.mjs +48 -47
- package/esm2022/lib/field-types/currency-field.component.mjs +54 -53
- package/esm2022/lib/field-types/date-field.component.mjs +46 -45
- package/esm2022/lib/field-types/dropdown-field.component.mjs +89 -87
- package/esm2022/lib/field-types/email-field.component.mjs +64 -63
- package/esm2022/lib/field-types/entity-ref-field.component.mjs +85 -71
- package/esm2022/lib/field-types/field-component.contract.mjs +2 -0
- package/esm2022/lib/field-types/file-field.component.mjs +88 -87
- package/esm2022/lib/field-types/group-field.component.mjs +50 -50
- package/esm2022/lib/field-types/image-field.component.mjs +92 -91
- package/esm2022/lib/field-types/month-year-field.component.mjs +80 -79
- package/esm2022/lib/field-types/multi-select-field.component.mjs +66 -65
- package/esm2022/lib/field-types/number-field.component.mjs +71 -75
- package/esm2022/lib/field-types/password-field.component.mjs +68 -67
- package/esm2022/lib/field-types/radio-field.component.mjs +66 -65
- package/esm2022/lib/field-types/text-field.component.mjs +81 -74
- package/esm2022/lib/field-types/textarea-field.component.mjs +48 -47
- package/esm2022/lib/form/dynamic-field/dynamic-field.component.mjs +53 -6
- package/esm2022/lib/form/dynamic-form.component.mjs +309 -20
- package/esm2022/lib/form/dynamic-record-form.component.mjs +36 -11
- package/esm2022/lib/providers/provide-field-types.mjs +1 -1
- package/esm2022/lib/providers/provide-ngx-dynamic-entity.mjs +8 -2
- package/esm2022/lib/services/cascade-data.service.mjs +2 -2
- package/esm2022/lib/services/entity-ref-cache.mjs +1 -1
- package/esm2022/lib/services/entity-ref-registry.service.mjs +2 -2
- package/esm2022/lib/services/entity-ref-selection.service.mjs +1 -1
- package/esm2022/lib/services/entity-reference.service.mjs +1 -1
- package/esm2022/lib/services/field-registry.service.mjs +1 -1
- package/esm2022/lib/services/file-upload.service.mjs +1 -1
- package/esm2022/lib/services/lookup-registry.service.mjs +2 -2
- package/esm2022/lib/services/rbac.service.mjs +1 -1
- package/esm2022/lib/services/validation-messages.service.mjs +56 -0
- package/esm2022/lib/services/validator-registry.service.mjs +35 -2
- package/esm2022/lib/tokens/injection-tokens.mjs +35 -6
- package/esm2022/public-api.mjs +23 -2
- package/fesm2022/ngx-dynamic-entity.mjs +1754 -1236
- package/fesm2022/ngx-dynamic-entity.mjs.map +1 -1
- package/lib/field-types/array-field.component.d.ts +7 -1
- package/lib/field-types/dropdown-field.component.d.ts +2 -1
- package/lib/field-types/entity-ref-field.component.d.ts +12 -2
- package/lib/field-types/field-component.contract.d.ts +49 -0
- package/lib/field-types/group-field.component.d.ts +1 -1
- package/lib/field-types/multi-select-field.component.d.ts +1 -1
- package/lib/field-types/number-field.component.d.ts +1 -0
- package/lib/field-types/radio-field.component.d.ts +1 -1
- package/lib/field-types/text-field.component.d.ts +10 -2
- package/lib/form/dynamic-field/dynamic-field.component.d.ts +39 -4
- package/lib/form/dynamic-form.component.d.ts +155 -8
- package/lib/form/dynamic-record-form.component.d.ts +13 -2
- package/lib/providers/provide-ngx-dynamic-entity.d.ts +25 -3
- package/lib/services/cascade-data.service.d.ts +1 -1
- package/lib/services/entity-ref-registry.service.d.ts +1 -1
- package/lib/services/lookup-registry.service.d.ts +1 -1
- package/lib/services/validation-messages.service.d.ts +43 -0
- package/lib/services/validator-registry.service.d.ts +13 -1
- package/lib/tokens/injection-tokens.d.ts +42 -7
- package/package.json +17 -18
- package/public-api.d.ts +12 -0
- package/styles.css +579 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ValidatorFn } from '@angular/forms';
|
|
1
|
+
import { AsyncValidatorFn, ValidatorFn } from '@angular/forms';
|
|
2
2
|
import type { FieldValidators } from '@dynamic-entity/core';
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
/**
|
|
@@ -6,6 +6,7 @@ import * as i0 from "@angular/core";
|
|
|
6
6
|
*/
|
|
7
7
|
export declare class ValidatorRegistryService {
|
|
8
8
|
private readonly consumerRegistry;
|
|
9
|
+
private readonly asyncRegistry;
|
|
9
10
|
/**
|
|
10
11
|
* Resolve a validator key string to a ValidatorFn.
|
|
11
12
|
* Supports parameterized built-ins like 'min:0', 'maxLength:255'.
|
|
@@ -15,6 +16,17 @@ export declare class ValidatorRegistryService {
|
|
|
15
16
|
resolveAll(validatorKeys?: string[]): ValidatorFn[];
|
|
16
17
|
/** Resolve a FieldValidators object or string[] into ValidatorFn[] */
|
|
17
18
|
resolveFromConfig(config?: FieldValidators | string[]): ValidatorFn[];
|
|
19
|
+
/**
|
|
20
|
+
* Resolve the async validators a field names, in `validators.customAsync`.
|
|
21
|
+
*
|
|
22
|
+
* Async validators are deliberately a separate registry and a separate config key: Angular
|
|
23
|
+
* attaches them through `setAsyncValidators`, runs them only once the synchronous ones
|
|
24
|
+
* pass, and holds the control in `pending` until they settle. Mixing them into the
|
|
25
|
+
* synchronous list would silently never run them.
|
|
26
|
+
*
|
|
27
|
+
* An unknown name is skipped rather than throwing, matching the synchronous behaviour.
|
|
28
|
+
*/
|
|
29
|
+
resolveAsyncFromConfig(config?: FieldValidators | string[]): AsyncValidatorFn[];
|
|
18
30
|
static ɵfac: i0.ɵɵFactoryDeclaration<ValidatorRegistryService, never>;
|
|
19
31
|
static ɵprov: i0.ɵɵInjectableDeclaration<ValidatorRegistryService>;
|
|
20
32
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { InjectionToken } from '@angular/core';
|
|
2
2
|
import type { Type } from '@angular/core';
|
|
3
|
-
import type { CommonModuleEntry, EntityReferenceLoader, FileUploadHandler, LookupListSource } from '@dynamic-entity/core';
|
|
4
3
|
import { type EntityRefCacheStore } from '../services/entity-ref-cache';
|
|
5
|
-
/** Roles that see XXXXXXXXX for masked fields
|
|
4
|
+
/** Roles that see XXXXXXXXX for masked fields. Presentational only — enforce authz server-side. */
|
|
6
5
|
export declare const MASKED_ROLES: InjectionToken<string[]>;
|
|
7
6
|
/**
|
|
8
7
|
* Consumer **overrides**: fieldType string → Angular component class.
|
|
@@ -43,10 +42,50 @@ export declare const ENTITY_REF_REGISTRY: InjectionToken<Map<string, EntityRefer
|
|
|
43
42
|
* })
|
|
44
43
|
*/
|
|
45
44
|
export declare const LOOKUP_REGISTRY: InjectionToken<Map<string, LookupListSource>>;
|
|
45
|
+
/**
|
|
46
|
+
* Ordered steps that move a saved record forward when a config's `version` increases.
|
|
47
|
+
*
|
|
48
|
+
* Without these, `EntityFormConfig.version` and `VersionedRecord._configVersion` are
|
|
49
|
+
* declarations nothing acts on: a schema can be edited freely while records keep their old
|
|
50
|
+
* shape, and nothing reconciles the two. Registering migrations makes the version numbers
|
|
51
|
+
* mean something.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* provideNgxDynamicEntity({
|
|
55
|
+
* migrations: [
|
|
56
|
+
* { from: 1, to: 2, description: 'split name', migrate: r => ({ ...r, firstName: r['name'] }) },
|
|
57
|
+
* ],
|
|
58
|
+
* })
|
|
59
|
+
*/
|
|
60
|
+
export declare const RECORD_MIGRATIONS: InjectionToken<RecordMigration[]>;
|
|
61
|
+
/**
|
|
62
|
+
* Overrides for the messages shown under an invalid field, keyed by Angular error key
|
|
63
|
+
* (`required`, `minlength`, `pattern`, …) plus a few field-specific keys.
|
|
64
|
+
*
|
|
65
|
+
* The built-in messages are English literals. Registering here is what makes a non-English
|
|
66
|
+
* form possible without re-implementing every field component; unlisted keys keep their
|
|
67
|
+
* default, so overriding one does not mean supplying them all.
|
|
68
|
+
*/
|
|
69
|
+
export declare const VALIDATION_MESSAGES: InjectionToken<Record<string, any>>;
|
|
46
70
|
/** Registry: validator key → ValidatorFn */
|
|
47
71
|
export declare const VALIDATOR_REGISTRY: InjectionToken<Map<string, any>>;
|
|
72
|
+
/**
|
|
73
|
+
* Registry: validator key → AsyncValidatorFn.
|
|
74
|
+
*
|
|
75
|
+
* Kept separate from VALIDATOR_REGISTRY because Angular applies the two differently: an async
|
|
76
|
+
* validator runs only once the synchronous ones pass, and puts the control into `pending`
|
|
77
|
+
* while it does. Name them from a schema with `validators: { customAsync: ['uniqueEmail'] }`.
|
|
78
|
+
*/
|
|
79
|
+
export declare const ASYNC_VALIDATOR_REGISTRY: InjectionToken<Map<string, any>>;
|
|
80
|
+
/**
|
|
81
|
+
* A registered hook: receives the payload, returns it (or a replacement), sync or async.
|
|
82
|
+
*
|
|
83
|
+
* Spelled out rather than typed as `Function`, which accepts class declarations and any
|
|
84
|
+
* arity and gives a consumer no signature to write against.
|
|
85
|
+
*/
|
|
86
|
+
export type HookFn = (data: any, context?: unknown) => unknown | Promise<unknown>;
|
|
48
87
|
/** Registry: hook key → async (data, context) => data */
|
|
49
|
-
export declare const HOOK_REGISTRY: InjectionToken<Map<string,
|
|
88
|
+
export declare const HOOK_REGISTRY: InjectionToken<Map<string, HookFn>>;
|
|
50
89
|
/**
|
|
51
90
|
* Consumer-registered list of common module tabs (documents, audit, tasks, etc.).
|
|
52
91
|
* The library ships no built-in implementations. Consumers provide their own list
|
|
@@ -82,10 +121,6 @@ export declare const UPLOAD_HANDLER: InjectionToken<FileUploadHandler>;
|
|
|
82
121
|
* { provide: ENTITY_REF_CACHE_STORE, useClass: SessionStorageRefCache }
|
|
83
122
|
*/
|
|
84
123
|
export declare const ENTITY_REF_CACHE_STORE: InjectionToken<EntityRefCacheStore>;
|
|
85
|
-
/**
|
|
86
|
-
* Consumer-provided predicate function to check whether user roles can edit system default tabs or fields.
|
|
87
|
-
* Defaults to allowing edits if not provided.
|
|
88
|
-
*/
|
|
89
124
|
/**
|
|
90
125
|
* Consumer-provided predicate function to check whether user roles can edit system default tabs or fields.
|
|
91
126
|
* Defaults to allowing edits if not provided.
|
package/package.json
CHANGED
|
@@ -1,35 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ngx-dynamic-entity",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Angular
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Angular standalone UI library for rendering dynamic entity forms.",
|
|
5
|
+
"//typings": "Local workspace resolution only: ng-packagr overwrites this with the correct in-tarball path ('index.d.ts') when generating dist/package.json. Do NOT add a 'main' field here — ng-packagr does not generate one, so it would be copied verbatim and resolve to dist/dist/... in the published package.",
|
|
5
6
|
"typings": "index.d.ts",
|
|
6
|
-
"main": "./dist/fesm2022/ngx-dynamic-entity.mjs",
|
|
7
7
|
"peerDependencies": {
|
|
8
|
-
"@angular/
|
|
9
|
-
"@angular/
|
|
10
|
-
"@angular/
|
|
11
|
-
"@
|
|
12
|
-
"@angular/material": "^17.0.0",
|
|
13
|
-
"@dynamic-entity/core": "^1.0.0",
|
|
8
|
+
"@angular/common": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
|
|
9
|
+
"@angular/core": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
|
|
10
|
+
"@angular/forms": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
|
|
11
|
+
"@dynamic-entity/core": "^1.2.0",
|
|
14
12
|
"rxjs": "^7.0.0"
|
|
15
13
|
},
|
|
16
|
-
"peerDependenciesMeta": {
|
|
17
|
-
"@angular/cdk": {
|
|
18
|
-
"optional": true
|
|
19
|
-
},
|
|
20
|
-
"@angular/material": {
|
|
21
|
-
"optional": true
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
14
|
"keywords": [
|
|
25
15
|
"angular",
|
|
26
16
|
"dynamic-entity",
|
|
27
17
|
"dynamic-forms",
|
|
28
|
-
"dynamic-table",
|
|
29
18
|
"rbac"
|
|
30
19
|
],
|
|
31
20
|
"license": "MIT",
|
|
32
21
|
"sideEffects": false,
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/berserker5619/Dynamic-Entity.git",
|
|
25
|
+
"directory": "packages/ngx-dynamic-entity"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/berserker5619/Dynamic-Entity/tree/main/packages/ngx-dynamic-entity#readme",
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/berserker5619/Dynamic-Entity/issues"
|
|
30
|
+
},
|
|
31
|
+
"author": "Nizamudeen",
|
|
33
32
|
"module": "fesm2022/ngx-dynamic-entity.mjs",
|
|
34
33
|
"exports": {
|
|
35
34
|
"./package.json": {
|
package/public-api.d.ts
CHANGED
|
@@ -13,16 +13,28 @@ export * from './lib/services/lookup-registry.service';
|
|
|
13
13
|
export * from './lib/services/rbac.service';
|
|
14
14
|
export * from './lib/services/rules-evaluation.service';
|
|
15
15
|
export * from './lib/services/config-source.service';
|
|
16
|
+
export * from './lib/services/validation-messages.service';
|
|
16
17
|
export * from './lib/form/dynamic-form.component';
|
|
17
18
|
export * from './lib/form/dynamic-record-form.component';
|
|
18
19
|
export * from './lib/form/dynamic-field/dynamic-field.component';
|
|
20
|
+
export * from './lib/field-types/field-component.contract';
|
|
19
21
|
export * from './lib/field-types/text-field.component';
|
|
20
22
|
export * from './lib/field-types/textarea-field.component';
|
|
21
23
|
export * from './lib/field-types/number-field.component';
|
|
24
|
+
export * from './lib/field-types/currency-field.component';
|
|
25
|
+
export * from './lib/field-types/email-field.component';
|
|
26
|
+
export * from './lib/field-types/password-field.component';
|
|
22
27
|
export * from './lib/field-types/checkbox-field.component';
|
|
28
|
+
export * from './lib/field-types/boolean-field.component';
|
|
23
29
|
export * from './lib/field-types/date-field.component';
|
|
30
|
+
export * from './lib/field-types/month-year-field.component';
|
|
24
31
|
export * from './lib/field-types/dropdown-field.component';
|
|
32
|
+
export * from './lib/field-types/radio-field.component';
|
|
25
33
|
export * from './lib/field-types/multi-select-field.component';
|
|
26
34
|
export * from './lib/field-types/entity-ref-field.component';
|
|
35
|
+
export * from './lib/field-types/group-field.component';
|
|
36
|
+
export * from './lib/field-types/array-field.component';
|
|
37
|
+
export * from './lib/field-types/image-field.component';
|
|
38
|
+
export * from './lib/field-types/file-field.component';
|
|
27
39
|
export { resolveLabel, resolveOptionLabel, resolveOptionValue, formatDisplayValue, valuesMatch, normalizeOption, normalizeConfig, } from '@dynamic-entity/core';
|
|
28
40
|
export type { EntityFormConfig, NestedTabConfig, NestedFieldConfig, FieldTableConfig, RichFieldType, LocalizedText, DropdownOption, VersionedRecord, EntityPermissions, RbacContext, FieldValidators, EntityReferenceConfig, EntityReferenceLoader, ReferenceOption, ReferenceLoaderContext, AutoPatchConfig, PatchOnTrueMapping, FileRef, FormRule, RuleCondition, RuleAction, RuleEvaluationResult, CommonModuleEntry, } from '@dynamic-entity/core';
|