@praxisui/dynamic-form 9.0.5-rc.9 → 9.0.6

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.5-rc.9",
3
+ "version": "9.0.6",
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.5-rc.9",
13
- "@praxisui/dynamic-fields": "^9.0.5-rc.9",
14
- "@praxisui/metadata-editor": "^9.0.5-rc.9",
15
- "@praxisui/rich-content": "^9.0.5-rc.9",
16
- "@praxisui/settings-panel": "^9.0.5-rc.9",
17
- "@praxisui/visual-builder": "^9.0.5-rc.9",
18
- "@praxisui/core": "^9.0.5-rc.9",
12
+ "@praxisui/ai": "^9.0.6",
13
+ "@praxisui/dynamic-fields": "^9.0.6",
14
+ "@praxisui/metadata-editor": "^9.0.6",
15
+ "@praxisui/rich-content": "^9.0.6",
16
+ "@praxisui/settings-panel": "^9.0.6",
17
+ "@praxisui/visual-builder": "^9.0.6",
18
+ "@praxisui/core": "^9.0.6",
19
19
  "rxjs": "^7.8.0"
20
20
  },
21
21
  "dependencies": {
@@ -27,16 +27,18 @@ source_of_truth:
27
27
  - "projects/praxis-ai/src/lib/core/services/agentic-authoring-turn-client.service.ts"
28
28
  - "projects/praxis-dynamic-form/src/lib/config-editor/praxis-dynamic-form-config-editor.ts"
29
29
  - "projects/praxis-dynamic-form/src/lib/utils/prepare-submit-payload.ts"
30
+ - "projects/praxis-dynamic-form/src/lib/services/reactive-determination-runtime.service.ts"
30
31
  - "projects/praxis-dynamic-fields/src/lib/directives/dynamic-field-loader.directive.ts"
31
32
  - "projects/praxis-dynamic-fields/src/lib/components/editable-collection/editable-collection.component.ts"
32
33
  - "projects/praxis-core/src/lib/models/form/form-config.model.ts"
34
+ - "projects/praxis-core/src/lib/models/form/reactive-determination.model.ts"
33
35
  - "projects/praxis-core/src/lib/models/form/form-layout.model.ts"
34
36
  - "projects/praxis-core/src/lib/services/schema-normalizer.service.ts"
35
37
  - "projects/praxis-core/src/lib/services/dynamic-form.service.ts"
36
38
  - "projects/praxis-core/src/lib/models/form/rule-property.schema.ts"
37
39
  - "projects/praxis-dynamic-form/docs/layout-items-visual-blocks.md"
38
- source_of_truth_last_verified: "2026-07-16"
39
- last_updated: "2026-07-16"
40
+ source_of_truth_last_verified: "2026-08-12"
41
+ last_updated: "2026-08-12"
40
42
  toc: true
41
43
  sidebar: true
42
44
  tags:
@@ -73,6 +75,21 @@ Este documento e a referencia canonica da API JSON de praxis-dynamic-form.
73
75
  - `backConfig`, `presentation` e `schemaPrefs` permanecem fora de `FormConfig`, mas fazem parte oficialmente do documento autoral persistivel em `contextSnapshot`.
74
76
  - APIs de compatibilidade como `applyConfigFromAdapter(...)` continuam aceitando payloads legados/parciais com semantica `merge-compat`, preservando campos nao informados.
75
77
 
78
+ ## Backend-owned reactive determinations
79
+
80
+ - `x-ui.reactiveDeterminations` e lido exclusivamente do request schema exato retornado por `/schemas/filtered`; nao integra nem e persistido em `FormConfig`.
81
+ - O runtime aceita somente o contrato fechado normalizado por `normalizeReactiveDeterminations`: trigger `on-change`, scope de create/edit, capability `POST`, no maximo 64 bindings totais, JSON Pointers sem duplicidade ou sobreposicao hierarquica e provenance estrutural. A lista e um unico grafo canonico: uma definicao invalida rejeita a projecao inteira, sem execucao parcial.
82
+ - `href`, request/response schemas e bindings sao compilados pelo Praxis Metadata. O Angular nao aceita callback, headers, method, URL ou write policy autorados pelo host/editor/LLM.
83
+ - Cada valor ou status relevante invalida imediatamente a geracao anterior, antes do debounce da proxima chamada; somente a geracao ainda autoritativa pode aplicar a resposta.
84
+ - Hrefs protocol-relative, com separadores codificados ou resolvidos fora da origem configurada da API falham de forma fechada.
85
+ - A resposta so e aplicada quando todos os bindings existem. Os controles alvo aninhados sao preenchidos antes da notificacao dos observers; determinacoes encadeadas recebem um unico sinal logico depois do commit completo, nao um disparo por output. A ordem da cadeia e derivada dos bindings existentes: downstream aguarda a geracao upstream e so executa apos outputs autoritativos ou inputs confirmados como inalterados. Output upstream `null`/`undefined` e geracao upstream com erro, invalida ou cancelada encerram downstream como `skipped`, sem chamada com dado ausente ou obsoleto. Se um controle rejeitar a escrita, o runtime tenta restaurar os anteriores e emite falha terminal. O resultado tem semantica fechada server-derived e substitui o draft alvo; o commit e um batch coordenado no cliente, sem promessa de transacao ACID.
86
+ - O estado permanece pending durante debounce, validacao assincrona e execucao. Uma tentativa de submit aguarda estabilizacao com timeout e repete a espera depois de hooks que podem alterar controles.
87
+ - Controles de output sao desabilitados transitoriamente como valores server-derived, sem mutar/persistir `FormConfig`; seus valores continuam em `getRawValue()`, `valueChange` e no payload de submit. Depois da hidratacao, fonte inicialmente preenchida entra em `pending` e e determinada antes de o draft ser considerado estavel; fonte inicial vazia encerra como `skipped/initial-source-empty`, satisfeita e sem HTTP. Alteracao programatica posterior em output owned invalida a autoridade anterior e reexecuta a capability.
88
+ - `reactiveDeterminationExecuted` publica apenas IDs, paths, provenance, estado (`pending`, `success`, `skipped` ou `error`), duracao, correlation ID e motivo. Valores do formulario e da resposta nao participam da evidencia.
89
+ - Hosts compostos recebem estado agregado por `reactiveDeterminationPendingChange`. Antes de navegar ou fechar, devem consultar `hasPendingReactiveDeterminations()` e `hasUnsatisfiedReactiveDeterminations()` e aguardar `waitForReactiveDeterminations(timeoutMs?)`; retorno `false` indica timeout ou geração mais recente sem draft autoritativo e bloqueia a transição. Correlações canceladas recebem terminal `skipped/superseded`.
90
+ - Cascatas de opcoes continuam em `optionSource.dependsOn`; recommendations, side-effect refresh, backend validation e workflow actions permanecem capacidades separadas.
91
+ - O comando backend final continua responsavel por autorizacao, recomputacao e validacao de qualquer decisao consequente.
92
+
76
93
  ## AI assistant and semantic authoring boundary
77
94
 
78
95
  `praxis-dynamic-form` usa o copiloto semantico Praxis como superficie assistiva contextual, nao como fonte primaria de regra de negocio. O componente pode abrir o assistente a partir de controles de configuracao, floating help ou selecao do canvas, mas a presenca global, minimizacao e retomada da sessao pertencem ao `PraxisAssistantSessionRegistryService`.
@@ -251,6 +268,8 @@ of initial values: a contextual `resourceId` never triggers entity hydration.
251
268
  | `submitIdempotencyKey` | `string \| null \| undefined` | No | action execution contract | `Idempotency-Key` | Identidade estável da tentativa; deve ser reutilizada em retries da mesma execução. |
252
269
  | `submitCorrelationId` | `string \| null \| undefined` | No | action execution contract | `X-Correlation-Id` | Correlação de observabilidade do comando entre host e backend. |
253
270
  | `submitResourceVersion` | `string \| number \| null \| undefined` | Conditional | action execution contract | quoted `If-Match` | Versão esperada do item; obrigatória quando `execution.preconditions.resourceVersionTransport` é `IF_MATCH`. |
271
+ | `submitResourceVersionTargetResourceKey` | `string \| null \| undefined` | Conditional | action execution contract | exact resource discovery | Recurso canônico cujo ETag atual deve ser lido quando a action protege um agregado diferente do recurso dono. Exige `submitResourceVersionTargetIdField`. |
272
+ | `submitResourceVersionTargetIdField` | `string \| null \| undefined` | Conditional | action execution contract | exact request field lookup | Campo escalar do payload que identifica o alvo concorrente. Exige `submitResourceVersionTargetResourceKey`; ausência, divergência de catálogo ou ETag ausente falham fechado. |
254
273
  | `responseSchemaUrl` | `string \| null \| undefined` | No | component-input | diagnostic only | Schema de resposta para diagnóstico e follow-up; não compõe campos editáveis nem o payload do comando. |
255
274
  | `enableCustomization` | `boolean` | No | component-input | boolean coercion | Alterna UX de edição visual/configuração. |
256
275
  | `formId` | `string \| undefined` | Yes (corporate flow) | component-input | component key scoping | Obrigatório para ciclo corporativo com persistência e sync. |
@@ -483,6 +502,19 @@ config local persistida -> config default criada do schema remoto -> erro de ini
483
502
 
484
503
  Falhas de inicialização (`config-load`/`form-build`) são bloqueantes e emitem `initializationError`. Divergências de schema são tratadas como estado (`schemaOutdated`) com emissão de evento, sem interromper formulário já carregado.
485
504
 
505
+ No submit, `RestApiResponse.errors` é materializado somente quando a resposta possui status HTTP
506
+ `4xx` conhecido. Cada detalhe cujo `target` resolve um controle é anexado como erro `server`, sem
507
+ remover validadores do cliente, e desaparece quando aquele controle muda. Erros de outros campos
508
+ permanecem ativos; todos os erros de servidor são limpos no início da próxima tentativa e após
509
+ sucesso. `target` aceita path Angular pontuado ou JSON Pointer. Targets desconhecidos não são
510
+ inferidos por texto e continuam como feedback global.
511
+
512
+ Precedência do feedback: resposta `4xx` com detalhes governados > mensagem customizada de submit
513
+ ou create/update > fallback normalizado e localizado. Falhas de rede, respostas `5xx` e respostas
514
+ sem status confiável nunca expõem `message`/`errors` do payload e usam as chaves
515
+ `global.submitError.*`. `visibleWhen`, mensagens locais e validação visual não substituem a
516
+ autorização e a validação de negócio do backend.
517
+
486
518
  ### Fail-open / fail-closed behavior
487
519
 
488
520
  | Condition | Mode | Runtime behavior | Consumer impact |
@@ -584,6 +616,8 @@ No ecossistema Praxis, ele funciona tanto como runtime final quanto como superfi
584
616
  | `submitIdempotencyKey` | `string \| undefined` | `undefined` | Active | Envia `Idempotency-Key` e preserva a identidade entre retries da mesma tentativa. |
585
617
  | `submitCorrelationId` | `string \| undefined` | `undefined` | Active | Envia `X-Correlation-Id` para rastreabilidade corporativa ponta a ponta. |
586
618
  | `submitResourceVersion` | `string \| number \| undefined` | `undefined` | Active | Envia a versão esperada como `If-Match`, sem inferir concorrência a partir do formulário. |
619
+ | `submitResourceVersionTargetResourceKey` | `string \| undefined` | `undefined` | Active | Quando não há `submitResourceVersion` estático, descobre o path do recurso canônico exato e lê o registro selecionado imediatamente antes do comando. É input runtime materializado pela action, não configuração de negócio authorável. |
620
+ | `submitResourceVersionTargetIdField` | `string \| undefined` | `undefined` | Active | Lê do payload preparado o identificador escalar do alvo concorrente e exige ETag na resposta de leitura. Não aceita labels, objetos de lookup ou fallback para `id`. |
587
621
  | `responseSchemaUrl` | `string \| undefined` | `undefined` | Active | Porta diagnóstica/read-only; não deve ser usada para mesclar propriedades do schema de resposta no formulário de comando. |
588
622
  | `enableCustomization` | `boolean` | `false` | Active | Habilita UX de customizacao do layout. |
589
623
  | `formId` | `string \| undefined` | `undefined` | Active | Chave de persistencia e identidade logica. |
@@ -1,15 +1,15 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { OnChanges, OnDestroy, EventEmitter, SimpleChanges, OnInit, ChangeDetectorRef, NgZone, Provider, AfterViewInit, ElementRef } from '@angular/core';
3
3
  import { HttpClient } from '@angular/common/http';
4
- import { FormGroup, FormBuilder, FormArray } from '@angular/forms';
4
+ import { FormGroup, AbstractControl, FormBuilder, FormArray } from '@angular/forms';
5
5
  import { Router, ActivatedRoute } from '@angular/router';
6
6
  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, FormConfigWithSections, FormLayoutItem, FormActionButton, AiCapability, BackConfig, FormPresentationConfig, 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, EnterpriseRuntimeContextService, 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';
10
+ import { AsyncConfigStorage, FormLayout, FieldMetadata, FormLayoutRule, FormRuleTargetType as FormRuleTargetType$1, PraxisJsonLogicService, FormSection, FormRow, FormColumn, FormConfig, FormConfigWithSections, FormLayoutItem, ReactiveDeterminationDefinition, ReactiveDeterminationExecutionEvent, FormActionButton, AiCapability, BackConfig, FormPresentationConfig, 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, EnterpriseRuntimeContextService, 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
- import { Observable, BehaviorSubject } from 'rxjs';
12
+ import { Observable, Subscription, BehaviorSubject } from 'rxjs';
13
13
  import { SettingsPanelService, SettingsValueProvider } from '@praxisui/settings-panel';
14
14
  import { BaseAiAdapter, AiResponseCompileResult, PatchResult, PraxisAssistantShellLayout, PraxisAssistantTurnViewState, PraxisAssistantShellLabels, PraxisAssistantSessionSnapshot, PraxisAssistantShellQuickReply, PraxisAssistantShellMessage } from '@praxisui/ai';
15
15
  import { KeyboardShortcutService } from '@praxisui/dynamic-fields';
@@ -361,6 +361,43 @@ declare class DynamicFormLayoutService {
361
361
  static ɵprov: i0.ɵɵInjectableDeclaration<DynamicFormLayoutService>;
362
362
  }
363
363
 
364
+ type ReactiveDeterminationExecutor = (definition: ReactiveDeterminationDefinition, requestBody: Record<string, unknown>, correlationId: string) => Observable<Record<string, unknown>>;
365
+ /** Internal scheduler for Metadata-compiled, backend reactive determinations. */
366
+ declare class ReactiveDeterminationRuntimeService {
367
+ private readonly pendingStateByForm;
368
+ private readonly ownedTargetsByForm;
369
+ private readonly committedControlsByForm;
370
+ private readonly publishingCommitByForm;
371
+ private nextConnectionId;
372
+ hasPending(form: FormGroup): boolean;
373
+ hasUnsatisfied(form: FormGroup): boolean;
374
+ waitForStable(form: FormGroup, timeoutMs?: number): Promise<boolean>;
375
+ observePending(form: FormGroup, observer: (pending: boolean) => void): Subscription;
376
+ isOwnedTarget(form: FormGroup, control: AbstractControl): boolean;
377
+ connect(form: FormGroup, definitions: ReactiveDeterminationDefinition[], executor: ReactiveDeterminationExecutor, onEvent?: (event: ReactiveDeterminationExecutionEvent) => void, operationTimeoutMs?: number): Subscription;
378
+ private resolveControls;
379
+ private waitForUpstreamDeterminations;
380
+ private claimTargets;
381
+ private buildInvocation;
382
+ private buildCommit;
383
+ private buildOutputFingerprint;
384
+ private commit;
385
+ private getOrCreateCommittedControls;
386
+ private event;
387
+ private getOrCreatePendingState;
388
+ private beginGeneration;
389
+ private satisfyGeneration;
390
+ private finishGeneration;
391
+ private clearDeterminationState;
392
+ private isCurrentGeneration;
393
+ private isPending;
394
+ private isSatisfied;
395
+ private notifyIfStable;
396
+ private notifyPendingChange;
397
+ static ɵfac: i0.ɵɵFactoryDeclaration<ReactiveDeterminationRuntimeService, never>;
398
+ static ɵprov: i0.ɵɵInjectableDeclaration<ReactiveDeterminationRuntimeService>;
399
+ }
400
+
364
401
  declare class CanvasStateService {
365
402
  private readonly _hoveredElement$;
366
403
  readonly hoveredElement$: rxjs.Observable<CanvasElement | null>;
@@ -408,6 +445,7 @@ declare class PraxisFormActionsComponent implements OnChanges, OnDestroy {
408
445
  private invalidSubmitHintCacheSignature;
409
446
  private invalidSubmitHintCacheValue;
410
447
  private readonly invalidSubmitHint;
448
+ readonly submitErrorTitle: string;
411
449
  /** Configuration object describing form action buttons */
412
450
  actions?: FormConfig['actions'];
413
451
  /** Whether the actions are rendered inside an editorial visual context */
@@ -678,6 +716,7 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
678
716
  private snackBar;
679
717
  private canvasState;
680
718
  private dynamicLayout;
719
+ private reactiveDeterminationRuntime;
681
720
  private errorMessages;
682
721
  private schemaNormalizer;
683
722
  private componentMetaRegistry;
@@ -699,6 +738,7 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
699
738
  private readonly assistantSessions;
700
739
  private readonly aiTurnOrchestrator;
701
740
  private readonly jsonLogic;
741
+ private readonly resourceDiscovery;
702
742
  private readonly aiAssistantSessionEffect;
703
743
  private readonly globalActions;
704
744
  private readonly DEBUG;
@@ -741,6 +781,10 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
741
781
  submitCorrelationId?: string | null;
742
782
  /** Current persisted resource version sent through If-Match when governed by the action. */
743
783
  submitResourceVersion?: string | number | null;
784
+ /** Canonical resource whose current ETag must be resolved when the command targets another aggregate. */
785
+ submitResourceVersionTargetResourceKey?: string | null;
786
+ /** Exact request field carrying the canonical identifier of the cross-resource version target. */
787
+ submitResourceVersionTargetIdField?: string | null;
744
788
  /** Canonical response schema URL exposed for runtime diagnostics/follow-up. */
745
789
  responseSchemaUrl?: string | null;
746
790
  /** API endpoint entry used to resolve relative canonical URLs in detached hosts. */
@@ -842,8 +886,14 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
842
886
  fieldRenderError: EventEmitter<DynamicFieldRenderErrorEvent>;
843
887
  /** Emits runtime rule diagnostics so hosts can surface or log invalid rules. */
844
888
  ruleDiagnosticsChange: EventEmitter<RuleApplicationDiagnostic[]>;
889
+ /** Emits metadata-only diagnostics for backend-owned form determinations. */
890
+ reactiveDeterminationExecuted: EventEmitter<ReactiveDeterminationExecutionEvent>;
891
+ /** Emits only aggregate runtime state; no request or response payload is exposed. */
892
+ reactiveDeterminationPendingChange: EventEmitter<boolean>;
893
+ private reactiveDeterminationPending;
845
894
  isLoading: boolean;
846
895
  submitting: boolean;
896
+ private submitPreparationInProgress;
847
897
  submitError: string | null;
848
898
  initializationStatus: 'idle' | 'loading' | 'success' | 'error';
849
899
  currentErrorMessage: string;
@@ -885,8 +935,15 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
885
935
  private readonly formConfigPersistenceGenerations;
886
936
  private readonly formConfigConflictBlockThrough;
887
937
  private schemaRootHooks?;
938
+ private schemaRootReactiveDeterminations;
939
+ private schemaRootOperationId;
888
940
  private destroy$;
941
+ private isDestroyed;
889
942
  private formValueChangesSubscription;
943
+ private readonly submitFieldErrorSubscriptions;
944
+ private activeSubmitErrorDetails;
945
+ private reactiveDeterminationSubscription;
946
+ private reactiveDeterminationScheduledBuildId;
890
947
  private dependencyPolicySubscription;
891
948
  private formBuildCycleId;
892
949
  private suppressedValueChangeBuildId;
@@ -970,7 +1027,7 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
970
1027
  protected isMounting: boolean;
971
1028
  private hasBuiltFormFromConfig;
972
1029
  private runtimeFieldMetadata;
973
- constructor(crud: GenericCrudService<any>, http: HttpClient, fb: FormBuilder, cdr: ChangeDetectorRef, layoutService: FormLayoutService, contextService: FormContextService, rulesService: FormRulesService, settingsPanel: SettingsPanelService, dialog: MatDialog, asyncConfigStorage: AsyncConfigStorage, connectionStorage: ConnectionStorage, dynamicForm: DynamicFormService, snackBar: MatSnackBar, canvasState: CanvasStateService, dynamicLayout: DynamicFormLayoutService, errorMessages: ErrorMessageService, schemaNormalizer: SchemaNormalizerService, componentMetaRegistry: ComponentMetadataRegistry, global: GlobalConfigService, componentKeys: ComponentKeyService, loadingOrchestrator: LoadingOrchestrator, ngZone: NgZone, apiUrlConfig: ApiUrlConfig, loadingRenderer?: PraxisLoadingRenderer | undefined, router?: Router | undefined, route?: ActivatedRoute | undefined, hooksRegistry?: FormHooksRegistry | undefined, hookPresets?: FormHookPreset[] | null | undefined, logger?: LoggerService | undefined, enterpriseRuntimeContext?: EnterpriseRuntimeContextService | undefined);
1030
+ constructor(crud: GenericCrudService<any>, http: HttpClient, fb: FormBuilder, cdr: ChangeDetectorRef, layoutService: FormLayoutService, contextService: FormContextService, rulesService: FormRulesService, settingsPanel: SettingsPanelService, dialog: MatDialog, asyncConfigStorage: AsyncConfigStorage, connectionStorage: ConnectionStorage, dynamicForm: DynamicFormService, snackBar: MatSnackBar, canvasState: CanvasStateService, dynamicLayout: DynamicFormLayoutService, reactiveDeterminationRuntime: ReactiveDeterminationRuntimeService, errorMessages: ErrorMessageService, schemaNormalizer: SchemaNormalizerService, componentMetaRegistry: ComponentMetadataRegistry, global: GlobalConfigService, componentKeys: ComponentKeyService, loadingOrchestrator: LoadingOrchestrator, ngZone: NgZone, apiUrlConfig: ApiUrlConfig, loadingRenderer?: PraxisLoadingRenderer | undefined, router?: Router | undefined, route?: ActivatedRoute | undefined, hooksRegistry?: FormHooksRegistry | undefined, hookPresets?: FormHookPreset[] | null | undefined, logger?: LoggerService | undefined, enterpriseRuntimeContext?: EnterpriseRuntimeContextService | undefined);
974
1031
  private emitLoadingState;
975
1032
  private buildLoadingContext;
976
1033
  private beginLoading;
@@ -978,6 +1035,7 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
978
1035
  private runHooks;
979
1036
  private resolveSubmitOperation;
980
1037
  private buildSubmitRequest;
1038
+ private resolveSubmitResourceVersion;
981
1039
  private normalizeSubmitMethod;
982
1040
  private formatResourceVersion;
983
1041
  private resolveSubmitHref;
@@ -1027,6 +1085,16 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
1027
1085
  private flushEntityHydrationState;
1028
1086
  private buildFormFromConfig;
1029
1087
  private resetFormValueChangesSubscription;
1088
+ private resetReactiveDeterminationSubscription;
1089
+ private scheduleReactiveDeterminationsActivation;
1090
+ /** True while at least one backend Reactive Determination is unsettled. */
1091
+ hasPendingReactiveDeterminations(): boolean;
1092
+ /** True when the latest settled generation failed or could not derive a current draft. */
1093
+ hasUnsatisfiedReactiveDeterminations(): boolean;
1094
+ /** Resolves true only when the latest generations settled successfully/current. */
1095
+ waitForReactiveDeterminations(timeoutMs?: number): Promise<boolean>;
1096
+ private setReactiveDeterminationPending;
1097
+ private handleReactiveDeterminationExecutionEvent;
1030
1098
  private resetDependencyPolicySubscription;
1031
1099
  private setupEntityLookupDependencyPolicies;
1032
1100
  private applyEntityLookupDependencyPolicy;
@@ -1193,8 +1261,13 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
1193
1261
  private _executeAction;
1194
1262
  private getFormActionEventId;
1195
1263
  onSubmit(): Promise<void>;
1264
+ private prepareAndSubmit;
1265
+ private waitForReactiveDeterminationsBeforeSubmit;
1196
1266
  private applySubmitFieldErrors;
1197
1267
  private clearSubmitFieldErrors;
1268
+ private clearSubmitFieldError;
1269
+ private resetSubmitErrorState;
1270
+ private resolveSubmitErrorMessage;
1198
1271
  private normalizeSubmitErrorTarget;
1199
1272
  private navigateAfterSave;
1200
1273
  private shouldConfirmCancelOnDirty;
@@ -1285,6 +1358,10 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
1285
1358
  private openRowEditor;
1286
1359
  private openColumnEditor;
1287
1360
  openSectionEditor(section: any, focusTarget?: 'title' | 'description'): void;
1361
+ private applyRowEditorValue;
1362
+ private applyColumnEditorValue;
1363
+ private resolveLayoutEditorLocation;
1364
+ private applyNestedLayoutEditorValue;
1288
1365
  private applySectionEditorValue;
1289
1366
  private resolveControlTypeEditorial;
1290
1367
  private getControlTypeIcon;
@@ -1394,8 +1471,8 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
1394
1471
  private logRowGapsSnapshot;
1395
1472
  private applyPresentationVars;
1396
1473
  private applyPresentationConfig;
1397
- 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; }, { optional: true; }]>;
1398
- 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; }; "submitIdempotencyKey": { "alias": "submitIdempotencyKey"; "required": false; }; "submitCorrelationId": { "alias": "submitCorrelationId"; "required": false; }; "submitResourceVersion": { "alias": "submitResourceVersion"; "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; }; "fieldIconPolicy": { "alias": "fieldIconPolicy"; "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>;
1474
+ 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, null, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }]>;
1475
+ 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; }; "submitIdempotencyKey": { "alias": "submitIdempotencyKey"; "required": false; }; "submitCorrelationId": { "alias": "submitCorrelationId"; "required": false; }; "submitResourceVersion": { "alias": "submitResourceVersion"; "required": false; }; "submitResourceVersionTargetResourceKey": { "alias": "submitResourceVersionTargetResourceKey"; "required": false; }; "submitResourceVersionTargetIdField": { "alias": "submitResourceVersionTargetIdField"; "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; }; "fieldIconPolicy": { "alias": "fieldIconPolicy"; "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"; "reactiveDeterminationExecuted": "reactiveDeterminationExecuted"; "reactiveDeterminationPendingChange": "reactiveDeterminationPendingChange"; }, never, never, true, never>;
1399
1476
  }
