@praxisui/table 8.0.0-beta.30 → 8.0.0-beta.32
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 +41 -4
- package/fesm2022/praxisui-table-filter-form-dialog-host.component-DbwGIMjF.mjs +232 -0
- package/fesm2022/{praxisui-table-praxisui-table-DFBE5wpp.mjs → praxisui-table-praxisui-table-BoDxoDos.mjs} +10297 -9404
- package/fesm2022/praxisui-table-table-agentic-authoring-turn-flow-CretQI6Z.mjs +847 -0
- package/fesm2022/{praxisui-table-table-ai.adapter-7THXe94D.mjs → praxisui-table-table-ai.adapter-DW9a89Gl.mjs} +215 -94
- package/fesm2022/praxisui-table.mjs +1 -1
- package/filter-drawer-adapter/package.json +2 -1
- package/package.json +21 -20
- package/src/lib/praxis-table.json-api.md +2 -1
- package/{index.d.ts → types/praxisui-table.d.ts} +28 -10
- package/fesm2022/praxisui-table-filter-form-dialog-host.component-CN9JWFoa.mjs +0 -220
- package/fesm2022/praxisui-table-table-agentic-authoring-turn-flow-EigJf8mp.mjs +0 -335
- /package/{filter-drawer-adapter/index.d.ts → types/praxisui-table-filter-drawer-adapter.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -168,10 +168,21 @@ Filtro runtime:
|
|
|
168
168
|
- The table assistant is part of the global Praxis semantic copilot experience, not a standalone table patch bot.
|
|
169
169
|
- In customization mode, opening the assistant registers a `PraxisAssistantContextSnapshot` through `PraxisAssistantSessionRegistryService`.
|
|
170
170
|
- The table session identity follows `table:{routeKey}:{componentInstanceId || tableId}` so multiple tables on the same page can preserve separate assistant sessions.
|
|
171
|
-
- Minimizing the table shell keeps
|
|
171
|
+
- Minimizing the table shell keeps the governed session in `PraxisAssistantSessionRegistryService` with `presence: 'origin-anchor'`; the visual affordance returns to the table assistant trigger, which changes to the minimized state and reopens the preserved session. The App Shell does not interpret or execute table semantics.
|
|
172
172
|
- The table snapshot stores only safe context: table identity, target, context chips, manifest reference, resource path, schema field names, data/runtime digests, capability refs and governance hints.
|
|
173
173
|
- Prompts that indicate shared business decisions, such as rules, policies, compliance, LGPD, approval, eligibility or access control, must be routed to governed `domain-rules` handoff instead of local table config patches.
|
|
174
174
|
|
|
175
|
+
### Consultative answers vs governed edits
|
|
176
|
+
|
|
177
|
+
`@praxisui/table` declares two component-level response modes through its authoring context:
|
|
178
|
+
|
|
179
|
+
- `consult/answer`: use when the user asks a factual or how-to question about the current table. Examples: "qual endpoint esta servindo esta tabela?", "quais campos existem nesta tabela?", "quais recursos de estilização a tabela suporta?" and "como criar uma coluna que soma duas colunas?".
|
|
180
|
+
- `edit/componentEditPlan`: use when the user asks to apply or materialize a change. Examples: "mostre ativo como badge verde", "crie uma coluna bonus com 10% do salario", "deixe o avatar vermelho quando salario for maior que 30000" and "anime as linhas com salario acima de 30000".
|
|
181
|
+
|
|
182
|
+
Consultative answers are selected by the backend/LLM from the component `responseModes` contract and return `type: "info"`. The table runtime must not classify user intent through local keywords; it only sends grounded context such as `resourcePath`, schema fields and the table authoring manifest, then renders the orchestrator response without an apply action. For how-to or documentation-style turns, the orchestrator should explain the governed operation shape and give a safe example instead of collecting missing edit parameters.
|
|
183
|
+
|
|
184
|
+
Governed edits must be selected by the same backend/LLM response-mode decision and produce a validated `componentEditPlan`; the table compiles that plan into a patch and only then exposes the review/apply step.
|
|
185
|
+
|
|
175
186
|
## Migration Note
|
|
176
187
|
|
|
177
188
|
- This release treats `enableCustomization=false` as the canonical default.
|
|
@@ -295,6 +306,29 @@ animacao. `rowConditionalRenderers` fica tipado no contrato publico para tooltip
|
|
|
295
306
|
e animacao de linha, preservando os campos planos `tooltip`/`animation` como
|
|
296
307
|
fallback.
|
|
297
308
|
|
|
309
|
+
Animações condicionais devem ser authoradas como decisão semântica, não como CSS
|
|
310
|
+
manual em `style.animation`. Para animar a linha inteira, use
|
|
311
|
+
`rowConditionalRenderers[].animation`; para animar somente uma célula/coluna, use
|
|
312
|
+
`columns[].conditionalRenderers[].animation`. Prefira presets semânticos
|
|
313
|
+
(`info-soft`, `success-confirm`, `warning-attention`, `critical-alert`,
|
|
314
|
+
`audit-review`, `sync-pending` ou aliases como `pulse-soft`, `sla-breach`,
|
|
315
|
+
`risk-critical`) antes de `type` bruto. Exemplo:
|
|
316
|
+
|
|
317
|
+
```ts
|
|
318
|
+
rowConditionalRenderers: [
|
|
319
|
+
{
|
|
320
|
+
id: 'salario-alto-pulse',
|
|
321
|
+
condition: { '>': [{ var: 'salario' }, 30000] },
|
|
322
|
+
animation: { preset: 'pulse-soft', trigger: 'onAppear', intensity: 'subtle', repeat: 'once' },
|
|
323
|
+
enabled: true,
|
|
324
|
+
},
|
|
325
|
+
]
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
`appearance.animations.enabled = false` desativa animações; os flags
|
|
329
|
+
`appearance.animations.specific.row` e `appearance.animations.specific.cell`
|
|
330
|
+
desativam seletivamente animações condicionais de linha e célula.
|
|
331
|
+
|
|
298
332
|
Colunas calculadas usam `columns[].computed.expression` como AST JSON Logic
|
|
299
333
|
canonico. Regras, estilos e renderers condicionais podem referenciar esses
|
|
300
334
|
valores via `computed.<field>`. Quando uma coluna calculada depende de outra
|
|
@@ -1757,9 +1791,9 @@ Deteccao:
|
|
|
1757
1791
|
- somente quando `FieldDefinition.controlType === 'avatar'`
|
|
1758
1792
|
|
|
1759
1793
|
Renderer aplicado:
|
|
1760
|
-
- `renderer: { type: 'avatar', avatar: { srcField,
|
|
1794
|
+
- `renderer: { type: 'avatar', avatar: { srcField, initialsField: 'nomeCompleto', shape: 'circle', size: 32 } }`
|
|
1761
1795
|
- alinhamento central e largura compacta (~56px)
|
|
1762
|
-
- `
|
|
1796
|
+
- `initialsField` deriva as iniciais a partir de um campo textual bruto
|
|
1763
1797
|
|
|
1764
1798
|
Avatar explicito:
|
|
1765
1799
|
- `renderer: { type: 'avatar', avatar: { srcField, initialsExpr, initialsField, shape: 'circle', size: 28 } }`
|
|
@@ -1767,7 +1801,7 @@ Avatar explicito:
|
|
|
1767
1801
|
- `initialsExpr` deve retornar as iniciais prontas; ele nao transforma automaticamente um campo bruto em iniciais
|
|
1768
1802
|
- quando quiser derivar iniciais a partir de um campo textual, prefira `initialsField`
|
|
1769
1803
|
- exemplo recomendado: `avatar: { srcField: 'photoUrl', initialsField: 'name' }`
|
|
1770
|
-
- exemplo de `initialsExpr` explicito: `avatar: { initialsExpr:
|
|
1804
|
+
- exemplo de `initialsExpr` explicito: `avatar: { initialsExpr: 'initials' }`
|
|
1771
1805
|
|
|
1772
1806
|
Comportamento importante:
|
|
1773
1807
|
- a autodeteccao ocorre apenas no bootstrap (nao sobrescreve configuracoes de colunas persistidas)
|
|
@@ -1777,8 +1811,11 @@ Comportamento importante:
|
|
|
1777
1811
|
Ajustes comuns:
|
|
1778
1812
|
- `renderer.avatar.shape`: `'square' | 'rounded' | 'circle'`
|
|
1779
1813
|
- `renderer.avatar.size`: numero em px
|
|
1814
|
+
- `renderer.avatar.backgroundColor`: cor de fundo do circulo
|
|
1815
|
+
- `renderer.avatar.textColor`: cor das iniciais
|
|
1780
1816
|
- `renderer.avatar.alt` / `altField`
|
|
1781
1817
|
- use `conditionalRenderers` para variar renderer por linha
|
|
1818
|
+
- exemplo condicional: `condition: { ">": [{ "var": "salario" }, 30000] }` com `avatar: { initialsField: 'name', backgroundColor: '#D32F2F', textColor: '#FFFFFF' }`
|
|
1782
1819
|
|
|
1783
1820
|
A11y, seguranca e performance:
|
|
1784
1821
|
- `alt`/`altField` sao respeitados
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Inject, Component } from '@angular/core';
|
|
3
|
+
import * as i1 from '@angular/material/dialog';
|
|
4
|
+
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
|
5
|
+
import * as i3 from '@angular/material/button';
|
|
6
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
7
|
+
import * as i14 from '@angular/material/progress-bar';
|
|
8
|
+
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
9
|
+
import * as i4 from '@angular/material/icon';
|
|
10
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
11
|
+
import * as i10 from '@angular/material/tooltip';
|
|
12
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
13
|
+
import { PraxisFilterForm } from '@praxisui/dynamic-form';
|
|
14
|
+
|
|
15
|
+
class FilterFormDialogHostComponent {
|
|
16
|
+
data;
|
|
17
|
+
ref;
|
|
18
|
+
valid = true;
|
|
19
|
+
ready = false;
|
|
20
|
+
lastValue = {};
|
|
21
|
+
formGroup = null;
|
|
22
|
+
canSave = false;
|
|
23
|
+
saving = false;
|
|
24
|
+
constructor(data, ref) {
|
|
25
|
+
this.data = data;
|
|
26
|
+
this.ref = ref;
|
|
27
|
+
}
|
|
28
|
+
onReady(ev) {
|
|
29
|
+
try {
|
|
30
|
+
this.formGroup = ev?.formGroup || null;
|
|
31
|
+
const dto = this.data?.initialDto || {};
|
|
32
|
+
if (ev?.formGroup && dto && Object.keys(dto).length) {
|
|
33
|
+
ev.formGroup.patchValue(dto, { emitEvent: false });
|
|
34
|
+
}
|
|
35
|
+
this.lastValue = this.formGroup?.getRawValue?.() ?? this.lastValue;
|
|
36
|
+
}
|
|
37
|
+
catch { }
|
|
38
|
+
this.ready = true;
|
|
39
|
+
this.updateCanSave();
|
|
40
|
+
}
|
|
41
|
+
onChange(ev) {
|
|
42
|
+
this.lastValue = ev?.formData ?? {};
|
|
43
|
+
this.updateCanSave();
|
|
44
|
+
}
|
|
45
|
+
onValidity(v) {
|
|
46
|
+
this.valid = v;
|
|
47
|
+
this.updateCanSave();
|
|
48
|
+
}
|
|
49
|
+
apply() {
|
|
50
|
+
const formData = this.formGroup?.getRawValue?.() ??
|
|
51
|
+
this.lastValue ??
|
|
52
|
+
this.data?.initialDto ??
|
|
53
|
+
{};
|
|
54
|
+
this.ref.close({ formData });
|
|
55
|
+
}
|
|
56
|
+
close() { this.ref.close(); }
|
|
57
|
+
clean(obj) {
|
|
58
|
+
const out = {};
|
|
59
|
+
Object.keys(obj || {}).forEach((k) => {
|
|
60
|
+
const v = obj[k];
|
|
61
|
+
if (v !== '' && v !== null && v !== undefined)
|
|
62
|
+
out[k] = v;
|
|
63
|
+
});
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
buildDtoForSave() {
|
|
67
|
+
const base = this.data?.initialDto || {};
|
|
68
|
+
const current = this.formGroup?.getRawValue?.() ?? this.lastValue ?? {};
|
|
69
|
+
const merged = { ...base, ...current };
|
|
70
|
+
return this.clean(merged);
|
|
71
|
+
}
|
|
72
|
+
updateCanSave() {
|
|
73
|
+
this.canSave =
|
|
74
|
+
this.ready &&
|
|
75
|
+
this.valid &&
|
|
76
|
+
Object.keys(this.buildDtoForSave() || {}).length > 0;
|
|
77
|
+
}
|
|
78
|
+
saveShortcutTooltip() {
|
|
79
|
+
if (this.saving) {
|
|
80
|
+
return this.data.i18n?.shortcutSaving || 'Salvando atalho...';
|
|
81
|
+
}
|
|
82
|
+
if (!this.valid) {
|
|
83
|
+
return this.data.i18n?.shortcutInvalid || 'Corrija os filtros antes de salvar o atalho.';
|
|
84
|
+
}
|
|
85
|
+
if (!Object.keys(this.buildDtoForSave() || {}).length) {
|
|
86
|
+
return this.data.i18n?.shortcutRequiresFilter || 'Preencha ao menos um filtro para salvar um atalho.';
|
|
87
|
+
}
|
|
88
|
+
return '';
|
|
89
|
+
}
|
|
90
|
+
saveShortcut() {
|
|
91
|
+
if (!this.canSave || this.saving)
|
|
92
|
+
return;
|
|
93
|
+
const dto = this.buildDtoForSave();
|
|
94
|
+
if (!Object.keys(dto).length)
|
|
95
|
+
return;
|
|
96
|
+
this.saving = true;
|
|
97
|
+
try {
|
|
98
|
+
this.data?.onSaveShortcut?.(dto);
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
this.saving = false;
|
|
102
|
+
this.updateCanSave();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: FilterFormDialogHostComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
106
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: FilterFormDialogHostComponent, isStandalone: true, selector: "praxis-filter-form-dialog-host", ngImport: i0, template: `
|
|
107
|
+
<div mat-dialog-title class="pfx-dialog-title" id="filterDialogTitle">
|
|
108
|
+
<div class="pfx-dialog-title-text">
|
|
109
|
+
<mat-icon>tune</mat-icon>
|
|
110
|
+
<span>{{ data.title || 'Filtro avançado' }}</span>
|
|
111
|
+
</div>
|
|
112
|
+
<button mat-icon-button type="button" class="pfx-dialog-close" (click)="close()"
|
|
113
|
+
[attr.aria-label]="data.i18n?.cancel || 'Fechar'">
|
|
114
|
+
<mat-icon>close</mat-icon>
|
|
115
|
+
</button>
|
|
116
|
+
</div>
|
|
117
|
+
<mat-dialog-content class="pfx-filter-dialog-content" aria-labelledby="filterDialogTitle">
|
|
118
|
+
@if (data?.schemaLoading) {
|
|
119
|
+
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
|
120
|
+
}
|
|
121
|
+
@if (data?.config && !ready) {
|
|
122
|
+
<div
|
|
123
|
+
class="pfx-dialog-loading"
|
|
124
|
+
role="status"
|
|
125
|
+
aria-live="polite"
|
|
126
|
+
>
|
|
127
|
+
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
|
128
|
+
<span>{{ data.i18n?.opening || 'Carregando filtros...' }}</span>
|
|
129
|
+
</div>
|
|
130
|
+
}
|
|
131
|
+
@if (data?.config) {
|
|
132
|
+
<praxis-filter-form
|
|
133
|
+
[class.pfx-form-pending]="!ready"
|
|
134
|
+
[formId]="data.formId"
|
|
135
|
+
[resourcePath]="data.resourcePath"
|
|
136
|
+
[mode]="'edit'"
|
|
137
|
+
[config]="data.config"
|
|
138
|
+
(formReady)="onReady($event)"
|
|
139
|
+
(valueChange)="onChange($event)"
|
|
140
|
+
(validityChange)="onValidity($event)"
|
|
141
|
+
></praxis-filter-form>
|
|
142
|
+
}
|
|
143
|
+
@if (!data?.config && !data?.schemaLoading) {
|
|
144
|
+
<p class="pfx-empty-state">{{ data.i18n?.noData || 'Nenhum dado' }}</p>
|
|
145
|
+
}
|
|
146
|
+
</mat-dialog-content>
|
|
147
|
+
<mat-dialog-actions align="end" class="pfx-dialog-actions">
|
|
148
|
+
@if (data?.allowSaveTags) {
|
|
149
|
+
<button mat-stroked-button type="button"
|
|
150
|
+
class="pfx-save-shortcut-button"
|
|
151
|
+
[disabled]="!canSave || saving"
|
|
152
|
+
[matTooltip]="saveShortcutTooltip()"
|
|
153
|
+
[matTooltipDisabled]="canSave && !saving"
|
|
154
|
+
(click)="saveShortcut()">
|
|
155
|
+
<mat-icon aria-hidden="true">{{ saving ? 'hourglass_empty' : 'bookmark_add' }}</mat-icon>
|
|
156
|
+
{{ data.i18n?.saveAsShortcut || 'Salvar como atalho' }}
|
|
157
|
+
</button>
|
|
158
|
+
}
|
|
159
|
+
<button mat-stroked-button type="button" (click)="close()">{{ data.i18n?.cancel || 'Cancelar' }}</button>
|
|
160
|
+
<button mat-flat-button color="primary" (click)="apply()" [disabled]="!valid">
|
|
161
|
+
{{ data.i18n?.apply || 'Aplicar' }}
|
|
162
|
+
</button>
|
|
163
|
+
</mat-dialog-actions>
|
|
164
|
+
`, 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(--mdc-dialog-subhead-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(--mdc-dialog-supporting-text-color, var(--md-sys-color-on-surface-variant))}.pfx-dialog-loading{display:flex;flex-direction:column;gap:10px;min-height:128px;justify-content:center;color:var(--mdc-dialog-supporting-text-color, var(--md-sys-color-on-surface-variant));font-size:.875rem}.pfx-form-pending{height:0;overflow:hidden;visibility:hidden;pointer-events:none}.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}.pfx-save-shortcut-button{margin-right:auto}.pfx-save-shortcut-button mat-icon{margin-right:6px;width:18px;height:18px;font-size:18px}\n"], dependencies: [{ 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: i14.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: PraxisFilterForm, selector: "praxis-filter-form", inputs: ["config", "formId", "resourcePath", "mode"], outputs: ["formReady", "valueChange", "submit", "requestSearch", "validityChange"] }] });
|
|
165
|
+
}
|
|
166
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: FilterFormDialogHostComponent, decorators: [{
|
|
167
|
+
type: Component,
|
|
168
|
+
args: [{ selector: 'praxis-filter-form-dialog-host', standalone: true, imports: [MatDialogModule, MatButtonModule, MatProgressBarModule, MatIconModule, MatTooltipModule, PraxisFilterForm], template: `
|
|
169
|
+
<div mat-dialog-title class="pfx-dialog-title" id="filterDialogTitle">
|
|
170
|
+
<div class="pfx-dialog-title-text">
|
|
171
|
+
<mat-icon>tune</mat-icon>
|
|
172
|
+
<span>{{ data.title || 'Filtro avançado' }}</span>
|
|
173
|
+
</div>
|
|
174
|
+
<button mat-icon-button type="button" class="pfx-dialog-close" (click)="close()"
|
|
175
|
+
[attr.aria-label]="data.i18n?.cancel || 'Fechar'">
|
|
176
|
+
<mat-icon>close</mat-icon>
|
|
177
|
+
</button>
|
|
178
|
+
</div>
|
|
179
|
+
<mat-dialog-content class="pfx-filter-dialog-content" aria-labelledby="filterDialogTitle">
|
|
180
|
+
@if (data?.schemaLoading) {
|
|
181
|
+
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
|
182
|
+
}
|
|
183
|
+
@if (data?.config && !ready) {
|
|
184
|
+
<div
|
|
185
|
+
class="pfx-dialog-loading"
|
|
186
|
+
role="status"
|
|
187
|
+
aria-live="polite"
|
|
188
|
+
>
|
|
189
|
+
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
|
190
|
+
<span>{{ data.i18n?.opening || 'Carregando filtros...' }}</span>
|
|
191
|
+
</div>
|
|
192
|
+
}
|
|
193
|
+
@if (data?.config) {
|
|
194
|
+
<praxis-filter-form
|
|
195
|
+
[class.pfx-form-pending]="!ready"
|
|
196
|
+
[formId]="data.formId"
|
|
197
|
+
[resourcePath]="data.resourcePath"
|
|
198
|
+
[mode]="'edit'"
|
|
199
|
+
[config]="data.config"
|
|
200
|
+
(formReady)="onReady($event)"
|
|
201
|
+
(valueChange)="onChange($event)"
|
|
202
|
+
(validityChange)="onValidity($event)"
|
|
203
|
+
></praxis-filter-form>
|
|
204
|
+
}
|
|
205
|
+
@if (!data?.config && !data?.schemaLoading) {
|
|
206
|
+
<p class="pfx-empty-state">{{ data.i18n?.noData || 'Nenhum dado' }}</p>
|
|
207
|
+
}
|
|
208
|
+
</mat-dialog-content>
|
|
209
|
+
<mat-dialog-actions align="end" class="pfx-dialog-actions">
|
|
210
|
+
@if (data?.allowSaveTags) {
|
|
211
|
+
<button mat-stroked-button type="button"
|
|
212
|
+
class="pfx-save-shortcut-button"
|
|
213
|
+
[disabled]="!canSave || saving"
|
|
214
|
+
[matTooltip]="saveShortcutTooltip()"
|
|
215
|
+
[matTooltipDisabled]="canSave && !saving"
|
|
216
|
+
(click)="saveShortcut()">
|
|
217
|
+
<mat-icon aria-hidden="true">{{ saving ? 'hourglass_empty' : 'bookmark_add' }}</mat-icon>
|
|
218
|
+
{{ data.i18n?.saveAsShortcut || 'Salvar como atalho' }}
|
|
219
|
+
</button>
|
|
220
|
+
}
|
|
221
|
+
<button mat-stroked-button type="button" (click)="close()">{{ data.i18n?.cancel || 'Cancelar' }}</button>
|
|
222
|
+
<button mat-flat-button color="primary" (click)="apply()" [disabled]="!valid">
|
|
223
|
+
{{ data.i18n?.apply || 'Aplicar' }}
|
|
224
|
+
</button>
|
|
225
|
+
</mat-dialog-actions>
|
|
226
|
+
`, 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(--mdc-dialog-subhead-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(--mdc-dialog-supporting-text-color, var(--md-sys-color-on-surface-variant))}.pfx-dialog-loading{display:flex;flex-direction:column;gap:10px;min-height:128px;justify-content:center;color:var(--mdc-dialog-supporting-text-color, var(--md-sys-color-on-surface-variant));font-size:.875rem}.pfx-form-pending{height:0;overflow:hidden;visibility:hidden;pointer-events:none}.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}.pfx-save-shortcut-button{margin-right:auto}.pfx-save-shortcut-button mat-icon{margin-right:6px;width:18px;height:18px;font-size:18px}\n"] }]
|
|
227
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
228
|
+
type: Inject,
|
|
229
|
+
args: [MAT_DIALOG_DATA]
|
|
230
|
+
}] }, { type: i1.MatDialogRef }] });
|
|
231
|
+
|
|
232
|
+
export { FilterFormDialogHostComponent };
|