@praxisui/dynamic-form 9.0.5-rc.8 → 9.0.5

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.8",
3
+ "version": "9.0.5",
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.8",
13
- "@praxisui/dynamic-fields": "^9.0.5-rc.8",
14
- "@praxisui/metadata-editor": "^9.0.5-rc.8",
15
- "@praxisui/rich-content": "^9.0.5-rc.8",
16
- "@praxisui/settings-panel": "^9.0.5-rc.8",
17
- "@praxisui/visual-builder": "^9.0.5-rc.8",
18
- "@praxisui/core": "^9.0.5-rc.8",
12
+ "@praxisui/ai": "^9.0.5",
13
+ "@praxisui/dynamic-fields": "^9.0.5",
14
+ "@praxisui/metadata-editor": "^9.0.5",
15
+ "@praxisui/rich-content": "^9.0.5",
16
+ "@praxisui/settings-panel": "^9.0.5",
17
+ "@praxisui/visual-builder": "^9.0.5",
18
+ "@praxisui/core": "^9.0.5",
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.
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.
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,42 @@ 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 commit;
384
+ private getOrCreateCommittedControls;
385
+ private event;
386
+ private getOrCreatePendingState;
387
+ private beginGeneration;
388
+ private satisfyGeneration;
389
+ private finishGeneration;
390
+ private clearDeterminationState;
391
+ private isCurrentGeneration;
392
+ private isPending;
393
+ private isSatisfied;
394
+ private notifyIfStable;
395
+ private notifyPendingChange;
396
+ static ɵfac: i0.ɵɵFactoryDeclaration<ReactiveDeterminationRuntimeService, never>;
397
+ static ɵprov: i0.ɵɵInjectableDeclaration<ReactiveDeterminationRuntimeService>;
398
+ }
399
+
364
400
  declare class CanvasStateService {
365
401
  private readonly _hoveredElement$;
366
402
  readonly hoveredElement$: rxjs.Observable<CanvasElement | null>;
@@ -408,6 +444,7 @@ declare class PraxisFormActionsComponent implements OnChanges, OnDestroy {
408
444
  private invalidSubmitHintCacheSignature;
409
445
  private invalidSubmitHintCacheValue;
410
446
  private readonly invalidSubmitHint;
447
+ readonly submitErrorTitle: string;
411
448
  /** Configuration object describing form action buttons */
412
449
  actions?: FormConfig['actions'];
413
450
  /** Whether the actions are rendered inside an editorial visual context */
@@ -678,6 +715,7 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
678
715
  private snackBar;
679
716
  private canvasState;
680
717
  private dynamicLayout;
718
+ private reactiveDeterminationRuntime;
681
719
  private errorMessages;
682
720
  private schemaNormalizer;
683
721
  private componentMetaRegistry;
@@ -699,6 +737,7 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
699
737
  private readonly assistantSessions;
700
738
  private readonly aiTurnOrchestrator;
701
739
  private readonly jsonLogic;
740
+ private readonly resourceDiscovery;
702
741
  private readonly aiAssistantSessionEffect;
703
742
  private readonly globalActions;
704
743
  private readonly DEBUG;
@@ -741,6 +780,10 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
741
780
  submitCorrelationId?: string | null;
742
781
  /** Current persisted resource version sent through If-Match when governed by the action. */
743
782
  submitResourceVersion?: string | number | null;
783
+ /** Canonical resource whose current ETag must be resolved when the command targets another aggregate. */
784
+ submitResourceVersionTargetResourceKey?: string | null;
785
+ /** Exact request field carrying the canonical identifier of the cross-resource version target. */
786
+ submitResourceVersionTargetIdField?: string | null;
744
787
  /** Canonical response schema URL exposed for runtime diagnostics/follow-up. */
745
788
  responseSchemaUrl?: string | null;
746
789
  /** API endpoint entry used to resolve relative canonical URLs in detached hosts. */
@@ -842,8 +885,14 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
842
885
  fieldRenderError: EventEmitter<DynamicFieldRenderErrorEvent>;
843
886
  /** Emits runtime rule diagnostics so hosts can surface or log invalid rules. */
844
887
  ruleDiagnosticsChange: EventEmitter<RuleApplicationDiagnostic[]>;
888
+ /** Emits metadata-only diagnostics for backend-owned form determinations. */
889
+ reactiveDeterminationExecuted: EventEmitter<ReactiveDeterminationExecutionEvent>;
890
+ /** Emits only aggregate runtime state; no request or response payload is exposed. */
891
+ reactiveDeterminationPendingChange: EventEmitter<boolean>;
892
+ private reactiveDeterminationPending;
845
893
  isLoading: boolean;
846
894
  submitting: boolean;
895
+ private submitPreparationInProgress;
847
896
  submitError: string | null;
848
897
  initializationStatus: 'idle' | 'loading' | 'success' | 'error';
849
898
  currentErrorMessage: string;
@@ -885,8 +934,15 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
885
934
  private readonly formConfigPersistenceGenerations;
886
935
  private readonly formConfigConflictBlockThrough;
887
936
  private schemaRootHooks?;
937
+ private schemaRootReactiveDeterminations;
938
+ private schemaRootOperationId;
888
939
  private destroy$;
940
+ private isDestroyed;
889
941
  private formValueChangesSubscription;
942
+ private readonly submitFieldErrorSubscriptions;
943
+ private activeSubmitErrorDetails;
944
+ private reactiveDeterminationSubscription;
945
+ private reactiveDeterminationScheduledBuildId;
890
946
  private dependencyPolicySubscription;
891
947
  private formBuildCycleId;
892
948
  private suppressedValueChangeBuildId;
@@ -970,7 +1026,7 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
970
1026
  protected isMounting: boolean;
971
1027
  private hasBuiltFormFromConfig;
972
1028
  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);
1029
+ 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
1030
  private emitLoadingState;
975
1031
  private buildLoadingContext;
976
1032
  private beginLoading;
@@ -978,6 +1034,7 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
978
1034
  private runHooks;
979
1035
  private resolveSubmitOperation;
980
1036
  private buildSubmitRequest;
1037
+ private resolveSubmitResourceVersion;
981
1038
  private normalizeSubmitMethod;
982
1039
  private formatResourceVersion;
983
1040
  private resolveSubmitHref;
@@ -1027,6 +1084,16 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
1027
1084
  private flushEntityHydrationState;
1028
1085
  private buildFormFromConfig;
1029
1086
  private resetFormValueChangesSubscription;
1087
+ private resetReactiveDeterminationSubscription;
1088
+ private scheduleReactiveDeterminationsActivation;
1089
+ /** True while at least one backend Reactive Determination is unsettled. */
1090
+ hasPendingReactiveDeterminations(): boolean;
1091
+ /** True when the latest settled generation failed or could not derive a current draft. */
1092
+ hasUnsatisfiedReactiveDeterminations(): boolean;
1093
+ /** Resolves true only when the latest generations settled successfully/current. */
1094
+ waitForReactiveDeterminations(timeoutMs?: number): Promise<boolean>;
1095
+ private setReactiveDeterminationPending;
1096
+ private handleReactiveDeterminationExecutionEvent;
1030
1097
  private resetDependencyPolicySubscription;
1031
1098
  private setupEntityLookupDependencyPolicies;
1032
1099
  private applyEntityLookupDependencyPolicy;
@@ -1193,8 +1260,13 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
1193
1260
  private _executeAction;
1194
1261
  private getFormActionEventId;
1195
1262
  onSubmit(): Promise<void>;
1263
+ private prepareAndSubmit;
1264
+ private waitForReactiveDeterminationsBeforeSubmit;
1196
1265
  private applySubmitFieldErrors;
1197
1266
  private clearSubmitFieldErrors;
1267
+ private clearSubmitFieldError;
1268
+ private resetSubmitErrorState;
1269
+ private resolveSubmitErrorMessage;
1198
1270
  private normalizeSubmitErrorTarget;
1199
1271
  private navigateAfterSave;
1200
1272
  private shouldConfirmCancelOnDirty;
@@ -1394,8 +1466,8 @@ declare class PraxisDynamicForm implements OnInit, OnChanges, OnDestroy {
1394
1466
  private logRowGapsSnapshot;
1395
1467
  private applyPresentationVars;
1396
1468
  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>;
1469
+ 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; }]>;
1470
+ 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
1471
  }
1400
1472
 
1401
1473
  declare class FormConfigService {