@praxisui/table 4.0.0-beta.0 → 5.0.0-beta.0
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
CHANGED
|
@@ -50,6 +50,8 @@ last_updated: "2026-03-07"
|
|
|
50
50
|
|
|
51
51
|
# @praxisui/table
|
|
52
52
|
|
|
53
|
+
> Estado canônico do workspace Angular: JSON Logic é o único contrato ativo de regras. Menções a DSL neste documento existem apenas como contexto histórico de migração ou referência para payloads legados.
|
|
54
|
+
|
|
53
55
|
## Documentation
|
|
54
56
|
|
|
55
57
|
- Documentação oficial: https://praxisui.dev
|
|
@@ -192,17 +194,17 @@ O novo editor é "column-first" e usa uma tipagem compartilhada com o Editor de
|
|
|
192
194
|
- Editores de valor dinâmicos: inputs numéricos, listas (CSV/múltipla seleção), datepickers.
|
|
193
195
|
- Grupos lógicos: construa condições com AND/OR/NOT e reordene via arrastar-e-soltar (CDK DragDrop).
|
|
194
196
|
- Preview: execute “Testar” para ver quantas linhas seriam afetadas pelas regras ativas.
|
|
195
|
-
- Import/Export: exporta JSON sem o campo `enabled`; importa com validação de
|
|
197
|
+
- Import/Export: exporta JSON sem o campo `enabled`; importa com validação estrutural de JSON Logic e sanitização de estilos (allowlist).
|
|
196
198
|
|
|
197
|
-
Exemplos de
|
|
199
|
+
Exemplos de JSON Logic:
|
|
198
200
|
|
|
199
|
-
```
|
|
200
|
-
contains
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
201
|
+
```json
|
|
202
|
+
{ "contains": [{ "var": "status" }, "Ativo"] }
|
|
203
|
+
{ "!": [{ "in": [{ "var": "status" }, ["A", "I"]] }] }
|
|
204
|
+
{ "and": [{ ">=": [{ "var": "price" }, 10] }, { "<=": [{ "var": "price" }, 20] }] }
|
|
205
|
+
{ "and": [{ ">=": [{ "var": "createdAt" }, "2024-10-01"] }, { "<=": [{ "var": "createdAt" }, "2024-10-31"] }] }
|
|
206
|
+
{ "or": [{ "==": [{ "var": "name" }, null] }, { "==": [{ "var": "name" }, ""] }] }
|
|
207
|
+
{ "==": [{ "var": "active" }, true] }
|
|
206
208
|
```
|
|
207
209
|
|
|
208
210
|
Notas sobre enum/CSV:
|
|
@@ -343,41 +345,15 @@ Notas
|
|
|
343
345
|
|
|
344
346
|
Onde é consumido (preview e runtime)
|
|
345
347
|
|
|
346
|
-
- Preview/validação no Editor de Regras
|
|
347
|
-
-
|
|
348
|
-
- Preview “Testar” (parse + evaluate): projects/praxis-table/src/lib/rules-editor/table-rules-editor.component.ts:909
|
|
348
|
+
- Preview/validação no Editor de Regras:
|
|
349
|
+
- Authoring canônico manual e visual em JSON Logic: `projects/praxis-table/src/lib/rules-editor/table-rules-editor.component.ts`
|
|
349
350
|
- Runtime na Tabela (aplica `rowConditionalStyles`/`conditionalStyles`):
|
|
350
|
-
-
|
|
351
|
+
- JSON Logic canônico + compatibilidade transitória de leitura DSL: `projects/praxis-table/src/lib/praxis-table.ts`
|
|
351
352
|
|
|
352
353
|
Observação
|
|
353
|
-
-
|
|
354
|
-
-
|
|
355
|
-
|
|
356
|
-
Exemplo de Provider (recomendado)
|
|
354
|
+
- JSON Logic é o contrato canônico para novas regras e para o editor de regras da tabela.
|
|
355
|
+
- O runtime ainda mantém compatibilidade transitória para regras DSL antigas.
|
|
357
356
|
|
|
358
|
-
```ts
|
|
359
|
-
import { Injectable } from '@angular/core';
|
|
360
|
-
import { FunctionRegistry } from '@praxisui/specification';
|
|
361
|
-
|
|
362
|
-
@Injectable({ providedIn: 'root' })
|
|
363
|
-
export class TableDslRegistryFactory {
|
|
364
|
-
private readonly registry = FunctionRegistry.getInstance<any>('orders-table-rules');
|
|
365
|
-
|
|
366
|
-
constructor() {
|
|
367
|
-
this.registry.clear();
|
|
368
|
-
this.registry.register('isStatus', (_row: any, value: any, expected: any) =>
|
|
369
|
-
String(value ?? '').toLowerCase() === String(expected ?? '').toLowerCase(),
|
|
370
|
-
);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
get(): FunctionRegistry<any> {
|
|
374
|
-
return this.registry;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
// Uso no host:
|
|
379
|
-
// <praxis-table [dslFunctionRegistry]="tableDslRegistryFactory.get()" ... />
|
|
380
|
-
```
|
|
381
357
|
|
|
382
358
|
### ⚙️ Painel de Configurações
|
|
383
359
|
|
|
@@ -771,7 +747,6 @@ sequenceDiagram
|
|
|
771
747
|
- `notifyIfOutdated: 'inline' | 'snackbar' | 'both' | 'none' = 'both'`
|
|
772
748
|
- `snoozeMs: number = 86400000`
|
|
773
749
|
- `autoOpenSettingsOnOutdated: boolean = false`
|
|
774
|
-
- `dslFunctionRegistry: FunctionRegistry<any> | null = null`
|
|
775
750
|
- Outputs:
|
|
776
751
|
- `schemaStatusChange: { outdated: boolean; serverHash?: string; lastVerifiedAt?: string; trigger?: string; tableId?: string }`
|
|
777
752
|
- Emitido tanto na verificação leve (304/200) quanto no bootstrap do schema (primeira carga via `loadSchema()`).
|
|
@@ -1543,7 +1518,6 @@ Veja também: `docs/host-crud-integration.md` (guia operacional host) e `project
|
|
|
1543
1518
|
- `notifyIfOutdated: 'inline' | 'snackbar' | 'both' | 'none' = 'both'` — seleciona como o runtime publica avisos de drift quando a política operacional estiver habilitada.
|
|
1544
1519
|
- `snoozeMs: number = 86400000` — tempo de soneca para avisos (ms).
|
|
1545
1520
|
- `autoOpenSettingsOnOutdated: boolean = false` — abre Configurações ao detectar schema desatualizado.
|
|
1546
|
-
- `dslFunctionRegistry: FunctionRegistry<any> | null = null` — adiciona funções DSL custom sem substituir o registry nativo.
|
|
1547
1521
|
- Output:
|
|
1548
1522
|
- `schemaStatusChange: { outdated: boolean; serverHash?: string; lastVerifiedAt?: string; tableId?: string }` — emitido após verificação leve (304/200).
|
|
1549
1523
|
|
|
@@ -1686,3 +1660,4 @@ Apache-2.0 — consulte `LICENSE` na raiz do workspace para detalhes.
|
|
|
1686
1660
|
**Parte do Praxis UI Workspace**
|
|
1687
1661
|
**Versão**: 2.0.0 (Unified Architecture)
|
|
1688
1662
|
**Compatibilidade**: Angular 18+
|
|
1663
|
+
|
|
@@ -591,6 +591,20 @@ Columns Analysis:
|
|
|
591
591
|
'behavior.expansion.detail.source.inlineSchema',
|
|
592
592
|
'behavior.expansion.detail.source.resourcePath.paramsMap',
|
|
593
593
|
]);
|
|
594
|
+
const jsonLogicObjectPaths = new Set([
|
|
595
|
+
'columns[].computed.expression',
|
|
596
|
+
'columns[].conditionalStyles[].condition',
|
|
597
|
+
'columns[].conditionalRenderers[].condition',
|
|
598
|
+
'rowConditionalStyles[].condition',
|
|
599
|
+
'toolbar.actions[].visibleWhen',
|
|
600
|
+
'toolbar.actions[].children[].visibleWhen',
|
|
601
|
+
'actions.row.actions[].visibleWhen',
|
|
602
|
+
'actions.row.actions[].disabledWhen',
|
|
603
|
+
'columns[].renderer.button.disabledCondition',
|
|
604
|
+
'columns[].renderer.toggle.disabledCondition',
|
|
605
|
+
'columns[].conditionalRenderers[].renderer.button.disabledCondition',
|
|
606
|
+
'columns[].conditionalRenderers[].renderer.toggle.disabledCondition',
|
|
607
|
+
]);
|
|
594
608
|
const recurse = (obj, currentPath) => {
|
|
595
609
|
if (typeof obj !== 'object' || obj === null)
|
|
596
610
|
return obj;
|
|
@@ -613,30 +627,26 @@ Columns Analysis:
|
|
|
613
627
|
const prefixMatch = Array.from(allowedPaths).some(p => p.startsWith(newPath + '.') || p.startsWith(newPath + '['));
|
|
614
628
|
if (exactMatch || prefixMatch) {
|
|
615
629
|
if (exactMatch
|
|
616
|
-
&& passthroughObjectPaths.has(newPath)
|
|
630
|
+
&& (passthroughObjectPaths.has(newPath) || jsonLogicObjectPaths.has(newPath))
|
|
617
631
|
&& typeof obj[key] === 'object'
|
|
618
|
-
&& obj[key] !== null
|
|
632
|
+
&& obj[key] !== null
|
|
633
|
+
&& !Array.isArray(obj[key])) {
|
|
619
634
|
cleanObj[key] = obj[key];
|
|
620
635
|
continue;
|
|
621
636
|
}
|
|
622
|
-
const val = recurse(obj[key], newPath);
|
|
623
637
|
if (newPath === 'columns[].computed.expression') {
|
|
624
|
-
if (typeof
|
|
625
|
-
warnings.push(`Computed expression
|
|
638
|
+
if (!obj[key] || typeof obj[key] !== 'object' || Array.isArray(obj[key])) {
|
|
639
|
+
warnings.push(`Computed expression inválida: ${newPath} (deve ser Json Logic)`);
|
|
626
640
|
continue;
|
|
627
641
|
}
|
|
628
|
-
|
|
629
|
-
if (!trimmed) {
|
|
642
|
+
if (Object.keys(obj[key]).length === 0) {
|
|
630
643
|
warnings.push(`Computed expression vazia: ${newPath}`);
|
|
631
644
|
continue;
|
|
632
645
|
}
|
|
633
|
-
|
|
634
|
-
warnings.push(`Computed expression muito longa: ${newPath}`);
|
|
635
|
-
continue;
|
|
636
|
-
}
|
|
637
|
-
cleanObj[key] = trimmed;
|
|
646
|
+
cleanObj[key] = obj[key];
|
|
638
647
|
continue;
|
|
639
648
|
}
|
|
649
|
+
const val = recurse(obj[key], newPath);
|
|
640
650
|
// Se for objeto vazio após limpeza, não inclui (salvo se for intenção explicita de limpar config, mas patch geralmente é aditivo)
|
|
641
651
|
if (typeof val === 'object' && val !== null && !Array.isArray(val) && Object.keys(val).length === 0) {
|
|
642
652
|
// ignora
|