@praxisui/crud 9.0.5-rc.12 → 9.0.5-rc.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -102,6 +102,7 @@ It emits:
102
102
 
103
103
  - `configureRequested`
104
104
  - `afterOpen`, `afterClose`, `afterSave`, `afterDelete`
105
+ - `reactiveDeterminationExecuted` (metadata-only evidence with action context) and `reactiveDeterminationPendingChange`
105
106
  - `error`
106
107
  - `rowClick`, `rowAction`, `selectionChange`. `rowAction` preserves the canonical table envelope (`row`, `action`, `resourceIdentity`) so a governed composition can update task context without forcing visual row selection.
107
108
  - `tableRuntimeConfigChange`
@@ -109,6 +110,8 @@ It emits:
109
110
 
110
111
  The component keeps `crudContext` stable for change detection and refreshes the table after successful save/delete flows.
111
112
 
113
+ Built-in modal, drawer and nested surface-frame form hosts do not close or complete save while a child Reactive Determination is pending; cancel waits for bounded stabilization and stays open on timeout. A custom `CrudDrawerAdapter` must bind `onReactiveDetermination` and `onReactiveDeterminationPendingChange`, use the child Dynamic Form stability API, and refuse every adapter-owned close/submit while pending. These callbacks are runtime-only and must never be persisted in CRUD metadata.
114
+
112
115
  ## Metadata Boundaries
113
116
 
114
117
  `resourcePath` and `resourceKey` are intentionally different:
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-08-13T13:48:00.302Z",
3
+ "generatedAt": "2026-08-13T17:03:40.689Z",
4
4
  "packageName": "@praxisui/crud",
5
- "packageVersion": "9.0.5-rc.12",
5
+ "packageVersion": "9.0.5-rc.13",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 2,
@@ -124,6 +124,18 @@
124
124
  "required": false,
125
125
  "description": "Emitido ao deletar."
126
126
  },
127
+ {
128
+ "name": "reactiveDeterminationExecuted",
129
+ "type": "{ action: string; event: ReactiveDeterminationExecutionEvent }",
130
+ "required": false,
131
+ "description": "Evidencia metadata-only encaminhada pelo formulario aberto, com contexto da acao CRUD."
132
+ },
133
+ {
134
+ "name": "reactiveDeterminationPendingChange",
135
+ "type": "{ action: string; pending: boolean }",
136
+ "required": false,
137
+ "description": "Estado agregado de estabilizacao do formulario aberto, sem valores sensiveis."
138
+ },
127
139
  {
128
140
  "name": "rowClick",
129
141
  "type": "{ row: unknown; index: number }",
@@ -7224,9 +7236,9 @@
7224
7236
  {
7225
7237
  "chunkIndex": 0,
7226
7238
  "chunkKind": "summary",
7227
- "content": "Component ID: praxis-crud\nSelector: praxis-crud\nFriendly Name: Praxis CRUD\nDescription: Tabela com operações de CRUD via metadados.\nLib/Package: @praxisui/crud\nTags: widget, crud, configurable, hasWizard, stable\nInputs:\n - metadata (CrudMetadata | string)\n - crudId (string)\n - componentInstanceId (string)\n - tableConfigPersistenceStrategy ('local-first' | 'input-first' | 'volatile')\n - context (Record<string, unknown>)\n - metadata.queryContext (PraxisDataQueryContext | null)\n - metadata.resource.schemaPath (string | null)\n - metadata.resource.title (string | null)\n - metadata.resource.formTitle (string | null)\n - metadata.filterCriteria (Record<string, unknown> | null)\n - metadata.form (FormConfig)\n - metadata.actions[].form (CrudActionFormContract)\n - enableCustomization (boolean)\n - authoringCapability (string | null)\nOutputs:\n - afterOpen ({ mode: FormOpenMode; action: string })\n - afterClose (void)\n - afterSave ({ id: string | number; data: unknown })\n - afterDelete ({ id: string | number })\n - rowClick ({ row: unknown; index: number })\n - rowAction (CrudActionRuntimeEvent)\n - selectionChange (unknown)\n - error (unknown)\n - configureRequested (void)\n - crudAuthoringDocumentApplied (CrudAuthoringWidgetPersistenceEvent)\n - crudAuthoringDocumentSaved (CrudAuthoringWidgetPersistenceEvent)\n",
7239
+ "content": "Component ID: praxis-crud\nSelector: praxis-crud\nFriendly Name: Praxis CRUD\nDescription: Tabela com operações de CRUD via metadados.\nLib/Package: @praxisui/crud\nTags: widget, crud, configurable, hasWizard, stable\nInputs:\n - metadata (CrudMetadata | string)\n - crudId (string)\n - componentInstanceId (string)\n - tableConfigPersistenceStrategy ('local-first' | 'input-first' | 'volatile')\n - context (Record<string, unknown>)\n - metadata.queryContext (PraxisDataQueryContext | null)\n - metadata.resource.schemaPath (string | null)\n - metadata.resource.title (string | null)\n - metadata.resource.formTitle (string | null)\n - metadata.filterCriteria (Record<string, unknown> | null)\n - metadata.form (FormConfig)\n - metadata.actions[].form (CrudActionFormContract)\n - enableCustomization (boolean)\n - authoringCapability (string | null)\nOutputs:\n - afterOpen ({ mode: FormOpenMode; action: string })\n - afterClose (void)\n - afterSave ({ id: string | number; data: unknown })\n - afterDelete ({ id: string | number })\n - reactiveDeterminationExecuted ({ action: string; event: ReactiveDeterminationExecutionEvent })\n - reactiveDeterminationPendingChange ({ action: string; pending: boolean })\n - rowClick ({ row: unknown; index: number })\n - rowAction (CrudActionRuntimeEvent)\n - selectionChange (unknown)\n - error (unknown)\n - configureRequested (void)\n - crudAuthoringDocumentApplied (CrudAuthoringWidgetPersistenceEvent)\n - crudAuthoringDocumentSaved (CrudAuthoringWidgetPersistenceEvent)\n",
7228
7240
  "sourcePointer": "projects/praxis-crud/src/lib/praxis-crud.metadata.ts",
7229
- "contentHash": "5f18e01c2da358f033eb9b8ee4616dac8a348addc3ce3e56bcb077b094c13300",
7241
+ "contentHash": "78a90bf2630d8c008dd8b162852e6a323bbf624d53295cf926c824cb34afa149",
7230
7242
  "sourceKind": "component_definition",
7231
7243
  "sourceId": "praxis-crud",
7232
7244
  "corpusVersion": "1.0.0"
@@ -193,6 +193,10 @@ class CrudLauncherService {
193
193
  presentation: mode === 'drawer' ? 'drawer' : 'modal',
194
194
  resourceIdentity,
195
195
  contextIdentity,
196
+ reactiveDeterminationCallbacks: {
197
+ onEvent: drawerCallbacks?.onReactiveDetermination,
198
+ onPendingChange: drawerCallbacks?.onReactiveDeterminationPendingChange,
199
+ },
196
200
  };
197
201
  const modalCfg = { ...(merged.metadata.defaults?.modal || {}) };
198
202
  const restoreFocus = resolveCrudRestoreFocus(modalCfg.restoreFocus, actionFocusOrigin);
@@ -243,6 +247,8 @@ class CrudLauncherService {
243
247
  restoreFocus,
244
248
  onClose: drawerCallbacks?.onClose,
245
249
  onResult: drawerCallbacks?.onResult,
250
+ onReactiveDetermination: drawerCallbacks?.onReactiveDetermination,
251
+ onReactiveDeterminationPendingChange: drawerCallbacks?.onReactiveDeterminationPendingChange,
246
252
  }));
