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

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
@@ -118,6 +118,16 @@ The component keeps `crudContext` stable for change detection and refreshes the
118
118
 
119
119
  `@praxisui/crud` owns CRUD orchestration: list surface, create/edit/view/delete actions, open mode resolution, parameter mapping, `initialValue`, back policy, and stable handoff to the form host.
120
120
 
121
+ For inferred canonical actions, discovery and launcher resolution are sequential
122
+ decision stages, not equivalent retry mechanisms. The launcher is considered
123
+ only when discovery did not select an executable surface. Once a governed
124
+ surface has been selected, a synchronous or asynchronous open failure is
125
+ fail-closed: the runtime emits the error and a correlated structured diagnostic
126
+ without attempting a second drawer/modal/route path. A table nested in
127
+ `PraxisCrudComponent` always delegates the action to that CRUD owner; a
128
+ standalone table owns its `surface.open` attempt and follows the same
129
+ single-path rule.
130
+
121
131
  Child component semantics stay with their owners:
122
132
 
123
133
  - table configuration belongs to `@praxisui/table`
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-08-12T23:49:15.227Z",
3
+ "generatedAt": "2026-08-13T13:48:00.302Z",
4
4
  "packageName": "@praxisui/crud",
5
- "packageVersion": "9.0.5-rc.10",
5
+ "packageVersion": "9.0.5-rc.12",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 2,
@@ -6,7 +6,7 @@ import { Router, ActivatedRoute, RouterLink } from '@angular/router';
6
6
  import { MatSnackBar } from '@angular/material/snack-bar';
7
7
  import { firstValueFrom, BehaviorSubject, Subscription } from 'rxjs';
8
8
  import * as i2$1 from '@praxisui/core';
9
- import { ASYNC_CONFIG_STORAGE, GlobalConfigService, CrudOperationResolutionService, LoggerService, SurfaceNavigationError, fillUndefined, SETTINGS_PANEL_DATA, PraxisI18nService, PraxisIconDirective, providePraxisI18nConfig, createDefaultTableConfig, EnterpriseRuntimeContextService, GLOBAL_SURFACE_SERVICE, SurfaceOutletRegistryService, ComponentKeyService, ResourceDiscoveryService, ResourceActionOpenAdapterService, ResourceSurfaceOpenAdapterService, normalizeSurfaceOperationContext, translateUnavailableWorkflowMessage, isSurfaceNavigationError, translateSurfaceNavigationRejected, EmptyStateCardComponent, RESOURCE_DISCOVERY_I18N_CONFIG, SURFACE_DRAWER_REF, SURFACE_DRAWER_CONTENT_DATA, PraxisIconButtonComponent, PraxisResourceIdentityComponent, GenericCrudService, ComponentMetadataRegistry } from '@praxisui/core';
9
+ import { ASYNC_CONFIG_STORAGE, GlobalConfigService, CrudOperationResolutionService, LoggerService, SurfaceNavigationError, fillUndefined, SETTINGS_PANEL_DATA, PraxisI18nService, PraxisIconDirective, providePraxisI18nConfig, createDefaultTableConfig, EnterpriseRuntimeContextService, GLOBAL_SURFACE_SERVICE, SurfaceOutletRegistryService, ComponentKeyService, ResourceDiscoveryService, ResourceActionOpenAdapterService, ResourceSurfaceOpenAdapterService, normalizeSurfaceOperationContext, translateUnavailableWorkflowMessage, isSurfaceNavigationError, translateSurfaceNavigationRejected, normalizeUnknownError, EmptyStateCardComponent, RESOURCE_DISCOVERY_I18N_CONFIG, SURFACE_DRAWER_REF, SURFACE_DRAWER_CONTENT_DATA, PraxisIconButtonComponent, PraxisResourceIdentityComponent, GenericCrudService, ComponentMetadataRegistry } from '@praxisui/core';
10
10
  import { SettingsPanelService } from '@praxisui/settings-panel';
11
11
  import { PraxisTableInlineAuthoringEditorComponent, PraxisTable } from '@praxisui/table';
12
12
  import { ConfirmDialogComponent } from '@praxisui/dynamic-fields';
