@praxisui/table 3.0.0-beta.1 → 3.0.0-beta.2
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 +120 -79
- package/fesm2022/praxisui-table.mjs +86 -31
- package/fesm2022/praxisui-table.mjs.map +1 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -379,7 +379,7 @@ Quando `resourcePath` é fornecido, a tabela se torna "inteligente":
|
|
|
379
379
|
Neste exemplo:
|
|
380
380
|
|
|
381
381
|
- `resourcePath="human-resources/departamentos"` instrui a tabela a se comunicar com o endpoint `/api/human-resources/departamentos`.
|
|
382
|
-
- A tabela fará requisições como `POST /api/human-resources/departamentos/filter` para obter os dados e `GET /api/human-resources/departamentos/
|
|
382
|
+
- 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.
|
|
383
383
|
- `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.
|
|
384
384
|
|
|
385
385
|
### Empty State + Quick Connect (sem `resourcePath`)
|
|
@@ -394,20 +394,22 @@ Ao aplicar/salvar, a `<praxis-table>` é automaticamente configurada para buscar
|
|
|
394
394
|
|
|
395
395
|
### Fluxo de Comunicação do `resourcePath`
|
|
396
396
|
|
|
397
|
-
O diagrama abaixo ilustra como a propriedade `resourcePath` conecta o componente frontend ao
|
|
397
|
+
O diagrama abaixo ilustra como a propriedade `resourcePath` conecta o componente frontend ao backend no runtime atual da tabela. Antes de iniciar o fluxo remoto, a lib resolve o modo de dados com precedência **`resourcePath` explícito > `data` local > conexão persistida**. Quando o modo efetivo é `remote`, o bootstrap ocorre em três etapas principais: **Configurar**, **Carregar Schema estrutural** e **Buscar Dados**.
|
|
398
398
|
|
|
399
399
|
```mermaid
|
|
400
400
|
sequenceDiagram
|
|
401
401
|
participant FE_Component as Componente Angular<br>(departamentos.html)
|
|
402
402
|
participant Praxis_Table as @praxisui/table<br>(praxis-table.ts)
|
|
403
403
|
participant Crud_Service as @praxisui/core<br>(generic-crud.service.ts)
|
|
404
|
+
participant Docs_Controller as ApiDocsController<br>(/schemas/filtered)
|
|
404
405
|
participant BE_Controller as Backend Controller<br>(DepartamentoController.java)
|
|
405
|
-
participant Abstract_Controller as AbstractCrudController
|
|
406
|
+
participant Abstract_Controller as AbstractCrudController<br>(/filter)
|
|
406
407
|
|
|
407
408
|
FE_Component->>Praxis_Table: Usa o componente com <br> <praxis-table resourcePath="human-resources/departamentos">
|
|
408
409
|
|
|
409
410
|
activate Praxis_Table
|
|
410
|
-
Praxis_Table->>Praxis_Table: ngOnChanges()
|
|
411
|
+
Praxis_Table->>Praxis_Table: ngOnInit()/ngOnChanges() resolve dataMode
|
|
412
|
+
Note over Praxis_Table: remote quando há resourcePath efetivo
|
|
411
413
|
Praxis_Table->>Crud_Service: 1. Chama crudService.configure("human-resources/departamentos")
|
|
412
414
|
|
|
413
415
|
activate Crud_Service
|
|
@@ -418,24 +420,19 @@ sequenceDiagram
|
|
|
418
420
|
Praxis_Table->>Crud_Service: Chama crudService.getSchema()
|
|
419
421
|
|
|
420
422
|
activate Crud_Service
|
|
421
|
-
Crud_Service->>Crud_Service:
|
|
422
|
-
Crud_Service->>
|
|
423
|
+
Crud_Service->>Crud_Service: schemaUrl() preserva o base path canônico
|
|
424
|
+
Crud_Service->>Crud_Service: Deriva path="/api/human-resources/departamentos/all"<br>operation="get", schemaType="response"
|
|
425
|
+
Crud_Service->>Docs_Controller: GET /schemas/filtered?path=.../all&operation=get&schemaType=response
|
|
423
426
|
deactivate Crud_Service
|
|
424
427
|
|
|
425
|
-
activate
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
Abstract_Controller->>Abstract_Controller: Gera e retorna o Schema da UI
|
|
431
|
-
Abstract_Controller-->>BE_Controller: Retorna o Schema
|
|
432
|
-
deactivate Abstract_Controller
|
|
433
|
-
|
|
434
|
-
BE_Controller-->>Crud_Service: Resposta HTTP com o JSON do Schema
|
|
435
|
-
deactivate BE_Controller
|
|
428
|
+
activate Docs_Controller
|
|
429
|
+
Docs_Controller->>Docs_Controller: Resolve grupo OpenAPI a partir do path
|
|
430
|
+
Docs_Controller->>Docs_Controller: Filtra payload estrutural + x-ui
|
|
431
|
+
Docs_Controller-->>Crud_Service: 200/304 com schema + ETag/X-Schema-Hash
|
|
432
|
+
deactivate Docs_Controller
|
|
436
433
|
|
|
437
434
|
activate Crud_Service
|
|
438
|
-
Crud_Service-->>Praxis_Table:
|
|
435
|
+
Crud_Service-->>Praxis_Table: Normaliza schema e retorna FieldDefinition[]
|
|
439
436
|
deactivate Crud_Service
|
|
440
437
|
|
|
441
438
|
Praxis_Table->>Praxis_Table: Constrói as colunas da tabela<br>a partir do schema recebido
|
|
@@ -460,13 +457,20 @@ sequenceDiagram
|
|
|
460
457
|
deactivate BE_Controller
|
|
461
458
|
|
|
462
459
|
activate Crud_Service
|
|
463
|
-
Crud_Service-->>Praxis_Table: Retorna
|
|
460
|
+
Crud_Service-->>Praxis_Table: Retorna Page<T> com os dados paginados
|
|
464
461
|
deactivate Crud_Service
|
|
465
462
|
|
|
466
463
|
Praxis_Table->>Praxis_Table: Atualiza o dataSource da tabela com os dados recebidos
|
|
467
464
|
deactivate Praxis_Table
|
|
468
465
|
```
|
|
469
466
|
|
|
467
|
+
Notas importantes:
|
|
468
|
+
|
|
469
|
+
- O host informa `resourcePath` sem o prefixo `/api`; o `GenericCrudService` resolve as URLs reais do backend a partir da configuração de API do host.
|
|
470
|
+
- O bootstrap de schema não depende mais de uma chamada frontend para `GET /{resource}/schemas`; o runtime consome diretamente `/schemas/filtered` com `ETag`/`X-Schema-Hash`.
|
|
471
|
+
- O `praxis-filter` acoplado acompanha o mesmo `resourcePath` em modo remoto e deriva seu schema via `/schemas/filtered?path=.../filter&operation=post&schemaType=request`.
|
|
472
|
+
- Sem `resourcePath` efetivo, a tabela não entra nesse fluxo remoto; ela cai em `local` ou `empty` conforme a precedência canônica.
|
|
473
|
+
|
|
470
474
|
## ℹ️ Dicas de UX (Tabela)
|
|
471
475
|
|
|
472
476
|
- Multi‑sort: habilite em Comportamento → Ordenação. No uso, mantenha Ctrl/Cmd pressionado ao clicar em múltiplas colunas.
|
|
@@ -805,12 +809,13 @@ sequenceDiagram
|
|
|
805
809
|
autonumber
|
|
806
810
|
participant PT as PraxisTable
|
|
807
811
|
participant GS as GenericCrudService
|
|
808
|
-
participant
|
|
812
|
+
participant Docs as ApiDocsController (/schemas/filtered)
|
|
809
813
|
|
|
810
814
|
PT->>GS: configure(resourcePath)
|
|
811
815
|
PT->>GS: getSchema()
|
|
812
|
-
GS->>
|
|
813
|
-
|
|
816
|
+
GS->>GS: deriva path=/api/.../all + schemaType=response
|
|
817
|
+
GS->>Docs: GET /schemas/filtered?path=.../all&operation=get&schemaType=response
|
|
818
|
+
Docs-->>GS: 200/304 schema + x-ui.resource.idField
|
|
814
819
|
GS->>GS: cache + lastResourceMeta.idField
|
|
815
820
|
GS-->>PT: FieldDefinition[] (normalizado)
|
|
816
821
|
Note over PT: idField = input || context || GS.getResourceIdField() || 'id'
|
|
@@ -827,11 +832,12 @@ sequenceDiagram
|
|
|
827
832
|
participant API as Backend
|
|
828
833
|
|
|
829
834
|
PT->>PT: key = getIdField() (precedência)
|
|
830
|
-
PT->>PT: id = row
|
|
835
|
+
PT->>PT: id = getNestedPropertyValue(row, key)
|
|
831
836
|
PT->>GS: delete(id)
|
|
832
837
|
GS->>API: DELETE {resource}/{id}
|
|
833
838
|
API-->>GS: 204 No Content
|
|
834
|
-
GS-->>PT: sucesso
|
|
839
|
+
GS-->>PT: sucesso
|
|
840
|
+
PT->>PT: fetchData() em modo remoto
|
|
835
841
|
```
|
|
836
842
|
|
|
837
843
|
### Troubleshooting rápido (idField)
|
|
@@ -882,78 +888,113 @@ export class ExampleComponent {
|
|
|
882
888
|
|
|
883
889
|
## ⚙️ Fluxo de Paginação e Filtros (Server-Side)
|
|
884
890
|
|
|
885
|
-
Quando a `<praxis-table>`
|
|
891
|
+
Quando a `<praxis-table>` opera com `resourcePath`, o runtime resolve o modo remoto e passa a delegar paginação, ordenação e filtros ao backend. Isso reduz tráfego, preserva a semântica do DTO de filtro e mantém o banco como fonte de verdade para `WHERE`, `ORDER BY`, `LIMIT` e `OFFSET`.
|
|
886
892
|
|
|
887
893
|
Importante: se você não configurar explicitamente as estratégias de paginação/ordenação no `TableConfig`, a tabela resolve automaticamente como `server` quando há `resourcePath`. Se preferir operar no cliente, defina `behavior.pagination.strategy = 'client'` e/ou `behavior.sorting.strategy = 'client'` conscientemente.
|
|
888
894
|
|
|
889
|
-
|
|
895
|
+
### Versão Pedagógica de Alto Nível
|
|
896
|
+
|
|
897
|
+
Esta é a leitura adequada para documentação pública e landing pages.
|
|
890
898
|
|
|
891
899
|
```mermaid
|
|
892
900
|
sequenceDiagram
|
|
893
|
-
participant
|
|
894
|
-
participant
|
|
895
|
-
participant
|
|
896
|
-
participant
|
|
897
|
-
participant
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
CrudService->>CrudService: Cria HttpParams:<br>page=1, size=10, sort=nome,asc
|
|
910
|
-
CrudService->>Controller: Requisição POST para /api/.../filter<br>Body: {nome: 'Tech'}<br>Params: ?page=1&size=10&sort=nome,asc
|
|
911
|
-
deactivate CrudService
|
|
912
|
-
|
|
913
|
-
activate Controller
|
|
914
|
-
Controller->>Controller: Spring injeta o corpo no FilterDTO<br>e os params no objeto Pageable.
|
|
915
|
-
Controller->>Service: Chama .filter(filterDTO, pageable)
|
|
916
|
-
deactivate Controller
|
|
917
|
-
|
|
918
|
-
activate Service
|
|
919
|
-
Service->>SpecBuilder: Chama .buildSpecification(filterDTO)
|
|
901
|
+
participant Usuario as Usuário
|
|
902
|
+
participant Tabela as praxis-table
|
|
903
|
+
participant Frontend as GenericCrudService
|
|
904
|
+
participant Backend as API Praxis
|
|
905
|
+
participant Banco as Banco de Dados
|
|
906
|
+
|
|
907
|
+
Usuario->>Tabela: muda página, ordena ou aplica filtro
|
|
908
|
+
Tabela->>Tabela: consolida filterCriteria + paginação + sort
|
|
909
|
+
Tabela->>Frontend: filter(criteria, pageable)
|
|
910
|
+
Frontend->>Backend: POST /api/.../filter?page&size&sort
|
|
911
|
+
Backend->>Banco: executa consulta filtrada e paginada
|
|
912
|
+
Banco-->>Backend: retorna página de resultados
|
|
913
|
+
Backend-->>Frontend: responde com página de DTOs
|
|
914
|
+
Frontend-->>Tabela: entrega Page<T>
|
|
915
|
+
Tabela->>Tabela: atualiza linhas, paginação e estado visual
|
|
916
|
+
```
|
|
920
917
|
|
|
921
|
-
|
|
922
|
-
SpecBuilder->>SpecBuilder: Itera nos campos do FilterDTO.<br>Encontra @Filterable no campo 'nome'.
|
|
923
|
-
SpecBuilder->>SpecBuilder: Cria um Predicate JPA:<br> `criteriaBuilder.like(root.get("nome"), "%tech%")`
|
|
924
|
-
SpecBuilder->>Service: Retorna a Specification JPA construída.
|
|
925
|
-
deactivate SpecBuilder
|
|
918
|
+
Leitura pedagógica:
|
|
926
919
|
|
|
927
|
-
|
|
920
|
+
1. **A tabela captura a intenção do usuário**: página, ordenação e filtros viram estado de consulta.
|
|
921
|
+
2. **O frontend envia o DTO de filtro para o endpoint canônico**: corpo JSON para filtro, query params para paginação e sort.
|
|
922
|
+
3. **O backend aplica o filtro no conjunto remoto**: não é a UI que filtra localmente em modo remoto.
|
|
923
|
+
4. **O resultado volta já paginado**: a tabela apenas renderiza a página retornada pela API.
|
|
928
924
|
|
|
929
|
-
|
|
930
|
-
Repository->>Repository: Spring Data JPA executa a<br>query SQL com WHERE, LIMIT, OFFSET, ORDER BY.
|
|
931
|
-
Repository-->>Service: Retorna um objeto Page<Entity> do BD.
|
|
932
|
-
deactivate Repository
|
|
925
|
+
### Versão Detalhada e Fiel ao Runtime Atual
|
|
933
926
|
|
|
934
|
-
|
|
935
|
-
deactivate Service
|
|
927
|
+
Esta versão documenta o fluxo real do `praxis-table`, do `praxis-filter`, do `GenericCrudService` e do `praxis-metadata-starter`.
|
|
936
928
|
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
929
|
+
```mermaid
|
|
930
|
+
sequenceDiagram
|
|
931
|
+
participant Host as Host / bindings
|
|
932
|
+
participant Tabela as PraxisTable
|
|
933
|
+
participant Filtro as PraxisFilter
|
|
934
|
+
participant Crud as GenericCrudService
|
|
935
|
+
participant Controller as AbstractCrudController
|
|
936
|
+
participant Service as BaseCrudService
|
|
937
|
+
participant Builder as GenericSpecificationsBuilder
|
|
938
|
+
participant Repo as JpaSpecificationExecutor
|
|
939
|
+
|
|
940
|
+
Host->>Tabela: fornece resourcePath
|
|
941
|
+
Tabela->>Crud: configure(resourcePath)
|
|
942
|
+
alt sem colunas prontas
|
|
943
|
+
Tabela->>Crud: getSchema()
|
|
944
|
+
Crud-->>Tabela: schema normalizado
|
|
945
|
+
else com colunas prontas
|
|
946
|
+
Tabela->>Tabela: verifyServerSchemaVersion()
|
|
947
|
+
end
|
|
941
948
|
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
949
|
+
alt advancedFilters habilitado
|
|
950
|
+
Tabela->>Filtro: monta praxis-filter
|
|
951
|
+
Filtro->>Crud: getFilteredSchema(...) ou getSchema()
|
|
952
|
+
Crud-->>Filtro: metadata de filtro
|
|
953
|
+
end
|
|
945
954
|
|
|
946
|
-
|
|
955
|
+
alt paginação
|
|
956
|
+
Tabela->>Tabela: onPageChange(pageIndex, pageSize)
|
|
957
|
+
else ordenação
|
|
958
|
+
Tabela->>Tabela: onSortChange(active, direction)
|
|
959
|
+
Tabela->>Tabela: reseta pageIndex = 0
|
|
960
|
+
else filtro avançado
|
|
961
|
+
Filtro-->>Tabela: submit/change/clear
|
|
962
|
+
Tabela->>Tabela: onAdvancedFilterSubmit(criteria)
|
|
963
|
+
end
|
|
947
964
|
|
|
965
|
+
Tabela->>Tabela: fetchData()
|
|
966
|
+
Tabela->>Tabela: monta PageableRequest com pageIndex, pageSize e sortField efetivo
|
|
967
|
+
Tabela->>Crud: filter(filterCriteria, pageable)
|
|
968
|
+
|
|
969
|
+
Crud->>Crud: normalizeRangeCriteria(...)
|
|
970
|
+
Crud->>Controller: POST /filter?page&size&sort
|
|
971
|
+
Note over Crud,Controller: body = filterCriteria JSON
|
|
972
|
+
|
|
973
|
+
Controller->>Controller: lê page,size,sort de query params
|
|
974
|
+
Controller->>Controller: PageableBuilder.from(page,size,sort,...)
|
|
975
|
+
Controller->>Service: filterMappedWithIncludeIds(filterDTO, pageable, includeIds, toDto)
|
|
976
|
+
|
|
977
|
+
Service->>Builder: buildSpecification(filterDTO, pageable)
|
|
978
|
+
Builder->>Builder: inspeciona campos @Filterable do DTO
|
|
979
|
+
Builder-->>Service: Specification pronta
|
|
980
|
+
Service->>Repo: findAll(specification, pageable)
|
|
981
|
+
Repo-->>Service: Page<Entity>
|
|
982
|
+
Service-->>Controller: Page<DTO>
|
|
983
|
+
|
|
984
|
+
Controller->>Controller: mapeia para EntityModel<DTO> e monta RestApiResponse.success(...)
|
|
985
|
+
Controller-->>Crud: HTTP 200
|
|
986
|
+
Crud->>Crud: unwrapPageResponse(...)
|
|
987
|
+
Crud-->>Tabela: Page<T>
|
|
988
|
+
Tabela->>Tabela: atualiza dataSubject, totalElements e paginator
|
|
948
989
|
```
|
|
949
990
|
|
|
950
|
-
### Pontos-Chave do Fluxo
|
|
991
|
+
### Pontos-Chave do Fluxo Real
|
|
951
992
|
|
|
952
|
-
1.
|
|
953
|
-
2.
|
|
954
|
-
3.
|
|
955
|
-
4.
|
|
956
|
-
5.
|
|
993
|
+
1. **`resourcePath` não dispara só fetch**: em modo remoto, a tabela primeiro configura o `GenericCrudService` e pode carregar schema antes da primeira busca.
|
|
994
|
+
2. **O filtro avançado vive em `praxis-filter`**: os eventos reais são `submit`, `change` e `clear`, que a tabela recebe como `onAdvancedFilterSubmit`, `onAdvancedFilterChange` e `onAdvancedFilterClear`.
|
|
995
|
+
3. **O controller não recebe `Pageable` pronto do Spring nesse endpoint**: ele reconstrói o `Pageable` a partir de `page`, `size` e `sort`.
|
|
996
|
+
4. **O backend do starter responde com `RestApiResponse<Page<...>>`**: o `GenericCrudService` faz `unwrapPageResponse(...)` para entregar `Page<T>` ao runtime da tabela.
|
|
997
|
+
5. **A coluna ordenada pode mapear para `sortField`**: o `active` da UI não é necessariamente o campo final enviado ao backend.
|
|
957
998
|
|
|
958
999
|
## 🎨 Edição Visual da Tabela: O Poder do Low-Code
|
|
959
1000
|
|