@praxisui/table 8.0.0-beta.51 → 8.0.0-beta.53

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.
@@ -33,7 +33,7 @@ import * as i13 from '@angular/cdk/drag-drop';
33
33
  import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
34
34
  import { Subject, debounceTime, takeUntil, of, firstValueFrom, BehaviorSubject, Subscription, take as take$1 } from 'rxjs';
35
35
  import * as i1 from '@praxisui/core';
36
- import { LoggerService, createCorporateLoggerConfig, ConsoleLoggerSink, PraxisJsonLogicService, PraxisIconDirective, PraxisI18nService, isTableConfigV2, providePraxisI18nConfig, PRAXIS_GLOBAL_ACTION_CATALOG, SURFACE_OPEN_I18N_NAMESPACE, isRequiredGlobalActionPayloadMissing, getGlobalActionUiSchema, getRequiredGlobalActionPayloadKeys, hasMeaningfulGlobalActionPayloadValue, SurfaceOpenActionEditorComponent, SURFACE_OPEN_I18N_CONFIG, INLINE_FILTER_CONTROL_TYPES, INLINE_FILTER_CONTROL_TYPE_VALUES, FieldControlType, normalizeControlTypeToken, ASYNC_CONFIG_STORAGE, resolveControlTypeAlias, mapFieldDefinitionsToMetadata, PraxisJsonLogicError, GLOBAL_ACTION_CATALOG, GenericCrudService, validateGlobalActionRefs, getGlobalActionCatalog, TableConfigService, createDefaultTableConfig, fillUndefined, deepMerge, INLINE_FILTER_ALIAS_TOKENS, GlobalConfigService, buildSchemaId, MemoryCacheAdapter, LocalStorageCacheAdapter, SchemaMetadataClient, resolveInlineFilterControlType, fetchWithETag, serializeEntityLookupValueForPayload, ComponentMetadataRegistry, AnalyticsStatsRequestBuilderService, buildApiUrl, normalizePraxisDataQueryContext, API_URL, PraxisCollectionExportService, ResourceDiscoveryService, ResourceQuickConnectComponent, translateResourceAvailabilityReason, assertPraxisCollectionExportArtifact, PRAXIS_LOADING_CTX, translateResourceDiscoveryText, supportsImplicitValuePresentation, resolveValuePresentation, translateUnavailableWorkflowMessage, CONNECTION_STORAGE, PRAXIS_LOADING_RENDERER, EmptyStateCardComponent, RESOURCE_DISCOVERY_I18N_CONFIG } from '@praxisui/core';
36
+ import { LoggerService, createCorporateLoggerConfig, ConsoleLoggerSink, PraxisJsonLogicService, PraxisIconDirective, PraxisI18nService, isTableConfigV2, providePraxisI18nConfig, PRAXIS_GLOBAL_ACTION_CATALOG, SURFACE_OPEN_I18N_NAMESPACE, isRequiredGlobalActionPayloadMissing, getGlobalActionUiSchema, getRequiredGlobalActionPayloadKeys, hasMeaningfulGlobalActionPayloadValue, SurfaceOpenActionEditorComponent, SURFACE_OPEN_I18N_CONFIG, INLINE_FILTER_CONTROL_TYPES, INLINE_FILTER_CONTROL_TYPE_VALUES, FieldControlType, normalizeControlTypeToken, ASYNC_CONFIG_STORAGE, resolveControlTypeAlias, mapFieldDefinitionsToMetadata, PraxisJsonLogicError, GLOBAL_ACTION_CATALOG, GenericCrudService, validateGlobalActionRefs, getGlobalActionCatalog, TableConfigService, createDefaultTableConfig, fillUndefined, deepMerge, INLINE_FILTER_ALIAS_TOKENS, GlobalConfigService, buildSchemaId, MemoryCacheAdapter, LocalStorageCacheAdapter, SchemaMetadataClient, resolveInlineFilterControlType, fetchWithETag, serializeEntityLookupValueForPayload, ComponentMetadataRegistry, AnalyticsStatsRequestBuilderService, buildApiUrl, normalizePraxisDataQueryContext, API_URL, PraxisCollectionExportService, ResourceDiscoveryService, ResourceSurfaceOpenAdapterService, ResourceQuickConnectComponent, translateResourceAvailabilityReason, assertPraxisCollectionExportArtifact, PRAXIS_LOADING_CTX, translateResourceDiscoveryText, supportsImplicitValuePresentation, resolveValuePresentation, translateUnavailableWorkflowMessage, CONNECTION_STORAGE, PRAXIS_LOADING_RENDERER, EmptyStateCardComponent, RESOURCE_DISCOVERY_I18N_CONFIG } from '@praxisui/core';
37
37
  import { PraxisRichContent } from '@praxisui/rich-content';
