@praxisui/table 8.0.0-beta.20 → 8.0.0-beta.21
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 +69 -0
- package/fesm2022/{praxisui-table-table-agentic-authoring-turn-flow-tu7jtTwV.mjs → praxisui-table-table-agentic-authoring-turn-flow-DRuE55Mi.mjs} +100 -0
- package/fesm2022/praxisui-table.mjs +1598 -343
- package/index.d.ts +212 -62
- package/package.json +10 -10
- package/src/lib/praxis-table.json-api.md +11 -1
package/README.md
CHANGED
|
@@ -163,6 +163,15 @@ Filtro runtime:
|
|
|
163
163
|
- The default is `false`; hosts opt in when they want settings, authoring affordances and schema-drift UX.
|
|
164
164
|
- Customization mode does not change the table data mode. It only gates configuration/editorial surfaces.
|
|
165
165
|
|
|
166
|
+
## Praxis Semantic Assistant
|
|
167
|
+
|
|
168
|
+
- The table assistant is part of the global Praxis semantic copilot experience, not a standalone table patch bot.
|
|
169
|
+
- In customization mode, opening the assistant registers a `PraxisAssistantContextSnapshot` through `PraxisAssistantSessionRegistryService`.
|
|
170
|
+
- The table session identity follows `table:{routeKey}:{componentInstanceId || tableId}` so multiple tables on the same page can preserve separate assistant sessions.
|
|
171
|
+
- Minimizing the table shell keeps a global minimized session that the App Shell can reopen; the App Shell does not interpret or execute table semantics.
|
|
172
|
+
- The table snapshot stores only safe context: table identity, target, context chips, manifest reference, resource path, schema field names, data/runtime digests, capability refs and governance hints.
|
|
173
|
+
- Prompts that indicate shared business decisions, such as rules, policies, compliance, LGPD, approval, eligibility or access control, must be routed to governed `domain-rules` handoff instead of local table config patches.
|
|
174
|
+
|
|
166
175
|
## Migration Note
|
|
167
176
|
|
|
168
177
|
- This release treats `enableCustomization=false` as the canonical default.
|
|
@@ -274,6 +283,25 @@ rowConditionalStyles: [
|
|
|
274
283
|
]
|
|
275
284
|
```
|
|
276
285
|
|
|
286
|
+
O editor especializado tambem persiste `effects: RuleEffectDefinition[]` em
|
|
287
|
+
`rowConditionalStyles` e `columns[].conditionalStyles`. O runtime consome esses
|
|
288
|
+
efeitos diretamente e ainda preserva `cssClass`/`style` como fallback de
|
|
289
|
+
compatibilidade, mantendo o ciclo abrir -> aplicar/salvar -> reabrir sem exigir
|
|
290
|
+
que consumidores recompilem manualmente os efeitos visuais.
|
|
291
|
+
|
|
292
|
+
Para renderizacao condicional, `columns[].conditionalRenderers` tambem aceita
|
|
293
|
+
`effects: RuleEffectDefinition[]` como fonte canonica para renderer, tooltip e
|
|
294
|
+
animacao. `rowConditionalRenderers` fica tipado no contrato publico para tooltip
|
|
295
|
+
e animacao de linha, preservando os campos planos `tooltip`/`animation` como
|
|
296
|
+
fallback.
|
|
297
|
+
|
|
298
|
+
Colunas calculadas usam `columns[].computed.expression` como AST JSON Logic
|
|
299
|
+
canonico. Regras, estilos e renderers condicionais podem referenciar esses
|
|
300
|
+
valores via `computed.<field>`. Quando uma coluna calculada depende de outra
|
|
301
|
+
coluna calculada, o runtime resolve a ordem de avaliacao por dependencias
|
|
302
|
+
declaradas ou referencias `var: "computed.<field>"`, evitando que o resultado
|
|
303
|
+
dependa da ordem fisica de `columns[]`.
|
|
304
|
+
|
|
277
305
|
```scss
|
|
278
306
|
.app-table .mat-mdc-row.app-row--priority-high {
|
|
279
307
|
background: linear-gradient(
|
|
@@ -471,6 +499,12 @@ por `PraxisAssistantTurnOrchestratorService`; a semantica especifica da tabela c
|
|
|
471
499
|
|
|
472
500
|
## Agentic Authoring & Manifest
|
|
473
501
|
|
|
502
|
+
Para acoes globais de `toolbar`, `row` e `bulk`, o authoring agentic aceita somente `GlobalActionRef` governado:
|
|
503
|
+
`actionId`, `payload`, `payloadExpr` e `meta`. O schema bloqueia propriedades arbitrarias e mantem `payloadExpr`
|
|
504
|
+
como escape avancado explicito, nao como objeto livre. Configuracoes novas devem persistir a acao em
|
|
505
|
+
`effects[].kind = "global-action"` com `effects[].globalAction`; `globalAction` plano permanece apenas como fallback
|
|
506
|
+
de compatibilidade para documentos existentes.
|
|
507
|
+
|
|
474
508
|
O `@praxisui/table` declara authoring agentic através de um `ComponentAuthoringManifest` canônico. O manifesto é a fonte versionada para descoberta de alvos, operações e validações de configuração da tabela.
|
|
475
509
|
|
|
476
510
|
- **Component ID:** `praxis-table`
|
|
@@ -1814,6 +1848,20 @@ actions: {
|
|
|
1814
1848
|
id: 'open-detail',
|
|
1815
1849
|
label: 'Abrir detalhe',
|
|
1816
1850
|
action: 'navigation.openRoute',
|
|
1851
|
+
effects: [
|
|
1852
|
+
{
|
|
1853
|
+
kind: 'global-action',
|
|
1854
|
+
globalAction: {
|
|
1855
|
+
actionId: 'navigation.openRoute',
|
|
1856
|
+
payload: {
|
|
1857
|
+
path: '/clientes/detalhe',
|
|
1858
|
+
query: {
|
|
1859
|
+
id: '${row.id}',
|
|
1860
|
+
},
|
|
1861
|
+
},
|
|
1862
|
+
},
|
|
1863
|
+
},
|
|
1864
|
+
],
|
|
1817
1865
|
globalAction: {
|
|
1818
1866
|
actionId: 'navigation.openRoute',
|
|
1819
1867
|
payload: {
|
|
@@ -1831,3 +1879,24 @@ actions: {
|
|
|
1831
1879
|
|
|
1832
1880
|
O runtime da tabela resolve templates como `${row.id}` antes de executar a
|
|
1833
1881
|
global action, o que permite reutilizar o mesmo contrato em `list` e `table`.
|
|
1882
|
+
Para configuracoes novas, `effects[].kind = 'global-action'` e o envelope
|
|
1883
|
+
canonico alinhado a `PraxisRuntimeGlobalActionEffect`; `globalAction` plano
|
|
1884
|
+
continua aceito como fallback de compatibilidade.
|
|
1885
|
+
O editor de acoes usa o mesmo adapter interno para toolbar, row e bulk actions:
|
|
1886
|
+
ao escolher novamente a mesma global action, ele preserva `payload` estruturado
|
|
1887
|
+
ou `payloadExpr` existente; ao trocar o `actionId`, ele descarta o payload antigo
|
|
1888
|
+
para evitar executar parametros de outra acao.
|
|
1889
|
+
|
|
1890
|
+
As acoes por linha tambem usam Json Logic canonico para `visibleWhen` e
|
|
1891
|
+
`disabledWhen`. O editor de acoes preserva esses objetos no fluxo
|
|
1892
|
+
abrir -> aplicar/salvar -> reabrir, por exemplo:
|
|
1893
|
+
|
|
1894
|
+
```ts
|
|
1895
|
+
{
|
|
1896
|
+
id: 'edit-active',
|
|
1897
|
+
label: 'Editar',
|
|
1898
|
+
action: 'edit',
|
|
1899
|
+
visibleWhen: { '===': [{ var: 'status' }, 'Ativo'] },
|
|
1900
|
+
disabledWhen: { '===': [{ var: 'status' }, 'Bloqueado'] },
|
|
1901
|
+
}
|
|
1902
|
+
```
|
|
@@ -26,6 +26,9 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
26
26
|
?.map((field) => this.toAiJsonObject(field))
|
|
27
27
|
.filter((field) => Object.keys(field).length > 0);
|
|
28
28
|
const contextHints = this.optionalJsonObject(this.adapter.getAuthoringContext?.());
|
|
29
|
+
if (this.shouldRouteToGovernedDecision(prompt, contextHints)) {
|
|
30
|
+
return this.toGovernedDecisionHandoff(prompt, request);
|
|
31
|
+
}
|
|
29
32
|
const response = await firstValueFrom(this.aiApi.getPatch({
|
|
30
33
|
componentId,
|
|
31
34
|
componentType,
|
|
@@ -173,9 +176,26 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
173
176
|
}
|
|
174
177
|
compileAdapterResponse(response) {
|
|
175
178
|
const compiled = this.adapter.compileAiResponse?.(response);
|
|
179
|
+
if (!compiled && response.patch && Object.keys(response.patch).length > 0) {
|
|
180
|
+
return {
|
|
181
|
+
type: 'error',
|
|
182
|
+
message: 'A tabela exige componentEditPlan validado pelo manifesto antes de gerar patch local.',
|
|
183
|
+
warnings: [
|
|
184
|
+
'free-table-patch-rejected',
|
|
185
|
+
'Use componentEditPlan validado contra PRAXIS_TABLE_AUTHORING_MANIFEST.',
|
|
186
|
+
],
|
|
187
|
+
};
|
|
188
|
+
}
|
|
176
189
|
if (!compiled) {
|
|
177
190
|
return response;
|
|
178
191
|
}
|
|
192
|
+
if (compiled.type === 'error') {
|
|
193
|
+
return {
|
|
194
|
+
type: 'error',
|
|
195
|
+
message: compiled.message || 'O componentEditPlan da tabela nao passou na validacao de capacidades.',
|
|
196
|
+
warnings: compiled.warnings,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
179
199
|
const warnings = [
|
|
180
200
|
...(response.warnings ?? []),
|
|
181
201
|
...(compiled.warnings ?? []),
|
|
@@ -183,6 +203,7 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
183
203
|
return {
|
|
184
204
|
...response,
|
|
185
205
|
...compiled,
|
|
206
|
+
patch: compiled.patch,
|
|
186
207
|
warnings: warnings.length ? warnings : undefined,
|
|
187
208
|
};
|
|
188
209
|
}
|
|
@@ -251,6 +272,85 @@ class TableAgenticAuthoringTurnFlow {
|
|
|
251
272
|
...(rowCount !== undefined ? { rowCount } : {}),
|
|
252
273
|
};
|
|
253
274
|
}
|
|
275
|
+
shouldRouteToGovernedDecision(prompt, contextHints) {
|
|
276
|
+
const normalized = prompt.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase();
|
|
277
|
+
const recommendedFlow = this.toRecord(contextHints?.['domainCatalog'])?.['recommendedAuthoringFlow'];
|
|
278
|
+
if (recommendedFlow === 'shared_rule_authoring')
|
|
279
|
+
return true;
|
|
280
|
+
return [
|
|
281
|
+
'regra',
|
|
282
|
+
'politica',
|
|
283
|
+
'policy',
|
|
284
|
+
'compliance',
|
|
285
|
+
'lgpd',
|
|
286
|
+
'privacidade',
|
|
287
|
+
'aprovacao',
|
|
288
|
+
'aprovar',
|
|
289
|
+
'publicar',
|
|
290
|
+
'materializar',
|
|
291
|
+
'enforcement',
|
|
292
|
+
'validacao de negocio',
|
|
293
|
+
'validar negocio',
|
|
294
|
+
'elegibilidade',
|
|
295
|
+
'permissao',
|
|
296
|
+
'acesso',
|
|
297
|
+
].some((term) => normalized.includes(term));
|
|
298
|
+
}
|
|
299
|
+
toGovernedDecisionHandoff(prompt, request) {
|
|
300
|
+
const message = 'Esse pedido parece alterar uma decisao de negocio compartilhada. A tabela pode ajudar a descrever o alvo, mas a regra deve seguir pelo fluxo governado de domain-rules antes de qualquer materializacao runtime.';
|
|
301
|
+
return {
|
|
302
|
+
state: 'clarification',
|
|
303
|
+
phase: 'clarify',
|
|
304
|
+
sessionId: request.sessionId,
|
|
305
|
+
assistantMessage: message,
|
|
306
|
+
statusText: 'Handoff governado necessario.',
|
|
307
|
+
canApply: false,
|
|
308
|
+
quickReplies: [
|
|
309
|
+
{
|
|
310
|
+
id: 'shared-rule-handoff',
|
|
311
|
+
label: 'Continuar como regra governada',
|
|
312
|
+
prompt,
|
|
313
|
+
kind: 'shared-rule-handoff',
|
|
314
|
+
description: 'Criar intake de domain-rules em vez de aplicar patch local na tabela.',
|
|
315
|
+
icon: 'rule',
|
|
316
|
+
tone: 'warning',
|
|
317
|
+
contextHints: {
|
|
318
|
+
flowId: 'shared_rule_authoring',
|
|
319
|
+
source: 'praxis-table',
|
|
320
|
+
recommendedAction: 'domain-rules/intake',
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
],
|
|
324
|
+
clarificationQuestions: [
|
|
325
|
+
{
|
|
326
|
+
id: 'table-governed-rule-confirmation',
|
|
327
|
+
type: 'confirm',
|
|
328
|
+
label: 'Deseja continuar pelo fluxo governado de regras compartilhadas?',
|
|
329
|
+
description: 'Esse caminho permite intake, simulacao, aprovacao/publicacao, materializacao e validacao de enforcement.',
|
|
330
|
+
required: true,
|
|
331
|
+
options: [
|
|
332
|
+
{
|
|
333
|
+
id: 'shared-rule-handoff',
|
|
334
|
+
label: 'Sim, continuar governado',
|
|
335
|
+
value: prompt,
|
|
336
|
+
description: 'Nao aplicar como patch local da tabela.',
|
|
337
|
+
contextHints: {
|
|
338
|
+
flowId: 'shared_rule_authoring',
|
|
339
|
+
source: 'praxis-table',
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
],
|
|
343
|
+
},
|
|
344
|
+
],
|
|
345
|
+
diagnostics: {
|
|
346
|
+
governedDecisionHandoff: {
|
|
347
|
+
flowId: 'shared_rule_authoring',
|
|
348
|
+
sourcePrompt: prompt,
|
|
349
|
+
sourceComponent: 'praxis-table',
|
|
350
|
+
},
|
|
351
|
+
},
|
|
352
|
+
};
|
|
353
|
+
}
|
|
254
354
|
optionalJsonObject(value) {
|
|
255
355
|
if (value === undefined || value === null) {
|
|
256
356
|
return undefined;
|