@@ -3834,11 +3834,13 @@ class PraxisCrudComponent {
3834
3834
  snack = inject(MatSnackBar);
3835
3835
  dialog = inject(DialogService);
3836
3836
  i18n = inject(PraxisI18nService);
3837
+ logger = inject(LoggerService, { optional: true });
3837
3838
  injector = inject(Injector);
3838
3839
  resourceDiscoveryInstance;
3839
3840
  actionOpenAdapterInstance;
3840
3841
  surfaceOpenAdapterInstance;
3841
3842
  materializedRefreshSequence = 0;
3843
+ surfaceOpenAttemptSequence = 0;
3842
3844
  global = (() => {
3843
3845
  try {
3844
3846
  return inject(GlobalConfigService);
@@ -4582,6 +4584,12 @@ class PraxisCrudComponent {
4582
4584
  return true;
4583
4585
  }
4584
4586
  const focusOrigin = this.resolveRuntimeFocusOrigin(runtimeEvent);
4587
+ const correlationId = [
4588
+ this.componentKeyId() || this.crudId || 'praxis-crud',
4589
+ 'surface.open',
4590
+ surface.id,
4591
+ ++this.surfaceOpenAttemptSequence,
4592
+ ].join(':');
4585
4593
  let openPromise;
4586
4594
  try {
4587
4595
  const surfaceContext = {
@@ -4592,6 +4600,7 @@ class PraxisCrudComponent {
4592
4600
  resourcePath,
4593
4601
  surfaceId: surface.id,
4594
4602
  operationId: surface.operationId,
4603
+ correlationId,
4595
4604
  },
4596
4605
  runtime: {
4597
4606
  row: row ?? null,
@@ -4607,11 +4616,8 @@ class PraxisCrudComponent {
4607
4616
  openPromise = handledInline ? Promise.resolve(undefined) : Promise.resolve(this.surfaceService.open(payload, surfaceContext));
4608
4617
  }
4609
4618
  catch (error) {
4610
- if (this.notifySurfaceNavigationFailure(error)) {
4611
- this.error.emit(error);
4612
- return true;
4613
- }
4614
- return false;
4619
+ this.reportDiscoveredSurfaceOpenFailure(error, normalizedAction, surface, resourcePath, correlationId);
4620
+ return true;
4615
4621
  }
4616
4622
  try {
4617
4623
  this.bindDiscoveredSurfaceLifecycle(await openPromise);
@@ -4621,8 +4627,7 @@ class PraxisCrudComponent {
4621
4627
  });
4622
4628
  }
4623
4629
  catch (err) {
4624
- this.error.emit(err);
4625
- this.notifySurfaceNavigationFailure(err);
4630
+ this.reportDiscoveredSurfaceOpenFailure(err, normalizedAction, surface, resourcePath, correlationId);
4626
4631
  }
4627
4632
  return true;
4628
4633
  }
@@ -4742,6 +4747,31 @@ class PraxisCrudComponent {
4742
4747
  this.snack.open(translateSurfaceNavigationRejected(this.i18n), undefined, { duration: 4500 });
4743
4748
  return true;
4744
4749
  }
4750
+ reportDiscoveredSurfaceOpenFailure(error, action, surface, resourcePath, correlationId) {
4751
+ const normalizedCause = normalizeUnknownError(error);
4752
+ this.error.emit(error);
4753
+ this.notifySurfaceNavigationFailure(error);
4754
+ this.logger?.warn('Discovered CRUD surface failed to open.', {
4755
+ context: {
4756
+ lib: '@praxisui/crud',
4757
+ component: 'PraxisCrudComponent',
4758
+ actionId: action,
4759
+ correlationId,
4760
+ },
4761
+ data: {
4762
+ surfaceId: surface.id,
4763
+ mode: 'drawer',
4764
+ resourcePath,
4765
+ selectedPath: 'surface.open',
4766
+ fallback: 'none',
4767
+ cause: {
4768
+ name: normalizedCause.name,
4769
+ message: normalizedCause.message,
4770
+ },
4771
+ },
4772
+ throttleKey: `crud:surface.open:${action}:${surface.id}`,
4773
+ });
4774
+ }
4745
4775
  async resolveDiscoveredActionCatalog(row) {
4746
4776
  try {
4747
4777
  if (row) {
package/package.json CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "name": "@praxisui/crud",
3
- "version": "9.0.5-rc.10",
3
+ "version": "9.0.5-rc.12",
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.10",
9
- "@praxisui/table": "^9.0.5-rc.10",
10
- "@praxisui/core": "^9.0.5-rc.10",
11
- "@praxisui/dynamic-fields": "^9.0.5-rc.10",
12
- "@praxisui/settings-panel": "^9.0.5-rc.10",
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",
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.10",
17
+ "@praxisui/ai": "^9.0.5-rc.12",
18
18
  "rxjs": "~7.8.0"
19
19
  },
20
20
  "dependencies": {
@@ -218,11 +218,13 @@ declare class PraxisCrudComponent implements OnChanges {
218
218
  private readonly snack;
219
219
  private readonly dialog;
220
220
  private readonly i18n;
221
+ private readonly logger;
221
222
  private readonly injector;
222
223
  private resourceDiscoveryInstance?;
223
224
  private actionOpenAdapterInstance?;
224
225
  private surfaceOpenAdapterInstance?;
225
226
  private materializedRefreshSequence;
227
+ private surfaceOpenAttemptSequence;
226
228
  private readonly global;
227
229
  private readonly surfaceService;
228
230
  private readonly surfaceOutlets;
@@ -302,6 +304,7 @@ declare class PraxisCrudComponent implements OnChanges {
302
304
  private resolveDiscoveredSurfaceCatalog;
303
305
  private tryOpenDiscoveredWorkflowAction;
304
306
  private notifySurfaceNavigationFailure;
307
+ private reportDiscoveredSurfaceOpenFailure;
305
308
  private resolveDiscoveredActionCatalog;
306
309
  private selectDiscoveredWorkflowAction;
307
310
  private resolveProvidedWorkflowAction;