247
253
  return { mode };
248
254
  }
@@ -3808,6 +3814,9 @@ class PraxisCrudComponent {
3808
3814
  afterClose = new EventEmitter();
3809
3815
  afterSave = new EventEmitter();
3810
3816
  afterDelete = new EventEmitter();
3817
+ /** Metadata-only Reactive Determination evidence from an open form host. */
3818
+ reactiveDeterminationExecuted = new EventEmitter();
3819
+ reactiveDeterminationPendingChange = new EventEmitter();
3811
3820
  error = new EventEmitter();
3812
3821
  rowClick = new EventEmitter();
3813
3822
  /** Emits the canonical table row-action envelope before the CRUD handles its surface/action. */
@@ -4053,6 +4062,14 @@ class PraxisCrudComponent {
4053
4062
  this.refreshTable();
4054
4063
  }
4055
4064
  },
4065
+ onReactiveDetermination: (event) => this.reactiveDeterminationExecuted.emit({
4066
+ action: effectiveAction.action,
4067
+ event,
4068
+ }),
4069
+ onReactiveDeterminationPendingChange: (pending) => this.reactiveDeterminationPendingChange.emit({
4070
+ action: effectiveAction.action,
4071
+ pending,
4072
+ }),
4056
4073
  }, {
4057
4074
  capabilities: effectiveAction.action === 'create'
4058
4075
  ? this.collectionCapabilities
@@ -4326,6 +4343,8 @@ class PraxisCrudComponent {
4326
4343
  const { mode, ref } = await this.launcher.launch(createAction, undefined, this.resolvedMetadata, this.componentKeyId(), {
4327
4344
  onClose: () => emitDrawerClose(),
4328
4345
  onResult: (result) => handleResult(result),
4346
+ onReactiveDetermination: (event) => this.reactiveDeterminationExecuted.emit({ action: normalizedAction, event }),
4347
+ onReactiveDeterminationPendingChange: (pending) => this.reactiveDeterminationPendingChange.emit({ action: normalizedAction, pending }),
4329
4348
  }, {
4330
4349
  capabilities: this.collectionCapabilities,
4331
4350
  links: this.tableCollectionLinks,
@@ -5497,7 +5516,7 @@ class PraxisCrudComponent {
5497
5516
  return Object.entries(params).reduce((current, [name, value]) => current.split(`{${name}}`).join(value), text);
5498
5517
  }
5499
5518
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisCrudComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5500
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisCrudComponent, isStandalone: true, selector: "praxis-crud", inputs: { metadata: "metadata", crudId: "crudId", componentInstanceId: "componentInstanceId", tableConfigPersistenceStrategy: "tableConfigPersistenceStrategy", context: "context", enableCustomization: "enableCustomization", authoringCapability: "authoringCapability" }, outputs: { configureRequested: "configureRequested", afterOpen: "afterOpen", afterClose: "afterClose", afterSave: "afterSave", afterDelete: "afterDelete", error: "error", rowClick: "rowClick", rowAction: "rowAction", selectionChange: "selectionChange", tableRuntimeConfigChange: "tableRuntimeConfigChange", crudAuthoringDocumentApplied: "crudAuthoringDocumentApplied", crudAuthoringDocumentSaved: "crudAuthoringDocumentSaved" }, providers: [
5519
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisCrudComponent, isStandalone: true, selector: "praxis-crud", inputs: { metadata: "metadata", crudId: "crudId", componentInstanceId: "componentInstanceId", tableConfigPersistenceStrategy: "tableConfigPersistenceStrategy", context: "context", enableCustomization: "enableCustomization", authoringCapability: "authoringCapability" }, outputs: { configureRequested: "configureRequested", afterOpen: "afterOpen", afterClose: "afterClose", afterSave: "afterSave", afterDelete: "afterDelete", reactiveDeterminationExecuted: "reactiveDeterminationExecuted", reactiveDeterminationPendingChange: "reactiveDeterminationPendingChange", error: "error", rowClick: "rowClick", rowAction: "rowAction", selectionChange: "selectionChange", tableRuntimeConfigChange: "tableRuntimeConfigChange", crudAuthoringDocumentApplied: "crudAuthoringDocumentApplied", crudAuthoringDocumentSaved: "crudAuthoringDocumentSaved" }, providers: [
5501
5520
  providePraxisI18nConfig(RESOURCE_DISCOVERY_I18N_CONFIG),
5502
5521
  providePraxisI18nConfig(PRAXIS_CRUD_RUNTIME_I18N_CONFIG),
5503
5522
  ], viewQueries: [{ propertyName: "table", first: true, predicate: PraxisTable, descendants: true }], usesOnChanges: true, ngImport: i0, template: `
@@ -5616,6 +5635,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
5616
5635
  type: Output
5617
5636
  }], afterDelete: [{
5618
5637
  type: Output
5638
+ }], reactiveDeterminationExecuted: [{
5639
+ type: Output
5640
+ }], reactiveDeterminationPendingChange: [{
5641
+ type: Output
5619
5642
  }], error: [{
5620
5643
  type: Output
5621
5644
  }], rowClick: [{
@@ -5663,6 +5686,8 @@ class DynamicFormDialogHostComponent {
5663
5686
  configStorage;
5664
5687
  surfaceRef;
5665
5688
  formComp;
5689
+ reactiveDeterminationExecuted = new EventEmitter();
5690
+ reactiveDeterminationPendingChange = new EventEmitter();
5666
5691
  modal = {};
5667
5692
  presentation = 'modal';
5668
5693
  maximized = false;
@@ -5997,6 +6022,8 @@ class DynamicFormDialogHostComponent {
5997
6022
  if (stage === 'before' || stage === 'error') {
5998
6023
  return;
5999
6024
  }
6025
+ if (this.formComp?.hasPendingReactiveDeterminations?.())
6026
+ return;
6000
6027
  if (this.modal.closeOnSave === false) {
6001
6028
  this.saveState();
6002
6029
  return;
@@ -6012,6 +6039,24 @@ class DynamicFormDialogHostComponent {
6012
6039
  }
6013
6040
  }
6014
6041
  onCancel() {
6042
+ if (this.formComp?.hasPendingReactiveDeterminations?.()) {
6043
+ void this.formComp.waitForReactiveDeterminations().then((stable) => {
6044
+ if (stable)
6045
+ this.continueCancel();
6046
+ });
6047
+ return;
6048
+ }
6049
+ this.continueCancel();
6050
+ }
6051
+ onReactiveDeterminationExecuted(event) {
6052
+ this.reactiveDeterminationExecuted.emit(event);
6053
+ this.data.reactiveDeterminationCallbacks?.onEvent?.(event);
6054
+ }
6055
+ onReactiveDeterminationPendingChange(pending) {
6056
+ this.reactiveDeterminationPendingChange.emit(pending);
6057
+ this.data.reactiveDeterminationCallbacks?.onPendingChange?.(pending);
6058
+ }
6059
+ continueCancel() {
6015
6060
  if (this.surfaceRef) {
6016
6061
  void this.canLeaveSurfaceFrame().then((allowed) => {
6017
6062
  if (!allowed)
@@ -6048,6 +6093,11 @@ class DynamicFormDialogHostComponent {
6048
6093
  }
6049
6094
  }
6050
6095
  async canLeaveSurfaceFrame() {
6096
+ if (this.formComp?.hasPendingReactiveDeterminations?.()) {
6097
+ const stable = await this.formComp.waitForReactiveDeterminations();
6098
+ if (!stable)
6099
+ return false;
6100
+ }
6051
6101
  if (this.terminalClose || !this.formComp?.form.dirty) {
6052
6102
  return true;
6053
6103
  }
@@ -6187,7 +6237,7 @@ class DynamicFormDialogHostComponent {
6187
6237
  return { ...horizontal, ...vertical };
6188
6238
  }
6189
6239
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DynamicFormDialogHostComponent, deps: [{ token: MatDialogRef, optional: true }, { token: MAT_DIALOG_DATA, optional: true }, { token: DialogService }, { token: i2$1.GenericCrudService }, { token: ASYNC_CONFIG_STORAGE }, { token: SURFACE_DRAWER_REF, optional: true }, { token: SURFACE_DRAWER_CONTENT_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component });
6190
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: DynamicFormDialogHostComponent, isStandalone: true, selector: "praxis-dynamic-form-dialog-host", host: { properties: { "attr.data-density": "modal.density || \"default\"", "attr.data-presentation": "presentation", "class.praxis-drawer": "presentation === \"drawer\"", "class.praxis-surface-frame": "isSurfaceFrame" }, classAttribute: "praxis-dialog" }, providers: [
6240
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: DynamicFormDialogHostComponent, isStandalone: true, selector: "praxis-dynamic-form-dialog-host", outputs: { reactiveDeterminationExecuted: "reactiveDeterminationExecuted", reactiveDeterminationPendingChange: "reactiveDeterminationPendingChange" }, host: { properties: { "attr.data-density": "modal.density || \"default\"", "attr.data-presentation": "presentation", "class.praxis-drawer": "presentation === \"drawer\"", "class.praxis-surface-frame": "isSurfaceFrame" }, classAttribute: "praxis-dialog" }, providers: [
6191
6241
  GenericCrudService,
6192
6242
  providePraxisI18nConfig(PRAXIS_CRUD_RUNTIME_I18N_CONFIG),
6193
6243
  ], viewQueries: [{ propertyName: "formComp", first: true, predicate: PraxisDynamicForm, descendants: true }], ngImport: i0, template: `
@@ -6286,9 +6336,11 @@ class DynamicFormDialogHostComponent {
6286
6336
  [actions]="formActions"
6287
6337
  (formSubmit)="onSave($event)"
6288
6338
  (formCancel)="onCancel()"
6339
+ (reactiveDeterminationExecuted)="onReactiveDeterminationExecuted($event)"
6340
+ (reactiveDeterminationPendingChange)="onReactiveDeterminationPendingChange($event)"
6289
6341
  ></praxis-dynamic-form>
6290
6342
  </mat-dialog-content>
6291
- `, isInline: true, styles: ["praxis-dynamic-form-dialog-host{--dlg-header-h: 56px;--dlg-footer-h: 56px;--dlg-pad: 16px;display:flex;flex-direction:column;height:100%;overflow:hidden}praxis-dynamic-form-dialog-host[data-density=compact]{--dlg-header-h: 44px;--dlg-footer-h: 44px;--dlg-pad: 12px}praxis-dynamic-form-dialog-host .dialog-header{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:var(--dlg-pad);min-height:var(--dlg-header-h);padding:10px var(--dlg-pad);margin:0;background:var(--md-sys-color-surface-container-high);border-bottom:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-title{margin:0;font:inherit;font-weight:600;color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-heading{display:grid;min-width:0;gap:2px}praxis-dynamic-form-dialog-host .dialog-title-icon{display:inline-grid;flex:0 0 auto;width:36px;height:36px;place-items:center;border-radius:10px;color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}praxis-dynamic-form-dialog-host .dialog-title-icon mat-icon{width:22px;height:22px;font-size:22px}praxis-dynamic-form-dialog-host .dialog-subtitle{display:-webkit-box;overflow:hidden;color:var(--md-sys-color-on-surface-variant);font-size:.82rem;font-weight:400;line-height:1.35;-webkit-box-orient:vertical;-webkit-line-clamp:2}praxis-dynamic-form-dialog-host .spacer{flex:1}praxis-dynamic-form-dialog-host .dialog-content{flex:1 1 auto;overflow:auto;padding:var(--dlg-pad);max-height:calc(100svh - var(--dlg-header-h) - 32px)}praxis-dynamic-form-dialog-host .crud-operation-context{position:sticky;top:0;z-index:1;display:grid;gap:.75rem;margin-block-end:var(--dlg-pad);padding-block:.5rem .75rem;background:var(--pfx-form-surface, var(--md-sys-color-surface));border-bottom:1px solid var(--md-sys-color-outline-variant)}praxis-dynamic-form-dialog-host .crud-resource-identity{display:grid;gap:.25rem;min-width:0}praxis-dynamic-form-dialog-host .crud-resource-identity__label{color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-label-medium, 500 .75rem/1rem inherit)}praxis-dynamic-form-dialog-host.praxis-drawer{--dlg-header-h: 72px;width:100%;min-width:0;max-width:100vw;height:100dvh;background:var(--pfx-form-surface, var(--md-sys-color-surface));color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-header{background:color-mix(in srgb,var(--md-sys-color-surface-container-high, var(--md-sys-color-surface)),transparent 4%)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content{display:flex;flex-direction:column;max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form{display:block;flex:1 1 auto;min-height:0}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form>.praxis-dynamic-form{min-height:100%}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form>.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections]{margin-top:auto;padding-top:var(--pfx-actions-gap-top, var(--pfx-section-gap, 20px))}praxis-dynamic-form-dialog-host.praxis-surface-frame .dialog-content{max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button{color:var(--md-sys-color-on-surface-variant)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button:hover{color:var(--md-sys-color-primary)}praxis-dynamic-form-dialog-host .dialog-footer{position:sticky;bottom:0;z-index:1;padding:var(--dlg-pad)}.pfx-blur-backdrop{background-color:var(--pfx-backdrop, rgba(15, 23, 42, .42))!important;backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%);-webkit-backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%)}.pfx-transparent-backdrop{background-color:transparent!important}.cdk-overlay-pane.pfx-dialog-pane{overflow:hidden;transition:width .2s ease,height .2s ease,margin .2s ease}.cdk-overlay-pane.pfx-dialog-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane .mdc-dialog__surface{display:flex;flex-direction:column;width:100%;min-width:0;height:100%;max-height:inherit;overflow:hidden;background:var(--pfx-form-surface, var(--md-sys-color-surface))!important;border:1px solid var(--pfx-form-stroke, var(--md-sys-color-outline-variant))!important}.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mdc-dialog__surface{backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.cdk-overlay-pane.pfx-drawer-pane{margin:0!important;border-radius:0!important;box-shadow:var(--md-sys-elevation-level3, 0 24px 80px rgba(15, 23, 42, .28)),0 0 0 1px color-mix(in srgb,var(--md-sys-color-outline, #64748b) 24%,transparent)}.cdk-overlay-pane.pfx-drawer-pane.pfx-drawer-maximized{margin:var(--pfx-drawer-edge-gap, 8px)!important}.cdk-overlay-pane.pfx-drawer-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-drawer-pane .mdc-dialog__surface{min-width:0!important;border-radius:0!important}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisResourceIdentityComponent, selector: "praxis-resource-identity", inputs: ["identity", "emptyTitle", "density", "showMetadataLabels", "showKeyLabel", "ariaLabel"] }, { kind: "component", type: PraxisDynamicForm, selector: "praxis-dynamic-form", inputs: ["resourcePath", "resourceId", "initialValue", "editorialContext", "mode", "config", "actions", "schemaSource", "schemaUrl", "readUrl", "submitUrl", "submitMethod", "submitIdempotencyKey", "submitCorrelationId", "submitResourceVersion", "responseSchemaUrl", "apiEndpointKey", "apiUrlEntry", "enableCustomization", "showAiAssistant", "formId", "componentInstanceId", "configPersistenceStrategy", "layout", "generatedLayoutPreset", "layoutPolicy", "backConfig", "hooks", "removeEmptyContainersOnSave", "reactiveValidation", "reactiveValidationDebounceMs", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "readonlyModeGlobal", "disabledModeGlobal", "presentationModeGlobal", "visibleGlobal", "fieldIconPolicy", "domainRules", "customEndpoints"], outputs: ["formSubmit", "formCancel", "formReset", "configChange", "configPatchChange", "formReady", "valueChange", "syncCompleted", "initializationError", "loadingStateChange", "enableCustomizationChange", "customAction", "actionConfirmation", "schemaStatusChange", "fieldRenderError", "ruleDiagnosticsChange", "formEffectExecuted"] }], encapsulation: i0.ViewEncapsulation.None });
6343
+ `, isInline: true, styles: ["praxis-dynamic-form-dialog-host{--dlg-header-h: 56px;--dlg-footer-h: 56px;--dlg-pad: 16px;display:flex;flex-direction:column;height:100%;overflow:hidden}praxis-dynamic-form-dialog-host[data-density=compact]{--dlg-header-h: 44px;--dlg-footer-h: 44px;--dlg-pad: 12px}praxis-dynamic-form-dialog-host .dialog-header{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:var(--dlg-pad);min-height:var(--dlg-header-h);padding:10px var(--dlg-pad);margin:0;background:var(--md-sys-color-surface-container-high);border-bottom:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-title{margin:0;font:inherit;font-weight:600;color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-heading{display:grid;min-width:0;gap:2px}praxis-dynamic-form-dialog-host .dialog-title-icon{display:inline-grid;flex:0 0 auto;width:36px;height:36px;place-items:center;border-radius:10px;color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}praxis-dynamic-form-dialog-host .dialog-title-icon mat-icon{width:22px;height:22px;font-size:22px}praxis-dynamic-form-dialog-host .dialog-subtitle{display:-webkit-box;overflow:hidden;color:var(--md-sys-color-on-surface-variant);font-size:.82rem;font-weight:400;line-height:1.35;-webkit-box-orient:vertical;-webkit-line-clamp:2}praxis-dynamic-form-dialog-host .spacer{flex:1}praxis-dynamic-form-dialog-host .dialog-content{flex:1 1 auto;overflow:auto;padding:var(--dlg-pad);max-height:calc(100svh - var(--dlg-header-h) - 32px)}praxis-dynamic-form-dialog-host .crud-operation-context{position:sticky;top:0;z-index:1;display:grid;gap:.75rem;margin-block-end:var(--dlg-pad);padding-block:.5rem .75rem;background:var(--pfx-form-surface, var(--md-sys-color-surface));border-bottom:1px solid var(--md-sys-color-outline-variant)}praxis-dynamic-form-dialog-host .crud-resource-identity{display:grid;gap:.25rem;min-width:0}praxis-dynamic-form-dialog-host .crud-resource-identity__label{color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-label-medium, 500 .75rem/1rem inherit)}praxis-dynamic-form-dialog-host.praxis-drawer{--dlg-header-h: 72px;width:100%;min-width:0;max-width:100vw;height:100dvh;background:var(--pfx-form-surface, var(--md-sys-color-surface));color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-header{background:color-mix(in srgb,var(--md-sys-color-surface-container-high, var(--md-sys-color-surface)),transparent 4%)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content{display:flex;flex-direction:column;max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form{display:block;flex:1 1 auto;min-height:0}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form>.praxis-dynamic-form{min-height:100%}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form>.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections]{margin-top:auto;padding-top:var(--pfx-actions-gap-top, var(--pfx-section-gap, 20px))}praxis-dynamic-form-dialog-host.praxis-surface-frame .dialog-content{max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button{color:var(--md-sys-color-on-surface-variant)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button:hover{color:var(--md-sys-color-primary)}praxis-dynamic-form-dialog-host .dialog-footer{position:sticky;bottom:0;z-index:1;padding:var(--dlg-pad)}.pfx-blur-backdrop{background-color:var(--pfx-backdrop, rgba(15, 23, 42, .42))!important;backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%);-webkit-backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%)}.pfx-transparent-backdrop{background-color:transparent!important}.cdk-overlay-pane.pfx-dialog-pane{overflow:hidden;transition:width .2s ease,height .2s ease,margin .2s ease}.cdk-overlay-pane.pfx-dialog-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane .mdc-dialog__surface{display:flex;flex-direction:column;width:100%;min-width:0;height:100%;max-height:inherit;overflow:hidden;background:var(--pfx-form-surface, var(--md-sys-color-surface))!important;border:1px solid var(--pfx-form-stroke, var(--md-sys-color-outline-variant))!important}.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mdc-dialog__surface{backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.cdk-overlay-pane.pfx-drawer-pane{margin:0!important;border-radius:0!important;box-shadow:var(--md-sys-elevation-level3, 0 24px 80px rgba(15, 23, 42, .28)),0 0 0 1px color-mix(in srgb,var(--md-sys-color-outline, #64748b) 24%,transparent)}.cdk-overlay-pane.pfx-drawer-pane.pfx-drawer-maximized{margin:var(--pfx-drawer-edge-gap, 8px)!important}.cdk-overlay-pane.pfx-drawer-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-drawer-pane .mdc-dialog__surface{min-width:0!important;border-radius:0!important}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisResourceIdentityComponent, selector: "praxis-resource-identity", inputs: ["identity", "emptyTitle", "density", "showMetadataLabels", "showKeyLabel", "ariaLabel"] }, { kind: "component", type: PraxisDynamicForm, selector: "praxis-dynamic-form", inputs: ["resourcePath", "resourceId", "initialValue", "editorialContext", "mode", "config", "actions", "schemaSource", "schemaUrl", "readUrl", "submitUrl", "submitMethod", "submitIdempotencyKey", "submitCorrelationId", "submitResourceVersion", "responseSchemaUrl", "apiEndpointKey", "apiUrlEntry", "enableCustomization", "showAiAssistant", "formId", "componentInstanceId", "configPersistenceStrategy", "layout", "generatedLayoutPreset", "layoutPolicy", "backConfig", "hooks", "removeEmptyContainersOnSave", "reactiveValidation", "reactiveValidationDebounceMs", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "readonlyModeGlobal", "disabledModeGlobal", "presentationModeGlobal", "visibleGlobal", "fieldIconPolicy", "domainRules", "customEndpoints"], outputs: ["formSubmit", "formCancel", "formReset", "configChange", "configPatchChange", "formReady", "valueChange", "syncCompleted", "initializationError", "loadingStateChange", "enableCustomizationChange", "customAction", "actionConfirmation", "schemaStatusChange", "fieldRenderError", "ruleDiagnosticsChange", "reactiveDeterminationExecuted", "reactiveDeterminationPendingChange"] }], encapsulation: i0.ViewEncapsulation.None });
6292
6344
  }
6293
6345
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DynamicFormDialogHostComponent, decorators: [{
6294
6346
  type: Component,
@@ -6404,6 +6456,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
6404
6456
  [actions]="formActions"
6405
6457
  (formSubmit)="onSave($event)"
6406
6458
  (formCancel)="onCancel()"
6459
+ (reactiveDeterminationExecuted)="onReactiveDeterminationExecuted($event)"
6460
+ (reactiveDeterminationPendingChange)="onReactiveDeterminationPendingChange($event)"
6407
6461
  ></praxis-dynamic-form>
6408
6462
  </mat-dialog-content>
6409
6463
  `, styles: ["praxis-dynamic-form-dialog-host{--dlg-header-h: 56px;--dlg-footer-h: 56px;--dlg-pad: 16px;display:flex;flex-direction:column;height:100%;overflow:hidden}praxis-dynamic-form-dialog-host[data-density=compact]{--dlg-header-h: 44px;--dlg-footer-h: 44px;--dlg-pad: 12px}praxis-dynamic-form-dialog-host .dialog-header{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:var(--dlg-pad);min-height:var(--dlg-header-h);padding:10px var(--dlg-pad);margin:0;background:var(--md-sys-color-surface-container-high);border-bottom:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-title{margin:0;font:inherit;font-weight:600;color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-heading{display:grid;min-width:0;gap:2px}praxis-dynamic-form-dialog-host .dialog-title-icon{display:inline-grid;flex:0 0 auto;width:36px;height:36px;place-items:center;border-radius:10px;color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}praxis-dynamic-form-dialog-host .dialog-title-icon mat-icon{width:22px;height:22px;font-size:22px}praxis-dynamic-form-dialog-host .dialog-subtitle{display:-webkit-box;overflow:hidden;color:var(--md-sys-color-on-surface-variant);font-size:.82rem;font-weight:400;line-height:1.35;-webkit-box-orient:vertical;-webkit-line-clamp:2}praxis-dynamic-form-dialog-host .spacer{flex:1}praxis-dynamic-form-dialog-host .dialog-content{flex:1 1 auto;overflow:auto;padding:var(--dlg-pad);max-height:calc(100svh - var(--dlg-header-h) - 32px)}praxis-dynamic-form-dialog-host .crud-operation-context{position:sticky;top:0;z-index:1;display:grid;gap:.75rem;margin-block-end:var(--dlg-pad);padding-block:.5rem .75rem;background:var(--pfx-form-surface, var(--md-sys-color-surface));border-bottom:1px solid var(--md-sys-color-outline-variant)}praxis-dynamic-form-dialog-host .crud-resource-identity{display:grid;gap:.25rem;min-width:0}praxis-dynamic-form-dialog-host .crud-resource-identity__label{color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-label-medium, 500 .75rem/1rem inherit)}praxis-dynamic-form-dialog-host.praxis-drawer{--dlg-header-h: 72px;width:100%;min-width:0;max-width:100vw;height:100dvh;background:var(--pfx-form-surface, var(--md-sys-color-surface));color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-header{background:color-mix(in srgb,var(--md-sys-color-surface-container-high, var(--md-sys-color-surface)),transparent 4%)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content{display:flex;flex-direction:column;max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form{display:block;flex:1 1 auto;min-height:0}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form>.praxis-dynamic-form{min-height:100%}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form>.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections]{margin-top:auto;padding-top:var(--pfx-actions-gap-top, var(--pfx-section-gap, 20px))}praxis-dynamic-form-dialog-host.praxis-surface-frame .dialog-content{max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button{color:var(--md-sys-color-on-surface-variant)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button:hover{color:var(--md-sys-color-primary)}praxis-dynamic-form-dialog-host .dialog-footer{position:sticky;bottom:0;z-index:1;padding:var(--dlg-pad)}.pfx-blur-backdrop{background-color:var(--pfx-backdrop, rgba(15, 23, 42, .42))!important;backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%);-webkit-backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%)}.pfx-transparent-backdrop{background-color:transparent!important}.cdk-overlay-pane.pfx-dialog-pane{overflow:hidden;transition:width .2s ease,height .2s ease,margin .2s ease}.cdk-overlay-pane.pfx-dialog-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane .mdc-dialog__surface{display:flex;flex-direction:column;width:100%;min-width:0;height:100%;max-height:inherit;overflow:hidden;background:var(--pfx-form-surface, var(--md-sys-color-surface))!important;border:1px solid var(--pfx-form-stroke, var(--md-sys-color-outline-variant))!important}.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mdc-dialog__surface{backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.cdk-overlay-pane.pfx-drawer-pane{margin:0!important;border-radius:0!important;box-shadow:var(--md-sys-elevation-level3, 0 24px 80px rgba(15, 23, 42, .28)),0 0 0 1px color-mix(in srgb,var(--md-sys-color-outline, #64748b) 24%,transparent)}.cdk-overlay-pane.pfx-drawer-pane.pfx-drawer-maximized{margin:var(--pfx-drawer-edge-gap, 8px)!important}.cdk-overlay-pane.pfx-drawer-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-drawer-pane .mdc-dialog__surface{min-width:0!important;border-radius:0!important}\n"] }]
@@ -6433,6 +6487,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
6433
6487
  }] }], propDecorators: { formComp: [{
6434
6488
  type: ViewChild,
6435
6489
  args: [PraxisDynamicForm]
6490
+ }], reactiveDeterminationExecuted: [{
6491
+ type: Output
6492
+ }], reactiveDeterminationPendingChange: [{
6493
+ type: Output
6436
6494
  }] } });
6437
6495
  function getFormSubmitStage(result) {
6438
6496
  if (!result || typeof result !== 'object' || !('stage' in result)) {
@@ -6739,6 +6797,16 @@ const PRAXIS_CRUD_COMPONENT_METADATA = {
6739
6797
  type: '{ id: string | number }',
6740
6798
  description: 'Emitido ao deletar.',
6741
6799
  },
6800
+ {
6801
+ name: 'reactiveDeterminationExecuted',
6802
+ type: '{ action: string; event: ReactiveDeterminationExecutionEvent }',
6803
+ description: 'Evidencia metadata-only encaminhada pelo formulario aberto, com contexto da acao CRUD.',
6804
+ },
6805
+ {
6806
+ name: 'reactiveDeterminationPendingChange',
6807
+ type: '{ action: string; pending: boolean }',
6808
+ description: 'Estado agregado de estabilizacao do formulario aberto, sem valores sensiveis.',
6809
+ },
6742
6810
  {
6743
6811
  name: 'rowClick',
6744
6812
  type: '{ row: unknown; index: number }',
package/package.json CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "name": "@praxisui/crud",
3
- "version": "9.0.5-rc.12",
3
+ "version": "9.0.5-rc.13",
4
4
  "description": "CRUD building blocks for Praxis UI: integrates dynamic forms and tables with unified configuration and services.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
7
7
  "@angular/core": "^21.0.0",
8
- "@praxisui/dynamic-form": "^9.0.5-rc.12",
9
- "@praxisui/table": "^9.0.5-rc.12",
10
- "@praxisui/core": "^9.0.5-rc.12",
11
- "@praxisui/dynamic-fields": "^9.0.5-rc.12",
12
- "@praxisui/settings-panel": "^9.0.5-rc.12",
8
+ "@praxisui/dynamic-form": "^9.0.5-rc.13",
9
+ "@praxisui/table": "^9.0.5-rc.13",
10
+ "@praxisui/core": "^9.0.5-rc.13",
11
+ "@praxisui/dynamic-fields": "^9.0.5-rc.13",
12
+ "@praxisui/settings-panel": "^9.0.5-rc.13",
13
13
  "@angular/cdk": "^21.0.0",
14
14
  "@angular/forms": "^21.0.0",
15
15
  "@angular/material": "^21.0.0",
16
16
  "@angular/router": "^21.0.0",
17
- "@praxisui/ai": "^9.0.5-rc.12",
17
+ "@praxisui/ai": "^9.0.5-rc.13",
18
18
  "rxjs": "~7.8.0"
19
19
  },
20
20
  "dependencies": {
@@ -51,6 +51,23 @@ interface CrudDrawerResult {
51
51
  type: CrudDrawerResultType;
52
52
  data?: Record<string, unknown>;
53
53
  }
54
+ /** Minimal structural evidence contract kept local to the light entrypoint. */
55
+ interface CrudReactiveDeterminationExecutionEvent {
56
+ determinationId: string;
57
+ operationId: string;
58
+ status: 'pending' | 'success' | 'skipped' | 'error';
59
+ sourcePaths: string[];
60
+ targetPaths: string[];
61
+ appliedTargetPaths?: string[];
62
+ correlationId: string;
63
+ durationMs: number;
64
+ reason?: string;
65
+ provenance: {
66
+ kind: 'platform' | 'host';
67
+ source: string;
68
+ version?: string;
69
+ };
70
+ }
54
71
  interface CrudDrawerOpenConfig {
55
72
  action: CrudAction;
56
73
  metadata: CrudMetadata;
@@ -68,6 +85,10 @@ interface CrudDrawerOpenConfig {
68
85
  * Hosts podem propagar `save/delete/close` para sincronizar telemetria/eventos.
69
86
  */
70
87
  onResult?: (result: CrudDrawerResult) => void;
88
+ /** Bind to the child form's metadata-only determination evidence. */
89
+ onReactiveDetermination?: (event: CrudReactiveDeterminationExecutionEvent) => void;
90
+ /** Bind to pending state and refuse every adapter-owned close/submit while true. */
91
+ onReactiveDeterminationPendingChange?: (pending: boolean) => void;
71
92
  }
72
93
  interface CrudDrawerAdapter {
73
94
  open(config: CrudDrawerOpenConfig): Promise<void> | void;
@@ -84,4 +105,4 @@ interface DialogConfig<D = any> extends MatDialogConfig<D> {
84
105
  declare const CRUD_DRAWER_ADAPTER: InjectionToken<CrudDrawerAdapter>;
85
106
 
86
107
  export { CRUD_DRAWER_ADAPTER };
87
- export type { CrudAction, CrudDefaults, CrudDrawerAdapter, CrudDrawerOpenConfig, CrudDrawerResult, CrudDrawerResultType, CrudHeaderConfig, CrudMetadata, CrudParamMapping, CrudResource, DialogConfig, FormOpenMode };
108
+ export type { CrudAction, CrudDefaults, CrudDrawerAdapter, CrudDrawerOpenConfig, CrudDrawerResult, CrudDrawerResultType, CrudHeaderConfig, CrudMetadata, CrudParamMapping, CrudReactiveDeterminationExecutionEvent, CrudResource, DialogConfig, FormOpenMode };
@@ -1,7 +1,7 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { NgZone, OnChanges, EventEmitter, SimpleChanges, OnInit, AfterViewInit, Provider, OnDestroy } from '@angular/core';
3
3
  import * as _praxisui_core from '@praxisui/core';
4
- import { RowAction, ToolbarAction, ApiEndpoint, ApiUrlEntry, DynamicFormLayoutPolicy, BackConfig, TableConfig, PraxisDataQueryContext, FormConfig, ResourceActionCatalogItem, ResourceSurfaceCatalogItem, MaterializedResourceIdentity, LoadingState, RestApiLinks, ResourceCapabilitySnapshot, SurfaceDrawerRef, GenericCrudService, AsyncConfigStorage, ComponentDocMeta, AiCapabilityCatalog, AiCapability, AiCapabilityCategory, AiValueKind, ComponentAuthoringManifest, SettingsValueProvider } from '@praxisui/core';
4
+ import { RowAction, ToolbarAction, ApiEndpoint, ApiUrlEntry, DynamicFormLayoutPolicy, BackConfig, TableConfig, PraxisDataQueryContext, FormConfig, ReactiveDeterminationExecutionEvent, ResourceActionCatalogItem, ResourceSurfaceCatalogItem, MaterializedResourceIdentity, LoadingState, RestApiLinks, ResourceCapabilitySnapshot, SurfaceDrawerRef, GenericCrudService, AsyncConfigStorage, ComponentDocMeta, AiCapabilityCatalog, AiCapability, AiCapabilityCategory, AiValueKind, ComponentAuthoringManifest, SettingsValueProvider } from '@praxisui/core';
5
5
  export { BackConfig } from '@praxisui/core';
6
6
  import { TableConfigPersistenceStrategy } from '@praxisui/table';
7
7
  import { MatDialogConfig, MatDialogRef, MatDialog } from '@angular/material/dialog';
@@ -192,6 +192,15 @@ declare class PraxisCrudComponent implements OnChanges {
192
192
  afterDelete: EventEmitter<{
193
193
  id: string | number;
194
194
  }>;
195
+ /** Metadata-only Reactive Determination evidence from an open form host. */
196
+ reactiveDeterminationExecuted: EventEmitter<{
197
+ action: string;
198
+ event: ReactiveDeterminationExecutionEvent;
199
+ }>;
200
+ reactiveDeterminationPendingChange: EventEmitter<{
201
+ action: string;
202
+ pending: boolean;
203
+ }>;
195
204
  error: EventEmitter<unknown>;
196
205
  rowClick: EventEmitter<unknown>;
197
206
  /** Emits the canonical table row-action envelope before the CRUD handles its surface/action. */
@@ -354,7 +363,7 @@ declare class PraxisCrudComponent implements OnChanges {
354
363
  private txWithParams;
355
364
  private interpolateTranslationParams;
356
365
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<PraxisCrudComponent, never>;
357
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<PraxisCrudComponent, "praxis-crud", never, { "metadata": { "alias": "metadata"; "required": true; }; "crudId": { "alias": "crudId"; "required": true; }; "componentInstanceId": { "alias": "componentInstanceId"; "required": false; }; "tableConfigPersistenceStrategy": { "alias": "tableConfigPersistenceStrategy"; "required": false; }; "context": { "alias": "context"; "required": false; }; "enableCustomization": { "alias": "enableCustomization"; "required": false; }; "authoringCapability": { "alias": "authoringCapability"; "required": false; }; }, { "configureRequested": "configureRequested"; "afterOpen": "afterOpen"; "afterClose": "afterClose"; "afterSave": "afterSave"; "afterDelete": "afterDelete"; "error": "error"; "rowClick": "rowClick"; "rowAction": "rowAction"; "selectionChange": "selectionChange"; "tableRuntimeConfigChange": "tableRuntimeConfigChange"; "crudAuthoringDocumentApplied": "crudAuthoringDocumentApplied"; "crudAuthoringDocumentSaved": "crudAuthoringDocumentSaved"; }, never, never, true, never>;
366
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<PraxisCrudComponent, "praxis-crud", never, { "metadata": { "alias": "metadata"; "required": true; }; "crudId": { "alias": "crudId"; "required": true; }; "componentInstanceId": { "alias": "componentInstanceId"; "required": false; }; "tableConfigPersistenceStrategy": { "alias": "tableConfigPersistenceStrategy"; "required": false; }; "context": { "alias": "context"; "required": false; }; "enableCustomization": { "alias": "enableCustomization"; "required": false; }; "authoringCapability": { "alias": "authoringCapability"; "required": false; }; }, { "configureRequested": "configureRequested"; "afterOpen": "afterOpen"; "afterClose": "afterClose"; "afterSave": "afterSave"; "afterDelete": "afterDelete"; "reactiveDeterminationExecuted": "reactiveDeterminationExecuted"; "reactiveDeterminationPendingChange": "reactiveDeterminationPendingChange"; "error": "error"; "rowClick": "rowClick"; "rowAction": "rowAction"; "selectionChange": "selectionChange"; "tableRuntimeConfigChange": "tableRuntimeConfigChange"; "crudAuthoringDocumentApplied": "crudAuthoringDocumentApplied"; "crudAuthoringDocumentSaved": "crudAuthoringDocumentSaved"; }, never, never, true, never>;
358
367
  }
359
368
 
360
369
  type CrudDrawerResultType = 'save' | 'delete' | 'close';
@@ -362,6 +371,36 @@ interface CrudDrawerResult {
362
371
  type: CrudDrawerResultType;
363
372
  data?: Record<string, unknown>;
364
373
  }
374
+ interface CrudDrawerOpenConfig {
375
+ action: CrudAction;
376
+ metadata: CrudMetadata;
377
+ inputs: Record<string, unknown>;
378
+ /** Read-only record context for existing-record drawers. It is never part of form inputs or submit payloads. */
379
+ resourceIdentity?: MaterializedResourceIdentity | null;
380
+ /** Read-only task scope for related operations. It is never part of form inputs or submit payloads. */
381
+ contextIdentity?: MaterializedResourceIdentity | null;
382
+ /**
383
+ * Ephemeral focus policy resolved for this opening. A host adapter must
384
+ * forward it to its native overlay and must never persist, clone, or put it
385
+ * into form inputs or submit payloads. When a responsive render replaces a
386
+ * detached HTMLElement, an adapter should recover the matching
387
+ * `data-praxis-focus-key` element before focusing it.
388
+ */
389
+ restoreFocus?: boolean | string | HTMLElement;
390
+ /**
391
+ * Notifica fechamento do drawer (cancelamento/fechamento externo/resultado finalizado).
392
+ */
393
+ onClose?: () => void;
394
+ /**
395
+ * Notifica resultado semântico do fluxo em drawer.
396
+ * Hosts podem propagar `save/delete/close` para sincronizar telemetria/eventos.
397
+ */
398
+ onResult?: (result: CrudDrawerResult) => void;
399
+ /** Bind to the child Dynamic Form metadata-only execution event. */
400
+ onReactiveDetermination?: (event: ReactiveDeterminationExecutionEvent) => void;
401
+ /** Bind to the child pending event and guard every adapter-owned close/submit. */
402
+ onReactiveDeterminationPendingChange?: (pending: boolean) => void;
403
+ }
365
404
 
366
405
  interface CrudLaunchRuntime {
367
406
  capabilities?: ResourceCapabilitySnapshot | null;
@@ -386,6 +425,8 @@ declare class CrudLauncherService {
386
425
  launch(action: CrudAction, row: Record<string, unknown> | undefined, metadata: CrudMetadata, componentKeyId?: string | null, drawerCallbacks?: {
387
426
  onClose?: () => void;
388
427
  onResult?: (result: CrudDrawerResult) => void;
428
+ onReactiveDetermination?: CrudDrawerOpenConfig['onReactiveDetermination'];
429
+ onReactiveDeterminationPendingChange?: CrudDrawerOpenConfig['onReactiveDeterminationPendingChange'];
389
430
  }, runtime?: CrudLaunchRuntime): Promise<{
390
431
  mode: FormOpenMode;
391
432
  ref?: DialogRef<any>;
@@ -431,6 +472,8 @@ declare class DynamicFormDialogHostComponent implements OnInit, AfterViewInit {
431
472
  private configStorage;
432
473
  private readonly surfaceRef;
433
474
  formComp?: PraxisDynamicForm;
475
+ reactiveDeterminationExecuted: EventEmitter<ReactiveDeterminationExecutionEvent>;
476
+ reactiveDeterminationPendingChange: EventEmitter<boolean>;
434
477
  modal: any;
435
478
  presentation: 'modal' | 'drawer' | 'surface-frame';
436
479
  maximized: boolean;
@@ -482,6 +525,9 @@ declare class DynamicFormDialogHostComponent implements OnInit, AfterViewInit {
482
525
  ngAfterViewInit(): void;
483
526
  onSave(result: unknown): void;
484
527
  onCancel(): void;
528
+ onReactiveDeterminationExecuted(event: ReactiveDeterminationExecutionEvent): void;
529
+ onReactiveDeterminationPendingChange(pending: boolean): void;
530
+ private continueCancel;
485
531
  private canLeaveSurfaceFrame;
486
532
  toggleMaximize(initial?: boolean): void;
487
533
  private resolveOverlayPane;
@@ -491,7 +537,7 @@ declare class DynamicFormDialogHostComponent implements OnInit, AfterViewInit {
491
537
  private updateHostPosition;
492
538
  private resolveMaximizedDrawerPosition;
493
539
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<DynamicFormDialogHostComponent, [{ optional: true; }, { optional: true; }, null, null, null, { optional: true; }, { optional: true; }]>;
494
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<DynamicFormDialogHostComponent, "praxis-dynamic-form-dialog-host", never, {}, {}, never, never, true, never>;
540
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DynamicFormDialogHostComponent, "praxis-dynamic-form-dialog-host", never, {}, { "reactiveDeterminationExecuted": "reactiveDeterminationExecuted"; "reactiveDeterminationPendingChange": "reactiveDeterminationPendingChange"; }, never, never, true, never>;
495
541
  }
496
542
 
497
543
  /** Metadata for PraxisCrudComponent */