@praxisui/table 8.0.0-beta.59 → 8.0.0-beta.60

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.
@@ -39578,7 +39578,7 @@ class PraxisTable {
39578
39578
  if (this.aiAdapter || this.aiAdapterLoadStarted)
39579
39579
  return;
39580
39580
  this.aiAdapterLoadStarted = true;
39581
- import('./praxisui-table-table-ai.adapter-CRQf8Vjv.mjs')
39581
+ import('./praxisui-table-table-ai.adapter-CRkIuL7q.mjs')
39582
39582
  .then(({ TableAiAdapter }) => {
39583
39583
  this.aiAdapter = new TableAiAdapter(this);
39584
39584
  this.initializeAiAssistantController();
@@ -39728,7 +39728,7 @@ class PraxisTable {
39728
39728
  initializeAiAssistantController() {
39729
39729
  if (!this.aiAdapter || this.aiAssistantController)
39730
39730
  return;
39731
- import('./praxisui-table-table-agentic-authoring-turn-flow-BoMxaF18.mjs')
39731
+ import('./praxisui-table-table-agentic-authoring-turn-flow-CmfIj9ao.mjs')
39732
39732
  .then(({ TableAgenticAuthoringTurnFlow }) => {
39733
39733
  if (this.aiAssistantController || !this.aiAdapter)
39734
39734
  return;
@@ -43604,6 +43604,11 @@ class PraxisTable {
43604
43604
  }
43605
43605
  async dispatchRowAction(action, row, runtimeOptions, extra) {
43606
43606
  const actionConfig = runtimeOptions?.actionConfig;
43607
+ const configuredRecordSurface = this.toRecordSurfaceActionConfig(actionConfig);
43608
+ if (configuredRecordSurface) {
43609
+ await this.openResourceRecordSurface(configuredRecordSurface, this.buildRecordRelatedSurfaceContextFromResourceSurface(configuredRecordSurface), row, [row]);
43610
+ return;
43611
+ }
43607
43612
  if (this.isResourceSurfaceCatalogItem(actionConfig)) {
43608
43613
  await this.openResourceRecordSurface(actionConfig, this.buildRecordRelatedSurfaceContextFromResourceSurface(actionConfig), row, [row]);
43609
43614
  return;
@@ -51351,6 +51356,15 @@ class PraxisTable {
51351
51356
  && typeof candidate.path === 'string'
51352
51357
  && typeof candidate.method === 'string';
51353
51358
  }
51359
+ toRecordSurfaceActionConfig(value) {
51360
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
51361
+ return null;
51362
+ }
51363
+ const candidate = value;
51364
+ return this.isResourceSurfaceCatalogItem(candidate.recordSurface)
51365
+ ? candidate.recordSurface
51366
+ : null;
51367
+ }
51354
51368
  isWritableRowSurface(surface) {
51355
51369
  return surface.kind === 'FORM' || surface.kind === 'PARTIAL_FORM';
51356
51370
  }
@@ -52245,6 +52259,16 @@ const tableConditionalAnimationSchema = {
52245
52259
  intensity: { enum: ['subtle', 'normal', 'strong'] },
52246
52260
  },
52247
52261
  };
52262
+ const tableTooltipSchema = {
52263
+ type: 'object',
52264
+ additionalProperties: false,
52265
+ properties: {
52266
+ text: { type: 'string' },
52267
+ position: { enum: ['top', 'right', 'bottom', 'left'] },
52268
+ bgColor: { type: 'string' },
52269
+ delayMs: { type: 'number' },
52270
+ },
52271
+ };
52248
52272
  const tableVisualRuleEffectSchema = {
52249
52273
  type: 'object',
52250
52274
  additionalProperties: false,
@@ -52301,16 +52325,7 @@ const tableVisualRuleEffectSchema = {
52301
52325
  },
52302
52326
  },
52303
52327
  animation: tableConditionalAnimationSchema,
52304
- tooltip: {
52305
- type: 'object',
52306
- additionalProperties: false,
52307
- properties: {
52308
- text: { type: 'string' },
52309
- position: { enum: ['top', 'right', 'bottom', 'left'] },
52310
- bgColor: { type: 'string' },
52311
- delayMs: { type: 'number' },
52312
- },
52313
- },
52328
+ tooltip: tableTooltipSchema,
52314
52329
  cssClass: { type: 'string' },
52315
52330
  inlineStyle: { type: 'string' },
52316
52331
  },
@@ -52656,6 +52671,33 @@ const tableExportSchema = {
52656
52671
  }
52657
52672
  }
52658
52673
  };
52674
+ const tableRuntimeOperationPlanSchema = {
52675
+ type: 'object',
52676
+ required: ['operations'],
52677
+ properties: {
52678
+ operations: {
52679
+ type: 'array',
52680
+ minItems: 1,
52681
+ items: {
52682
+ type: 'object',
52683
+ required: ['operationId', 'input'],
52684
+ properties: {
52685
+ operationId: { enum: ['table.filter.apply', 'table.export.run'] },
52686
+ input: {
52687
+ type: 'object',
52688
+ minProperties: 1,
52689
+ properties: {
52690
+ criteria: { type: 'object' },
52691
+ format: { enum: EXPORT_FORMATS },
52692
+ scope: { enum: EXPORT_SCOPES },
52693
+ },
52694
+ },
52695
+ description: { type: 'string' },
52696
+ },
52697
+ },
52698
+ },
52699
+ },
52700
+ };
52659
52701
  const tableFilteringSchema = {
52660
52702
  type: 'object',
52661
52703
  minProperties: 1,
@@ -53168,6 +53210,7 @@ const PRAXIS_TABLE_AUTHORING_MANIFEST = {
53168
53210
  { kind: 'localization', resolver: 'localization-config', description: 'Localizacao e formatos regionais' },
53169
53211
  { kind: 'performance', resolver: 'performance-config', description: 'Configuracoes de performance' },
53170
53212
  { kind: 'data', resolver: 'data-config', description: 'Configuracoes de dados' },
53213
+ { kind: 'runtimeOperation', resolver: 'table-runtime-operation-contract', description: 'Operacoes runtime revisaveis sem mutar a configuracao persistida' },
53171
53214
  { kind: 'accessibility', resolver: 'accessibility-config', description: 'Acessibilidade' }
53172
53215
  ],
53173
53216
  operations: [
@@ -53485,16 +53528,22 @@ const PRAXIS_TABLE_AUTHORING_MANIFEST = {
53485
53528
  id: { type: 'string', description: 'Identificador estável do renderer condicional (usado para deduplicação)' },
53486
53529
  condition: { type: 'object', description: 'AST Json Logic' },
53487
53530
  renderer: rendererSchema,
53531
+ tooltip: tableTooltipSchema,
53488
53532
  animation: tableConditionalAnimationSchema,
53489
53533
  effects: { type: 'array', items: tableVisualRuleEffectSchema },
53490
53534
  enabled: { type: 'boolean' },
53491
53535
  description: { type: 'string' }
53492
53536
  },
53493
- anyOf: [{ required: ['renderer'] }, { required: ['animation'] }, { required: ['effects'] }]
53537
+ anyOf: [{ required: ['renderer'] }, { required: ['tooltip'] }, { required: ['animation'] }, { required: ['effects'] }]
53494
53538
  },
53495
53539
  effects: [{ kind: 'append-unique', path: 'columns[].conditionalRenderers[]', key: 'id' }],
53496
53540
  validators: ['target-column-exists', 'computed-expression-valid', 'renderer-config-match'],
53497
- affectedPaths: ['columns[].conditionalRenderers[]', 'columns[].conditionalRenderers[].animation', 'columns[].conditionalRenderers[].effects'],
53541
+ affectedPaths: [
53542
+ 'columns[].conditionalRenderers[]',
53543
+ 'columns[].conditionalRenderers[].tooltip',
53544
+ 'columns[].conditionalRenderers[].animation',
53545
+ 'columns[].conditionalRenderers[].effects'
53546
+ ],
53498
53547
  submissionImpact: 'visual-only',
53499
53548
  preconditions: ['config-initialized', 'target-exists']
53500
53549
  },
@@ -53643,6 +53692,10 @@ const PRAXIS_TABLE_AUTHORING_MANIFEST = {
53643
53692
  color: { type: 'string' },
53644
53693
  visibleWhen: { type: 'object', description: 'AST Json Logic' },
53645
53694
  disabledWhen: { type: 'object', description: 'AST Json Logic' },
53695
+ recordSurface: {
53696
+ type: 'object',
53697
+ description: 'ResourceSurfaceCatalogItem canonico preservado para abrir uma superficie relacionada ao registro da linha clicada.'
53698
+ },
53646
53699
  globalAction: globalActionRefSchema,
53647
53700
  effects: { type: 'array', items: globalActionEffectSchema },
53648
53701
  }
@@ -54360,6 +54413,21 @@ const PRAXIS_TABLE_AUTHORING_MANIFEST = {
54360
54413
  submissionImpact: 'config-only',
54361
54414
  preconditions: ['config-initialized']
54362
54415
  },
54416
+ {
54417
+ operationId: 'tableRuntimeOperations.plan',
54418
+ title: 'Planejar operacoes runtime da tabela',
54419
+ scope: 'global',
54420
+ targetKind: 'runtimeOperation',
54421
+ target: { kind: 'runtimeOperation', resolver: 'table-runtime-operation-contract', ambiguityPolicy: 'fail', required: false },
54422
+ inputSchema: tableRuntimeOperationPlanSchema,
54423
+ effects: [{ kind: 'set-value', path: 'tableRuntimeOperations' }],
54424
+ affectedPaths: [
54425
+ 'tableRuntimeOperations',
54426
+ ],
54427
+ validators: ['runtime-operation-declared'],
54428
+ submissionImpact: 'none',
54429
+ preconditions: ['config-initialized']
54430
+ },
54363
54431
  {
54364
54432
  operationId: 'appearance.configure',
54365
54433
  title: 'Configurar aparencia',
@@ -54568,6 +54636,12 @@ const PRAXIS_TABLE_AUTHORING_MANIFEST = {
54568
54636
  level: 'error',
54569
54637
  code: 'TB016',
54570
54638
  description: 'Regras condicionais de coluna devem ter id estavel, condition Json Logic e ao menos cssClass ou style.'
54639
+ },
54640
+ {
54641
+ validatorId: 'runtime-operation-declared',
54642
+ level: 'error',
54643
+ code: 'TB019',
54644
+ description: 'Operacoes runtime devem usar operationId e input declarados em tableRuntimeOperations sem alterar a configuracao persistida.'
54571
54645
  }
54572
54646
  ],
54573
54647
  roundTripRequirements: [
@@ -57234,6 +57308,8 @@ const TABLE_AI_CAPABILITIES = {
57234
57308
  { path: 'actions.row.display', category: 'actions', valueKind: 'enum', allowedValues: ENUMS.rowActionDisplay, description: 'Modo de exibição das ações (menu/buttons/icons).', dependsOn: 'actions.row.enabled' },
57235
57309
  { path: 'actions.row.trigger', category: 'actions', valueKind: 'enum', allowedValues: ENUMS.rowActionTrigger, description: 'Como as ações aparecem (hover/always/click).', dependsOn: 'actions.row.enabled' },
57236
57310
  { path: 'actions.row.discovery.enabled', category: 'actions', valueKind: 'boolean', description: 'Controla se a tabela enriquece ações por linha com discovery contextual de HATEOAS/capabilities.', dependsOn: 'actions.row.enabled', safetyNotes: 'Use false quando a experiência precisar mostrar apenas ações curadas pelo host.' },
57311
+ { path: 'actions.row.actions[]', category: 'actions', valueKind: 'array', description: 'Ações curadas exibidas em cada linha da tabela. Use para criar botões de linha com GlobalActionRef governada, como surface.open.', dependsOn: 'actions.row.enabled', intentExamples: ['adicionar botão em cada linha', 'criar ação de linha para abrir uma superfície relacionada'] },
57312
+ { path: 'actions.row.actions[].recordSurface', category: 'actions', valueKind: 'object', description: 'ResourceSurfaceCatalogItem canonico preservado para uma acao de linha abrir a superficie relacionada ao registro clicado sem sobrescrever a identidade da surface.', dependsOn: 'actions.row.actions[]', intentExamples: ['botão de linha para abrir folha de pagamento', 'ação por linha para abrir timeline relacionada'] },
57237
57313
  { path: 'actions.row.actions[].globalAction.[actionId]', category: 'actions', valueKind: 'string', description: 'Identificador canônico de global action para a ação por linha (ex.: "navigation.openRoute", "surface.open", "toast.success").', dependsOn: 'actions.row.enabled', intentExamples: ['navegar para detalhe interno ao clicar na linha', 'abrir drawer com surface.open', 'mostrar toast de sucesso'] },
57238
57314
  { path: 'actions.row.actions[].globalAction.payload', category: 'actions', valueKind: 'object', description: 'Payload estruturado da global action por linha. Para `navigation.openRoute`, templates como `${row.id}` são resolvidos antes da navegação; para ações como `surface.open`, `payload.*` continua sendo o envelope canônico do evento consumido pelo destino.', dependsOn: 'actions.row.actions[].globalAction.[actionId]', intentExamples: ['abrir detalhe com query.id da linha', 'passar state.selectedId usando a linha atual'], example: '{ "path": "/clientes/detalhe", "query": { "id": "${row.id}" }, "state": { "selectedId": "${row.id}" } }' },
57239
57315
  { path: 'actions.row.actions[].visibleWhen', category: 'actions', valueKind: 'expression', description: 'Condicao canonica em JSON Logic para exibir a acao por linha.', dependsOn: 'actions.row.enabled', safetyNotes: 'Invalid Json Logic segue a politica de fallback da tabela por ambiente.' },
@@ -57570,6 +57646,7 @@ const TABLE_COMPONENT_EDIT_PLAN_ALLOWED_CHANGE_KINDS = [
57570
57646
  'configure_table_sorting',
57571
57647
  'configure_toolbar',
57572
57648
  'add_toolbar_action',
57649
+ 'add_row_action',
57573
57650
  'configure_export',
57574
57651
  'set_table_density',
57575
57652
  'set_toolbar_visibility',
@@ -57603,6 +57680,7 @@ const TABLE_COMPONENT_EDIT_PLAN_OPERATION_IDS = [
57603
57680
  'behavior.sorting.configure',
57604
57681
  'toolbar.configure',
57605
57682
  'toolbar.action.add',
57683
+ 'rowAction.add',
57606
57684
  'export.configure',
57607
57685
  'appearance.density.set',
57608
57686
  'toolbar.visibility.set',
@@ -57637,6 +57715,7 @@ const TABLE_COMPONENT_EDIT_PLAN_EXPECTED_PATHS = {
57637
57715
  configure_table_sorting: 'behavior.sorting',
57638
57716
  configure_toolbar: 'toolbar',
57639
57717
  add_toolbar_action: 'toolbar.actions[]',
57718
+ add_row_action: 'actions.row.actions[]',
57640
57719
  configure_export: 'export',
57641
57720
  set_table_density: 'appearance.density',
57642
57721
  set_toolbar_visibility: 'toolbar.visible',
@@ -57670,6 +57749,7 @@ const TABLE_COMPONENT_EDIT_PLAN_OPERATION_ID_TO_CHANGE_KIND = {
57670
57749
  'behavior.sorting.configure': 'configure_table_sorting',
57671
57750
  'toolbar.configure': 'configure_toolbar',
57672
57751
  'toolbar.action.add': 'add_toolbar_action',
57752
+ 'rowAction.add': 'add_row_action',
57673
57753
  'export.configure': 'configure_export',
57674
57754
  'appearance.density.set': 'set_table_density',
57675
57755
  'toolbar.visibility.set': 'set_toolbar_visibility',
@@ -57703,6 +57783,7 @@ const TABLE_COMPONENT_EDIT_PLAN_OPERATION_VALUE_KEYS = {
57703
57783
  'behavior.sorting.configure': '',
57704
57784
  'toolbar.configure': '',
57705
57785
  'toolbar.action.add': '',
57786
+ 'rowAction.add': '',
57706
57787
  'export.configure': '',
57707
57788
  'appearance.density.set': 'density',
57708
57789
  'toolbar.visibility.set': 'visible',
@@ -57950,18 +58031,54 @@ function coerceTableComponentEditPlans(value) {
57950
58031
  if (!value || typeof value !== 'object')
57951
58032
  return null;
57952
58033
  const candidate = value;
58034
+ const textualPlans = coerceTableComponentEditPlansFromText(candidate);
58035
+ if (textualPlans)
58036
+ return textualPlans;
57953
58037
  const nested = candidate['componentEditPlan']
57954
58038
  ?? candidate['componentEditPlans']
57955
58039
  ?? candidate['tableEditPlan']
57956
58040
  ?? candidate['tableEditPlans']
57957
58041
  ?? candidate['editPlan']
57958
58042
  ?? candidate['editPlans']
58043
+ ?? (candidate['kind'] === 'componentEditPlan' ? candidate : null)
58044
+ ?? (Array.isArray(candidate['operations']) ? candidate : null)
57959
58045
  ?? (candidate['kind'] === TABLE_COMPONENT_EDIT_PLAN_KIND || candidate['kind'] === TABLE_COMPONENT_EDIT_PLAN_BATCH_KIND ? candidate : null);
57960
58046
  if (!nested || typeof nested !== 'object')
57961
58047
  return null;
57962
58048
  const plans = coercePlanList(nested);
57963
58049
  return plans.length > 0 ? plans : null;
57964
58050
  }
58051
+ function coerceTableComponentEditPlansFromText(candidate) {
58052
+ for (const key of ['message', 'assistantMessage', 'content', 'explanation']) {
58053
+ const text = typeof candidate[key] === 'string' ? candidate[key].trim() : '';
58054
+ if (!text || (!text.includes('componentEditPlan') && !text.includes('operationId')))
58055
+ continue;
58056
+ const parsed = parseJsonObjectFromText(text);
58057
+ if (!parsed || parsed === candidate)
58058
+ continue;
58059
+ const plans = coerceTableComponentEditPlans(parsed);
58060
+ if (plans?.length)
58061
+ return plans;
58062
+ }
58063
+ return null;
58064
+ }
58065
+ function parseJsonObjectFromText(text) {
58066
+ const withoutFence = text
58067
+ .replace(/^```(?:json)?\s*/i, '')
58068
+ .replace(/\s*```$/i, '')
58069
+ .trim();
58070
+ const start = withoutFence.indexOf('{');
58071
+ const end = withoutFence.lastIndexOf('}');
58072
+ if (start < 0 || end <= start)
58073
+ return null;
58074
+ try {
58075
+ const parsed = JSON.parse(withoutFence.slice(start, end + 1));
58076
+ return coerceRecord(parsed);
58077
+ }
58078
+ catch {
58079
+ return null;
58080
+ }
58081
+ }
57965
58082
  function coerceTableComponentEditPlan(value) {
57966
58083
  return coerceTableComponentEditPlans(value)?.[0] ?? null;
57967
58084
  }
@@ -58081,6 +58198,27 @@ function compileTableComponentEditPlan(plan, currentConfig) {
58081
58198
  failureCodes,
58082
58199
  };
58083
58200
  }
58201
+ if (plan.changeKind === 'add_row_action') {
58202
+ const action = valueValidation.value;
58203
+ const currentRowActions = currentConfig.actions?.row;
58204
+ const existingActions = Array.isArray(currentRowActions?.actions)
58205
+ ? [...currentRowActions.actions]
58206
+ : [];
58207
+ return {
58208
+ patch: {
58209
+ actions: {
58210
+ row: {
58211
+ ...currentRowActions,
58212
+ enabled: true,
58213
+ actions: mergeActionPatchesById(existingActions, [action]),
58214
+ },
58215
+ },
58216
+ },
58217
+ explanation: plan.explanation || defaultExplanation(plan.changeKind, field, valueValidation.value),
58218
+ warnings,
58219
+ failureCodes,
58220
+ };
58221
+ }
58084
58222
  if (plan.changeKind === 'configure_advanced_filters') {
58085
58223
  return {
58086
58224
  patch: {
@@ -58431,6 +58569,7 @@ function mergeTablePatches(left, right) {
58431
58569
  const behavior = mergeObjectPatch(left.behavior, right.behavior);
58432
58570
  const appearance = mergeObjectPatch(left.appearance, right.appearance);
58433
58571
  const toolbar = mergeObjectPatch(left.toolbar, right.toolbar);
58572
+ const actions = mergeObjectPatch(left.actions, right.actions);
58434
58573
  const rowConditionalRenderers = mergeRulePatches(left.rowConditionalRenderers, right.rowConditionalRenderers);
58435
58574
  const rowConditionalStyles = mergeRulePatches(left.rowConditionalStyles, right.rowConditionalStyles);
58436
58575
  if (columns !== undefined)
@@ -58441,6 +58580,8 @@ function mergeTablePatches(left, right) {
58441
58580
  merged.appearance = appearance;
58442
58581
  if (toolbar !== undefined)
58443
58582
  merged.toolbar = toolbar;
58583
+ if (actions !== undefined)
58584
+ merged.actions = actions;
58444
58585
  if (rowConditionalRenderers !== undefined) {
58445
58586
  merged.rowConditionalRenderers = rowConditionalRenderers;
58446
58587
  }
@@ -58524,6 +58665,9 @@ function applyPatchToWorkingConfig(config, patch) {
58524
58665
  if (patchAny.toolbar) {
58525
58666
  next.toolbar = mergeObjectPatch(next.toolbar, patchAny.toolbar);
58526
58667
  }
58668
+ if (patchAny.actions) {
58669
+ next.actions = mergeObjectPatch(next.actions, patchAny.actions);
58670
+ }
58527
58671
  if (Array.isArray(patchAny.rowConditionalRenderers)) {
58528
58672
  next.rowConditionalRenderers = mergeRulePatches(next.rowConditionalRenderers, patchAny.rowConditionalRenderers);
58529
58673
  }
@@ -58718,6 +58862,9 @@ function validateValueForChangeKind(changeKind, rawValue, allowedValues) {
58718
58862
  if (changeKind === 'add_toolbar_action') {
58719
58863
  return validateToolbarActionValue(rawValue);
58720
58864
  }
58865
+ if (changeKind === 'add_row_action') {
58866
+ return validateRowActionValue(rawValue);
58867
+ }
58721
58868
  if (changeKind === 'configure_export') {
58722
58869
  return validateObjectValue(rawValue, 'export configuration');
58723
58870
  }
@@ -58772,6 +58919,48 @@ function validateToolbarActionValue(rawValue) {
58772
58919
  failureCodes: [],
58773
58920
  };
58774
58921
  }
58922
+ function validateRowActionValue(rawValue) {
58923
+ const value = coerceRecord(rawValue);
58924
+ if (!value) {
58925
+ return { failureCodes: ['row action must be object'] };
58926
+ }
58927
+ const id = normalizeText(value['id']);
58928
+ const label = normalizeText(value['label']);
58929
+ const action = normalizeText(value['action']);
58930
+ const failureCodes = [];
58931
+ if (!id)
58932
+ failureCodes.push('row action id is required');
58933
+ if (!label)
58934
+ failureCodes.push('row action label is required');
58935
+ if (!action)
58936
+ failureCodes.push('row action action is required');
58937
+ const recordSurfaceValidation = value['recordSurface'] === undefined
58938
+ ? []
58939
+ : validateRecordSurfaceValue(value['recordSurface']);
58940
+ failureCodes.push(...recordSurfaceValidation);
58941
+ if (failureCodes.length > 0) {
58942
+ return { failureCodes };
58943
+ }
58944
+ return {
58945
+ value: {
58946
+ icon: normalizeText(value['icon']) || 'open_in_new',
58947
+ ...value,
58948
+ id,
58949
+ label,
58950
+ action,
58951
+ },
58952
+ failureCodes: [],
58953
+ };
58954
+ }
58955
+ function validateRecordSurfaceValue(rawValue) {
58956
+ const surface = coerceRecord(rawValue);
58957
+ if (!surface)
58958
+ return ['row action recordSurface must be object'];
58959
+ const requiredFields = ['id', 'resourceKey', 'kind', 'scope', 'path', 'method', 'schemaId', 'schemaUrl'];
58960
+ return requiredFields
58961
+ .filter((field) => !normalizeText(surface[field]))
58962
+ .map((field) => `row action recordSurface ${field} is required`);
58963
+ }
58775
58964
  function validateAdvancedFiltersValue(rawValue) {
58776
58965
  const value = coerceRecord(rawValue);
58777
58966
  if (!value) {
@@ -58984,6 +59173,10 @@ function defaultExplanation(changeKind, field, value) {
58984
59173
  const action = coerceRecord(value);
58985
59174
  return `Acao ${normalizeText(action?.['label']) || normalizeText(action?.['id']) || 'da toolbar'} adicionada a toolbar.`;
58986
59175
  }
59176
+ if (changeKind === 'add_row_action') {
59177
+ const action = coerceRecord(value);
59178
+ return `Acao ${normalizeText(action?.['label']) || normalizeText(action?.['id']) || 'de linha'} adicionada as linhas da tabela.`;
59179
+ }
58987
59180
  if (changeKind === 'set_table_density') {
58988
59181
  return `Densidade da tabela atualizada para ${String(value)}.`;
58989
59182
  }
@@ -556,7 +556,8 @@ class TableAgenticAuthoringTurnFlow {
556
556
  }
557
557
  compileAdapterResponse(response, request) {
558
558
  if (response.type === 'clarification' || response.type === 'info' || response.type === 'error') {
559
- const compiledExecutable = this.responseMayContainRuntimeOperationEnvelope(response)
559
+ const compiledExecutable = !this.responseCarriesClarificationChoices(response)
560
+ && this.responseMayContainExecutableEnvelope(response)
560
561
  ? this.adapter.compileAiResponse?.(response)
561
562
  : null;
562
563
  if (compiledExecutable?.patch && Object.keys(compiledExecutable.patch).length > 0) {
@@ -579,6 +580,10 @@ class TableAgenticAuthoringTurnFlow {
579
580
  warnings: compiledExecutable.warnings,
580
581
  };
581
582
  }
583
+ const continuedSurfaceRowAction = this.selectedRecordSurfaceRowActionPlanForClarification(response, request);
584
+ if (continuedSurfaceRowAction) {
585
+ return this.compileAdapterResponse(continuedSurfaceRowAction, request);
586
+ }
582
587
  return response;
583
588
  }
584
589
  const compiled = this.adapter.compileAiResponse?.(response);
@@ -633,6 +638,18 @@ class TableAgenticAuthoringTurnFlow {
633
638
  warnings: warnings.length ? warnings : undefined,
634
639
  };
635
640
  }
641
+ responseCarriesClarificationChoices(response) {
642
+ if (response.type !== 'clarification')
643
+ return false;
644
+ const record = response;
645
+ const questions = Array.isArray(response.questions) ? response.questions : [];
646
+ const optionPayloads = Array.isArray(record['optionPayloads']) ? record['optionPayloads'] : [];
647
+ return questions.length > 0 || optionPayloads.length > 0;
648
+ }
649
+ responseMayContainExecutableEnvelope(response) {
650
+ return this.responseMayContainRuntimeOperationEnvelope(response)
651
+ || this.responseMayContainComponentEditPlanEnvelope(response);
652
+ }
636
653
  responseMayContainRuntimeOperationEnvelope(response) {
637
654
  const record = response;
638
655
  if (record['tableRuntimeOperations'])
@@ -645,6 +662,15 @@ class TableAgenticAuthoringTurnFlow {
645
662
  return value.includes('tableRuntimeOperations') && value.includes('operationId');
646
663
  });
647
664
  }
665
+ responseMayContainComponentEditPlanEnvelope(response) {
666
+ const record = response;
667
+ if (record['componentEditPlan'] || record['tableEditPlan'] || record['editPlan'])
668
+ return true;
669
+ return ['message', 'assistantMessage', 'content', 'explanation'].some((key) => {
670
+ const value = this.stringValue(record[key]);
671
+ return value.includes('componentEditPlan') && value.includes('operationId');
672
+ });
673
+ }
648
674
  isGovernedSelectedRecordFilterResponse(response) {
649
675
  return (response.warnings ?? []).some((warning) => [
650
676
  'selected-record-filter-request-materialized',
@@ -884,6 +910,135 @@ class TableAgenticAuthoringTurnFlow {
884
910
  ],
885
911
  };
886
912
  }
913
+ selectedRecordSurfaceRowActionPlanForClarification(response, request) {
914
+ if (!request)
915
+ return null;
916
+ const normalizedPrompt = this.normalizeLabel(request.prompt ?? '');
917
+ const normalizedConversation = this.normalizeLabel([
918
+ ...(request.messages ?? []).slice(-8).map((message) => message?.text ?? ''),
919
+ request.prompt ?? '',
920
+ ].join(' '));
921
+ if (!this.textMentionsRowActionRequest(normalizedPrompt || normalizedConversation)) {
922
+ return null;
923
+ }
924
+ const clarificationKind = this.selectedRecordSurfaceRowActionClarificationKind(response);
925
+ if (!clarificationKind)
926
+ return null;
927
+ const contextHints = this.contextHintsFor(request);
928
+ const surfaces = this.selectedRecordSurfaces(contextHints);
929
+ if (!surfaces.length)
930
+ return null;
931
+ const ranked = surfaces
932
+ .map((surface) => ({
933
+ surface,
934
+ score: this.selectedRecordSurfacePromptScore(normalizedConversation || normalizedPrompt, surface),
935
+ }))
936
+ .filter((entry) => entry.score >= 2)
937
+ .sort((left, right) => right.score - left.score);
938
+ if (!ranked.length || (ranked.length > 1 && ranked[0].score === ranked[1].score)) {
939
+ return null;
940
+ }
941
+ const surface = ranked[0].surface;
942
+ const resourceSurface = this.toRecord(surface['resourceSurface']);
943
+ if (!this.isResourceSurfaceCatalogDigest(resourceSurface)) {
944
+ return null;
945
+ }
946
+ const surfaceId = this.stringValue(surface['id']) || this.stringValue(resourceSurface['id']);
947
+ if (!surfaceId)
948
+ return null;
949
+ const surfaceLabel = this.stringValue(surface['label'])
950
+ || this.stringValue(resourceSurface['title'])
951
+ || this.humanizeField(surfaceId);
952
+ const actionId = `open-${this.slugifyActionId(surfaceId)}`;
953
+ const rowAction = {
954
+ id: actionId,
955
+ label: surfaceLabel,
956
+ action: 'surface.open',
957
+ icon: 'open_in_new',
958
+ recordSurface: this.toAiJsonObject(resourceSurface),
959
+ };
960
+ // Residual continuity guard: this runs only after the LLM returned a
961
+ // clarification/info response for a row-button request. The target surface
962
+ // is ranked from declared canonical recordSurfaces and recent conversation
963
+ // context, so the guard repairs materialization without becoming primary
964
+ // intent routing by local command text.
965
+ return {
966
+ type: 'patch',
967
+ componentEditPlan: {
968
+ kind: 'praxis.table.component-edit-plan',
969
+ version: '1.0',
970
+ componentId: 'praxis-table',
971
+ operationId: 'rowAction.add',
972
+ changeKind: 'add_row_action',
973
+ capabilityPath: 'actions.row.actions[]',
974
+ input: rowAction,
975
+ value: rowAction,
976
+ },
977
+ explanation: `Vou criar um botão em cada linha para abrir ${surfaceLabel}.`,
978
+ warnings: [
979
+ clarificationKind === 'technical'
980
+ ? 'selected-record-surface-row-action-continued-from-technical-clarification'
981
+ : 'selected-record-surface-row-action-continued-from-generic-clarification',
982
+ clarificationKind === 'technical'
983
+ ? 'Residual continuity guard acted only after LLM asked for technical row-action details while declared recordSurfaces and conversation history already grounded the target surface.'
984
+ : 'Residual continuity guard acted only after LLM asked a generic dataset/listing clarification while declared recordSurfaces and a row-action request already grounded the target surface.',
985
+ ],
986
+ };
987
+ }
988
+ selectedRecordSurfaceRowActionClarificationKind(response) {
989
+ const text = this.normalizeLabel([
990
+ response.message ?? '',
991
+ response.explanation ?? '',
992
+ ...(response.questions ?? []),
993
+ ].join(' '));
994
+ if ([
995
+ 'surface to open',
996
+ 'button label',
997
+ 'placement in row',
998
+ 'mais detalhes sobre surface',
999
+ 'mais detalhes sobre button',
1000
+ 'mais detalhes sobre placement',
1001
+ ].some((needle) => text.includes(needle))) {
1002
+ return 'technical';
1003
+ }
1004
+ if ([
1005
+ 'qual conjunto de dados',
1006
+ 'conjunto de dados',
1007
+ 'dados voce quer listar',
1008
+ 'dados você quer listar',
1009
+ 'quer listar',
1010
+ 'listar',
1011
+ 'dataset',
1012
+ ].some((needle) => text.includes(this.normalizeLabel(needle)))) {
1013
+ return 'generic-dataset';
1014
+ }
1015
+ return null;
1016
+ }
1017
+ textMentionsRowActionRequest(normalizedText) {
1018
+ return [
1019
+ 'botao',
1020
+ 'acao de linha',
1021
+ 'acoes de linha',
1022
+ 'nas linhas',
1023
+ 'por linha',
1024
+ 'em cada linha',
1025
+ ].some((needle) => normalizedText.includes(needle));
1026
+ }
1027
+ isResourceSurfaceCatalogDigest(value) {
1028
+ if (!value)
1029
+ return false;
1030
+ return !!this.stringValue(value['id'])
1031
+ && !!this.stringValue(value['kind'])
1032
+ && !!this.stringValue(value['scope'])
1033
+ && !!this.stringValue(value['path'])
1034
+ && !!this.stringValue(value['method']);
1035
+ }
1036
+ slugifyActionId(value) {
1037
+ return this.normalizeLabel(value)
1038
+ .replace(/[^a-z0-9]+/gu, '-')
1039
+ .replace(/^-+|-+$/gu, '')
1040
+ || 'surface';
1041
+ }
887
1042
  promptRequestsSimilarRecords(normalizedPrompt) {
888
1043
  return [
889
1044
  'registro parecido',
@@ -1660,6 +1815,9 @@ class TableAgenticAuthoringTurnFlow {
1660
1815
  case 'toolbar.action.add':
1661
1816
  case 'add_toolbar_action':
1662
1817
  return `Vou adicionar a acao **${this.stringValue(input['label']) || this.stringValue(input['id']) || 'solicitada'}** na barra da tabela.`;
1818
+ case 'rowAction.add':
1819
+ case 'add_row_action':
1820
+ return `Vou criar um botao em cada linha para abrir **${this.stringValue(input['label']) || this.stringValue(input['id']) || 'a opcao solicitada'}**.`;
1663
1821
  case 'export.configure':
1664
1822
  return this.describeExportConfigure(input);
1665
1823
  case 'appearance.density.set':
@@ -1,7 +1,7 @@
1
1
  import { firstValueFrom } from 'rxjs';
2
2
  import { BaseAiAdapter, createComponentAuthoringContext } from '@praxisui/ai';
3
3
  import { deepMerge } from '@praxisui/core';
4
- import { z as TABLE_COMPONENT_EDIT_PLAN_OPERATION_IDS, k as PRAXIS_TABLE_AUTHORING_MANIFEST, T as TABLE_AI_CAPABILITIES, R as coerceTableComponentEditPlans, W as compileTableComponentEditPlans, G as TASK_PRESETS, $ as getTableComponentEditPlanCapabilities, w as TABLE_COMPONENT_EDIT_PLAN_EXPECTED_PATHS, u as TABLE_COMPONENT_EDIT_PLAN_ALLOWED_CHANGE_KINDS, x as TABLE_COMPONENT_EDIT_PLAN_JSON_SCHEMA, E as TABLE_COMPONENT_EDIT_PLAN_VERSION, v as TABLE_COMPONENT_EDIT_PLAN_BATCH_KIND, y as TABLE_COMPONENT_EDIT_PLAN_KIND } from './praxisui-table-praxisui-table-DmOoFvig.mjs';
4
+ import { z as TABLE_COMPONENT_EDIT_PLAN_OPERATION_IDS, k as PRAXIS_TABLE_AUTHORING_MANIFEST, T as TABLE_AI_CAPABILITIES, R as coerceTableComponentEditPlans, W as compileTableComponentEditPlans, G as TASK_PRESETS, $ as getTableComponentEditPlanCapabilities, w as TABLE_COMPONENT_EDIT_PLAN_EXPECTED_PATHS, u as TABLE_COMPONENT_EDIT_PLAN_ALLOWED_CHANGE_KINDS, x as TABLE_COMPONENT_EDIT_PLAN_JSON_SCHEMA, E as TABLE_COMPONENT_EDIT_PLAN_VERSION, v as TABLE_COMPONENT_EDIT_PLAN_BATCH_KIND, y as TABLE_COMPONENT_EDIT_PLAN_KIND } from './praxisui-table-praxisui-table-D7mgtcbB.mjs';
5
5
 
6
6
  const TABLE_COMPONENT_CONTEXT_PACK = {
7
7
  version: 'v1',
@@ -1932,7 +1932,7 @@ class TableAiAdapter extends BaseAiAdapter {
1932
1932
  : 'Preparei uma operacao de runtime para a tabela.',
1933
1933
  };
1934
1934
  }
1935
- const componentEditPlans = coerceTableComponentEditPlans(response);
1935
+ const componentEditPlans = this.hydrateRecordSurfaceRowActionPlans(coerceTableComponentEditPlans(response));
1936
1936
  if (!componentEditPlans) {
1937
1937
  return null;
1938
1938
  }
@@ -2073,6 +2073,11 @@ class TableAiAdapter extends BaseAiAdapter {
2073
2073
  useWhen: [
2074
2074
  'The user asks to change table configuration, visual rules, renderers, columns, behavior, actions, or appearance.',
2075
2075
  ],
2076
+ rules: [
2077
+ 'When the user asks to add a row button, row option, or action in each row for a declared record surface, use rowAction.add with capabilityPath "actions.row.actions[]".',
2078
+ 'For a rowAction.add that opens a declared record surface, set action id/label for the row button and preserve the declared surface under value.recordSurface; never overwrite the canonical recordSurface.id with the row action id.',
2079
+ 'Use human-facing labels from recordSurfaces for row action labels; do not ask for technical fields such as surface to open, button label, or placement in row when the conversation already grounded one declared surface.',
2080
+ ],
2076
2081
  },
2077
2082
  {
2078
2083
  kind: 'runtime',
@@ -2206,9 +2211,43 @@ class TableAiAdapter extends BaseAiAdapter {
2206
2211
  ...this.buildRecordSurfaceSemanticDigest(surface),
2207
2212
  source: surface.source,
2208
2213
  target: surface.target,
2214
+ ...(surface.resourceSurface ? { resourceSurface: this.sanitizeRecordSurfaceForAuthoring(surface.resourceSurface) } : {}),
2209
2215
  })),
2210
2216
  };
2211
2217
  }
2218
+ sanitizeRecordSurfaceForAuthoring(value) {
2219
+ const surface = this.toRecord(value);
2220
+ if (!surface)
2221
+ return null;
2222
+ const tags = this.compactStringArray(surface['tags']);
2223
+ const out = {};
2224
+ [
2225
+ 'id',
2226
+ 'resourceKey',
2227
+ 'kind',
2228
+ 'scope',
2229
+ 'title',
2230
+ 'description',
2231
+ 'intent',
2232
+ 'operationId',
2233
+ 'path',
2234
+ 'method',
2235
+ 'schemaId',
2236
+ 'schemaUrl',
2237
+ ].forEach((key) => {
2238
+ const text = this.stringValue(surface[key]);
2239
+ if (text)
2240
+ out[key] = text;
2241
+ });
2242
+ const availability = this.toRecord(surface['availability']);
2243
+ if (availability)
2244
+ out['availability'] = availability;
2245
+ if (typeof surface['order'] === 'number')
2246
+ out['order'] = surface['order'];
2247
+ if (tags.length)
2248
+ out['tags'] = tags;
2249
+ return Object.keys(out).length ? out : null;
2250
+ }
2212
2251
  buildRecordSurfaceSemanticDigest(surface) {
2213
2252
  const resourceSurface = this.toRecord(surface['resourceSurface']);
2214
2253
  if (!resourceSurface) {
@@ -2771,6 +2810,46 @@ class TableAiAdapter extends BaseAiAdapter {
2771
2810
  .map((surface) => this.toRecord(surface))
2772
2811
  .find((surface) => this.stringValue(surface?.['id']).toLowerCase() === normalized) ?? null;
2773
2812
  }
2813
+ hydrateRecordSurfaceRowActionPlans(plans) {
2814
+ if (!plans?.length)
2815
+ return plans;
2816
+ return plans.map((plan) => this.hydrateRecordSurfaceRowActionPlan(plan));
2817
+ }
2818
+ hydrateRecordSurfaceRowActionPlan(plan) {
2819
+ const operationId = this.stringValue(plan.operationId);
2820
+ const changeKind = this.stringValue(plan.changeKind);
2821
+ if (operationId !== 'rowAction.add' && changeKind !== 'add_row_action')
2822
+ return plan;
2823
+ const input = this.toRecord(plan.input) ?? this.toRecord(plan.value);
2824
+ if (!input)
2825
+ return plan;
2826
+ const nestedValue = this.toRecord(input['value']);
2827
+ const declaredSurfaceId = this.stringValue(this.toRecord(input['recordSurface'])?.['id'])
2828
+ || this.stringValue(this.toRecord(nestedValue?.['recordSurface'])?.['id']);
2829
+ if (!declaredSurfaceId)
2830
+ return plan;
2831
+ const surfaceEntry = this.getRecordSurfaceById(declaredSurfaceId);
2832
+ const resourceSurface = this.toRecord(surfaceEntry?.['resourceSurface']) ?? surfaceEntry;
2833
+ if (!resourceSurface)
2834
+ return plan;
2835
+ const label = this.stringValue(input['label'])
2836
+ || this.stringValue(surfaceEntry?.['label'])
2837
+ || this.stringValue(resourceSurface['title'])
2838
+ || declaredSurfaceId;
2839
+ const rowAction = {
2840
+ ...input,
2841
+ id: this.stringValue(input['id']) || `open-${declaredSurfaceId}`,
2842
+ label,
2843
+ action: this.stringValue(input['action']) || 'surface.open',
2844
+ icon: this.stringValue(input['icon']) || 'open_in_new',
2845
+ recordSurface: resourceSurface,
2846
+ };
2847
+ return {
2848
+ ...plan,
2849
+ input: rowAction,
2850
+ value: rowAction,
2851
+ };
2852
+ }
2774
2853
  toRecord(value) {
2775
2854
  return value && typeof value === 'object' && !Array.isArray(value)
2776
2855
  ? value
@@ -3114,7 +3193,7 @@ Columns Analysis:
3114
3193
  const context = this.extractContextForIntent(classification);
3115
3194
  const caps = this.getFilteredCapabilities(classification?.category);
3116
3195
  const result = await firstValueFrom(aiService.executeEnrichedPrompt(userInput, context.desc, context.config, caps));
3117
- const componentEditPlans = coerceTableComponentEditPlans(result);
3196
+ const componentEditPlans = this.hydrateRecordSurfaceRowActionPlans(coerceTableComponentEditPlans(result));
3118
3197
  if (componentEditPlans) {
3119
3198
  const compiled = compileTableComponentEditPlans(componentEditPlans, this.getCompileConfig());
3120
3199
  if (compiled.patch) {
@@ -1 +1 @@
1
- export { A as AnalyticsTableConfigAdapterService, a as AnalyticsTableContractService, b as AnalyticsTableStatsApiService, B as BOOLEAN_PRESETS, c as BehaviorConfigEditorComponent, C as CURRENCY_PRESETS, d as ColumnsConfigEditorComponent, D as DATE_PRESETS, e as DataFormatterComponent, f as DataFormattingService, F as FORMULA_TEMPLATES, g as FilterConfigService, h as FilterSettingsComponent, i as FormulaGeneratorService, J as JsonConfigEditorComponent, M as MessagesLocalizationEditorComponent, N as NUMBER_PRESETS, P as PERCENTAGE_PRESETS, j as PRAXIS_FILTER_COMPONENT_METADATA, k as PRAXIS_TABLE_AUTHORING_MANIFEST, l as PRAXIS_TABLE_COMPONENT_METADATA, m as PraxisFilter, n as PraxisFilterWidgetConfigEditor, o as PraxisTable, p as PraxisTableConfigEditor, q as PraxisTableInlineAuthoringEditorComponent, r as PraxisTableToolbar, s as PraxisTableWidgetConfigEditor, S as STRING_PRESETS, T as TABLE_AI_CAPABILITIES, t as TABLE_COMPONENT_AI_CAPABILITIES, u as TABLE_COMPONENT_EDIT_PLAN_ALLOWED_CHANGE_KINDS, v as TABLE_COMPONENT_EDIT_PLAN_BATCH_KIND, w as TABLE_COMPONENT_EDIT_PLAN_EXPECTED_PATHS, x as TABLE_COMPONENT_EDIT_PLAN_JSON_SCHEMA, y as TABLE_COMPONENT_EDIT_PLAN_KIND, E as TABLE_COMPONENT_EDIT_PLAN_VERSION, G as TASK_PRESETS, H as TableDefaultsProvider, I as TableRulesEditorComponent, K as ToolbarActionsEditorComponent, V as ValueMappingEditorComponent, L as VisualFormulaBuilderComponent, O as buildTableApplyPlan, Q as coerceTableComponentEditPlan, R as coerceTableComponentEditPlans, U as compileTableComponentEditPlan, W as compileTableComponentEditPlans, X as createTableAuthoringDocument, Y as getActionId, Z as getEnum, _ as getTableCapabilities, $ as getTableComponentEditPlanCapabilities, a0 as isTableRendererSupportedByRichContentP0, a1 as mapTableRendererToRichContentP0, a2 as normalizeTableAuthoringDocument, a3 as parseLegacyOrTableDocument, a4 as providePraxisFilterMetadata, a5 as providePraxisTableMetadata, a6 as serializeTableAuthoringDocument, a7 as toCanonicalTableConfig, a8 as validateTableAuthoringDocument } from './praxisui-table-praxisui-table-DmOoFvig.mjs';
1
+ export { A as AnalyticsTableConfigAdapterService, a as AnalyticsTableContractService, b as AnalyticsTableStatsApiService, B as BOOLEAN_PRESETS, c as BehaviorConfigEditorComponent, C as CURRENCY_PRESETS, d as ColumnsConfigEditorComponent, D as DATE_PRESETS, e as DataFormatterComponent, f as DataFormattingService, F as FORMULA_TEMPLATES, g as FilterConfigService, h as FilterSettingsComponent, i as FormulaGeneratorService, J as JsonConfigEditorComponent, M as MessagesLocalizationEditorComponent, N as NUMBER_PRESETS, P as PERCENTAGE_PRESETS, j as PRAXIS_FILTER_COMPONENT_METADATA, k as PRAXIS_TABLE_AUTHORING_MANIFEST, l as PRAXIS_TABLE_COMPONENT_METADATA, m as PraxisFilter, n as PraxisFilterWidgetConfigEditor, o as PraxisTable, p as PraxisTableConfigEditor, q as PraxisTableInlineAuthoringEditorComponent, r as PraxisTableToolbar, s as PraxisTableWidgetConfigEditor, S as STRING_PRESETS, T as TABLE_AI_CAPABILITIES, t as TABLE_COMPONENT_AI_CAPABILITIES, u as TABLE_COMPONENT_EDIT_PLAN_ALLOWED_CHANGE_KINDS, v as TABLE_COMPONENT_EDIT_PLAN_BATCH_KIND, w as TABLE_COMPONENT_EDIT_PLAN_EXPECTED_PATHS, x as TABLE_COMPONENT_EDIT_PLAN_JSON_SCHEMA, y as TABLE_COMPONENT_EDIT_PLAN_KIND, E as TABLE_COMPONENT_EDIT_PLAN_VERSION, G as TASK_PRESETS, H as TableDefaultsProvider, I as TableRulesEditorComponent, K as ToolbarActionsEditorComponent, V as ValueMappingEditorComponent, L as VisualFormulaBuilderComponent, O as buildTableApplyPlan, Q as coerceTableComponentEditPlan, R as coerceTableComponentEditPlans, U as compileTableComponentEditPlan, W as compileTableComponentEditPlans, X as createTableAuthoringDocument, Y as getActionId, Z as getEnum, _ as getTableCapabilities, $ as getTableComponentEditPlanCapabilities, a0 as isTableRendererSupportedByRichContentP0, a1 as mapTableRendererToRichContentP0, a2 as normalizeTableAuthoringDocument, a3 as parseLegacyOrTableDocument, a4 as providePraxisFilterMetadata, a5 as providePraxisTableMetadata, a6 as serializeTableAuthoringDocument, a7 as toCanonicalTableConfig, a8 as validateTableAuthoringDocument } from './praxisui-table-praxisui-table-D7mgtcbB.mjs';
package/package.json CHANGED
@@ -1,23 +1,23 @@
1
1
  {
2
2
  "name": "@praxisui/table",
3
- "version": "8.0.0-beta.59",
3
+ "version": "8.0.0-beta.60",
4
4
  "description": "Advanced data table for Angular (Praxis UI) with editing, filtering, sorting, virtualization, and settings panel integration.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
7
7
  "@angular/core": "^21.0.0",
8
- "@praxisui/ai": "^8.0.0-beta.59",
9
- "@praxisui/core": "^8.0.0-beta.59",
10
- "@praxisui/dynamic-fields": "^8.0.0-beta.59",
11
- "@praxisui/dynamic-form": "^8.0.0-beta.59",
12
- "@praxisui/metadata-editor": "^8.0.0-beta.59",
13
- "@praxisui/rich-content": "^8.0.0-beta.59",
14
- "@praxisui/settings-panel": "^8.0.0-beta.59",
15
- "@praxisui/table-rule-builder": "^8.0.0-beta.59",
8
+ "@praxisui/ai": "^8.0.0-beta.60",
9
+ "@praxisui/core": "^8.0.0-beta.60",
10
+ "@praxisui/dynamic-fields": "^8.0.0-beta.60",
11
+ "@praxisui/dynamic-form": "^8.0.0-beta.60",
12
+ "@praxisui/metadata-editor": "^8.0.0-beta.60",
13
+ "@praxisui/rich-content": "^8.0.0-beta.60",
14
+ "@praxisui/settings-panel": "^8.0.0-beta.60",
15
+ "@praxisui/table-rule-builder": "^8.0.0-beta.60",
16
16
  "@angular/cdk": "^21.0.0",
17
17
  "@angular/forms": "^21.0.0",
18
18
  "@angular/material": "^21.0.0",
19
19
  "@angular/router": "^21.0.0",
20
- "@praxisui/dialog": "^8.0.0-beta.59",
20
+ "@praxisui/dialog": "^8.0.0-beta.60",
21
21
  "rxjs": "~7.8.0"
22
22
  },
23
23
  "dependencies": {
@@ -316,6 +316,7 @@ Este arquivo foi adaptado para o padrao canonico atual sem remover conteudo tecn
316
316
  | `behavior.expansion.interaction.motion` | object | No | runtime-defaults | preset-driven | Presets controlados (`none`, `subtle-slide`, `accordion`, `fade-scale`) com respeito a `prefers-reduced-motion`; `durationMs` aceita `0` para desabilitar motion temporal. |
317
317
  | `appearance.responsive` | object | No | component-defaults | numeric-breakpoint | Breakpoint móvel inválido é normalizado para `768`. |
318
318
  | `toolbar.actions[]` | array | No | `[]` | action-contract | Ações de toolbar com roteamento para `toolbarAction`/`bulkAction`. |
319
+ | `actions.row.actions[].recordSurface` | object | No | none | `ResourceSurfaceCatalogItem` | Preserva a identidade canônica da superfície relacionada aberta por uma ação de linha, mantendo `actions.row.actions[].id` como identidade do botão. |
319
320
  | `actions.row.discovery.enabled` | boolean | No | `true` | row-action-discovery | Controla se row actions podem ser enriquecidas por HATEOAS/capabilities. Configure `false` para manter somente ações declaradas em `actions.row.actions[]`. |
320
321
  | `columns[].renderer` | object | No | field-type-driven | renderer-contract | Renderers condicionais, payload expr e ações interativas. |
321
322
 
@@ -2095,6 +2095,7 @@ declare class PraxisTable implements OnInit, OnChanges, AfterViewInit, AfterCont
2095
2095
  private findItemSurface;
2096
2096
  private isRowSurfaceAction;
2097
2097
  private isResourceSurfaceCatalogItem;
2098
+ private toRecordSurfaceActionConfig;
2098
2099
  private isWritableRowSurface;
2099
2100
  private isReadableRowSurface;
2100
2101
  private getDiscoveredSurfaceIcon;
@@ -4096,9 +4097,9 @@ type ComponentEditPlanCapability = {
4096
4097
  declare const TABLE_COMPONENT_EDIT_PLAN_KIND = "praxis.table.component-edit-plan";
4097
4098
  declare const TABLE_COMPONENT_EDIT_PLAN_BATCH_KIND = "praxis.table.component-edit-plan.batch";
4098
4099
  declare const TABLE_COMPONENT_EDIT_PLAN_VERSION = "1.0";
4099
- type TableComponentEditChangeKind = 'add_column' | 'set_column_format' | 'set_column_header' | 'set_column_visibility' | 'set_column_filterable' | 'set_column_sortable' | 'set_column_width' | 'set_column_order' | 'set_column_align' | 'set_column_style' | 'set_column_header_style' | 'set_column_sticky' | 'set_column_conditional_style' | 'set_row_conditional_style' | 'set_column_computed' | 'set_column_value_mapping' | 'set_column_renderer' | 'set_column_badge_renderer' | 'set_column_conditional_badge_renderers' | 'set_row_conditional_renderer' | 'configure_table_filtering' | 'configure_advanced_filters' | 'add_advanced_filter_fields' | 'remove_advanced_filter_fields' | 'configure_table_pagination' | 'configure_table_selection' | 'configure_table_sorting' | 'configure_toolbar' | 'add_toolbar_action' | 'configure_export' | 'set_table_density' | 'set_toolbar_visibility';
4100
- type TableComponentEditOperationId = 'column.add' | 'column.format.set' | 'column.header.set' | 'column.visibility.set' | 'column.filterable.set' | 'column.sortable.set' | 'column.width.set' | 'column.order.set' | 'column.align.set' | 'column.style.set' | 'column.headerStyle.set' | 'column.sticky.set' | 'column.renderer.set' | 'column.valueMapping.set' | 'column.conditionalStyle.add' | 'row.styleRule.add' | 'column.conditionalRenderer.add' | 'column.computed.add' | 'row.conditionalRenderer.add' | 'behavior.filtering.configure' | 'filter.advanced.configure' | 'filter.advanced.fields.add' | 'filter.advanced.fields.remove' | 'behavior.pagination.configure' | 'behavior.selection.configure' | 'behavior.sorting.configure' | 'toolbar.configure' | 'toolbar.action.add' | 'export.configure' | 'appearance.density.set' | 'toolbar.visibility.set';
4101
- declare const TABLE_COMPONENT_EDIT_PLAN_ALLOWED_CHANGE_KINDS: readonly ["add_column", "set_column_format", "set_column_header", "set_column_visibility", "set_column_filterable", "set_column_sortable", "set_column_width", "set_column_order", "set_column_align", "set_column_style", "set_column_header_style", "set_column_sticky", "set_column_conditional_style", "set_row_conditional_style", "set_column_computed", "set_column_value_mapping", "set_column_renderer", "set_column_badge_renderer", "set_column_conditional_badge_renderers", "set_row_conditional_renderer", "configure_table_filtering", "configure_advanced_filters", "add_advanced_filter_fields", "remove_advanced_filter_fields", "configure_table_pagination", "configure_table_selection", "configure_table_sorting", "configure_toolbar", "add_toolbar_action", "configure_export", "set_table_density", "set_toolbar_visibility"];
4100
+ type TableComponentEditChangeKind = 'add_column' | 'set_column_format' | 'set_column_header' | 'set_column_visibility' | 'set_column_filterable' | 'set_column_sortable' | 'set_column_width' | 'set_column_order' | 'set_column_align' | 'set_column_style' | 'set_column_header_style' | 'set_column_sticky' | 'set_column_conditional_style' | 'set_row_conditional_style' | 'set_column_computed' | 'set_column_value_mapping' | 'set_column_renderer' | 'set_column_badge_renderer' | 'set_column_conditional_badge_renderers' | 'set_row_conditional_renderer' | 'configure_table_filtering' | 'configure_advanced_filters' | 'add_advanced_filter_fields' | 'remove_advanced_filter_fields' | 'configure_table_pagination' | 'configure_table_selection' | 'configure_table_sorting' | 'configure_toolbar' | 'add_toolbar_action' | 'add_row_action' | 'configure_export' | 'set_table_density' | 'set_toolbar_visibility';
4101
+ type TableComponentEditOperationId = 'column.add' | 'column.format.set' | 'column.header.set' | 'column.visibility.set' | 'column.filterable.set' | 'column.sortable.set' | 'column.width.set' | 'column.order.set' | 'column.align.set' | 'column.style.set' | 'column.headerStyle.set' | 'column.sticky.set' | 'column.renderer.set' | 'column.valueMapping.set' | 'column.conditionalStyle.add' | 'row.styleRule.add' | 'column.conditionalRenderer.add' | 'column.computed.add' | 'row.conditionalRenderer.add' | 'behavior.filtering.configure' | 'filter.advanced.configure' | 'filter.advanced.fields.add' | 'filter.advanced.fields.remove' | 'behavior.pagination.configure' | 'behavior.selection.configure' | 'behavior.sorting.configure' | 'toolbar.configure' | 'toolbar.action.add' | 'rowAction.add' | 'export.configure' | 'appearance.density.set' | 'toolbar.visibility.set';
4102
+ declare const TABLE_COMPONENT_EDIT_PLAN_ALLOWED_CHANGE_KINDS: readonly ["add_column", "set_column_format", "set_column_header", "set_column_visibility", "set_column_filterable", "set_column_sortable", "set_column_width", "set_column_order", "set_column_align", "set_column_style", "set_column_header_style", "set_column_sticky", "set_column_conditional_style", "set_row_conditional_style", "set_column_computed", "set_column_value_mapping", "set_column_renderer", "set_column_badge_renderer", "set_column_conditional_badge_renderers", "set_row_conditional_renderer", "configure_table_filtering", "configure_advanced_filters", "add_advanced_filter_fields", "remove_advanced_filter_fields", "configure_table_pagination", "configure_table_selection", "configure_table_sorting", "configure_toolbar", "add_toolbar_action", "add_row_action", "configure_export", "set_table_density", "set_toolbar_visibility"];
4102
4103
  declare const TABLE_COMPONENT_EDIT_PLAN_EXPECTED_PATHS: Record<TableComponentEditChangeKind, string>;
4103
4104
  interface TableComponentEditPlan {
4104
4105
  kind?: typeof TABLE_COMPONENT_EDIT_PLAN_KIND;
@@ -4140,7 +4141,7 @@ declare const TABLE_COMPONENT_EDIT_PLAN_JSON_SCHEMA: {
4140
4141
  readonly $defs: {
4141
4142
  readonly changeKind: {
4142
4143
  readonly type: "string";
4143
- readonly enum: readonly ["add_column", "set_column_format", "set_column_header", "set_column_visibility", "set_column_filterable", "set_column_sortable", "set_column_width", "set_column_order", "set_column_align", "set_column_style", "set_column_header_style", "set_column_sticky", "set_column_conditional_style", "set_row_conditional_style", "set_column_computed", "set_column_value_mapping", "set_column_renderer", "set_column_badge_renderer", "set_column_conditional_badge_renderers", "set_row_conditional_renderer", "configure_table_filtering", "configure_advanced_filters", "add_advanced_filter_fields", "remove_advanced_filter_fields", "configure_table_pagination", "configure_table_selection", "configure_table_sorting", "configure_toolbar", "add_toolbar_action", "configure_export", "set_table_density", "set_toolbar_visibility"];
4144
+ readonly enum: readonly ["add_column", "set_column_format", "set_column_header", "set_column_visibility", "set_column_filterable", "set_column_sortable", "set_column_width", "set_column_order", "set_column_align", "set_column_style", "set_column_header_style", "set_column_sticky", "set_column_conditional_style", "set_row_conditional_style", "set_column_computed", "set_column_value_mapping", "set_column_renderer", "set_column_badge_renderer", "set_column_conditional_badge_renderers", "set_row_conditional_renderer", "configure_table_filtering", "configure_advanced_filters", "add_advanced_filter_fields", "remove_advanced_filter_fields", "configure_table_pagination", "configure_table_selection", "configure_table_sorting", "configure_toolbar", "add_toolbar_action", "add_row_action", "configure_export", "set_table_density", "set_toolbar_visibility"];
4144
4145
  };
4145
4146
  readonly capabilityPath: {
4146
4147
  readonly type: "string";
@@ -4221,7 +4222,7 @@ declare const TABLE_COMPONENT_EDIT_PLAN_JSON_SCHEMA: {
4221
4222
  readonly const: "praxis-table";
4222
4223
  };
4223
4224
  readonly operationId: {
4224
- readonly enum: readonly ["column.add", "column.format.set", "column.header.set", "column.visibility.set", "column.filterable.set", "column.sortable.set", "column.width.set", "column.order.set", "column.align.set", "column.style.set", "column.headerStyle.set", "column.sticky.set", "column.renderer.set", "column.valueMapping.set", "column.conditionalStyle.add", "row.styleRule.add", "column.conditionalRenderer.add", "column.computed.add", "row.conditionalRenderer.add", "behavior.filtering.configure", "filter.advanced.configure", "filter.advanced.fields.add", "filter.advanced.fields.remove", "behavior.pagination.configure", "behavior.selection.configure", "behavior.sorting.configure", "toolbar.configure", "toolbar.action.add", "export.configure", "appearance.density.set", "toolbar.visibility.set"];
4225
+ readonly enum: readonly ["column.add", "column.format.set", "column.header.set", "column.visibility.set", "column.filterable.set", "column.sortable.set", "column.width.set", "column.order.set", "column.align.set", "column.style.set", "column.headerStyle.set", "column.sticky.set", "column.renderer.set", "column.valueMapping.set", "column.conditionalStyle.add", "row.styleRule.add", "column.conditionalRenderer.add", "column.computed.add", "row.conditionalRenderer.add", "behavior.filtering.configure", "filter.advanced.configure", "filter.advanced.fields.add", "filter.advanced.fields.remove", "behavior.pagination.configure", "behavior.selection.configure", "behavior.sorting.configure", "toolbar.configure", "toolbar.action.add", "rowAction.add", "export.configure", "appearance.density.set", "toolbar.visibility.set"];
4225
4226
  };
4226
4227
  readonly target: true;
4227
4228
  readonly input: true;