38
38
  import * as i2 from '@angular/material/toolbar';
39
39
  import { MatToolbarModule } from '@angular/material/toolbar';
@@ -37942,6 +37942,7 @@ class PraxisTable {
37942
37942
  static ROW_DISCOVERY_CACHE_LIMIT = 500;
37943
37943
  static ROW_DISCOVERY_MAX_CONCURRENT_REQUESTS = 2;
37944
37944
  _resourceDiscovery;
37945
+ _resourceSurfaceOpenAdapter;
37945
37946
  paginatorSelectConfig = {
37946
37947
  panelClass: 'praxis-table-paginator-select-panel',
37947
37948
  };
@@ -38732,6 +38733,44 @@ class PraxisTable {
38732
38733
  this.warnLog('[PraxisTable] Nao foi possivel preparar schema de filtro para contexto AI', error);
38733
38734
  }
38734
38735
  }
38736
+ async ensureAiAssistantRecordSurfaceContext() {
38737
+ const selectedRows = this.getSelectedRowsSnapshot()
38738
+ .slice(0, PraxisTable.AI_SELECTION_ROW_LIMIT);
38739
+ if (!selectedRows.length) {
38740
+ return;
38741
+ }
38742
+ await Promise.all(selectedRows.map((row) => this.ensureAiAssistantRowCapabilitySnapshot(row)));
38743
+ }
38744
+ getAiAssistantRecordSurfacesContext() {
38745
+ const configuredPack = this.aiContext?.recordSurfaces ?? null;
38746
+ const configuredSurfaces = Array.isArray(configuredPack?.surfaces)
38747
+ ? configuredPack.surfaces
38748
+ : [];
38749
+ const resourceSurfaces = this.buildAiAssistantResourceSurfaceContexts();
38750
+ if (!configuredSurfaces.length && !resourceSurfaces.length) {
38751
+ return null;
38752
+ }
38753
+ const surfacesById = new Map();
38754
+ for (const surface of configuredSurfaces) {
38755
+ if (!surface?.id)
38756
+ continue;
38757
+ surfacesById.set(String(surface.id), surface);
38758
+ }
38759
+ for (const surface of resourceSurfaces) {
38760
+ if (!surface?.id || surfacesById.has(surface.id))
38761
+ continue;
38762
+ surfacesById.set(surface.id, surface);
38763
+ }
38764
+ const source = configuredSurfaces.length && resourceSurfaces.length
38765
+ ? 'mixed'
38766
+ : resourceSurfaces.length
38767
+ ? 'resource-capabilities'
38768
+ : configuredPack?.source ?? 'dynamic-page-composition';
38769
+ return {
38770
+ source,
38771
+ surfaces: [...surfacesById.values()],
38772
+ };
38773
+ }
38735
38774
  getAiAssistantSelectedRowsContext() {
38736
38775
  const selectedRows = this.getSelectedRowsSnapshot();
38737
38776
  if (!selectedRows.length) {
@@ -38762,6 +38801,85 @@ class PraxisTable {
38762
38801
  fields,
38763
38802
  };
38764
38803
  }
38804
+ async ensureAiAssistantRowCapabilitySnapshot(row) {
38805
+ const rowLinks = this.getRowLinks(row);
38806
+ if (!rowLinks) {
38807
+ return;
38808
+ }
38809
+ const href = this.resolveRowDiscoveryHref(rowLinks, 'capabilities');
38810
+ if (!href || this.hasFreshRowCapabilitySnapshot(href)) {
38811
+ return;
38812
+ }
38813
+ const inFlight = this.rowCapabilityInFlightByHref.get(href);
38814
+ if (inFlight) {
38815
+ await inFlight;
38816
+ return;
38817
+ }
38818
+ try {
38819
+ const snapshot = await firstValueFrom(this.resourceDiscovery.getCapabilities(rowLinks, this.buildRowDiscoveryOptions())
38820
+ .pipe(take$1(1)));
38821
+ this.clearRowCapabilityError(href);
38822
+ this.rememberRowCapabilitySnapshot(href, snapshot);
38823
+ if (row && typeof row === 'object') {
38824
+ this.rowContextRuntimeByRef.delete(row);
38825
+ }
38826
+ }
38827
+ catch (error) {
38828
+ this.rememberRowCapabilityError(href);
38829
+ this.warnLog('[PraxisTable] Nao foi possivel preparar surfaces de registro para contexto AI', error);
38830
+ }
38831
+ }
38832
+ buildAiAssistantResourceSurfaceContexts() {
38833
+ const selectedRows = this.getSelectedRowsSnapshot();
38834
+ if (!selectedRows.length || !this.resourcePath) {
38835
+ return [];
38836
+ }
38837
+ const surfacesById = new Map();
38838
+ for (const row of selectedRows) {
38839
+ const snapshot = this.getCachedRowCapabilitySnapshot(row);
38840
+ for (const surface of snapshot?.surfaces ?? []) {
38841
+ if (!this.isRowSurfaceAction(surface)) {
38842
+ continue;
38843
+ }
38844
+ const id = String(surface.id || '').trim();
38845
+ if (!id || surfacesById.has(id)) {
38846
+ continue;
38847
+ }
38848
+ surfacesById.set(id, this.buildRecordRelatedSurfaceContextFromResourceSurface(surface));
38849
+ }
38850
+ }
38851
+ return [...surfacesById.values()];
38852
+ }
38853
+ buildRecordRelatedSurfaceContextFromResourceSurface(surface, sourceWidget = this.resolveAiAssistantOwnerId()) {
38854
+ const id = String(surface.id || '').trim();
38855
+ return {
38856
+ id,
38857
+ label: surface.title || this.humanizeResourceSurfaceLabel(id),
38858
+ relation: 'record.resource-surface',
38859
+ operationId: 'dynamicPage.surface.open',
38860
+ source: {
38861
+ widget: sourceWidget,
38862
+ componentType: 'praxis-table',
38863
+ port: 'rowSelection',
38864
+ resourcePath: this.resourcePath,
38865
+ },
38866
+ target: {
38867
+ widget: `${sourceWidget}.surface.${id}`,
38868
+ componentType: 'resource-surface',
38869
+ port: 'surface.open',
38870
+ resourcePath: this.resourcePath,
38871
+ },
38872
+ resourceSurface: this.cloneForEmit(surface),
38873
+ description: surface.description || null,
38874
+ };
38875
+ }
38876
+ humanizeResourceSurfaceLabel(value) {
38877
+ return String(value || '')
38878
+ .replace(/[-_]+/g, ' ')
38879
+ .replace(/([a-z])([A-Z])/g, '$1 $2')
38880
+ .replace(/\b\w/g, (match) => match.toUpperCase())
38881
+ .trim() || 'Superfície relacionada';
38882
+ }
38765
38883
  aiAdapter = null;
38766
38884
  aiAdapterLoadStarted = false;
38767
38885
  aiAssistantOpenAfterAdapterLoad = false;
@@ -39400,6 +39518,9 @@ class PraxisTable {
39400
39518
  get resourceDiscovery() {
39401
39519
  return this._resourceDiscovery ??= this.injector.get(ResourceDiscoveryService);
39402
39520
  }
39521
+ get resourceSurfaceOpenAdapter() {
39522
+ return this._resourceSurfaceOpenAdapter ??= this.injector.get(ResourceSurfaceOpenAdapterService);
39523
+ }
39403
39524
  ensureAiAdapterLoaded(openAfterLoad = false) {
39404
39525
  if (openAfterLoad && !this.aiAdapter) {
39405
39526
  this.aiAssistantOpenAfterAdapterLoad = true;
@@ -39407,7 +39528,7 @@ class PraxisTable {
39407
39528
  if (this.aiAdapter || this.aiAdapterLoadStarted)
39408
39529
  return;
39409
39530
  this.aiAdapterLoadStarted = true;
39410
- import('./praxisui-table-table-ai.adapter-hB4KVFil.mjs')
39531
+ import('./praxisui-table-table-ai.adapter-rtjGFq_B.mjs')
39411
39532
  .then(({ TableAiAdapter }) => {
39412
39533
  this.aiAdapter = new TableAiAdapter(this);
39413
39534
  this.initializeAiAssistantController();
@@ -39557,7 +39678,7 @@ class PraxisTable {
39557
39678
  initializeAiAssistantController() {
39558
39679
  if (!this.aiAdapter || this.aiAssistantController)
39559
39680
  return;
39560
- import('./praxisui-table-table-agentic-authoring-turn-flow-DtoCwCVX.mjs')
39681
+ import('./praxisui-table-table-agentic-authoring-turn-flow-B075RDUj.mjs')
39561
39682
  .then(({ TableAgenticAuthoringTurnFlow }) => {
39562
39683
  if (this.aiAssistantController || !this.aiAdapter)
39563
39684
  return;
@@ -40226,6 +40347,11 @@ class PraxisTable {
40226
40347
  const row = selectedRows[0];
40227
40348
  if (!row)
40228
40349
  return false;
40350
+ const resourceSurfaceContext = this.resolveResourceRecordSurfaceContext(surface);
40351
+ if (resourceSurfaceContext?.resourceSurface) {
40352
+ void this.openResourceRecordSurface(resourceSurfaceContext.resourceSurface, resourceSurfaceContext, row, selectedRows);
40353
+ return true;
40354
+ }
40229
40355
  const index = Array.isArray(this.dataSource?.data)
40230
40356
  ? this.dataSource.data.indexOf(row)
40231
40357
  : -1;
@@ -40244,6 +40370,72 @@ class PraxisTable {
40244
40370
  this.rowClick.emit({ row, index });
40245
40371
  return true;
40246
40372
  }
40373
+ resolveResourceRecordSurfaceContext(surface) {
40374
+ const directResourceSurface = surface?.['resourceSurface'];
40375
+ if (directResourceSurface && typeof directResourceSurface === 'object' && !Array.isArray(directResourceSurface)) {
40376
+ return surface;
40377
+ }
40378
+ const surfaceId = String(surface?.['id'] || '').trim();
40379
+ if (!surfaceId) {
40380
+ return null;
40381
+ }
40382
+ const contexts = this.getAiAssistantRecordSurfacesContext()?.surfaces ?? [];
40383
+ return contexts.find((candidate) => candidate.resourceSurface
40384
+ && String(candidate.id || '').trim().toLowerCase() === surfaceId.toLowerCase()) ?? null;
40385
+ }
40386
+ async openResourceRecordSurface(surface, contextSurface, row, selectedRows) {
40387
+ const resourceId = this.getRowId(row);
40388
+ try {
40389
+ const payload = this.resourceSurfaceOpenAdapter.toPayload(surface, {
40390
+ resourcePath: this.resourcePath,
40391
+ resourceId,
40392
+ endpointKey: this.crudContext?.endpointKey,
40393
+ title: surface.title || contextSurface.label,
40394
+ subtitle: surface.description || contextSurface.description || undefined,
40395
+ });
40396
+ const result = await this.globalActions.execute('surface.open', payload, {
40397
+ sourceId: this.tableId || this.componentInstanceId || 'praxis-table',
40398
+ output: 'recordSurfaceOpen',
40399
+ payload: {
40400
+ surface: contextSurface,
40401
+ selectedRow: row,
40402
+ selectedRows,
40403
+ selectedCount: selectedRows.length,
40404
+ tableId: this.tableId,
40405
+ },
40406
+ runtime: {
40407
+ row,
40408
+ selection: {
40409
+ selectedRows,
40410
+ selectedCount: selectedRows.length,
40411
+ },
40412
+ },
40413
+ meta: {
40414
+ actionId: 'dynamicPage.surface.open',
40415
+ surfaceId: contextSurface.id,
40416
+ actionConfig: surface,
40417
+ },
40418
+ });
40419
+ if (!result.success) {
40420
+ this.warnLog('[PraxisTable] Falha ao abrir surface de registro descoberta por capabilities', { surfaceId: surface.id, error: result.error }, { actionId: 'dynamicPage.surface.open' });
40421
+ this.showActionFeedbackMessage('errors', 'dynamicPage.surface.open', {
40422
+ label: surface.title || contextSurface.label,
40423
+ error: result.error,
40424
+ fallback: result.error || 'Erro ao abrir superfície relacionada',
40425
+ duration: 3000,
40426
+ });
40427
+ }
40428
+ }
40429
+ catch (error) {
40430
+ this.warnLog('[PraxisTable] Falha ao preparar surface de registro descoberta por capabilities', { surfaceId: surface.id, error }, { actionId: 'dynamicPage.surface.open' });
40431
+ this.showActionFeedbackMessage('errors', 'dynamicPage.surface.open', {
40432
+ label: surface.title || contextSurface.label,
40433
+ error,
40434
+ fallback: 'Erro ao abrir superfície relacionada',
40435
+ duration: 3000,
40436
+ });
40437
+ }
40438
+ }
40247
40439
  isRowExpansionRuntimeEnabled() {
40248
40440
  return this.isRowExpansionSupported();
40249
40441
  }
@@ -43362,6 +43554,10 @@ class PraxisTable {
43362
43554
  }
43363
43555
  async dispatchRowAction(action, row, runtimeOptions, extra) {
43364
43556
  const actionConfig = runtimeOptions?.actionConfig;
43557
+ if (this.isResourceSurfaceCatalogItem(actionConfig)) {
43558
+ await this.openResourceRecordSurface(actionConfig, this.buildRecordRelatedSurfaceContextFromResourceSurface(actionConfig), row, [row]);
43559
+ return;
43560
+ }
43365
43561
  if (this.resolveActionGlobalActionRef(actionConfig)) {
43366
43562
  const payload = Object.prototype.hasOwnProperty.call(runtimeOptions || {}, 'payload')
43367
43563
  ? runtimeOptions?.payload
@@ -49026,7 +49222,7 @@ class PraxisTable {
49026
49222
  return null;
49027
49223
  const text = Object.prototype.hasOwnProperty.call(cfg, 'text')
49028
49224
  ? cfg.text
49029
- : cfg.textField ? this.getNestedPropertyValue(row, cfg.textField) : null;
49225
+ : cfg.textField ? this.getRendererTextFieldValue(row, column, cfg.textField) : null;
49030
49226
  return text != null ? String(text) : null;
49031
49227
  }
49032
49228
  getBadgeIcon(row, column) {
@@ -49483,9 +49679,14 @@ class PraxisTable {
49483
49679
  return null;
49484
49680
  const t = Object.prototype.hasOwnProperty.call(cfg, 'text')
49485
49681
  ? cfg.text
49486
- : cfg.textField ? this.getNestedPropertyValue(row, cfg.textField) : null;
49682
+ : cfg.textField ? this.getRendererTextFieldValue(row, column, cfg.textField) : null;
49487
49683
  return t != null ? String(t) : null;
49488
49684
  }
49685
+ getRendererTextFieldValue(row, column, textField) {
49686
+ return textField === column.field
49687
+ ? this.getCellValue(row, column)
49688
+ : this.getNestedPropertyValue(row, textField);
49689
+ }
49489
49690
  getChipRichContentNodes(row, column) {
49490
49691
  const nodes = [];
49491
49692
  const icon = this.getChipIcon(row, column);
@@ -51069,6 +51270,17 @@ class PraxisTable {
51069
51270
  isRowSurfaceAction(surface) {
51070
51271
  return this.isWritableRowSurface(surface) || this.isReadableRowSurface(surface);
51071
51272
  }
51273
+ isResourceSurfaceCatalogItem(value) {
51274
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
51275
+ return false;
51276
+ }
51277
+ const candidate = value;
51278
+ return typeof candidate.id === 'string'
51279
+ && typeof candidate.kind === 'string'
51280
+ && typeof candidate.scope === 'string'
51281
+ && typeof candidate.path === 'string'
51282
+ && typeof candidate.method === 'string';
51283
+ }
51072
51284
  isWritableRowSurface(surface) {
51073
51285
  return surface.kind === 'FORM' || surface.kind === 'PARTIAL_FORM';
51074
51286
  }