1400
1477
 
1401
1478
  declare class FormConfigService {
@@ -1716,6 +1793,7 @@ declare class PraxisDynamicFormConfigEditor implements SettingsValueProvider, On
1716
1793
  ngOnDestroy(): void;
1717
1794
  onLayoutSelect(event: any): void;
1718
1795
  private openColumnEditor;
1796
+ private applyColumnEditorValue;
1719
1797
  onCascadeApply(patch: Record<string, Partial<FieldDefinition>>): void;
1720
1798
  private syncCascadeManagerFields;
1721
1799
  private stripLegacy;
@@ -2397,6 +2475,7 @@ declare class SectionEditorComponent implements OnInit, AfterViewInit, OnDestroy
2397
2475
  readonly globalActionCatalog: ActionCatalogOption[];
2398
2476
  readonly customActionValue = "__custom__";
2399
2477
  private destroy$;
2478
+ private initialValueSig;
2400
2479
  titleInput?: ElementRef<HTMLInputElement>;
2401
2480
  descriptionInput?: ElementRef<HTMLTextAreaElement>;
2402
2481
  constructor(fb: FormBuilder, data: {
@@ -2520,6 +2599,7 @@ declare class ColumnEditorComponent implements OnInit, OnDestroy, SettingsValueP
2520
2599
  isBusy$: BehaviorSubject<boolean>;
2521
2600
  private destroy$;
2522
2601
  private _previewTimer;
2602
+ private initialValueSig;
2523
2603
  private readonly i18n;
2524
2604
  constructor(fb: FormBuilder, data: {
2525
2605
  column: FormColumn;