@praxisui/table 8.0.0-beta.0 → 8.0.0-beta.100
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 +236 -13
- package/docs/DSL-Extensions-Guide.md +23 -0
- package/docs/adr/2026-03-dynamic-filter-cross-lib-coupling.md +107 -0
- package/docs/adr/2026-03-filter-drawer-adapter-light-entrypoint.md +105 -0
- package/docs/adr/2026-03-table-editor-idfield-decision.md +85 -0
- package/docs/column-resize-reorder-implementation-plan.md +338 -0
- package/docs/column-resize-reorder-review-prompt.md +34 -0
- package/docs/dynamic-filter-architecture-overview.md +207 -0
- package/docs/dynamic-filter-backend-contract-cheatsheet.md +167 -0
- package/docs/dynamic-filter-editor-settings-guide.md +229 -0
- package/docs/dynamic-filter-host-integration-guide.md +266 -0
- package/docs/dynamic-filter-payload-contract.md +332 -0
- package/docs/dynamic-filter-range-filters-guide.md +296 -0
- package/docs/dynamic-filter-troubleshooting-guide.md +257 -0
- package/docs/dynamic-inline-filter-catalog.md +147 -0
- package/docs/e2e-column-drag-playwright.md +62 -0
- package/docs/expandable-rows-enterprise-big-leagues-plan.md +1080 -0
- package/docs/json-logic-operators-and-helpers.md +57 -0
- package/docs/local-data-mode-precedence.md +12 -0
- package/docs/local-data-pre-implementation-baseline.md +22 -0
- package/docs/local-data-preimplementation-go-no-go.md +39 -0
- package/docs/local-data-support-implementation-plan.md +524 -0
- package/docs/local-data-support-pr-package.md +66 -0
- package/docs/localization-persistence-merge.md +22 -0
- package/docs/performance-hardening-v2-implementation-plan.md +479 -0
- package/docs/playground-scenario-curation-plan.md +482 -0
- package/docs/playground-scenario-second-opinion-prompt.md +121 -0
- package/docs/playground-scenario-second-opinion-review.md +234 -0
- package/docs/release-notes-p1-hardening.md +76 -0
- package/docs/table-authoring-document-completeness-checklist.md +120 -0
- package/docs/table-editor-capability-review-prompt.md +349 -0
- package/docs/visual-rules-editor-transition.md +29 -0
- package/fesm2022/praxisui-table-filter-form-dialog-host.component-DbwGIMjF.mjs +232 -0
- package/fesm2022/praxisui-table-praxisui-table-MXizgJYx.mjs +60987 -0
- package/fesm2022/praxisui-table-table-agentic-authoring-turn-flow-BJWah3jp.mjs +9641 -0
- package/fesm2022/praxisui-table-table-ai.adapter-DFyMRt4g.mjs +3999 -0
- package/fesm2022/praxisui-table.mjs +1 -50362
- package/filter-drawer-adapter/package.json +2 -1
- package/package.json +22 -14
- package/src/lib/praxis-table.json-api.md +1361 -0
- package/{index.d.ts → types/praxisui-table.d.ts} +918 -121
- package/fesm2022/praxisui-table-filter-form-dialog-host.component-EHoM1uuJ.mjs +0 -165
- package/fesm2022/praxisui-table-table-ai.adapter-CFyyQB26.mjs +0 -831
- /package/{filter-drawer-adapter/index.d.ts → types/praxisui-table-filter-drawer-adapter.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
2
|
title: "Table"
|
|
3
3
|
slug: "table-overview"
|
|
4
4
|
description: "Visao geral do @praxisui/table com TableConfig unificada, filtros, renderers, performance e integracao enterprise."
|
|
@@ -163,6 +163,27 @@ 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 the governed session in `PraxisAssistantSessionRegistryService` with `presence: 'origin-anchor'`; the visual affordance returns to the table assistant trigger, which changes to the minimized state and reopens the preserved session. 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
|
+
- When rows are selected, the assistant context includes a governed `table-row-selection` digest with selected count, id field, selected ids and a small sanitized row sample. The runtime never uses selected row text to decide primary intent; the LLM/backend receives the digest only as grounding after the assistant turn has the table component scope.
|
|
174
|
+
- 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.
|
|
175
|
+
|
|
176
|
+
### Consultative answers vs governed edits
|
|
177
|
+
|
|
178
|
+
`@praxisui/table` declares two component-level response modes through its authoring context:
|
|
179
|
+
|
|
180
|
+
- `consult/answer`: use when the user asks a factual or how-to question about the current table. Examples: "qual endpoint esta servindo esta tabela?", "quais campos existem nesta tabela?", "quais recursos de estilização a tabela suporta?" and "como criar uma coluna que soma duas colunas?".
|
|
181
|
+
- `edit/componentEditPlan`: use when the user asks to apply or materialize a change. Examples: "mostre ativo como badge verde", "crie uma coluna bonus com 10% do salario", "deixe o avatar vermelho quando salario for maior que 30000" and "anime as linhas com salario acima de 30000".
|
|
182
|
+
|
|
183
|
+
Consultative answers are selected by the backend/LLM from the component `responseModes` contract and return `type: "info"`. The table runtime must not classify user intent through local keywords; it only sends grounded context such as `resourcePath`, schema fields and the table authoring manifest, then renders the orchestrator response without an apply action. For how-to or documentation-style turns, the orchestrator should explain the governed operation shape and give a safe example instead of collecting missing edit parameters.
|
|
184
|
+
|
|
185
|
+
Governed edits must be selected by the same backend/LLM response-mode decision and produce a validated `componentEditPlan`; the table compiles that plan into a patch and only then exposes the review/apply step.
|
|
186
|
+
|
|
166
187
|
## Migration Note
|
|
167
188
|
|
|
168
189
|
- This release treats `enableCustomization=false` as the canonical default.
|
|
@@ -187,6 +208,8 @@ Para garantir que a tabela, filtros e editores reflitam o tema do app host:
|
|
|
187
208
|
Observação: tokens `--md-sys-*` e `--mdc-theme-*` continuam aceitos quando presentes.
|
|
188
209
|
Nota: a classe de tema é decisão do host (`.dark-theme` ou `.theme-dark`/`.theme-light`); mantenha tokens e componentes no mesmo escopo.
|
|
189
210
|
|
|
211
|
+
Surface stacking is owned by `@praxisui/table`: when toolbar, grid and paginator are rendered as one table surface, the runtime flattens the internal join corners and keeps only the outer corners rounded. Host apps should theme the table through Material/Praxis tokens instead of targeting internal descendants such as `.mat-mdc-table`, `.mat-mdc-paginator` or `.praxis-toolbar` to repair border radius joins.
|
|
212
|
+
|
|
190
213
|
## ✨ CaracterÃsticas Principais
|
|
191
214
|
|
|
192
215
|
### ðŸ—ï¸ Arquitetura Unificada
|
|
@@ -256,6 +279,82 @@ O novo editor é "column-first" e usa uma tipagem compartilhada com o Editor d
|
|
|
256
279
|
- Preview: execute “Testar†para ver quantas linhas seriam afetadas pelas regras ativas.
|
|
257
280
|
- Import/Export: exporta JSON sem o campo `enabled`; importa com validação estrutural de JSON Logic e sanitização de estilos (allowlist).
|
|
258
281
|
|
|
282
|
+
#### Estados de linha vs estilos de célula
|
|
283
|
+
|
|
284
|
+
Use `rowConditionalStyles` quando a condição descreve o estado semântico da linha inteira, como prioridade, SLA vencido, item sem responsável, bloqueio ou estagnação. Para temas e faixas visuais, prefira `cssClass` em `rowConditionalStyles` e resolva a aparência no CSS do host. Isso preserva o ownership de tema do host e evita que gradientes ou backgrounds reiniciem em cada célula.
|
|
285
|
+
|
|
286
|
+
Use `columns[].conditionalStyles` quando o destaque pertence a uma coluna específica, como texto negativo em vermelho, status em badge, valor monetário fora da faixa ou ícone contextual de uma célula.
|
|
287
|
+
|
|
288
|
+
Padrão recomendado:
|
|
289
|
+
|
|
290
|
+
```ts
|
|
291
|
+
rowConditionalStyles: [
|
|
292
|
+
{
|
|
293
|
+
condition: { contains: [{ var: 'prioridadeNome' }, 'Alta'] },
|
|
294
|
+
cssClass: 'app-row--priority-high',
|
|
295
|
+
description: 'Prioridade alta recebe âncora visual de linha.',
|
|
296
|
+
},
|
|
297
|
+
]
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
O editor especializado tambem persiste `effects: RuleEffectDefinition[]` em
|
|
301
|
+
`rowConditionalStyles` e `columns[].conditionalStyles`. O runtime consome esses
|
|
302
|
+
efeitos diretamente e ainda preserva `cssClass`/`style` como fallback de
|
|
303
|
+
compatibilidade, mantendo o ciclo abrir -> aplicar/salvar -> reabrir sem exigir
|
|
304
|
+
que consumidores recompilem manualmente os efeitos visuais.
|
|
305
|
+
|
|
306
|
+
Para renderizacao condicional, `columns[].conditionalRenderers` tambem aceita
|
|
307
|
+
`effects: RuleEffectDefinition[]` como fonte canonica para renderer, tooltip e
|
|
308
|
+
animacao. `rowConditionalRenderers` fica tipado no contrato publico para tooltip
|
|
309
|
+
e animacao de linha, preservando os campos planos `tooltip`/`animation` como
|
|
310
|
+
fallback.
|
|
311
|
+
|
|
312
|
+
Animações condicionais devem ser authoradas como decisão semântica, não como CSS
|
|
313
|
+
manual em `style.animation`. Para animar a linha inteira, use
|
|
314
|
+
`rowConditionalRenderers[].animation`; para animar somente uma célula/coluna, use
|
|
315
|
+
`columns[].conditionalRenderers[].animation`. Prefira presets semânticos
|
|
316
|
+
(`info-soft`, `success-confirm`, `warning-attention`, `critical-alert`,
|
|
317
|
+
`audit-review`, `sync-pending` ou aliases como `pulse-soft`, `sla-breach`,
|
|
318
|
+
`risk-critical`) antes de `type` bruto. Exemplo:
|
|
319
|
+
|
|
320
|
+
```ts
|
|
321
|
+
rowConditionalRenderers: [
|
|
322
|
+
{
|
|
323
|
+
id: 'salario-alto-pulse',
|
|
324
|
+
condition: { '>': [{ var: 'salario' }, 30000] },
|
|
325
|
+
animation: { preset: 'pulse-soft', trigger: 'onAppear', intensity: 'subtle', repeat: 'once' },
|
|
326
|
+
enabled: true,
|
|
327
|
+
},
|
|
328
|
+
]
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
`appearance.animations.enabled = false` desativa animações; os flags
|
|
332
|
+
`appearance.animations.specific.row` e `appearance.animations.specific.cell`
|
|
333
|
+
desativam seletivamente animações condicionais de linha e célula.
|
|
334
|
+
|
|
335
|
+
Colunas calculadas usam `columns[].computed.expression` como AST JSON Logic
|
|
336
|
+
canonico. Regras, estilos e renderers condicionais podem referenciar esses
|
|
337
|
+
valores via `computed.<field>`. Quando uma coluna calculada depende de outra
|
|
338
|
+
coluna calculada, o runtime resolve a ordem de avaliacao por dependencias
|
|
339
|
+
declaradas ou referencias `var: "computed.<field>"`, evitando que o resultado
|
|
340
|
+
dependa da ordem fisica de `columns[]`.
|
|
341
|
+
|
|
342
|
+
```scss
|
|
343
|
+
.app-table .mat-mdc-row.app-row--priority-high {
|
|
344
|
+
background: linear-gradient(
|
|
345
|
+
90deg,
|
|
346
|
+
color-mix(in srgb, var(--md-sys-color-error-container) 42%, transparent),
|
|
347
|
+
transparent
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
.app-table .mat-mdc-row.app-row--priority-high .mat-mdc-cell {
|
|
352
|
+
background: transparent;
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
Evite aplicar gradientes de estado de linha diretamente em `.mat-mdc-cell`. Como cada célula tem largura, sticky behavior e renderer próprios, o gradiente pode parecer quebrado por coluna, especialmente em tema dark.
|
|
357
|
+
|
|
259
358
|
Exemplos de JSON Logic:
|
|
260
359
|
|
|
261
360
|
```json
|
|
@@ -428,14 +527,40 @@ Um botão de engrenagem será exibido no canto superior direito. Ao clicar n
|
|
|
428
527
|
|
|
429
528
|
As alterações podem ser aplicadas temporariamente com **Aplicar** ou salvas de forma persistente com **Salvar & Fechar**.
|
|
430
529
|
|
|
530
|
+
### Assistente de IA da Tabela
|
|
531
|
+
|
|
532
|
+
Quando `enableCustomization` esta ativo, a tabela expoe o assistente de IA pelo shell canonico de `@praxisui/ai`.
|
|
533
|
+
O chrome conversacional, `sessionId`, `clientTurnId`, respostas rapidas e ciclo de revisao/aplicacao sao orquestrados
|
|
534
|
+
por `PraxisAssistantTurnOrchestratorService`; a semantica especifica da tabela continua em `TableAiAdapter` e no
|
|
535
|
+
`TableAgenticAuthoringTurnFlow`.
|
|
536
|
+
|
|
537
|
+
## Agentic Authoring & Manifest
|
|
538
|
+
|
|
539
|
+
Para acoes globais de `toolbar`, `row` e `bulk`, o authoring agentic aceita somente `GlobalActionRef` governado:
|
|
540
|
+
`actionId`, `payload`, `payloadExpr` e `meta`. O schema bloqueia propriedades arbitrarias e mantem `payloadExpr`
|
|
541
|
+
como escape avancado explicito, nao como objeto livre. Configuracoes novas devem persistir a acao em
|
|
542
|
+
`effects[].kind = "global-action"` com `effects[].globalAction`; `globalAction` plano permanece apenas como fallback
|
|
543
|
+
de compatibilidade para documentos existentes.
|
|
544
|
+
|
|
545
|
+
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.
|
|
546
|
+
|
|
547
|
+
- **Component ID:** `praxis-table`
|
|
548
|
+
- **Config Schema:** `TableConfig`
|
|
549
|
+
- **Alvos Editáveis:** `column`, `computedColumn`, `renderer`, `conditionalRenderer`, `rowAction`, `toolbarAction`, `toolbar`, `filter`, `grouping`, `selection`, `export`, `appearance`, `expansion`, `rule`, `meta`, `bulkAction`, `contextAction`, `pagination`, `sorting`, `interaction`, `loading`, `emptyState`, `resizing`, `dragging`, `editing`, `messages`, `localization`, `performance`, `data`, `accessibility`.
|
|
550
|
+
- **Famílias de Operações:** Operações com target resolvers próprios por operação, alinhadas ao contrato canônico de configuração da tabela e aos paths publicados pelo pacote.
|
|
551
|
+
- **Validação:** Validadores determinísticos cobrem unicidade, integridade de caminhos, suporte a renderizadores, presets de formatação, segurança de estilos, segurança de resource binding somente em `expansion.detailSource.configure`, apresentação do detalhe expansível em `expansion.detailPresentation.configure`, e preservação de round-trip do editor.
|
|
552
|
+
|
|
553
|
+
O manifesto (v2.0.0) é exportado como `PRAXIS_TABLE_AUTHORING_MANIFEST` e projetado no `ai_registry` como contrato canônico de authoring. Essa projeção não deve ser tratada como aprovação semântica automática: cada operação precisa manter evidência testada de target resolver, paths canônicos, efeitos coerentes e validators pertinentes ao que a operação realmente edita. O gate `validate:authoring-contracts` deve rejeitar cobertura nominal, como validators globais sem uso ou validators ligados a operações não relacionadas.
|
|
554
|
+
|
|
431
555
|
## 🚀 Instalação
|
|
432
556
|
|
|
433
557
|
```bash
|
|
434
|
-
npm install @praxisui/core @praxisui/table
|
|
558
|
+
npm install @praxisui/ai @praxisui/core @praxisui/table
|
|
435
559
|
```
|
|
436
560
|
|
|
437
561
|
Peers necessários (instale no app host):
|
|
438
562
|
- `@angular/core` `^20.0.0`, `@angular/common` `^20.0.0`
|
|
563
|
+
- `@praxisui/ai` `^8.0.0-beta.0`
|
|
439
564
|
- `@praxisui/core` `^0.0.1`
|
|
440
565
|
- `@praxisui/dynamic-fields` `^0.0.1` (quando usar editores/inputs dinâmicos)
|
|
441
566
|
- `@praxisui/dynamic-form` `^0.0.1` (quando integrar com formulários dinâmicos)
|
|
@@ -460,7 +585,7 @@ Quando `resourcePath` é fornecido, a tabela se torna "inteligente":
|
|
|
460
585
|
Neste exemplo:
|
|
461
586
|
|
|
462
587
|
- `resourcePath="human-resources/departamentos"` instrui a tabela a se comunicar com o endpoint `/api/human-resources/departamentos`.
|
|
463
|
-
- A tabela fará requisições como `POST /api/human-resources/departamentos/filter` para obter os dados e `GET /schemas/filtered?path=/api/human-resources/departamentos/
|
|
588
|
+
- A tabela fará requisições como `POST /api/human-resources/departamentos/filter` para obter os dados e `GET /schemas/filtered?path=/api/human-resources/departamentos/filter&operation=post&schemaType=response` para obter o schema estrutural usado no bootstrap das colunas.
|
|
464
589
|
- `enableCustomization` controla explicitamente o gate de edição visual. O default canônico agora é `false`; declare `[enableCustomization]="true"` quando o host quiser expor customização e surfaces editoriais.
|
|
465
590
|
|
|
466
591
|
### Consulta Declarativa com `queryContext`
|
|
@@ -523,8 +648,8 @@ sequenceDiagram
|
|
|
523
648
|
|
|
524
649
|
activate Crud_Service
|
|
525
650
|
Crud_Service->>Crud_Service: schemaUrl() preserva o base path canônico
|
|
526
|
-
Crud_Service->>Crud_Service: Deriva path="/api/human-resources/departamentos/
|
|
527
|
-
Crud_Service->>Docs_Controller: GET /schemas/filtered?path=.../
|
|
651
|
+
Crud_Service->>Crud_Service: Deriva path="/api/human-resources/departamentos/filter"<br>operation="post", schemaType="response"
|
|
652
|
+
Crud_Service->>Docs_Controller: GET /schemas/filtered?path=.../filter&operation=post&schemaType=response
|
|
528
653
|
deactivate Crud_Service
|
|
529
654
|
|
|
530
655
|
activate Docs_Controller
|
|
@@ -896,7 +1021,7 @@ onSchemaStatus(ev: { outdated: boolean; serverHash?: string; lastVerifiedAt?: st
|
|
|
896
1021
|
|
|
897
1022
|
- O backend anota o schema com `x-ui.resource.idField` (e `idFieldValid`) via `/schemas/filtered`.
|
|
898
1023
|
- A tabela adota o campo identificador automaticamente com a seguinte precedência:
|
|
899
|
-
-
|
|
1024
|
+
- `config.meta.idField` (persistido) → contexto runtime/serviço derivado do schema → `'id'`.
|
|
900
1025
|
- Se `config.meta.idField` divergir do servidor, o componente alerta o usuário e mantém o valor do TableConfig até reconciliação.
|
|
901
1026
|
- A resolução ocorre no `loadSchema()` e também é considerada em tempo de execução para evitar corridas.
|
|
902
1027
|
- Para recursos cuja PK não é `id`, defina `getIdFieldName()` no controller backend correspondente.
|
|
@@ -914,12 +1039,12 @@ sequenceDiagram
|
|
|
914
1039
|
|
|
915
1040
|
PT->>GS: configure(resourcePath)
|
|
916
1041
|
PT->>GS: getSchema()
|
|
917
|
-
GS->>GS: deriva path=/api/.../
|
|
918
|
-
GS->>Docs: GET /schemas/filtered?path=.../
|
|
1042
|
+
GS->>GS: deriva path=/api/.../filter + operation=post + schemaType=response
|
|
1043
|
+
GS->>Docs: GET /schemas/filtered?path=.../filter&operation=post&schemaType=response
|
|
919
1044
|
Docs-->>GS: 200/304 schema + x-ui.resource.idField
|
|
920
1045
|
GS->>GS: cache + lastResourceMeta.idField
|
|
921
1046
|
GS-->>PT: FieldDefinition[] (normalizado)
|
|
922
|
-
Note over PT: idField =
|
|
1047
|
+
Note over PT: idField = config.meta.idField || runtime/schema || 'id'
|
|
923
1048
|
PT->>PT: construir colunas e renderizar
|
|
924
1049
|
```
|
|
925
1050
|
|
|
@@ -944,7 +1069,7 @@ sequenceDiagram
|
|
|
944
1069
|
### Troubleshooting rápido (idField)
|
|
945
1070
|
|
|
946
1071
|
- A ação delete falhou por ID ausente: verifique se o schema contém `x-ui.resource.idField` e se a coluna correspondente existe no dataset.
|
|
947
|
-
- O ID está em outra propriedade: defina
|
|
1072
|
+
- O ID está em outra propriedade: defina `config.meta.idField` no TableConfig; ajuste o backend com `getIdFieldName()` para persistir o comportamento derivado do schema.
|
|
948
1073
|
- Cache 304 sem idField aplicado: confirme que o serviço recebeu o body pelo menos uma vez (200) e que `GenericCrudService.getResourceIdField()` retorna o valor esperado.
|
|
949
1074
|
|
|
950
1075
|
### Uso com Dados Locais (Client-Side)
|
|
@@ -1669,9 +1794,9 @@ Deteccao:
|
|
|
1669
1794
|
- somente quando `FieldDefinition.controlType === 'avatar'`
|
|
1670
1795
|
|
|
1671
1796
|
Renderer aplicado:
|
|
1672
|
-
- `renderer: { type: 'avatar', avatar: { srcField,
|
|
1797
|
+
- `renderer: { type: 'avatar', avatar: { srcField, initialsField: 'nomeCompleto', shape: 'circle', size: 32 } }`
|
|
1673
1798
|
- alinhamento central e largura compacta (~56px)
|
|
1674
|
-
- `
|
|
1799
|
+
- `initialsField` deriva as iniciais a partir de um campo textual bruto
|
|
1675
1800
|
|
|
1676
1801
|
Avatar explicito:
|
|
1677
1802
|
- `renderer: { type: 'avatar', avatar: { srcField, initialsExpr, initialsField, shape: 'circle', size: 28 } }`
|
|
@@ -1679,7 +1804,7 @@ Avatar explicito:
|
|
|
1679
1804
|
- `initialsExpr` deve retornar as iniciais prontas; ele nao transforma automaticamente um campo bruto em iniciais
|
|
1680
1805
|
- quando quiser derivar iniciais a partir de um campo textual, prefira `initialsField`
|
|
1681
1806
|
- exemplo recomendado: `avatar: { srcField: 'photoUrl', initialsField: 'name' }`
|
|
1682
|
-
- exemplo de `initialsExpr` explicito: `avatar: { initialsExpr:
|
|
1807
|
+
- exemplo de `initialsExpr` explicito: `avatar: { initialsExpr: 'initials' }`
|
|
1683
1808
|
|
|
1684
1809
|
Comportamento importante:
|
|
1685
1810
|
- a autodeteccao ocorre apenas no bootstrap (nao sobrescreve configuracoes de colunas persistidas)
|
|
@@ -1689,8 +1814,11 @@ Comportamento importante:
|
|
|
1689
1814
|
Ajustes comuns:
|
|
1690
1815
|
- `renderer.avatar.shape`: `'square' | 'rounded' | 'circle'`
|
|
1691
1816
|
- `renderer.avatar.size`: numero em px
|
|
1817
|
+
- `renderer.avatar.backgroundColor`: cor de fundo do circulo
|
|
1818
|
+
- `renderer.avatar.textColor`: cor das iniciais
|
|
1692
1819
|
- `renderer.avatar.alt` / `altField`
|
|
1693
1820
|
- use `conditionalRenderers` para variar renderer por linha
|
|
1821
|
+
- exemplo condicional: `condition: { ">": [{ "var": "salario" }, 30000] }` com `avatar: { initialsField: 'name', backgroundColor: '#D32F2F', textColor: '#FFFFFF' }`
|
|
1694
1822
|
|
|
1695
1823
|
A11y, seguranca e performance:
|
|
1696
1824
|
- `alt`/`altField` sao respeitados
|
|
@@ -1717,3 +1845,98 @@ Apache-2.0 — consulte `LICENSE` na raiz do workspace para detalhes.
|
|
|
1717
1845
|
**Versão**: 2.0.0 (Unified Architecture)
|
|
1718
1846
|
**Compatibilidade**: Angular 18+
|
|
1719
1847
|
|
|
1848
|
+
## Discovery contextual em ações por linha
|
|
1849
|
+
|
|
1850
|
+
Use `actions.row.discovery.enabled=false` quando a tabela precisar operar em uma
|
|
1851
|
+
experiência corporativa estritamente curada pelo host. Nesse modo, o runtime
|
|
1852
|
+
mantém somente as ações declaradas em `actions.row.actions[]` e não adiciona
|
|
1853
|
+
ações descobertas dinamicamente por HATEOAS/capabilities.
|
|
1854
|
+
|
|
1855
|
+
```ts
|
|
1856
|
+
actions: {
|
|
1857
|
+
row: {
|
|
1858
|
+
enabled: true,
|
|
1859
|
+
display: 'buttons',
|
|
1860
|
+
discovery: { enabled: false },
|
|
1861
|
+
actions: [
|
|
1862
|
+
{ id: 'briefing', label: 'Briefing', action: 'inspect-surfaces' },
|
|
1863
|
+
{ id: 'capabilities', label: 'Capabilities', action: 'inspect-actions' },
|
|
1864
|
+
],
|
|
1865
|
+
},
|
|
1866
|
+
}
|
|
1867
|
+
```
|
|
1868
|
+
|
|
1869
|
+
O campo controla apenas a descoberta contextual de row actions. Ele não desativa
|
|
1870
|
+
`behavior.expansion.detail.source.mode="hypermedia"`; quando a expansão
|
|
1871
|
+
hypermedia estiver ativa, o detail ainda pode resolver `surfaces` e `actions`
|
|
1872
|
+
sob demanda ao expandir a linha. O default continua habilitado quando
|
|
1873
|
+
`actions.row.discovery.enabled` é omitido.
|
|
1874
|
+
|
|
1875
|
+
## Row action para navegação interna
|
|
1876
|
+
|
|
1877
|
+
Use `navigation.openRoute` quando a ação da linha precisar abrir uma rota
|
|
1878
|
+
interna levando o identificador do registro selecionado.
|
|
1879
|
+
|
|
1880
|
+
```ts
|
|
1881
|
+
actions: {
|
|
1882
|
+
row: {
|
|
1883
|
+
enabled: true,
|
|
1884
|
+
display: 'buttons',
|
|
1885
|
+
discovery: { enabled: false },
|
|
1886
|
+
actions: [
|
|
1887
|
+
{
|
|
1888
|
+
id: 'open-detail',
|
|
1889
|
+
label: 'Abrir detalhe',
|
|
1890
|
+
action: 'navigation.openRoute',
|
|
1891
|
+
effects: [
|
|
1892
|
+
{
|
|
1893
|
+
kind: 'global-action',
|
|
1894
|
+
globalAction: {
|
|
1895
|
+
actionId: 'navigation.openRoute',
|
|
1896
|
+
payload: {
|
|
1897
|
+
path: '/clientes/detalhe',
|
|
1898
|
+
query: {
|
|
1899
|
+
id: '${row.id}',
|
|
1900
|
+
},
|
|
1901
|
+
},
|
|
1902
|
+
},
|
|
1903
|
+
},
|
|
1904
|
+
],
|
|
1905
|
+
globalAction: {
|
|
1906
|
+
actionId: 'navigation.openRoute',
|
|
1907
|
+
payload: {
|
|
1908
|
+
path: '/clientes/detalhe',
|
|
1909
|
+
query: {
|
|
1910
|
+
id: '${row.id}',
|
|
1911
|
+
},
|
|
1912
|
+
},
|
|
1913
|
+
},
|
|
1914
|
+
},
|
|
1915
|
+
],
|
|
1916
|
+
},
|
|
1917
|
+
}
|
|
1918
|
+
```
|
|
1919
|
+
|
|
1920
|
+
O runtime da tabela resolve templates como `${row.id}` antes de executar a
|
|
1921
|
+
global action, o que permite reutilizar o mesmo contrato em `list` e `table`.
|
|
1922
|
+
Para configuracoes novas, `effects[].kind = 'global-action'` e o envelope
|
|
1923
|
+
canonico alinhado a `PraxisRuntimeGlobalActionEffect`; `globalAction` plano
|
|
1924
|
+
continua aceito como fallback de compatibilidade.
|
|
1925
|
+
O editor de acoes usa o mesmo adapter interno para toolbar, row e bulk actions:
|
|
1926
|
+
ao escolher novamente a mesma global action, ele preserva `payload` estruturado
|
|
1927
|
+
ou `payloadExpr` existente; ao trocar o `actionId`, ele descarta o payload antigo
|
|
1928
|
+
para evitar executar parametros de outra acao.
|
|
1929
|
+
|
|
1930
|
+
As acoes por linha tambem usam Json Logic canonico para `visibleWhen` e
|
|
1931
|
+
`disabledWhen`. O editor de acoes preserva esses objetos no fluxo
|
|
1932
|
+
abrir -> aplicar/salvar -> reabrir, por exemplo:
|
|
1933
|
+
|
|
1934
|
+
```ts
|
|
1935
|
+
{
|
|
1936
|
+
id: 'edit-active',
|
|
1937
|
+
label: 'Editar',
|
|
1938
|
+
action: 'edit',
|
|
1939
|
+
visibleWhen: { '===': [{ var: 'status' }, 'Ativo'] },
|
|
1940
|
+
disabledWhen: { '===': [{ var: 'status' }, 'Bloqueado'] },
|
|
1941
|
+
}
|
|
1942
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Guia Historico: Remocao da DSL Runtime
|
|
2
|
+
|
|
3
|
+
O runtime DSL legado foi removido de `@praxisui/table`.
|
|
4
|
+
|
|
5
|
+
Estado canonico atual:
|
|
6
|
+
|
|
7
|
+
- JSON Logic e o unico contrato suportado para regras novas e para o editor de regras.
|
|
8
|
+
- A tabela nao executa mais expressoes DSL em string no runtime.
|
|
9
|
+
- Hosts que ainda possuam payloads DSL precisam migrar essas regras para JSON Logic antes de reutiliza-las.
|
|
10
|
+
|
|
11
|
+
Nao existe mais:
|
|
12
|
+
|
|
13
|
+
- registry publico de funcoes DSL
|
|
14
|
+
- extensoes DSL publicas de data/JSON
|
|
15
|
+
- path oficial de validacao DSL no runtime da tabela
|
|
16
|
+
|
|
17
|
+
Para o caminho suportado, use:
|
|
18
|
+
|
|
19
|
+
- [json-logic-operators-and-helpers.md](./json-logic-operators-and-helpers.md)
|
|
20
|
+
- [praxis-table.json-api.md](../src/lib/praxis-table.json-api.md)
|
|
21
|
+
- [table-rules-editor.component.ts](../src/lib/rules-editor/table-rules-editor.component.ts)
|
|
22
|
+
|
|
23
|
+
Este arquivo permanece apenas para redirecionar links antigos que ainda apontavam para "DSL extensions".
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "ADR - Dynamic Filter as Cross-Library Feature"
|
|
3
|
+
slug: "adr-dynamic-filter-cross-lib-coupling-2026-03"
|
|
4
|
+
description: "Decisao de arquitetura para tratar o filtro dinamico como feature transversal entre table, dynamic-fields e metadata-starter, com documentacao e contrato coordenados."
|
|
5
|
+
doc_type: "adr"
|
|
6
|
+
document_kind: "adr-record"
|
|
7
|
+
category: "architecture"
|
|
8
|
+
audience:
|
|
9
|
+
- "frontend"
|
|
10
|
+
- "backend"
|
|
11
|
+
- "architect"
|
|
12
|
+
- "platform-team"
|
|
13
|
+
level: "advanced"
|
|
14
|
+
status: "implemented"
|
|
15
|
+
owner: "praxis-ui"
|
|
16
|
+
tags:
|
|
17
|
+
- "dynamic-filter"
|
|
18
|
+
- "table"
|
|
19
|
+
- "dynamic-fields"
|
|
20
|
+
- "metadata-starter"
|
|
21
|
+
- "architecture"
|
|
22
|
+
toc: true
|
|
23
|
+
sidebar: true
|
|
24
|
+
related_docs:
|
|
25
|
+
- "dynamic-filter-architecture-overview"
|
|
26
|
+
- "dynamic-filter-payload-contract"
|
|
27
|
+
- "dynamic-filter-range-filters-guide"
|
|
28
|
+
- "dynamic-filter-host-integration-guide"
|
|
29
|
+
- "dynamic-filter-troubleshooting-guide"
|
|
30
|
+
last_updated: "2026-03-07"
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
# ADR: Dynamic Filter as Cross-Library Feature
|
|
34
|
+
|
|
35
|
+
## Status
|
|
36
|
+
|
|
37
|
+
`implemented`
|
|
38
|
+
|
|
39
|
+
## Context
|
|
40
|
+
|
|
41
|
+
Historicamente, o filtro dinâmico podia ser lido de forma fragmentada:
|
|
42
|
+
|
|
43
|
+
- `table` como componente “dono” da experiência;
|
|
44
|
+
- `dynamic-fields` como catálogo de controles;
|
|
45
|
+
- `metadata-starter` como detalhe backend separado.
|
|
46
|
+
|
|
47
|
+
Esse modelo é insuficiente para documentação e governança porque os problemas reais atravessam as três camadas.
|
|
48
|
+
|
|
49
|
+
Exemplos concretos:
|
|
50
|
+
|
|
51
|
+
- o `PraxisFilter` decide variantes inline e persistência local;
|
|
52
|
+
- os campos `filter-*-inline` definem UX, acessibilidade e envelopes de interação;
|
|
53
|
+
- o backend normaliza ranges e rejeita payload inválido com `FILTER_PAYLOAD_INVALID`.
|
|
54
|
+
|
|
55
|
+
Se a documentação tratar essas partes como silos, o resultado é incompleto.
|
|
56
|
+
|
|
57
|
+
## Decision
|
|
58
|
+
|
|
59
|
+
Adotar oficialmente o filtro dinâmico como feature transversal do ecossistema Praxis.
|
|
60
|
+
|
|
61
|
+
Isso implica:
|
|
62
|
+
|
|
63
|
+
- a entrada principal de uso público continua em `@praxisui/table`;
|
|
64
|
+
- contratos visuais e metadata dos inline continuam canônicos em `@praxisui/dynamic-fields`;
|
|
65
|
+
- contrato HTTP, normalização e semântica operacional do payload devem citar explicitamente `praxis-metadata-starter`;
|
|
66
|
+
- a documentação da feature deve ser pensada como trilha, e não como README solto por biblioteca.
|
|
67
|
+
|
|
68
|
+
## Consequences
|
|
69
|
+
|
|
70
|
+
### Positivas
|
|
71
|
+
|
|
72
|
+
- documentação mais didática e completa;
|
|
73
|
+
- troubleshooting mais rápido;
|
|
74
|
+
- menos divergência entre frontend e backend;
|
|
75
|
+
- maior clareza sobre onde documentar payload, range e settings.
|
|
76
|
+
|
|
77
|
+
### Custos
|
|
78
|
+
|
|
79
|
+
- manutenção documental coordenada entre bibliotecas;
|
|
80
|
+
- necessidade de `related_docs` e slugs estáveis;
|
|
81
|
+
- revisão mais cuidadosa quando a feature evoluir.
|
|
82
|
+
|
|
83
|
+
## Non-goals
|
|
84
|
+
|
|
85
|
+
- fundir fisicamente as bibliotecas;
|
|
86
|
+
- mover os componentes inline para dentro de `table`;
|
|
87
|
+
- duplicar documentação canônica entre libs.
|
|
88
|
+
|
|
89
|
+
## Implementation Outline
|
|
90
|
+
|
|
91
|
+
1. Manter `table` como ponto de entrada da jornada.
|
|
92
|
+
2. Referenciar `dynamic-fields` como fonte de verdade para catálogo inline e metadata.
|
|
93
|
+
3. Referenciar `metadata-starter` como fonte de verdade para payload backend e normalização.
|
|
94
|
+
4. Publicar a trilha documental completa sob `projects/praxis-table/docs`.
|
|
95
|
+
|
|
96
|
+
## Acceptance Criteria
|
|
97
|
+
|
|
98
|
+
- trilha documental cobrindo arquitetura, integração host, payload, range, catálogo inline e troubleshooting;
|
|
99
|
+
- referências explícitas ao `metadata-starter` nos documentos de contrato;
|
|
100
|
+
- navegação consistente entre docs relacionados.
|
|
101
|
+
|
|
102
|
+
## Source References
|
|
103
|
+
|
|
104
|
+
- `projects/praxis-table/src/lib/components/praxis-filter/praxis-filter.component.ts`
|
|
105
|
+
- `projects/praxis-dynamic-fields/docs/dynamic-fields-inline-components-guide.md` (slug publicado: `dynamic-fields-inline-components-guide`)
|
|
106
|
+
- `../praxis-metadata-starter/src/main/java/org/praxisplatform/uischema/filter/web/FilterRequestBodyAdvice.java`
|
|
107
|
+
- `../praxis-metadata-starter/src/main/java/org/praxisplatform/uischema/filter/range/RangePayloadNormalizer.java`
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "ADR - Lightweight Filter Drawer Adapter Entrypoint for @praxisui/table"
|
|
3
|
+
slug: "adr-table-filter-drawer-adapter-light-entrypoint-2026-03"
|
|
4
|
+
description: "Decisao de arquitetura para expor um sub-entrypoint leve de filter drawer adapter em @praxisui/table e reduzir impacto de bundle inicial em apps host."
|
|
5
|
+
doc_type: "adr"
|
|
6
|
+
document_kind: "adr-record"
|
|
7
|
+
category: "architecture"
|
|
8
|
+
audience:
|
|
9
|
+
- "frontend"
|
|
10
|
+
- "architect"
|
|
11
|
+
- "platform-team"
|
|
12
|
+
level: "advanced"
|
|
13
|
+
status: "implemented"
|
|
14
|
+
owner: "praxis-ui"
|
|
15
|
+
tags:
|
|
16
|
+
- "table"
|
|
17
|
+
- "filter"
|
|
18
|
+
- "drawer"
|
|
19
|
+
- "adapter"
|
|
20
|
+
- "bundle"
|
|
21
|
+
- "entrypoint"
|
|
22
|
+
toc: true
|
|
23
|
+
sidebar: true
|
|
24
|
+
last_updated: "2026-03-06"
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
# ADR: Lightweight Filter Drawer Adapter Entrypoint for `@praxisui/table`
|
|
28
|
+
|
|
29
|
+
## Status
|
|
30
|
+
|
|
31
|
+
`implemented`
|
|
32
|
+
|
|
33
|
+
## Context
|
|
34
|
+
|
|
35
|
+
Hosts que registram `FILTER_DRAWER_ADAPTER` no bootstrap podem carregar partes desnecessarias do pacote no `initial bundle`.
|
|
36
|
+
|
|
37
|
+
No estado atual:
|
|
38
|
+
- O token `FILTER_DRAWER_ADAPTER` e o contrato leve publicado vivem em `projects/praxis-table/filter-drawer-adapter/src/filter-drawer-adapter.ts`.
|
|
39
|
+
- O barrel raiz (`projects/praxis-table/src/public-api.ts`) exporta tabela, filtro, editores e recursos adicionais.
|
|
40
|
+
|
|
41
|
+
Resultado observado no issue cross-lib:
|
|
42
|
+
- inflacao relevante de bundle inicial com adapters ativos.
|
|
43
|
+
|
|
44
|
+
## Decision
|
|
45
|
+
|
|
46
|
+
Adotar sub-entrypoint leve para o contrato do adapter:
|
|
47
|
+
|
|
48
|
+
- Novo path de consumo recomendado: `@praxisui/table/filter-drawer-adapter`
|
|
49
|
+
- Exportar somente:
|
|
50
|
+
- `FILTER_DRAWER_ADAPTER`
|
|
51
|
+
- `FilterDrawerAdapter`
|
|
52
|
+
- contratos minimos relacionados ao adapter
|
|
53
|
+
|
|
54
|
+
Compatibilidade:
|
|
55
|
+
- manter um unico caminho publico para consumo host via sub-entrypoint leve.
|
|
56
|
+
- atualizar docs/boilerplates para usar o subpath leve.
|
|
57
|
+
|
|
58
|
+
## Non-goals
|
|
59
|
+
|
|
60
|
+
- Alterar comportamento de `PraxisFilter` em runtime.
|
|
61
|
+
- Redesenhar o contrato funcional do adapter.
|
|
62
|
+
|
|
63
|
+
## Implementation Outline
|
|
64
|
+
|
|
65
|
+
1. Criar entrypoint secundario focado em adapter/token.
|
|
66
|
+
2. Publicar o subpath via secondary entrypoint do `ng-packagr`.
|
|
67
|
+
3. Atualizar docs de integracao e boilerplates para usar subpath leve.
|
|
68
|
+
4. Medir bundle no host de referencia antes/depois.
|
|
69
|
+
|
|
70
|
+
## Acceptance Criteria
|
|
71
|
+
|
|
72
|
+
- Subpath novo publicado e adotavel em host.
|
|
73
|
+
- Documentacao atualizada com recomendacao canonica.
|
|
74
|
+
- Reducao relevante do `initial bundle` com adapters ativos (meta orientadora: `-40%` sobre baseline atual).
|
|
75
|
+
|
|
76
|
+
Estado atual dos criterios:
|
|
77
|
+
- Publicacao do subpath: concluida.
|
|
78
|
+
- Documentacao canonica: concluida.
|
|
79
|
+
- Benchmark de bundle no host de referencia: pendente.
|
|
80
|
+
|
|
81
|
+
## Implementation Status
|
|
82
|
+
|
|
83
|
+
- Implementado em `2026-03-06`:
|
|
84
|
+
- secondary entrypoint `projects/praxis-table/filter-drawer-adapter`
|
|
85
|
+
- export removido do barrel raiz `projects/praxis-table/src/public-api.ts`
|
|
86
|
+
- docs/boilerplates atualizados para recomendar `@praxisui/table/filter-drawer-adapter`
|
|
87
|
+
- Validacao concluida nesta workspace:
|
|
88
|
+
- build da lib e publicacao do subpath em `dist/praxis-table/filter-drawer-adapter`
|
|
89
|
+
- Medicao de bundle host:
|
|
90
|
+
- pendente de benchmark reproduzivel do host de referencia nesta workspace
|
|
91
|
+
|
|
92
|
+
## Risks and Mitigations
|
|
93
|
+
|
|
94
|
+
- Risco: diferenca pequena de bundle em alguns perfis de build.
|
|
95
|
+
- Mitigacao: capturar metricas por perfil (dev/prod) e registrar resultado real.
|
|
96
|
+
- Risco: divergencia entre token interno e token publicado no sub-entrypoint.
|
|
97
|
+
- Mitigacao: garantir singleton compartilhado e validar identidade em spec dedicada.
|
|
98
|
+
- Risco: boilerplates permanecerem em path inconsistente.
|
|
99
|
+
- Mitigacao: checklist de migracao em docs/templates e PRs de ajuste.
|
|
100
|
+
|
|
101
|
+
## Source References
|
|
102
|
+
|
|
103
|
+
- `projects/praxis-table/filter-drawer-adapter/src/filter-drawer-adapter.ts`
|
|
104
|
+
- `projects/praxis-table/src/public-api.ts`
|
|
105
|
+
- `docs/issues/drawer-adapters-bundle-entrypoints.md` (historico cross-lib)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# ADR: Decisão Provisória Sobre `idField` no `TableAuthoringDocument`
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Proposto
|
|
6
|
+
|
|
7
|
+
## Contexto
|
|
8
|
+
|
|
9
|
+
Durante o desenho do `tableEditorCapability`, surgiu uma ambiguidade estrutural sobre `idField`.
|
|
10
|
+
|
|
11
|
+
No código atual de `praxis-table`, `idField` aparece em dois papéis:
|
|
12
|
+
|
|
13
|
+
- como resolução operacional do host/runtime para identificar linhas;
|
|
14
|
+
- como metadado persistido em `config.meta.idField` em alguns fluxos de apply/save.
|
|
15
|
+
|
|
16
|
+
Isso cria ambiguidade arquitetural:
|
|
17
|
+
|
|
18
|
+
- se `idField` for binding operacional, ele deve viver fora do `TableConfig` canônico;
|
|
19
|
+
- se `idField` for semântica persistível do componente, ele deve viver no `TableConfig` e não em bindings paralelos.
|
|
20
|
+
|
|
21
|
+
Enquanto essa decisão não for estabilizada, o contrato do documento de autoria permanece frágil.
|
|
22
|
+
|
|
23
|
+
## Decisão
|
|
24
|
+
|
|
25
|
+
Para o piloto de `praxis-table`, adotar temporariamente `idField` como parte de `bindings`, não como parte obrigatória de `config.meta`.
|
|
26
|
+
|
|
27
|
+
Shape provisório:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
interface TableBindings {
|
|
31
|
+
resourcePath?: string | null;
|
|
32
|
+
idField?: string;
|
|
33
|
+
horizontalScroll?: 'auto' | 'wrap' | 'none';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface TableAuthoringDocument {
|
|
37
|
+
kind: 'praxis.table.editor';
|
|
38
|
+
version: 1;
|
|
39
|
+
config: TableConfig;
|
|
40
|
+
bindings?: TableBindings;
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Regras decorrentes
|
|
45
|
+
|
|
46
|
+
1. O documento persistível de autoria deve serializar `bindings.idField`, não depender de `config.meta.idField`.
|
|
47
|
+
2. O parser de legado pode ler `config.meta.idField` e migrar para `bindings.idField`.
|
|
48
|
+
3. `toCanonicalConfig()` não deve reescrever `config.meta.idField` por padrão.
|
|
49
|
+
4. Se o runtime quiser persistir `meta.idField` por compatibilidade, isso deve ser decisão explícita do adapter/save flow, não efeito implícito da capability.
|
|
50
|
+
5. A revisão futura deve decidir se:
|
|
51
|
+
- `idField` permanece binding de integração, ou
|
|
52
|
+
- `idField` sobe para semântica persistível do `TableConfig`.
|
|
53
|
+
|
|
54
|
+
## Motivo da decisão
|
|
55
|
+
|
|
56
|
+
Essa opção minimiza acoplamento prematuro com a semântica atual do runtime e evita consolidar como padrão algo que ainda parece misturar:
|
|
57
|
+
|
|
58
|
+
- identidade persistível do componente
|
|
59
|
+
- integração com dataset/servidor
|
|
60
|
+
|
|
61
|
+
Também permite migrar o protocolo sem bloquear o piloto do `tableEditorCapability`.
|
|
62
|
+
|
|
63
|
+
## Consequências
|
|
64
|
+
|
|
65
|
+
### Positivas
|
|
66
|
+
|
|
67
|
+
- simplifica a primeira iteração do documento canônico;
|
|
68
|
+
- evita duplicação automática entre `bindings.idField` e `config.meta.idField`;
|
|
69
|
+
- deixa explícito que a decisão definitiva ainda está em aberto.
|
|
70
|
+
|
|
71
|
+
### Negativas
|
|
72
|
+
|
|
73
|
+
- o piloto conviverá temporariamente com duas representações possíveis de `idField`;
|
|
74
|
+
- adapters de compatibilidade talvez precisem continuar lendo/escrevendo `meta.idField` por um tempo;
|
|
75
|
+
- a generalização cross-component ainda não fica fechada.
|
|
76
|
+
|
|
77
|
+
## Critério para revisão futura
|
|
78
|
+
|
|
79
|
+
Antes de promover o modelo como padrão do ecossistema, revisar esta ADR e decidir de forma definitiva:
|
|
80
|
+
|
|
81
|
+
1. `idField` é binding operacional do host?
|
|
82
|
+
2. `idField` é semântica persistível do componente?
|
|
83
|
+
3. existe necessidade real de ambos?
|
|
84
|
+
|
|
85
|
+
Sem essa decisão, o contrato do documento continua semanticamente ambíguo.
|