@praxisui/table 3.0.0-beta.0 → 3.0.0-beta.10
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 +171 -82
- package/fesm2022/praxisui-table-filter-drawer-adapter.mjs +0 -1
- package/fesm2022/{praxisui-table-filter-form-dialog-host.component-C2rQnHE1.mjs → praxisui-table-filter-form-dialog-host.component-EHoM1uuJ.mjs} +2 -3
- package/fesm2022/praxisui-table-table-ai.adapter-C5rjLb8E.mjs +0 -1
- package/fesm2022/praxisui-table.mjs +5594 -2673
- package/index.d.ts +145 -61
- package/package.json +7 -7
- package/fesm2022/praxisui-table-filter-drawer-adapter.mjs.map +0 -1
- package/fesm2022/praxisui-table-filter-form-dialog-host.component-C2rQnHE1.mjs.map +0 -1
- package/fesm2022/praxisui-table-table-ai.adapter-C5rjLb8E.mjs.map +0 -1
- package/fesm2022/praxisui-table.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -379,9 +379,30 @@ 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
|
+
### Consulta Declarativa com `queryContext`
|
|
386
|
+
|
|
387
|
+
Para orquestração entre widgets em `praxis-dynamic-page`, o contrato semântico primário da tabela passa a ser `queryContext`.
|
|
388
|
+
|
|
389
|
+
```html
|
|
390
|
+
<praxis-table
|
|
391
|
+
resourcePath="human-resources/departamentos"
|
|
392
|
+
[queryContext]="{
|
|
393
|
+
filters: { status: 'ACTIVE' },
|
|
394
|
+
sort: ['nome,asc'],
|
|
395
|
+
page: { index: 0, size: 25 }
|
|
396
|
+
}"
|
|
397
|
+
></praxis-table>
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
Regras atuais:
|
|
401
|
+
|
|
402
|
+
- `queryContext.filters` já participa do pipeline efetivo da tabela
|
|
403
|
+
- `filterCriteria` continua aceito como bridge legada de compatibilidade
|
|
404
|
+
- em novo authoring, examples e bindings, prefira `queryContext`
|
|
405
|
+
|
|
385
406
|
### Empty State + Quick Connect (sem `resourcePath`)
|
|
386
407
|
|
|
387
408
|
Se a tabela for renderizada sem `resourcePath`, um cartão de "Empty State" é exibido convidando a conectar o componente a um recurso. Basta clicar em "Conectar a recurso" para abrir um painel rápido com um único campo:
|
|
@@ -394,20 +415,22 @@ Ao aplicar/salvar, a `<praxis-table>` é automaticamente configurada para buscar
|
|
|
394
415
|
|
|
395
416
|
### Fluxo de Comunicação do `resourcePath`
|
|
396
417
|
|
|
397
|
-
O diagrama abaixo ilustra como a propriedade `resourcePath` conecta o componente frontend ao
|
|
418
|
+
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
419
|
|
|
399
420
|
```mermaid
|
|
400
421
|
sequenceDiagram
|
|
401
422
|
participant FE_Component as Componente Angular<br>(departamentos.html)
|
|
402
423
|
participant Praxis_Table as @praxisui/table<br>(praxis-table.ts)
|
|
403
424
|
participant Crud_Service as @praxisui/core<br>(generic-crud.service.ts)
|
|
425
|
+
participant Docs_Controller as ApiDocsController<br>(/schemas/filtered)
|
|
404
426
|
participant BE_Controller as Backend Controller<br>(DepartamentoController.java)
|
|
405
|
-
participant Abstract_Controller as AbstractCrudController
|
|
427
|
+
participant Abstract_Controller as AbstractCrudController<br>(/filter)
|
|
406
428
|
|
|
407
429
|
FE_Component->>Praxis_Table: Usa o componente com <br> <praxis-table resourcePath="human-resources/departamentos">
|
|
408
430
|
|
|
409
431
|
activate Praxis_Table
|
|
410
|
-
Praxis_Table->>Praxis_Table: ngOnChanges()
|
|
432
|
+
Praxis_Table->>Praxis_Table: ngOnInit()/ngOnChanges() resolve dataMode
|
|
433
|
+
Note over Praxis_Table: remote quando há resourcePath efetivo
|
|
411
434
|
Praxis_Table->>Crud_Service: 1. Chama crudService.configure("human-resources/departamentos")
|
|
412
435
|
|
|
413
436
|
activate Crud_Service
|
|
@@ -418,24 +441,19 @@ sequenceDiagram
|
|
|
418
441
|
Praxis_Table->>Crud_Service: Chama crudService.getSchema()
|
|
419
442
|
|
|
420
443
|
activate Crud_Service
|
|
421
|
-
Crud_Service->>Crud_Service:
|
|
422
|
-
Crud_Service->>
|
|
444
|
+
Crud_Service->>Crud_Service: schemaUrl() preserva o base path canônico
|
|
445
|
+
Crud_Service->>Crud_Service: Deriva path="/api/human-resources/departamentos/all"<br>operation="get", schemaType="response"
|
|
446
|
+
Crud_Service->>Docs_Controller: GET /schemas/filtered?path=.../all&operation=get&schemaType=response
|
|
423
447
|
deactivate Crud_Service
|
|
424
448
|
|
|
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
|
|
449
|
+
activate Docs_Controller
|
|
450
|
+
Docs_Controller->>Docs_Controller: Resolve grupo OpenAPI a partir do path
|
|
451
|
+
Docs_Controller->>Docs_Controller: Filtra payload estrutural + x-ui
|
|
452
|
+
Docs_Controller-->>Crud_Service: 200/304 com schema + ETag/X-Schema-Hash
|
|
453
|
+
deactivate Docs_Controller
|
|
436
454
|
|
|
437
455
|
activate Crud_Service
|
|
438
|
-
Crud_Service-->>Praxis_Table:
|
|
456
|
+
Crud_Service-->>Praxis_Table: Normaliza schema e retorna FieldDefinition[]
|
|
439
457
|
deactivate Crud_Service
|
|
440
458
|
|
|
441
459
|
Praxis_Table->>Praxis_Table: Constrói as colunas da tabela<br>a partir do schema recebido
|
|
@@ -460,13 +478,20 @@ sequenceDiagram
|
|
|
460
478
|
deactivate BE_Controller
|
|
461
479
|
|
|
462
480
|
activate Crud_Service
|
|
463
|
-
Crud_Service-->>Praxis_Table: Retorna
|
|
481
|
+
Crud_Service-->>Praxis_Table: Retorna Page<T> com os dados paginados
|
|
464
482
|
deactivate Crud_Service
|
|
465
483
|
|
|
466
484
|
Praxis_Table->>Praxis_Table: Atualiza o dataSource da tabela com os dados recebidos
|
|
467
485
|
deactivate Praxis_Table
|
|
468
486
|
```
|
|
469
487
|
|
|
488
|
+
Notas importantes:
|
|
489
|
+
|
|
490
|
+
- 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.
|
|
491
|
+
- 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`.
|
|
492
|
+
- O `praxis-filter` acoplado acompanha o mesmo `resourcePath` em modo remoto e deriva seu schema via `/schemas/filtered?path=.../filter&operation=post&schemaType=request`.
|
|
493
|
+
- Sem `resourcePath` efetivo, a tabela não entra nesse fluxo remoto; ela cai em `local` ou `empty` conforme a precedência canônica.
|
|
494
|
+
|
|
470
495
|
## ℹ️ Dicas de UX (Tabela)
|
|
471
496
|
|
|
472
497
|
- Multi‑sort: habilite em Comportamento → Ordenação. No uso, mantenha Ctrl/Cmd pressionado ao clicar em múltiplas colunas.
|
|
@@ -805,12 +830,13 @@ sequenceDiagram
|
|
|
805
830
|
autonumber
|
|
806
831
|
participant PT as PraxisTable
|
|
807
832
|
participant GS as GenericCrudService
|
|
808
|
-
participant
|
|
833
|
+
participant Docs as ApiDocsController (/schemas/filtered)
|
|
809
834
|
|
|
810
835
|
PT->>GS: configure(resourcePath)
|
|
811
836
|
PT->>GS: getSchema()
|
|
812
|
-
GS->>
|
|
813
|
-
|
|
837
|
+
GS->>GS: deriva path=/api/.../all + schemaType=response
|
|
838
|
+
GS->>Docs: GET /schemas/filtered?path=.../all&operation=get&schemaType=response
|
|
839
|
+
Docs-->>GS: 200/304 schema + x-ui.resource.idField
|
|
814
840
|
GS->>GS: cache + lastResourceMeta.idField
|
|
815
841
|
GS-->>PT: FieldDefinition[] (normalizado)
|
|
816
842
|
Note over PT: idField = input || context || GS.getResourceIdField() || 'id'
|
|
@@ -827,11 +853,12 @@ sequenceDiagram
|
|
|
827
853
|
participant API as Backend
|
|
828
854
|
|
|
829
855
|
PT->>PT: key = getIdField() (precedência)
|
|
830
|
-
PT->>PT: id = row
|
|
856
|
+
PT->>PT: id = getNestedPropertyValue(row, key)
|
|
831
857
|
PT->>GS: delete(id)
|
|
832
858
|
GS->>API: DELETE {resource}/{id}
|
|
833
859
|
API-->>GS: 204 No Content
|
|
834
|
-
GS-->>PT: sucesso
|
|
860
|
+
GS-->>PT: sucesso
|
|
861
|
+
PT->>PT: fetchData() em modo remoto
|
|
835
862
|
```
|
|
836
863
|
|
|
837
864
|
### Troubleshooting rápido (idField)
|
|
@@ -882,78 +909,113 @@ export class ExampleComponent {
|
|
|
882
909
|
|
|
883
910
|
## ⚙️ Fluxo de Paginação e Filtros (Server-Side)
|
|
884
911
|
|
|
885
|
-
Quando a `<praxis-table>`
|
|
912
|
+
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
913
|
|
|
887
914
|
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
915
|
|
|
889
|
-
|
|
916
|
+
### Versão Pedagógica de Alto Nível
|
|
917
|
+
|
|
918
|
+
Esta é a leitura adequada para documentação pública e landing pages.
|
|
890
919
|
|
|
891
920
|
```mermaid
|
|
892
921
|
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)
|
|
922
|
+
participant Usuario as Usuário
|
|
923
|
+
participant Tabela as praxis-table
|
|
924
|
+
participant Frontend as GenericCrudService
|
|
925
|
+
participant Backend as API Praxis
|
|
926
|
+
participant Banco as Banco de Dados
|
|
927
|
+
|
|
928
|
+
Usuario->>Tabela: muda página, ordena ou aplica filtro
|
|
929
|
+
Tabela->>Tabela: consolida filterCriteria + paginação + sort
|
|
930
|
+
Tabela->>Frontend: filter(criteria, pageable)
|
|
931
|
+
Frontend->>Backend: POST /api/.../filter?page&size&sort
|
|
932
|
+
Backend->>Banco: executa consulta filtrada e paginada
|
|
933
|
+
Banco-->>Backend: retorna página de resultados
|
|
934
|
+
Backend-->>Frontend: responde com página de DTOs
|
|
935
|
+
Frontend-->>Tabela: entrega Page<T>
|
|
936
|
+
Tabela->>Tabela: atualiza linhas, paginação e estado visual
|
|
937
|
+
```
|
|
920
938
|
|
|
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
|
|
939
|
+
Leitura pedagógica:
|
|
926
940
|
|
|
927
|
-
|
|
941
|
+
1. **A tabela captura a intenção do usuário**: página, ordenação e filtros viram estado de consulta.
|
|
942
|
+
2. **O frontend envia o DTO de filtro para o endpoint canônico**: corpo JSON para filtro, query params para paginação e sort.
|
|
943
|
+
3. **O backend aplica o filtro no conjunto remoto**: não é a UI que filtra localmente em modo remoto.
|
|
944
|
+
4. **O resultado volta já paginado**: a tabela apenas renderiza a página retornada pela API.
|
|
928
945
|
|
|
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
|
|
946
|
+
### Versão Detalhada e Fiel ao Runtime Atual
|
|
933
947
|
|
|
934
|
-
|
|
935
|
-
deactivate Service
|
|
948
|
+
Esta versão documenta o fluxo real do `praxis-table`, do `praxis-filter`, do `GenericCrudService` e do `praxis-metadata-starter`.
|
|
936
949
|
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
950
|
+
```mermaid
|
|
951
|
+
sequenceDiagram
|
|
952
|
+
participant Host as Host / bindings
|
|
953
|
+
participant Tabela as PraxisTable
|
|
954
|
+
participant Filtro as PraxisFilter
|
|
955
|
+
participant Crud as GenericCrudService
|
|
956
|
+
participant Controller as AbstractCrudController
|
|
957
|
+
participant Service as BaseCrudService
|
|
958
|
+
participant Builder as GenericSpecificationsBuilder
|
|
959
|
+
participant Repo as JpaSpecificationExecutor
|
|
960
|
+
|
|
961
|
+
Host->>Tabela: fornece resourcePath
|
|
962
|
+
Tabela->>Crud: configure(resourcePath)
|
|
963
|
+
alt sem colunas prontas
|
|
964
|
+
Tabela->>Crud: getSchema()
|
|
965
|
+
Crud-->>Tabela: schema normalizado
|
|
966
|
+
else com colunas prontas
|
|
967
|
+
Tabela->>Tabela: verifyServerSchemaVersion()
|
|
968
|
+
end
|
|
941
969
|
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
970
|
+
alt advancedFilters habilitado
|
|
971
|
+
Tabela->>Filtro: monta praxis-filter
|
|
972
|
+
Filtro->>Crud: getFilteredSchema(...) ou getSchema()
|
|
973
|
+
Crud-->>Filtro: metadata de filtro
|
|
974
|
+
end
|
|
945
975
|
|
|
946
|
-
|
|
976
|
+
alt paginação
|
|
977
|
+
Tabela->>Tabela: onPageChange(pageIndex, pageSize)
|
|
978
|
+
else ordenação
|
|
979
|
+
Tabela->>Tabela: onSortChange(active, direction)
|
|
980
|
+
Tabela->>Tabela: reseta pageIndex = 0
|
|
981
|
+
else filtro avançado
|
|
982
|
+
Filtro-->>Tabela: submit/change/clear
|
|
983
|
+
Tabela->>Tabela: onAdvancedFilterSubmit(criteria)
|
|
984
|
+
end
|
|
947
985
|
|
|
986
|
+
Tabela->>Tabela: fetchData()
|
|
987
|
+
Tabela->>Tabela: monta PageableRequest com pageIndex, pageSize e sortField efetivo
|
|
988
|
+
Tabela->>Crud: filter(filterCriteria, pageable)
|
|
989
|
+
|
|
990
|
+
Crud->>Crud: normalizeRangeCriteria(...)
|
|
991
|
+
Crud->>Controller: POST /filter?page&size&sort
|
|
992
|
+
Note over Crud,Controller: body = filterCriteria JSON
|
|
993
|
+
|
|
994
|
+
Controller->>Controller: lê page,size,sort de query params
|
|
995
|
+
Controller->>Controller: PageableBuilder.from(page,size,sort,...)
|
|
996
|
+
Controller->>Service: filterMappedWithIncludeIds(filterDTO, pageable, includeIds, toDto)
|
|
997
|
+
|
|
998
|
+
Service->>Builder: buildSpecification(filterDTO, pageable)
|
|
999
|
+
Builder->>Builder: inspeciona campos @Filterable do DTO
|
|
1000
|
+
Builder-->>Service: Specification pronta
|
|
1001
|
+
Service->>Repo: findAll(specification, pageable)
|
|
1002
|
+
Repo-->>Service: Page<Entity>
|
|
1003
|
+
Service-->>Controller: Page<DTO>
|
|
1004
|
+
|
|
1005
|
+
Controller->>Controller: mapeia para EntityModel<DTO> e monta RestApiResponse.success(...)
|
|
1006
|
+
Controller-->>Crud: HTTP 200
|
|
1007
|
+
Crud->>Crud: unwrapPageResponse(...)
|
|
1008
|
+
Crud-->>Tabela: Page<T>
|
|
1009
|
+
Tabela->>Tabela: atualiza dataSubject, totalElements e paginator
|
|
948
1010
|
```
|
|
949
1011
|
|
|
950
|
-
### Pontos-Chave do Fluxo
|
|
1012
|
+
### Pontos-Chave do Fluxo Real
|
|
951
1013
|
|
|
952
|
-
1.
|
|
953
|
-
2.
|
|
954
|
-
3.
|
|
955
|
-
4.
|
|
956
|
-
5.
|
|
1014
|
+
1. **`resourcePath` não dispara só fetch**: em modo remoto, a tabela primeiro configura o `GenericCrudService` e pode carregar schema antes da primeira busca.
|
|
1015
|
+
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`.
|
|
1016
|
+
3. **O controller não recebe `Pageable` pronto do Spring nesse endpoint**: ele reconstrói o `Pageable` a partir de `page`, `size` e `sort`.
|
|
1017
|
+
4. **O backend do starter responde com `RestApiResponse<Page<...>>`**: o `GenericCrudService` faz `unwrapPageResponse(...)` para entregar `Page<T>` ao runtime da tabela.
|
|
1018
|
+
5. **A coluna ordenada pode mapear para `sortField`**: o `active` da UI não é necessariamente o campo final enviado ao backend.
|
|
957
1019
|
|
|
958
1020
|
## 🎨 Edição Visual da Tabela: O Poder do Low-Code
|
|
959
1021
|
|
|
@@ -1366,7 +1428,7 @@ Para documentação completa da API, consulte `projects/praxis-core/README.md`.
|
|
|
1366
1428
|
O `PraxisFilter` pode ser acoplado à barra de ferramentas da tabela. O exemplo abaixo mostra a busca de pessoas por CPF e status.
|
|
1367
1429
|
|
|
1368
1430
|
```html
|
|
1369
|
-
<praxis-filter [resourcePath]="'pessoas'" [formId]="'pessoas-filter'" [persistenceKey]="'pessoas-filter-v1'" [alwaysVisibleFields]="['status']" (
|
|
1431
|
+
<praxis-filter [resourcePath]="'pessoas'" [formId]="'pessoas-filter'" [persistenceKey]="'pessoas-filter-v1'" [alwaysVisibleFields]="['status']" (requestSearch)="onFilter($event)"></praxis-filter> <praxis-table [data]="tableData"></praxis-table>
|
|
1370
1432
|
```
|
|
1371
1433
|
|
|
1372
1434
|
```ts
|
|
@@ -1450,9 +1512,16 @@ Notas rápidas (Flow ETag no Filter):
|
|
|
1450
1512
|
|
|
1451
1513
|
## Formatação de Colunas (format)
|
|
1452
1514
|
|
|
1453
|
-
Cada coluna pode declarar `type` e uma string de formatação `format` consumida pelo `DataFormattingService`. Os tipos suportados são: `string`, `number`, `currency`, `percentage`, `date`, `boolean`, `custom`.
|
|
1515
|
+
Cada coluna pode declarar `type` e uma string de formatação `format` consumida pelo `DataFormattingService`. Os tipos suportados são: `string`, `number`, `currency`, `percentage`, `date`, `datetime`, `time`, `boolean`, `custom`.
|
|
1516
|
+
|
|
1517
|
+
Regra geral:
|
|
1518
|
+
- `format` explícito continua com precedência máxima.
|
|
1519
|
+
- Para `number`, `currency`, `percentage`, `date`, `datetime` e `time`, a tabela também consegue derivar formatação básica a partir de `type + config.localization`, mesmo quando `format` estiver ausente.
|
|
1520
|
+
- `string`, `boolean` e `custom` continuam conservadores; nesses casos, use `format` explícito quando precisar de transformação.
|
|
1454
1521
|
|
|
1455
|
-
|
|
1522
|
+
Nota de plataforma:
|
|
1523
|
+
- o contrato público da tabela continua sendo `column.type + config.localization + format`.
|
|
1524
|
+
- a tabela converge internamente para a semântica canônica horizontal do core, mas não expõe `valuePresentation` como bloco público de configuração de coluna.
|
|
1456
1525
|
|
|
1457
1526
|
Tipos e padrões de `format`:
|
|
1458
1527
|
- number (DecimalPipe)
|
|
@@ -1484,10 +1553,30 @@ Exemplos de ColumnDefinition:
|
|
|
1484
1553
|
{ field: 'ativo', type: 'boolean', format: 'yes-no', header: 'Ativo' }
|
|
1485
1554
|
```
|
|
1486
1555
|
|
|
1556
|
+
Exemplos com defaults implícitos por `type + localization`:
|
|
1557
|
+
```ts
|
|
1558
|
+
{
|
|
1559
|
+
localization: {
|
|
1560
|
+
locale: 'pt-BR',
|
|
1561
|
+
currency: { code: 'BRL', symbol: 'R$', position: 'before', spacing: true, precision: 2 },
|
|
1562
|
+
dateTime: { dateFormat: 'dd/MM/yyyy', timeFormat: 'HH:mm', dateTimeFormat: 'dd/MM/yyyy HH:mm', firstDayOfWeek: 1 },
|
|
1563
|
+
number: { decimalSeparator: ',', thousandsSeparator: '.', defaultPrecision: 2, negativeSign: '-', negativeSignPosition: 'before' },
|
|
1564
|
+
},
|
|
1565
|
+
columns: [
|
|
1566
|
+
{ field: 'salario', type: 'currency', header: 'Salário' },
|
|
1567
|
+
{ field: 'criadoEm', type: 'date', header: 'Criado em' },
|
|
1568
|
+
{ field: 'taxa', type: 'percentage', header: 'Taxa' },
|
|
1569
|
+
],
|
|
1570
|
+
}
|
|
1571
|
+
```
|
|
1572
|
+
|
|
1487
1573
|
Observações:
|
|
1488
1574
|
- `|nosep` remove separadores de milhar da saída formatada.
|
|
1489
1575
|
- Para datas inválidas ou valores não numéricos, o serviço retorna o valor original (com aviso no console).
|
|
1490
1576
|
- Colunas com renderizador `custom` não passam por formatação automática.
|
|
1577
|
+
- Precedência de locale para formatação: `config.localization.locale` -> `LOCALE_ID` do host.
|
|
1578
|
+
- Quando `config.localization.currency` estiver presente, a tabela usa esse bloco como override para código, símbolo, posição, espaçamento e precisão da moeda.
|
|
1579
|
+
- Quando `config.localization.number` estiver presente, a tabela respeita `decimalSeparator`, `thousandsSeparator`, `defaultPrecision`, `negativeSign` e `negativeSignPosition` em number/currency/percentage.
|
|
1491
1580
|
|
|
1492
1581
|
Exemplos práticos no workspace (rotas):
|
|
1493
1582
|
- Regras Visuais (Simples): `/table-rules-simple`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { Inject, Component } from '@angular/core';
|
|
3
|
-
import * as
|
|
3
|
+
import * as i2 from '@angular/common';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
5
|
import * as i1 from '@angular/material/dialog';
|
|
6
6
|
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
|
@@ -115,7 +115,7 @@ class FilterFormDialogHostComponent {
|
|
|
115
115
|
{{ data.i18n?.apply || 'Aplicar' }}
|
|
116
116
|
</button>
|
|
117
117
|
</mat-dialog-actions>
|
|
118
|
-
`, isInline: true, styles: [".pfx-dialog-title{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-right:8px}.pfx-dialog-title-text{display:inline-flex;align-items:center;gap:8px;font-weight:600;color:var(--md-sys-color-on-surface)}.pfx-dialog-close{margin-left:auto}.pfx-filter-dialog-content{display:flex;flex-direction:column;gap:12px;padding-top:8px}.pfx-empty-state{margin:8px 0 0;color:var(--md-sys-color-on-surface-variant)}.pfx-dialog-actions{padding:var(--pdx-dialog-actions-padding, 12px 24px 16px);border-top:1px solid var(--md-sys-color-outline-variant);background:transparent;display:flex;align-items:center;gap:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type:
|
|
118
|
+
`, isInline: true, styles: [".pfx-dialog-title{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-right:8px}.pfx-dialog-title-text{display:inline-flex;align-items:center;gap:8px;font-weight:600;color:var(--md-sys-color-on-surface)}.pfx-dialog-close{margin-left:auto}.pfx-filter-dialog-content{display:flex;flex-direction:column;gap:12px;padding-top:8px}.pfx-empty-state{margin:8px 0 0;color:var(--md-sys-color-on-surface-variant)}.pfx-dialog-actions{padding:var(--pdx-dialog-actions-padding, 12px 24px 16px);border-top:1px solid var(--md-sys-color-outline-variant);background:transparent;display:flex;align-items:center;gap:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i15.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: PraxisFilterForm, selector: "praxis-filter-form", inputs: ["config", "formId", "resourcePath", "mode"], outputs: ["formReady", "valueChange", "submit", "requestSearch", "validityChange"] }] });
|
|
119
119
|
}
|
|
120
120
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: FilterFormDialogHostComponent, decorators: [{
|
|
121
121
|
type: Component,
|
|
@@ -163,4 +163,3 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
163
163
|
}] }, { type: i1.MatDialogRef }] });
|
|
164
164
|
|
|
165
165
|
export { FilterFormDialogHostComponent };
|
|
166
|
-
//# sourceMappingURL=praxisui-table-filter-form-dialog-host.component-C2rQnHE1.mjs.map
|