@praxisui/table 8.0.0-beta.19 → 8.0.0-beta.20

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.
Files changed (36) hide show
  1. package/README.md +39 -5
  2. package/docs/DSL-Extensions-Guide.md +23 -0
  3. package/docs/adr/2026-03-dynamic-filter-cross-lib-coupling.md +107 -0
  4. package/docs/adr/2026-03-filter-drawer-adapter-light-entrypoint.md +105 -0
  5. package/docs/adr/2026-03-table-editor-idfield-decision.md +85 -0
  6. package/docs/column-resize-reorder-implementation-plan.md +338 -0
  7. package/docs/column-resize-reorder-review-prompt.md +34 -0
  8. package/docs/dynamic-filter-architecture-overview.md +207 -0
  9. package/docs/dynamic-filter-backend-contract-cheatsheet.md +167 -0
  10. package/docs/dynamic-filter-editor-settings-guide.md +229 -0
  11. package/docs/dynamic-filter-host-integration-guide.md +217 -0
  12. package/docs/dynamic-filter-payload-contract.md +331 -0
  13. package/docs/dynamic-filter-range-filters-guide.md +289 -0
  14. package/docs/dynamic-filter-troubleshooting-guide.md +220 -0
  15. package/docs/dynamic-inline-filter-catalog.md +147 -0
  16. package/docs/e2e-column-drag-playwright.md +62 -0
  17. package/docs/expandable-rows-enterprise-big-leagues-plan.md +1080 -0
  18. package/docs/json-logic-operators-and-helpers.md +57 -0
  19. package/docs/local-data-mode-precedence.md +12 -0
  20. package/docs/local-data-pre-implementation-baseline.md +22 -0
  21. package/docs/local-data-preimplementation-go-no-go.md +39 -0
  22. package/docs/local-data-support-implementation-plan.md +524 -0
  23. package/docs/local-data-support-pr-package.md +66 -0
  24. package/docs/localization-persistence-merge.md +22 -0
  25. package/docs/performance-hardening-v2-implementation-plan.md +479 -0
  26. package/docs/playground-scenario-curation-plan.md +482 -0
  27. package/docs/playground-scenario-second-opinion-prompt.md +121 -0
  28. package/docs/playground-scenario-second-opinion-review.md +234 -0
  29. package/docs/release-notes-p1-hardening.md +76 -0
  30. package/docs/table-authoring-document-completeness-checklist.md +120 -0
  31. package/docs/table-editor-capability-review-prompt.md +349 -0
  32. package/docs/visual-rules-editor-transition.md +29 -0
  33. package/fesm2022/praxisui-table.mjs +301 -14
  34. package/index.d.ts +13 -0
  35. package/package.json +15 -9
  36. package/src/lib/praxis-table.json-api.md +1315 -0
package/README.md CHANGED
@@ -514,7 +514,7 @@ Quando `resourcePath` é fornecido, a tabela se torna "inteligente":
514
514
  Neste exemplo:
515
515
 
516
516
  - `resourcePath="human-resources/departamentos"` instrui a tabela a se comunicar com o endpoint `/api/human-resources/departamentos`.
517
- - 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/all&operation=get&schemaType=response` para obter o schema estrutural usado no bootstrap das colunas.
517
+ - 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.
518
518
  - `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.
519
519
 
520
520
  ### Consulta Declarativa com `queryContext`
@@ -577,8 +577,8 @@ sequenceDiagram
577
577
 
578
578
  activate Crud_Service
579
579
  Crud_Service->>Crud_Service: schemaUrl() preserva o base path canônico
580
- Crud_Service->>Crud_Service: Deriva path="/api/human-resources/departamentos/all"<br>operation="get", schemaType="response"
581
- Crud_Service->>Docs_Controller: GET /schemas/filtered?path=.../all&operation=get&schemaType=response
580
+ Crud_Service->>Crud_Service: Deriva path="/api/human-resources/departamentos/filter"<br>operation="post", schemaType="response"
581
+ Crud_Service->>Docs_Controller: GET /schemas/filtered?path=.../filter&operation=post&schemaType=response
582
582
  deactivate Crud_Service
583
583
 
584
584
  activate Docs_Controller
@@ -968,8 +968,8 @@ sequenceDiagram
968
968
 
969
969
  PT->>GS: configure(resourcePath)
970
970
  PT->>GS: getSchema()
971
- GS->>GS: deriva path=/api/.../all + schemaType=response
972
- GS->>Docs: GET /schemas/filtered?path=.../all&operation=get&schemaType=response
971
+ GS->>GS: deriva path=/api/.../filter + operation=post + schemaType=response
972
+ GS->>Docs: GET /schemas/filtered?path=.../filter&operation=post&schemaType=response
973
973
  Docs-->>GS: 200/304 schema + x-ui.resource.idField
974
974
  GS->>GS: cache + lastResourceMeta.idField
975
975
  GS-->>PT: FieldDefinition[] (normalizado)
@@ -1797,3 +1797,37 @@ O campo controla apenas a descoberta contextual de row actions. Ele não desativ
1797
1797
  hypermedia estiver ativa, o detail ainda pode resolver `surfaces` e `actions`
1798
1798
  sob demanda ao expandir a linha. O default continua habilitado quando
1799
1799
  `actions.row.discovery.enabled` é omitido.
1800
+
1801
+ ## Row action para navegação interna
1802
+
1803
+ Use `navigation.openRoute` quando a ação da linha precisar abrir uma rota
1804
+ interna levando o identificador do registro selecionado.
1805
+
1806
+ ```ts
1807
+ actions: {
1808
+ row: {
1809
+ enabled: true,
1810
+ display: 'buttons',
1811
+ discovery: { enabled: false },
1812
+ actions: [
1813
+ {
1814
+ id: 'open-detail',
1815
+ label: 'Abrir detalhe',
1816
+ action: 'navigation.openRoute',
1817
+ globalAction: {
1818
+ actionId: 'navigation.openRoute',
1819
+ payload: {
1820
+ path: '/clientes/detalhe',
1821
+ query: {
1822
+ id: '${row.id}',
1823
+ },
1824
+ },
1825
+ },
1826
+ },
1827
+ ],
1828
+ },
1829
+ }
1830
+ ```
1831
+
1832
+ O runtime da tabela resolve templates como `${row.id}` antes de executar a
1833
+ global action, o que permite reutilizar o mesmo contrato em `list` e `table`.
@@ -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.