@praxisui/dynamic-form 9.0.0-beta.22 → 9.0.0-beta.25

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": "@praxisui/dynamic-form",
3
- "version": "9.0.0-beta.22",
3
+ "version": "9.0.0-beta.25",
4
4
  "description": "Angular dynamic form engine for Praxis UI: metadata-driven forms, hooks, and services integrating @praxisui/* packages.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
@@ -9,13 +9,13 @@
9
9
  "@angular/forms": "^21.0.0",
10
10
  "@angular/material": "^21.0.0",
11
11
  "@angular/router": "^21.0.0",
12
- "@praxisui/ai": "^9.0.0-beta.22",
13
- "@praxisui/dynamic-fields": "^9.0.0-beta.22",
14
- "@praxisui/metadata-editor": "^9.0.0-beta.22",
15
- "@praxisui/rich-content": "^9.0.0-beta.22",
16
- "@praxisui/settings-panel": "^9.0.0-beta.22",
17
- "@praxisui/visual-builder": "^9.0.0-beta.22",
18
- "@praxisui/core": "^9.0.0-beta.22",
12
+ "@praxisui/ai": "^9.0.0-beta.25",
13
+ "@praxisui/dynamic-fields": "^9.0.0-beta.25",
14
+ "@praxisui/metadata-editor": "^9.0.0-beta.25",
15
+ "@praxisui/rich-content": "^9.0.0-beta.25",
16
+ "@praxisui/settings-panel": "^9.0.0-beta.25",
17
+ "@praxisui/visual-builder": "^9.0.0-beta.25",
18
+ "@praxisui/core": "^9.0.0-beta.25",
19
19
  "rxjs": "^7.8.0"
20
20
  },
