@praxisui/table 8.0.0-beta.2 → 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.
- package/README.md +81 -8
- 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 +217 -0
- package/docs/dynamic-filter-payload-contract.md +331 -0
- package/docs/dynamic-filter-range-filters-guide.md +289 -0
- package/docs/dynamic-filter-troubleshooting-guide.md +220 -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-table-ai.adapter-DxjDaQqy.mjs → praxisui-table-table-ai.adapter-fS74fZ7o.mjs} +14 -5
- package/fesm2022/praxisui-table.mjs +3650 -324
- package/index.d.ts +120 -51
- package/package.json +15 -9
- package/src/lib/praxis-table.json-api.md +1315 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Dynamic Filter Troubleshooting Guide"
|
|
3
|
+
slug: "dynamic-filter-troubleshooting-guide"
|
|
4
|
+
description: "Runbook de troubleshooting do filtro dinamico, cobrindo payload invalido, ranges, schema desatualizado, persistencia local e falhas comuns entre table, dynamic-fields e metadata-starter."
|
|
5
|
+
doc_type: "troubleshooting"
|
|
6
|
+
document_kind: "runbook"
|
|
7
|
+
component: "table"
|
|
8
|
+
category: "troubleshooting"
|
|
9
|
+
audience:
|
|
10
|
+
- "host"
|
|
11
|
+
- "frontend"
|
|
12
|
+
- "backend"
|
|
13
|
+
- "ops"
|
|
14
|
+
level: "advanced"
|
|
15
|
+
status: "active"
|
|
16
|
+
owner: "praxis-ui"
|
|
17
|
+
tags:
|
|
18
|
+
- "dynamic-filter"
|
|
19
|
+
- "troubleshooting"
|
|
20
|
+
- "FILTER_PAYLOAD_INVALID"
|
|
21
|
+
- "schema"
|
|
22
|
+
- "range"
|
|
23
|
+
order: 32
|
|
24
|
+
icon: "healing"
|
|
25
|
+
toc: true
|
|
26
|
+
sidebar: true
|
|
27
|
+
search_boost: 1.2
|
|
28
|
+
reading_time: 20
|
|
29
|
+
estimated_setup_time: 35
|
|
30
|
+
version: "1.0"
|
|
31
|
+
related_docs:
|
|
32
|
+
- "dynamic-filter-payload-contract"
|
|
33
|
+
- "dynamic-filter-range-filters-guide"
|
|
34
|
+
- "dynamic-filter-host-integration-guide"
|
|
35
|
+
- "dynamic-filter-backend-contract-cheatsheet"
|
|
36
|
+
keywords:
|
|
37
|
+
- "FILTER_PAYLOAD_INVALID"
|
|
38
|
+
- "schemaOutdated"
|
|
39
|
+
- "metaChanged"
|
|
40
|
+
- "schemaStatusChange"
|
|
41
|
+
source_of_truth:
|
|
42
|
+
- "projects/praxis-table/src/lib/components/praxis-filter/praxis-filter.component.ts"
|
|
43
|
+
- "../praxis-metadata-starter/src/main/java/org/praxisplatform/uischema/rest/exceptionhandler/GlobalExceptionHandler.java"
|
|
44
|
+
- "../praxis-metadata-starter/src/main/java/org/praxisplatform/uischema/filter/range/RangePayloadNormalizer.java"
|
|
45
|
+
- "../praxis-metadata-starter/src/main/java/org/praxisplatform/uischema/filter/specification/GenericSpecificationsBuilder.java"
|
|
46
|
+
last_updated: "2026-03-07"
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
# Dynamic Filter Troubleshooting Guide
|
|
50
|
+
|
|
51
|
+
## Objetivo
|
|
52
|
+
|
|
53
|
+
Fornecer um runbook direto para diagnosticar e corrigir problemas recorrentes do filtro dinâmico em produção e em integração local.
|
|
54
|
+
|
|
55
|
+
## Pré-requisitos
|
|
56
|
+
|
|
57
|
+
- Conhecimento básico do pipeline `PraxisFilter -> payload -> metadata-starter`.
|
|
58
|
+
- Acesso ao payload enviado pelo host e à resposta HTTP do backend.
|
|
59
|
+
- Familiaridade com `related_docs` desta trilha.
|
|
60
|
+
|
|
61
|
+
## Operational Response
|
|
62
|
+
|
|
63
|
+
Ao investigar um incidente no filtro, siga esta ordem:
|
|
64
|
+
|
|
65
|
+
1. validar o payload efetivamente enviado pelo host;
|
|
66
|
+
2. confirmar se o schema do filtro está atualizado;
|
|
67
|
+
3. verificar se houve normalização ou rejeição de range no backend;
|
|
68
|
+
4. checar persistência local e preferências reaplicadas;
|
|
69
|
+
5. revisar `controlType` inline e overrides de metadata.
|
|
70
|
+
|
|
71
|
+
```mermaid
|
|
72
|
+
flowchart TD
|
|
73
|
+
incident["Incident in dynamic filter"] --> payload["Inspect payload sent by host"]
|
|
74
|
+
payload --> schema["Validate current schema and drift"]
|
|
75
|
+
schema --> range["Check range normalization and backend rejection"]
|
|
76
|
+
range --> persistence["Inspect local persistence and restored state"]
|
|
77
|
+
persistence --> inline["Review inline controlType and metadata overrides"]
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Sintoma: `400 FILTER_PAYLOAD_INVALID`
|
|
81
|
+
|
|
82
|
+
### Causa provável
|
|
83
|
+
|
|
84
|
+
O backend rejeitou o payload durante normalização ou construção da specification.
|
|
85
|
+
|
|
86
|
+
### Onde olhar
|
|
87
|
+
|
|
88
|
+
- `GlobalExceptionHandler`
|
|
89
|
+
- `RangePayloadNormalizer`
|
|
90
|
+
- `GenericSpecificationsBuilder`
|
|
91
|
+
|
|
92
|
+
### Casos típicos
|
|
93
|
+
|
|
94
|
+
- payload escalar de range;
|
|
95
|
+
- lista com mais de dois limites;
|
|
96
|
+
- `BETWEEN_EXCLUSIVE` sem dois limites válidos;
|
|
97
|
+
- alias conflitante para o mesmo range;
|
|
98
|
+
- tipo incompatível com a operação (`LIKE` com valor não textual, `IN` sem lista etc.).
|
|
99
|
+
|
|
100
|
+
### Resposta esperada
|
|
101
|
+
|
|
102
|
+
HTTP `400` com `errors[].properties.code = FILTER_PAYLOAD_INVALID`.
|
|
103
|
+
|
|
104
|
+
## Sintoma: range não filtra ou filtra errado
|
|
105
|
+
|
|
106
|
+
### Causa provável
|
|
107
|
+
|
|
108
|
+
O shape enviado não respeita o contrato ou foi interpretado de maneira diferente da esperada.
|
|
109
|
+
|
|
110
|
+
### Checklist
|
|
111
|
+
|
|
112
|
+
1. O campo backend usa operação `BETWEEN`, `BETWEEN_EXCLUSIVE`, `NOT_BETWEEN` ou `OUTSIDE_RANGE`?
|
|
113
|
+
2. O frontend enviou lista canônica ou objeto canônico?
|
|
114
|
+
3. Há `null` explícito preservando upper-only ou lower-only?
|
|
115
|
+
4. Existe mistura de aliases como `from` e `minPrice` ao mesmo tempo?
|
|
116
|
+
|
|
117
|
+
### Ação
|
|
118
|
+
|
|
119
|
+
Compare o payload com o guia de ranges antes de tentar “corrigir no controller”.
|
|
120
|
+
|
|
121
|
+
## Sintoma: campo inline não aparece na barra compacta
|
|
122
|
+
|
|
123
|
+
### Causa provável
|
|
124
|
+
|
|
125
|
+
O host pode ter aplicado opt-out para a variante inline ou o campo não foi promovido corretamente para `alwaysVisibleFields`.
|
|
126
|
+
|
|
127
|
+
### Onde olhar
|
|
128
|
+
|
|
129
|
+
- `alwaysVisibleFields`
|
|
130
|
+
- `alwaysVisibleFieldMetadataOverrides`
|
|
131
|
+
- flags `useInline*Variant`
|
|
132
|
+
- catálogo inline canônico
|
|
133
|
+
|
|
134
|
+
### Ação
|
|
135
|
+
|
|
136
|
+
Confirme:
|
|
137
|
+
|
|
138
|
+
- se o nome do campo existe no schema;
|
|
139
|
+
- se a variante inline está habilitada;
|
|
140
|
+
- se o `controlType` é o nome canônico publicado;
|
|
141
|
+
- se o campo deveria mesmo estar na toolbar e não apenas no avançado.
|
|
142
|
+
|
|
143
|
+
## Sintoma: schema mudou e o filtro ficou inconsistente
|
|
144
|
+
|
|
145
|
+
### Sinais
|
|
146
|
+
|
|
147
|
+
- `schemaStatusChange` emitindo `outdated: true`
|
|
148
|
+
- comportamento divergente entre o schema atual e o estado local persistido
|
|
149
|
+
|
|
150
|
+
### Causa provável
|
|
151
|
+
|
|
152
|
+
O schema do backend mudou, mas o estado local ou as preferências ainda refletem a versão antiga.
|
|
153
|
+
|
|
154
|
+
### Ação
|
|
155
|
+
|
|
156
|
+
1. observar `metaChanged` e `schemaStatusChange`;
|
|
157
|
+
2. reconciliar schema quando necessário;
|
|
158
|
+
3. limpar persistência local se o contrato mudou estruturalmente;
|
|
159
|
+
4. revalidar `alwaysVisibleFields` e overrides.
|
|
160
|
+
|
|
161
|
+
## Sintoma: filtro parece “preso” ou restaura estado inesperado
|
|
162
|
+
|
|
163
|
+
### Causa provável
|
|
164
|
+
|
|
165
|
+
Persistência local ativa com `filter-dto:<key>` e `filter-config:<key>`.
|
|
166
|
+
|
|
167
|
+
### Ação
|
|
168
|
+
|
|
169
|
+
- revisar o `persistenceKey`;
|
|
170
|
+
- limpar config e DTO persistidos;
|
|
171
|
+
- confirmar se o ambiente de teste não está herdando estado anterior.
|
|
172
|
+
|
|
173
|
+
## Sintoma: tags não funcionam como esperado
|
|
174
|
+
|
|
175
|
+
### Causa provável
|
|
176
|
+
|
|
177
|
+
`allowSaveTags` não está habilitado, ou a expectativa do produto sobre tags não está alinhada com o runtime.
|
|
178
|
+
|
|
179
|
+
### Ação
|
|
180
|
+
|
|
181
|
+
- confirmar `allowSaveTags`;
|
|
182
|
+
- revisar se as tags são só visualização ou presets operacionais;
|
|
183
|
+
- evitar documentar tags como comportamento universal do filtro.
|
|
184
|
+
|
|
185
|
+
## Sintoma: comportamento diferente entre modal e drawer
|
|
186
|
+
|
|
187
|
+
### Causa provável
|
|
188
|
+
|
|
189
|
+
Configuração distinta em `advancedOpenMode` e/ou `advancedClearButtonsEnabled`.
|
|
190
|
+
|
|
191
|
+
### Ação
|
|
192
|
+
|
|
193
|
+
Verificar:
|
|
194
|
+
|
|
195
|
+
- modo de abertura atual;
|
|
196
|
+
- clear buttons avançados;
|
|
197
|
+
- densidade e largura dos campos no contexto real.
|
|
198
|
+
|
|
199
|
+
## Matriz rápida de causa e correção
|
|
200
|
+
|
|
201
|
+
| Sintoma | Causa mais provável | Correção inicial |
|
|
202
|
+
| --- | --- | --- |
|
|
203
|
+
| `400 FILTER_PAYLOAD_INVALID` | payload incompatível com operação | revisar payload e contrato backend |
|
|
204
|
+
| range vazio “vira filtro” | serialização indevida no host | remover objeto vazio antes do envio |
|
|
205
|
+
| inline não aparece | flag inline ausente ou campo não pinado | revisar settings editor |
|
|
206
|
+
| schema fica desatualizado | drift entre backend e estado local | reconciliar schema e limpar persistência |
|
|
207
|
+
| filtro restaura valor antigo | `persistenceKey`/storage reaplicando estado | limpar `filter-dto:*` e `filter-config:*` |
|
|
208
|
+
|
|
209
|
+
## Regra operacional final
|
|
210
|
+
|
|
211
|
+
Nunca trate bug de filtro só como problema de UI.
|
|
212
|
+
|
|
213
|
+
No Praxis, a falha pode estar em qualquer uma destas camadas:
|
|
214
|
+
|
|
215
|
+
- metadata/schema;
|
|
216
|
+
- runtime do `praxis-filter`;
|
|
217
|
+
- configuração do host;
|
|
218
|
+
- payload enviado;
|
|
219
|
+
- normalização do `metadata-starter`;
|
|
220
|
+
- specification backend.
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Dynamic Inline Filter Catalog"
|
|
3
|
+
slug: "dynamic-inline-filter-catalog"
|
|
4
|
+
description: "Catalogo de referencia da trilha inline do filtro dinamico em praxis-table, com foco em decisao de uso e dependencia de runtime."
|
|
5
|
+
doc_type: "reference"
|
|
6
|
+
document_kind: "host-guide"
|
|
7
|
+
component: "table"
|
|
8
|
+
category: "integration"
|
|
9
|
+
audience:
|
|
10
|
+
- "frontend"
|
|
11
|
+
- "host"
|
|
12
|
+
- "architect"
|
|
13
|
+
- "designer"
|
|
14
|
+
level: "advanced"
|
|
15
|
+
status: "active"
|
|
16
|
+
owner: "praxis-ui"
|
|
17
|
+
tags:
|
|
18
|
+
- "table"
|
|
19
|
+
- "dynamic-filter"
|
|
20
|
+
- "inline"
|
|
21
|
+
- "catalog"
|
|
22
|
+
last_updated: "2026-03-07"
|
|
23
|
+
toc: true
|
|
24
|
+
sidebar: true
|
|
25
|
+
deprecated_paths:
|
|
26
|
+
- "dynamic-filter-inline-catalog.md"
|
|
27
|
+
deprecated_slugs:
|
|
28
|
+
- "dynamic-filter-inline-catalog"
|
|
29
|
+
related_docs:
|
|
30
|
+
- "dynamic-filter-host-integration-guide"
|
|
31
|
+
- "dynamic-filter-editor-settings-guide"
|
|
32
|
+
- "dynamic-filter-payload-contract"
|
|
33
|
+
- "dynamic-filter-range-filters-guide"
|
|
34
|
+
- "dynamic-fields-inline-filter-catalog"
|
|
35
|
+
keywords:
|
|
36
|
+
- "praxis-filter"
|
|
37
|
+
- "inline controls"
|
|
38
|
+
- "toolbar filters"
|
|
39
|
+
- "always visible filters"
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
# Dynamic Inline Filter Catalog
|
|
43
|
+
|
|
44
|
+
## Objetivo
|
|
45
|
+
|
|
46
|
+
Mapear a trilha inline do `praxis-table` sem confundir o consumidor com fields de formulario comum.
|
|
47
|
+
|
|
48
|
+
```mermaid
|
|
49
|
+
flowchart LR
|
|
50
|
+
Host["Host define filtros visiveis"] --> Table["praxis-table governa a jornada inline"]
|
|
51
|
+
Table --> Toolbar["toolbar sempre visivel"]
|
|
52
|
+
Table --> Payload["payload emitido para filter"]
|
|
53
|
+
Table --> DynamicFields["dynamic-fields fornece controlType inline"]
|
|
54
|
+
DynamicFields --> Components["componentes compactos e metadata-driven"]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Pre-requisitos
|
|
58
|
+
|
|
59
|
+
- entendimento basico de `praxis-table`, `praxis-filter` e `@praxisui/dynamic-fields`
|
|
60
|
+
- familiaridade com filtros always visible vs painel avancado
|
|
61
|
+
|
|
62
|
+
## Como ler este catalogo
|
|
63
|
+
|
|
64
|
+
- `table` e a feature owner da jornada de filtro
|
|
65
|
+
- `dynamic-fields` e o owner dos componentes inline
|
|
66
|
+
- este documento existe para conectar jornada, UX e integracao host
|
|
67
|
+
|
|
68
|
+
## Quando usar inline
|
|
69
|
+
|
|
70
|
+
Prefira filtros inline quando:
|
|
71
|
+
|
|
72
|
+
- o campo precisa ficar visivel na toolbar;
|
|
73
|
+
- a interacao cabe em espaco compacto;
|
|
74
|
+
- o resumo do valor continua legivel sem abrir painel avancado;
|
|
75
|
+
- o backend ja entende o payload emitido por essa trilha.
|
|
76
|
+
|
|
77
|
+
## Quando evitar inline
|
|
78
|
+
|
|
79
|
+
Evite inline quando:
|
|
80
|
+
|
|
81
|
+
- o campo exige leitura longa ou configuracao extensa;
|
|
82
|
+
- o resumo do valor vira ruido (`primeiro +N` sem contexto suficiente);
|
|
83
|
+
- o fluxo depende de lookup rico, formulario multi-etapas ou ajuda contextual pesada;
|
|
84
|
+
- a acessibilidade degrada por excesso de compactacao.
|
|
85
|
+
|
|
86
|
+
## Familias principais
|
|
87
|
+
|
|
88
|
+
### Texto
|
|
89
|
+
|
|
90
|
+
- `inlineInput`
|
|
91
|
+
|
|
92
|
+
### Selecao
|
|
93
|
+
|
|
94
|
+
- `inlineSelect`
|
|
95
|
+
- `inlineSearchableSelect`
|
|
96
|
+
- `inlineAsyncSelect`
|
|
97
|
+
- `inlineMultiSelect`
|
|
98
|
+
- `inlineAutocomplete`
|
|
99
|
+
- `inlineEntityLookup`
|
|
100
|
+
|
|
101
|
+
`entityLookup` vindo de metadata canonica e projetado como always visible usa `inlineEntityLookup` na toolbar compacta. O host deve preferir `controlType: "entityLookup"` no schema e reservar `inlineEntityLookup` para overrides visuais explicitos.
|
|
102
|
+
|
|
103
|
+
### Numero e range
|
|
104
|
+
|
|
105
|
+
- `inlineNumber`
|
|
106
|
+
- `inlineCurrency`
|
|
107
|
+
- `inlineCurrencyRange`
|
|
108
|
+
- `inlineRange`
|
|
109
|
+
- `inlineRating`
|
|
110
|
+
- `inlineDistanceRadius`
|
|
111
|
+
- `inlineScorePriority`
|
|
112
|
+
|
|
113
|
+
### Data e tempo
|
|
114
|
+
|
|
115
|
+
- `inlineDate`
|
|
116
|
+
- `inlineDateRange`
|
|
117
|
+
- `inlineTime`
|
|
118
|
+
- `inlineTimeRange`
|
|
119
|
+
- `inlineRelativePeriod`
|
|
120
|
+
|
|
121
|
+
### Outros especializados
|
|
122
|
+
|
|
123
|
+
- `inlineTreeSelect`
|
|
124
|
+
- `inlinePipelineStatus`
|
|
125
|
+
- `inlineSentiment`
|
|
126
|
+
- `inlineColorLabel`
|
|
127
|
+
- `inlineToggle`
|
|
128
|
+
|
|
129
|
+
## Fonte de verdade do componente
|
|
130
|
+
|
|
131
|
+
Para detalhe de cada controlType, shape de valor e metadata:
|
|
132
|
+
|
|
133
|
+
- consulte [Dynamic Fields Inline Filter Catalog](../../praxis-dynamic-fields/docs/dynamic-fields-inline-filter-catalog.md)
|
|
134
|
+
|
|
135
|
+
## Fonte de verdade da jornada
|
|
136
|
+
|
|
137
|
+
Para integracao real do filtro:
|
|
138
|
+
|
|
139
|
+
- consulte [Dynamic Filter Host Integration Guide](./dynamic-filter-host-integration-guide.md)
|
|
140
|
+
- consulte [Dynamic Filter Payload Contract](./dynamic-filter-payload-contract.md)
|
|
141
|
+
- consulte [Dynamic Filter Range Filters Guide](./dynamic-filter-range-filters-guide.md)
|
|
142
|
+
|
|
143
|
+
## Regra editorial
|
|
144
|
+
|
|
145
|
+
- `dynamic-fields` documenta o componente
|
|
146
|
+
- `table` documenta quando ele entra na jornada
|
|
147
|
+
- o host decide quais campos ficam sempre visiveis e quais degradam para painel avancado
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# PraxisTable E2E (Playwright) - Column Drag
|
|
2
|
+
|
|
3
|
+
Este pacote valida gesto real de drag de colunas (pointer) em ambiente browser, reduzindo risco de regressao de drop area/layout que nao aparece em testes unitarios.
|
|
4
|
+
|
|
5
|
+
## Arquivos
|
|
6
|
+
|
|
7
|
+
- `projects/praxis-table/test-dev/e2e/column-drag.playwright.spec.ts`
|
|
8
|
+
- `projects/praxis-table/test-dev/e2e/column-drag-visual-evidence.playwright.spec.ts`
|
|
9
|
+
- `tools/e2e/playwright/praxis-table-column-drag.playwright.config.ts`
|
|
10
|
+
- `tools/e2e/playwright/run-praxis-table-column-drag.sh`
|
|
11
|
+
|
|
12
|
+
## Cobertura do teste
|
|
13
|
+
|
|
14
|
+
1. Abre `http://127.0.0.1:4003/table-local-data-features-demo` com storage limpo.
|
|
15
|
+
2. Valida contrato default: `Reordenar colunas por arraste` inicia habilitado no editor.
|
|
16
|
+
3. Valida affordance primario de drag no header (`grab` no idle, `grabbing` durante gesto quando suportado pelo browser).
|
|
17
|
+
4. Valida o contrato visual do grip: sem fundo/borda de botao, dimensao discreta e opacidade baixa no estado idle.
|
|
18
|
+
5. Valida a discoverability do grip em hover/focus (estado visivel sem ruído visual excessivo).
|
|
19
|
+
6. Valida o mesmo contrato na rota `http://127.0.0.1:4003/filter-demo`.
|
|
20
|
+
7. Desabilita drag via editor, persiste (`Salvar & Fechar`) e valida que os handles somem no runtime.
|
|
21
|
+
8. Valida gesto real: arrastar pelo titulo reordena; arrastar pelo icone visual de drag tambem reordena.
|
|
22
|
+
9. Executa o mesmo gesto com `prefers-reduced-motion: reduce`, validando transicoes desativadas e reorder funcional.
|
|
23
|
+
|
|
24
|
+
## Como executar
|
|
25
|
+
|
|
26
|
+
1. Suba a aplicacao:
|
|
27
|
+
- `npm start`
|
|
28
|
+
2. Em outro terminal:
|
|
29
|
+
- `tools/e2e/playwright/run-praxis-table-column-drag.sh`
|
|
30
|
+
|
|
31
|
+
Pre-requisito:
|
|
32
|
+
|
|
33
|
+
- `@playwright/test` instalado no workspace (`npm install -D @playwright/test`).
|
|
34
|
+
|
|
35
|
+
Variaveis opcionais:
|
|
36
|
+
|
|
37
|
+
- `PLAYWRIGHT_BASE_URL` (default: `http://127.0.0.1:4003`)
|
|
38
|
+
- `PLAYWRIGHT_CHROMIUM_EXECUTABLE` (override do binario Chromium)
|
|
39
|
+
- `PLAYWRIGHT_USE_WEB_SERVER=1` (delega start/stop do server ao Playwright usando `tools/e2e/playwright/start-filter-demo-server.sh`)
|
|
40
|
+
|
|
41
|
+
## Captura de evidencia visual (before/after)
|
|
42
|
+
|
|
43
|
+
1. BEFORE:
|
|
44
|
+
- `EVIDENCE_OUT_DIR=artifacts/praxis-table/filter-demo-drag-affordance/before node node_modules/playwright/cli.js test --config tools/e2e/playwright/praxis-table-column-drag.playwright.config.ts projects/praxis-table/test-dev/e2e/column-drag-visual-evidence.playwright.spec.ts`
|
|
45
|
+
2. AFTER:
|
|
46
|
+
- `EVIDENCE_OUT_DIR=artifacts/praxis-table/filter-demo-drag-affordance/after node node_modules/playwright/cli.js test --config tools/e2e/playwright/praxis-table-column-drag.playwright.config.ts projects/praxis-table/test-dev/e2e/column-drag-visual-evidence.playwright.spec.ts`
|
|
47
|
+
|
|
48
|
+
Artefatos gerados por run:
|
|
49
|
+
|
|
50
|
+
- `01-full-page.png`
|
|
51
|
+
- `02-component-table.png`
|
|
52
|
+
- `03-bug-element-crop.png`
|
|
53
|
+
- `04-dom-dump-header-cell.json`
|
|
54
|
+
- `05-computed-styles-handle.json`
|
|
55
|
+
|
|
56
|
+
## Notas enterprise
|
|
57
|
+
|
|
58
|
+
- O teste usa seletor funcional (settings button + switches + handles) e valida efeito final (ordem de colunas), nao apenas classes CSS.
|
|
59
|
+
- O contrato de UX fica coberto em pontos criticos de governanca: default seguro, opt-out no editor, cursor como affordance principal, discoverability do grip e modo de movimento reduzido.
|
|
60
|
+
- Em `pointer: coarse`, o grip permanece visivel em baixa opacidade para melhorar discoverability sem voltar ao padrao de botao circular.
|
|
61
|
+
- Seletores E2E sao locale-agnostic com `data-testid` estavel (evita flake por traducao/copy).
|
|
62
|
+
- O runner tenta usar Chromium do sistema para reduzir dependencia de download de browser no CI.
|