21
21
  "dependencies": {
@@ -132,6 +132,7 @@ Essa fronteira preserva a premissa de plataforma: o formulario materializa e exp
132
132
  | `formRulesState` | not-specified | not-specified | n/a | Active | Persistido para round-trip do builder visual. |
133
133
  | `hooks` | not-specified | not-specified | n/a | Active | Integracao de ciclo (before/after) via runtime de hooks. |
134
134
  | `hints` | not-specified | not-specified | n/a | Declared-only | Mantido no contrato/editor; sem render dedicado no template principal. |
135
+ | `helpPresentation` | `FormHelpPresentationConfig` | No | `{ display: "inline" }` | Active | Politica visual para exibir `hint`/`helpText` dos campos sem alterar semantica dos DTOs; erros de validacao continuam inline. |
135
136
  | `fieldMetadata[].array` | `FieldArrayConfig` | No | n/a | Active | Contrato de Editable Collection apenas quando `fieldMetadata[].controlType === "array"` ou quando `x-ui.array` foi publicado explicitamente. |
136
137
 
137
138
  Nota editorial:
@@ -577,6 +578,7 @@ No ecossistema Praxis, ele funciona tanto como runtime final quanto como superfi
577
578
  | `componentInstanceId` | `string \| undefined` | `undefined` | Active | Isola instancias com mesmo `formId`. |
578
579
  | `layout` | `FormLayout \| undefined` | `undefined` | Partial | Funciona como override estrutural em parte dos fluxos de layout/editor. |
579
580
  | `generatedLayoutPreset` | `'default' \| 'compactPresentation'` | `'default'` | Active | Usado apenas ao criar a configuracao inicial a partir de schema/metadata; nao reprocessa layouts persistidos ou authorados. |
581
+ | `layoutPolicy` | `DynamicFormLayoutPolicy \| null` | `null` | Active | Politica opt-in para materializar layout a partir do schema atual. Use `source: 'schema'` com `persistence: 'transient'` para detalhe/read-only e command forms schema-driven sem persistir `sections` geradas. Em `mode='view'`, `intent: 'detail'` ou `preset: 'compactPresentation'` ativa apresentacao quando `presentationModeGlobal` nao foi informado; use `[presentationModeGlobal]=false` para controles read-only tradicionais. No preset `compactPresentation`, `x-ui.width` explicito empacota campos em linhas de 12 colunas; campos sem width permanecem full-width. `schemaType` e `schemaOperation` sao validados contra `schemaUrl` quando a URL declara esses parametros. |
580
582
  | `backConfig` | `BackConfig \| undefined` | `undefined` | Active | Integra retorno/navegacao no painel de configuracao; `confirmOnDirty` tem precedencia sobre `behavior.confirmOnUnsavedChanges` no cancel. |
581
583
  | `hooks` | `FormHooksLayout \| undefined` | `undefined` | Active | Override direto de hooks sobre `config.hooks`. |
582
584
  | `customEndpoints` | `EndpointConfig` | `{}` | Active | Override de endpoints no CRUD service interno. |
@@ -589,8 +591,28 @@ No ecossistema Praxis, ele funciona tanto como runtime final quanto como superfi
589
591
  | `readonlyModeGlobal` | `boolean \| null` | `null` | Active | Estado global de leitura propagado para loader. |
590
592
  | `disabledModeGlobal` | `boolean \| null` | `null` | Active | Estado global de desabilitado propagado para loader. |
591
593
  | `presentationModeGlobal` | `boolean \| null` | `null` | Active | Modo apresentacao global (efetivo em `view`). |
594
+ | `fieldIconPolicy` | `'all' \| 'presentation-only' \| 'none'` | `'all'` | Active | Controla icones `prefixIcon`/`suffixIcon` vindos da metadata dos campos. `all` preserva o comportamento atual; `presentation-only` mantem icones decorativos no modo apresentacao e oculta os slots de icone em controles input/read-only tradicionais; `none` oculta esses slots em todos os modos. |
592
595
  | `visibleGlobal` | `boolean \| null` | `null` | Active | Visibilidade global propagada para loader. |
593
596
 
597
+ #### Migration baseline for ErgonX-style screens
598
+
599
+ For enterprise migrations that must become templates for many screens, `layoutPolicy`,
600
+ `helpPresentation` and `fieldIconPolicy` should be selected as part of the DTO/schema
601
+ handoff, not patched locally after visual review.
602
+
603
+ Recommended baseline:
604
+
605
+ | Surface | Inputs | Contract gate |
606
+ | --- | --- | --- |
607
+ | Detail/read-only | `layoutPolicy.source='schema'`, `intent='detail'`, `preset='compactPresentation'`, `persistence='transient'`, `schemaType='response'` | Response DTO publishes business grouping, order, labels, value presentation and safe widths. |
608
+ | Create/edit | `layoutPolicy.source='schema'`, `intent='command'`, `preset='groupedCommand'`, `persistence='transient'`, `schemaType='request'` | Request DTO/write contract publishes only editable fields, validators, options and help text required for the command. |
609
+ | Dense command drawer | `config.helpPresentation.display='auto'` with `preferPopoverForControls` for select, checkbox, toggle, date/datepickers and numeric controls | DTO help text is semantic and not a substitute for validation messages. |
610
+ | Input-heavy operational form | `fieldIconPolicy='presentation-only'` | Icons remain useful in read-only presentation but do not crowd editable controls. |
611
+
612
+ If a field requires a local label, local help text, local option mapping or local code/description
613
+ composition to look correct, the schema is not ready for scalable migration. Fix the backend DTO,
614
+ OpenAPI `x-ui` metadata or option/value-presentation contract first.
615
+
594
616
  #### Regras compartilhadas materializadas
595
617
 
596
618
  `domainRules` separa regra corporativa compartilhavel de regra materializada no `FormConfig`. Quando habilitado, o componente consulta o backend de configuracao via `DomainRuleFormRulesService`, transforma cada materializacao em `FormLayoutRule` e aplica a lista combinada:
@@ -7,7 +7,7 @@ import { MatDialog } from '@angular/material/dialog';
7
7
  import { MatSnackBar } from '@angular/material/snack-bar';
8
8
  import { CdkDragStart, CdkDragMove, CdkDragEnd, CdkDragDrop } from '@angular/cdk/drag-drop';
9
9
  import * as _praxisui_core from '@praxisui/core';
10
- import { AsyncConfigStorage, FormLayout, FieldMetadata, FormLayoutRule, FormRuleTargetType as FormRuleTargetType$1, PraxisJsonLogicService, FormSection, FormRow, FormColumn, FormConfig, FormLayoutItem, FormActionButton, AiCapability, BackConfig, RichBlockHostCapabilities, ApiEndpoint, ApiUrlEntry, FormHooksLayout, EndpointConfig, FormSubmitEvent, FormReadyEvent, FormValueChangeEvent, SyncResult, FormInitializationError, LoadingState, FormCustomActionEvent, FormActionConfirmationEvent, RichContentDocument, JsonLogicRecord, GenericCrudService, ConnectionStorage, DynamicFormService, ErrorMessageService, SchemaNormalizerService, ComponentMetadataRegistry, GlobalConfigService, ComponentKeyService, LoadingOrchestrator, ApiUrlConfig, PraxisLoadingRenderer, FormHooksRegistry, FormHookPreset, LoggerService, FormSectionHeaderAction, FormSectionHeaderConfig, FormConfigState, JsonLogicExpression, GlobalActionCatalogEntry, PraxisRuntimeConditionalEffectRule, PraxisRuntimeGlobalActionEffect, SurfaceOpenPayload, GlobalActionField, PraxisEffectPolicy, FieldDefinition, ComponentDocMeta, Breakpoint, DomainRuleRequestOptions, DomainRuleService, DomainRuleMaterialization, IconPickerService, GlobalActionRef, AiCapabilityCategory, AiCapabilityCatalog, AiValueKind, ComponentAuthoringManifest } from '@praxisui/core';
10
+ import { AsyncConfigStorage, FormLayout, FieldMetadata, FormLayoutRule, FormRuleTargetType as FormRuleTargetType$1, PraxisJsonLogicService, FormSection, FormRow, FormColumn, FormConfig, FormLayoutItem, FormActionButton, AiCapability, BackConfig, RichBlockHostCapabilities, ApiEndpoint, ApiUrlEntry, DynamicFormLayoutPolicy, FormHooksLayout, EndpointConfig, FormSubmitEvent, FormReadyEvent, FormValueChangeEvent, SyncResult, FormInitializationError, LoadingState, FormCustomActionEvent, FormActionConfirmationEvent, RichContentDocument, JsonLogicRecord, GenericCrudService, ConnectionStorage, DynamicFormService, ErrorMessageService, SchemaNormalizerService, ComponentMetadataRegistry, GlobalConfigService, ComponentKeyService, LoadingOrchestrator, ApiUrlConfig, PraxisLoadingRenderer, FormHooksRegistry, FormHookPreset, LoggerService, FormSectionHeaderAction, FormSectionHeaderConfig, FormConfigState, JsonLogicExpression, FormHelpPresentationConfig, GlobalActionCatalogEntry, PraxisRuntimeConditionalEffectRule, PraxisRuntimeGlobalActionEffect, SurfaceOpenPayload, GlobalActionField, PraxisEffectPolicy, FieldDefinition, ComponentDocMeta, Breakpoint, DomainRuleRequestOptions, DomainRuleService, DomainRuleMaterialization, TableConfig, IconPickerService, GlobalActionRef, AiCapabilityCategory, AiCapabilityCatalog, AiValueKind, ComponentAuthoringManifest } from '@praxisui/core';
11
11
  import * as rxjs from 'rxjs';
12
12
  import { Observable, BehaviorSubject } from 'rxjs';
13
13
  import { SettingsPanelService, SettingsValueProvider } from '@praxisui/settings-panel';
@@ -206,6 +206,7 @@ interface GenerateFormConfigFromMetadataOptions {
206
206
  fieldsPerRow?: number;
207
207
  defaultSectionTitle?: string;
208
208
  layoutPreset?: DynamicFormGeneratedLayoutPreset;
209
+ presentationRoleMap?: Record<string, string>;
209
210
  }
210
211
  declare class DynamicFormLayoutService {
211
212
  private readonly changesSubject;
@@ -227,6 +228,10 @@ declare class DynamicFormLayoutService {
227
228
  private inferCompactPresentationSpan;
228
229
  private clampGridSpan;
229
230
  private resolveGroupOrder;
231
+ private withCompactPresentationFieldDefaults;
232
+ private resolveFieldPresentationRole;
233
+ private resolvePresentationRole;
234
+ private normalizePresentationRole;
230
235
  private genId;
231
236
  private capitalizeFirstLetter;
232
237
  private assertIndex;
@@ -768,6 +773,8 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
768
773
  layout?: FormLayout;
769
774
  /** Metadata-driven layout preset used only when creating an initial config from schema. */
770
775
  generatedLayoutPreset: DynamicFormGeneratedLayoutPreset;
776
+ /** Opt-in policy for schema-driven transient layout materialization. */
777
+ layoutPolicy?: DynamicFormLayoutPolicy | null;
771
778
  /** Optional navigation back config (from CRUD host) */
772
779
  backConfig?: BackConfig;
773
780
  /** Optional direct hooks declaration for testing/demo (overrides config.hooks) */
@@ -797,6 +804,7 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
797
804
  get invalidRequiredFieldLabels(): string[];
798
805
  /** Value propagated to DynamicFieldLoader; null allows per-field metadata */
799
806
  get presentationForLoader(): boolean | null;
807
+ getRenderableFieldsForLoader(fields: FieldMetadata[]): FieldMetadata[];
800
808
  /** Custom endpoints for CRUD operations */
801
809
  private _customEndpoints;
802
810
  get customEndpoints(): EndpointConfig;
@@ -992,6 +1000,10 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
992
1000
  private persistFormConfig;
993
1001
  private createDefaultConfig;
994
1002
  private createConfigFromHostConfig;
1003
+ private shouldUseSchemaLayoutPolicy;
1004
+ private layoutPolicyRequestsPresentation;
1005
+ private shouldPersistGeneratedConfig;
1006
+ private createSchemaMaterializedConfig;
995
1007
  private reconcileLoadedConfigWithServerSchema;
996
1008
  private hostConfigHasAuthoredLocalFieldsNotInLocalConfig;
997
1009
  private syncWithServer;
@@ -1147,6 +1159,7 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
1147
1159
  private _showConfirmationDialog;
1148
1160
  onFormAction(event: PraxisFormActionEvent): void;
1149
1161
  private dispatchRichContentAction;
1162
+ private emitRichContentCustomAction;
1150
1163
  private isRichContentActionAvailable;
1151
1164
  private hasRichContentCapability;
1152
1165
  private buildRichContentActionContext;
@@ -1349,7 +1362,7 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
1349
1362
  private applyPresentationVars;
1350
1363
  private applyPresentationConfig;
1351
1364
  static ɵfac: i0.ɵɵFactoryDeclaration<PraxisDynamicForm, [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }]>;
1352
- static ɵcmp: i0.ɵɵComponentDeclaration<PraxisDynamicForm, "praxis-dynamic-form", never, { "resourcePath": { "alias": "resourcePath"; "required": false; }; "resourceId": { "alias": "resourceId"; "required": false; }; "initialValue": { "alias": "initialValue"; "required": false; }; "editorialContext": { "alias": "editorialContext"; "required": false; }; "mode": { "alias": "mode"; "required": false; }; "config": { "alias": "config"; "required": false; }; "actions": { "alias": "actions"; "required": false; }; "schemaSource": { "alias": "schemaSource"; "required": false; }; "schemaUrl": { "alias": "schemaUrl"; "required": false; }; "readUrl": { "alias": "readUrl"; "required": false; }; "submitUrl": { "alias": "submitUrl"; "required": false; }; "submitMethod": { "alias": "submitMethod"; "required": false; }; "responseSchemaUrl": { "alias": "responseSchemaUrl"; "required": false; }; "apiEndpointKey": { "alias": "apiEndpointKey"; "required": false; }; "apiUrlEntry": { "alias": "apiUrlEntry"; "required": false; }; "enableCustomization": { "alias": "enableCustomization"; "required": false; }; "showAiAssistant": { "alias": "showAiAssistant"; "required": false; }; "formId": { "alias": "formId"; "required": false; }; "componentInstanceId": { "alias": "componentInstanceId"; "required": false; }; "configPersistenceStrategy": { "alias": "configPersistenceStrategy"; "required": false; }; "layout": { "alias": "layout"; "required": false; }; "generatedLayoutPreset": { "alias": "generatedLayoutPreset"; "required": false; }; "backConfig": { "alias": "backConfig"; "required": false; }; "hooks": { "alias": "hooks"; "required": false; }; "removeEmptyContainersOnSave": { "alias": "removeEmptyContainersOnSave"; "required": false; }; "reactiveValidation": { "alias": "reactiveValidation"; "required": false; }; "reactiveValidationDebounceMs": { "alias": "reactiveValidationDebounceMs"; "required": false; }; "notifyIfOutdated": { "alias": "notifyIfOutdated"; "required": false; }; "snoozeMs": { "alias": "snoozeMs"; "required": false; }; "autoOpenSettingsOnOutdated": { "alias": "autoOpenSettingsOnOutdated"; "required": false; }; "readonlyModeGlobal": { "alias": "readonlyModeGlobal"; "required": false; }; "disabledModeGlobal": { "alias": "disabledModeGlobal"; "required": false; }; "presentationModeGlobal": { "alias": "presentationModeGlobal"; "required": false; }; "visibleGlobal": { "alias": "visibleGlobal"; "required": false; }; "domainRules": { "alias": "domainRules"; "required": false; }; "customEndpoints": { "alias": "customEndpoints"; "required": false; }; }, { "formSubmit": "formSubmit"; "formCancel": "formCancel"; "formReset": "formReset"; "configChange": "configChange"; "configPatchChange": "configPatchChange"; "formReady": "formReady"; "valueChange": "valueChange"; "syncCompleted": "syncCompleted"; "initializationError": "initializationError"; "loadingStateChange": "loadingStateChange"; "enableCustomizationChange": "enableCustomizationChange"; "customAction": "customAction"; "actionConfirmation": "actionConfirmation"; "schemaStatusChange": "schemaStatusChange"; "fieldRenderError": "fieldRenderError"; "ruleDiagnosticsChange": "ruleDiagnosticsChange"; }, never, never, true, never>;
1365
+ static ɵcmp: i0.ɵɵComponentDeclaration<PraxisDynamicForm, "praxis-dynamic-form", never, { "resourcePath": { "alias": "resourcePath"; "required": false; }; "resourceId": { "alias": "resourceId"; "required": false; }; "initialValue": { "alias": "initialValue"; "required": false; }; "editorialContext": { "alias": "editorialContext"; "required": false; }; "mode": { "alias": "mode"; "required": false; }; "config": { "alias": "config"; "required": false; }; "actions": { "alias": "actions"; "required": false; }; "schemaSource": { "alias": "schemaSource"; "required": false; }; "schemaUrl": { "alias": "schemaUrl"; "required": false; }; "readUrl": { "alias": "readUrl"; "required": false; }; "submitUrl": { "alias": "submitUrl"; "required": false; }; "submitMethod": { "alias": "submitMethod"; "required": false; }; "responseSchemaUrl": { "alias": "responseSchemaUrl"; "required": false; }; "apiEndpointKey": { "alias": "apiEndpointKey"; "required": false; }; "apiUrlEntry": { "alias": "apiUrlEntry"; "required": false; }; "enableCustomization": { "alias": "enableCustomization"; "required": false; }; "showAiAssistant": { "alias": "showAiAssistant"; "required": false; }; "formId": { "alias": "formId"; "required": false; }; "componentInstanceId": { "alias": "componentInstanceId"; "required": false; }; "configPersistenceStrategy": { "alias": "configPersistenceStrategy"; "required": false; }; "layout": { "alias": "layout"; "required": false; }; "generatedLayoutPreset": { "alias": "generatedLayoutPreset"; "required": false; }; "layoutPolicy": { "alias": "layoutPolicy"; "required": false; }; "backConfig": { "alias": "backConfig"; "required": false; }; "hooks": { "alias": "hooks"; "required": false; }; "removeEmptyContainersOnSave": { "alias": "removeEmptyContainersOnSave"; "required": false; }; "reactiveValidation": { "alias": "reactiveValidation"; "required": false; }; "reactiveValidationDebounceMs": { "alias": "reactiveValidationDebounceMs"; "required": false; }; "notifyIfOutdated": { "alias": "notifyIfOutdated"; "required": false; }; "snoozeMs": { "alias": "snoozeMs"; "required": false; }; "autoOpenSettingsOnOutdated": { "alias": "autoOpenSettingsOnOutdated"; "required": false; }; "readonlyModeGlobal": { "alias": "readonlyModeGlobal"; "required": false; }; "disabledModeGlobal": { "alias": "disabledModeGlobal"; "required": false; }; "presentationModeGlobal": { "alias": "presentationModeGlobal"; "required": false; }; "visibleGlobal": { "alias": "visibleGlobal"; "required": false; }; "domainRules": { "alias": "domainRules"; "required": false; }; "customEndpoints": { "alias": "customEndpoints"; "required": false; }; }, { "formSubmit": "formSubmit"; "formCancel": "formCancel"; "formReset": "formReset"; "configChange": "configChange"; "configPatchChange": "configPatchChange"; "formReady": "formReady"; "valueChange": "valueChange"; "syncCompleted": "syncCompleted"; "initializationError": "initializationError"; "loadingStateChange": "loadingStateChange"; "enableCustomizationChange": "enableCustomizationChange"; "customAction": "customAction"; "actionConfirmation": "actionConfirmation"; "schemaStatusChange": "schemaStatusChange"; "fieldRenderError": "fieldRenderError"; "ruleDiagnosticsChange": "ruleDiagnosticsChange"; }, never, never, true, never>;
1353
1366
  }
1354
1367
 
1355
1368
  declare class FormConfigService {
@@ -1547,6 +1560,12 @@ declare class PraxisDynamicFormConfigEditor implements SettingsValueProvider, On
1547
1560
  };
1548
1561
  /** Ensure hints object exists (normalized upstream) */
1549
1562
  private ensureHints;
1563
+ get helpPresentationDraft(): Required<FormHelpPresentationConfig>;
1564
+ onHelpPresentationDisplayChange(display: FormHelpPresentationConfig['display']): void;
1565
+ onHelpPresentationInlineMaxLengthChange(inlineMaxLength: number | string | null): void;
1566
+ private updateHelpPresentation;
1567
+ getHelpPreferPopoverControlsText(): string;
1568
+ onHelpPreferPopoverControlsChange(value: string): void;
1550
1569
  schemaPrefs: {
1551
1570
  notifyIfOutdated: 'inline' | 'snackbar' | 'both' | 'none';
1552
1571
  snoozeMs: number;
@@ -2172,6 +2191,7 @@ interface Ergadm00034CompactPresentationExample {
2172
2191
  readonly resourcePath: string;
2173
2192
  readonly layoutPreset: 'compactPresentation';
2174
2193
  readonly rows: readonly Ergadm00034LegacyFrequencyRow[];
2194
+ readonly tableConfig: TableConfig;
2175
2195
  readonly metadata: readonly FieldMetadata[];
2176
2196
  readonly initialValue: Record<string, unknown>;
2177
2197
  }