@praxisui/table-rule-builder 8.0.0-beta.9 → 8.0.0-beta.91
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
|
@@ -31,6 +31,44 @@ Peers (Angular v20): `@angular/core`, `@angular/common`, `@angular/forms`, `@ang
|
|
|
31
31
|
- Contrato runtime atual: animação é suportada em `rowConditionalRenderers` e `columns[].conditionalRenderers` (com precedência `rule.animation > rule.renderer.animation` e first-match por efeito real).
|
|
32
32
|
- Tipos: `RuleEffectDefinition`, `RuleScope`
|
|
33
33
|
|
|
34
|
+
## Conditional effects alignment
|
|
35
|
+
|
|
36
|
+
`RuleEffectsPanelComponent` edits one aggregate `RuleEffectDefinition` because a visual rule can combine style, layout, icon, background, animation and tooltip in a single authoring surface.
|
|
37
|
+
|
|
38
|
+
When the panel is embedded by `@praxisui/table`, the table rule entry stores the visual payload as `effects: RuleEffectDefinition[]`. That keeps the persisted rule aligned with the platform shape `PraxisRuntimeConditionalEffectRule<RuleEffectDefinition>` while preserving `@praxisui/table` as the owner of table placement into `rowConditionalRenderers`, `columns[].conditionalRenderers` and conditional style surfaces.
|
|
39
|
+
|
|
40
|
+
Existing singular `effects: RuleEffectDefinition` payloads are accepted on load and normalized back to the canonical array on apply.
|
|
41
|
+
|
|
34
42
|
## Testes
|
|
35
43
|
|
|
36
44
|
- Target oficial no workspace: `ng test praxis-table-rule-builder --watch=false --browsers=ChromeHeadless`
|
|
45
|
+
|
|
46
|
+
## Agentic Authoring Contract
|
|
47
|
+
|
|
48
|
+
`PRAXIS_TABLE_RULE_BUILDER_AUTHORING_MANIFEST` is the governed AI contract for this package and is exported from the public API.
|
|
49
|
+
|
|
50
|
+
The manifest owns only table rule visual effects:
|
|
51
|
+
|
|
52
|
+
- rule identity and condition/effect attachment
|
|
53
|
+
- supported effect categories from `EffectRegistryService`
|
|
54
|
+
- built-in `DEFAULT_EFFECT_PRESETS`
|
|
55
|
+
- semantic animation presets and aliases
|
|
56
|
+
- fail-closed conversion through `toCellClassAndStyle(...)`
|
|
57
|
+
|
|
58
|
+
It does not own table column, datasource, renderer placement or `TableConfigV2` semantics. Those changes must delegate to the `praxis-table` authoring manifest.
|
|
59
|
+
Operations that mutate the effect panel write canonical runtime surfaces: `RuleEffectDefinition`, `RuleEffectDefinition.animation`, `RuleEffectsPanelComponent.effectsForm`, `valueChange` and explicit `delegatedAuthoringOperations`.
|
|
60
|
+
The contract does not persist a local `ruleEffects.rules` tree.
|
|
61
|
+
|
|
62
|
+
Governed operation families:
|
|
63
|
+
|
|
64
|
+
- `rule.add`
|
|
65
|
+
- `rule.remove`
|
|
66
|
+
- `condition.set`
|
|
67
|
+
- `effect.add`
|
|
68
|
+
- `effect.update`
|
|
69
|
+
- `effect.remove`
|
|
70
|
+
- `preset.apply`
|
|
71
|
+
- `animation.set`
|
|
72
|
+
- `tableIntegration.delegate`
|
|
73
|
+
|
|
74
|
+
Stable identities are `ruleId`, `effectId` and `presetKey`; array indexes are not canonical identities. Destructive rule/effect removal requires explicit confirmation.
|
|
@@ -22,6 +22,7 @@ import * as i4 from '@angular/material/button-toggle';
|
|
|
22
22
|
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
|
23
23
|
import * as i6 from '@angular/material/slider';
|
|
24
24
|
import { MatSliderModule } from '@angular/material/slider';
|
|
25
|
+
import { PdxColorPickerComponent } from '@praxisui/dynamic-fields';
|
|
25
26
|
|
|
26
27
|
const RULE_ANIMATION_TYPE_SET = new Set([
|
|
27
28
|
'pulse',
|
|
@@ -237,18 +238,30 @@ class EstiloEditorComponent {
|
|
|
237
238
|
group;
|
|
238
239
|
// Public for template (strictTemplates): used by mat-slider
|
|
239
240
|
formatOpacity(v) { return (v ?? 0).toFixed(2); }
|
|
240
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
241
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
241
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: EstiloEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
242
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: EstiloEditorComponent, isStandalone: true, selector: "praxis-effects-estilo-editor", inputs: { group: "group" }, ngImport: i0, template: `
|
|
242
243
|
<div class="estilo-grid" role="group" aria-label="Editor de estilo" [formGroup]="group">
|
|
243
|
-
<
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
244
|
+
<pdx-color-picker
|
|
245
|
+
label="Cor do texto"
|
|
246
|
+
formControlName="color"
|
|
247
|
+
[format]="'hex'"
|
|
248
|
+
[preview]="true"
|
|
249
|
+
[views]="['gradient', 'palette']"
|
|
250
|
+
[paletteSettings]="{ preset: 'material', columns: 8 }"
|
|
251
|
+
[gradientSettings]="{ showOpacity: false, channel: 'hsv' }"
|
|
252
|
+
[popupSettings]="{ width: 340 }"
|
|
253
|
+
></pdx-color-picker>
|
|
247
254
|
|
|
248
|
-
<
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
255
|
+
<pdx-color-picker
|
|
256
|
+
label="Cor de fundo do texto"
|
|
257
|
+
formControlName="bgColor"
|
|
258
|
+
[format]="'hex'"
|
|
259
|
+
[preview]="true"
|
|
260
|
+
[views]="['gradient', 'palette']"
|
|
261
|
+
[paletteSettings]="{ preset: 'material', columns: 8 }"
|
|
262
|
+
[gradientSettings]="{ showOpacity: false, channel: 'hsv' }"
|
|
263
|
+
[popupSettings]="{ width: 340 }"
|
|
264
|
+
></pdx-color-picker>
|
|
252
265
|
|
|
253
266
|
<div class="toggles">
|
|
254
267
|
<mat-button-toggle-group multiple>
|
|
@@ -289,29 +302,41 @@ class EstiloEditorComponent {
|
|
|
289
302
|
</label>
|
|
290
303
|
</div>
|
|
291
304
|
</div>
|
|
292
|
-
`, isInline: true, styles: [".estilo-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;align-items:start}.toggles{display:flex;align-items:center;gap:8px}.sliders{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.slider{display:flex;flex-direction:column;gap:6px}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
305
|
+
`, isInline: true, styles: [".estilo-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;align-items:start}.toggles{display:flex;align-items:center;gap:8px}.sliders{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.slider{display:flex;flex-direction:column;gap:6px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i4.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i4.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: i6.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: i6.MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }, { kind: "component", type: PdxColorPickerComponent, selector: "pdx-color-picker", inputs: ["actionsLayout", "activeView", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "clearButton", "disabledMode", "readonlyMode", "visible", "presentationMode", "fillMode", "format", "gradientSettings", "icon", "iconClass", "svgIcon", "paletteSettings", "popupSettings", "preview", "rounded", "size", "tabindex", "views", "maxRecent", "showRecent"], outputs: ["valueChange", "open", "close", "cancel", "activeViewChange", "activeColorClick", "focusEvent", "blurEvent"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
293
306
|
}
|
|
294
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
307
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: EstiloEditorComponent, decorators: [{
|
|
295
308
|
type: Component,
|
|
296
309
|
args: [{ selector: 'praxis-effects-estilo-editor', standalone: true, imports: [
|
|
297
|
-
CommonModule,
|
|
298
310
|
ReactiveFormsModule,
|
|
299
311
|
MatFormFieldModule,
|
|
300
312
|
MatInputModule,
|
|
301
313
|
MatButtonToggleModule,
|
|
302
314
|
MatIconModule,
|
|
303
315
|
MatSliderModule,
|
|
316
|
+
PdxColorPickerComponent
|
|
304
317
|
], template: `
|
|
305
318
|
<div class="estilo-grid" role="group" aria-label="Editor de estilo" [formGroup]="group">
|
|
306
|
-
<
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
319
|
+
<pdx-color-picker
|
|
320
|
+
label="Cor do texto"
|
|
321
|
+
formControlName="color"
|
|
322
|
+
[format]="'hex'"
|
|
323
|
+
[preview]="true"
|
|
324
|
+
[views]="['gradient', 'palette']"
|
|
325
|
+
[paletteSettings]="{ preset: 'material', columns: 8 }"
|
|
326
|
+
[gradientSettings]="{ showOpacity: false, channel: 'hsv' }"
|
|
327
|
+
[popupSettings]="{ width: 340 }"
|
|
328
|
+
></pdx-color-picker>
|
|
310
329
|
|
|
311
|
-
<
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
330
|
+
<pdx-color-picker
|
|
331
|
+
label="Cor de fundo do texto"
|
|
332
|
+
formControlName="bgColor"
|
|
333
|
+
[format]="'hex'"
|
|
334
|
+
[preview]="true"
|
|
335
|
+
[views]="['gradient', 'palette']"
|
|
336
|
+
[paletteSettings]="{ preset: 'material', columns: 8 }"
|
|
337
|
+
[gradientSettings]="{ showOpacity: false, channel: 'hsv' }"
|
|
338
|
+
[popupSettings]="{ width: 340 }"
|
|
339
|
+
></pdx-color-picker>
|
|
315
340
|
|
|
316
341
|
<div class="toggles">
|
|
317
342
|
<mat-button-toggle-group multiple>
|
|
@@ -359,8 +384,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
359
384
|
|
|
360
385
|
class LayoutEditorComponent {
|
|
361
386
|
group;
|
|
362
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
363
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
387
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: LayoutEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
388
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: LayoutEditorComponent, isStandalone: true, selector: "praxis-effects-layout-editor", inputs: { group: "group" }, ngImport: i0, template: `
|
|
364
389
|
<div class="layout-grid" role="group" aria-label="Editor de layout" [formGroup]="group">
|
|
365
390
|
<div class="borders">
|
|
366
391
|
<span class="lbl">Borda</span>
|
|
@@ -401,11 +426,11 @@ class LayoutEditorComponent {
|
|
|
401
426
|
<input matInput type="number" formControlName="elevation" placeholder="6" />
|
|
402
427
|
</mat-form-field>
|
|
403
428
|
</div>
|
|
404
|
-
`, isInline: true, styles: [".layout-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;align-items:center}.borders,.align{display:flex;align-items:center;gap:8px}.lbl{font-size:.85rem;opacity:.8}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
429
|
+
`, isInline: true, styles: [".layout-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;align-items:center}.borders,.align{display:flex;align-items:center;gap:8px}.lbl{font-size:.85rem;opacity:.8}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i4.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i4.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
405
430
|
}
|
|
406
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
431
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: LayoutEditorComponent, decorators: [{
|
|
407
432
|
type: Component,
|
|
408
|
-
args: [{ selector: 'praxis-effects-layout-editor', standalone: true, imports: [
|
|
433
|
+
args: [{ selector: 'praxis-effects-layout-editor', standalone: true, imports: [ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatButtonToggleModule, MatIconModule], template: `
|
|
409
434
|
<div class="layout-grid" role="group" aria-label="Editor de layout" [formGroup]="group">
|
|
410
435
|
<div class="borders">
|
|
411
436
|
<span class="lbl">Borda</span>
|
|
@@ -453,8 +478,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
453
478
|
|
|
454
479
|
class IconeBadgeEditorComponent {
|
|
455
480
|
group;
|
|
456
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
457
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
481
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: IconeBadgeEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
482
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: IconeBadgeEditorComponent, isStandalone: true, selector: "praxis-effects-icone-badge-editor", inputs: { group: "group" }, ngImport: i0, template: `
|
|
458
483
|
<div class="icone-grid" role="group" aria-label="Editor de ícone e badge" [formGroup]="group">
|
|
459
484
|
<mat-form-field appearance="outline">
|
|
460
485
|
<mat-label>Ícone (mat-icon)</mat-label>
|
|
@@ -492,11 +517,11 @@ class IconeBadgeEditorComponent {
|
|
|
492
517
|
</mat-button-toggle-group>
|
|
493
518
|
</div>
|
|
494
519
|
</div>
|
|
495
|
-
`, isInline: true, styles: [".icone-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;align-items:center}.pos,.variant{display:flex;align-items:center;gap:8px}.lbl{font-size:.85rem;opacity:.8}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
520
|
+
`, isInline: true, styles: [".icone-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;align-items:center}.pos,.variant{display:flex;align-items:center;gap:8px}.lbl{font-size:.85rem;opacity:.8}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i4.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i4.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: MatIconModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
496
521
|
}
|
|
497
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
522
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: IconeBadgeEditorComponent, decorators: [{
|
|
498
523
|
type: Component,
|
|
499
|
-
args: [{ selector: 'praxis-effects-icone-badge-editor', standalone: true, imports: [
|
|
524
|
+
args: [{ selector: 'praxis-effects-icone-badge-editor', standalone: true, imports: [ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatButtonToggleModule, MatIconModule], template: `
|
|
500
525
|
<div class="icone-grid" role="group" aria-label="Editor de ícone e badge" [formGroup]="group">
|
|
501
526
|
<mat-form-field appearance="outline">
|
|
502
527
|
<mat-label>Ícone (mat-icon)</mat-label>
|
|
@@ -541,8 +566,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
541
566
|
|
|
542
567
|
class FundoEditorComponent {
|
|
543
568
|
group;
|
|
544
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
545
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
569
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: FundoEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
570
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: FundoEditorComponent, isStandalone: true, selector: "praxis-effects-fundo-editor", inputs: { group: "group" }, ngImport: i0, template: `
|
|
546
571
|
<div class="fundo-grid" role="group" aria-label="Editor de fundo" [formGroup]="group">
|
|
547
572
|
<mat-form-field appearance="outline">
|
|
548
573
|
<mat-label>Cor</mat-label>
|
|
@@ -566,11 +591,11 @@ class FundoEditorComponent {
|
|
|
566
591
|
</mat-slider>
|
|
567
592
|
</label>
|
|
568
593
|
</div>
|
|
569
|
-
`, isInline: true, styles: [".fundo-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;align-items:center}.full{grid-column:1 / -1}.slider{display:flex;flex-direction:column;gap:6px}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
594
|
+
`, isInline: true, styles: [".fundo-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;align-items:center}.full{grid-column:1 / -1}.slider{display:flex;flex-direction:column;gap:6px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: i6.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: i6.MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
570
595
|
}
|
|
571
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
596
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: FundoEditorComponent, decorators: [{
|
|
572
597
|
type: Component,
|
|
573
|
-
args: [{ selector: 'praxis-effects-fundo-editor', standalone: true, imports: [
|
|
598
|
+
args: [{ selector: 'praxis-effects-fundo-editor', standalone: true, imports: [ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatSliderModule], template: `
|
|
574
599
|
<div class="fundo-grid" role="group" aria-label="Editor de fundo" [formGroup]="group">
|
|
575
600
|
<mat-form-field appearance="outline">
|
|
576
601
|
<mat-label>Cor</mat-label>
|
|
@@ -601,8 +626,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
601
626
|
|
|
602
627
|
class AnimacaoEditorComponent {
|
|
603
628
|
group;
|
|
604
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
605
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
629
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AnimacaoEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
630
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: AnimacaoEditorComponent, isStandalone: true, selector: "praxis-effects-animacao-editor", inputs: { group: "group" }, ngImport: i0, template: `
|
|
606
631
|
<div class="anim-grid" role="group" aria-label="Editor de animação" [formGroup]="group">
|
|
607
632
|
<label class="anim-toggle">
|
|
608
633
|
<input type="checkbox" formControlName="enabled" />
|
|
@@ -677,11 +702,11 @@ class AnimacaoEditorComponent {
|
|
|
677
702
|
</select>
|
|
678
703
|
</mat-form-field>
|
|
679
704
|
</div>
|
|
680
|
-
`, isInline: true, styles: [".anim-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;align-items:center}.anim-toggle{grid-column:1 / -1;display:inline-flex;align-items:center;gap:8px;color:inherit;font-size:.9rem}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
705
|
+
`, isInline: true, styles: [".anim-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;align-items:center}.anim-toggle{grid-column:1 / -1;display:inline-flex;align-items:center;gap:8px;color:inherit;font-size:.9rem}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
681
706
|
}
|
|
682
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
707
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AnimacaoEditorComponent, decorators: [{
|
|
683
708
|
type: Component,
|
|
684
|
-
args: [{ selector: 'praxis-effects-animacao-editor', standalone: true, imports: [
|
|
709
|
+
args: [{ selector: 'praxis-effects-animacao-editor', standalone: true, imports: [ReactiveFormsModule, MatFormFieldModule, MatInputModule], template: `
|
|
685
710
|
<div class="anim-grid" role="group" aria-label="Editor de animação" [formGroup]="group">
|
|
686
711
|
<label class="anim-toggle">
|
|
687
712
|
<input type="checkbox" formControlName="enabled" />
|
|
@@ -763,8 +788,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
763
788
|
|
|
764
789
|
class TooltipEditorComponent {
|
|
765
790
|
group;
|
|
766
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
767
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
791
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: TooltipEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
792
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: TooltipEditorComponent, isStandalone: true, selector: "praxis-effects-tooltip-editor", inputs: { group: "group" }, ngImport: i0, template: `
|
|
768
793
|
<div class="tooltip-grid" role="group" aria-label="Editor de tooltip" [formGroup]="group">
|
|
769
794
|
<mat-form-field appearance="outline" class="full">
|
|
770
795
|
<mat-label>Texto</mat-label>
|
|
@@ -788,11 +813,11 @@ class TooltipEditorComponent {
|
|
|
788
813
|
<input matInput type="number" formControlName="delayMs" placeholder="300" />
|
|
789
814
|
</mat-form-field>
|
|
790
815
|
</div>
|
|
791
|
-
`, isInline: true, styles: [".tooltip-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;align-items:center}.full{grid-column:1 / -1}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
816
|
+
`, isInline: true, styles: [".tooltip-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;align-items:center}.full{grid-column:1 / -1}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
792
817
|
}
|
|
793
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
818
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: TooltipEditorComponent, decorators: [{
|
|
794
819
|
type: Component,
|
|
795
|
-
args: [{ selector: 'praxis-effects-tooltip-editor', standalone: true, imports: [
|
|
820
|
+
args: [{ selector: 'praxis-effects-tooltip-editor', standalone: true, imports: [ReactiveFormsModule, MatFormFieldModule, MatInputModule], template: `
|
|
796
821
|
<div class="tooltip-grid" role="group" aria-label="Editor de tooltip" [formGroup]="group">
|
|
797
822
|
<mat-form-field appearance="outline" class="full">
|
|
798
823
|
<mat-label>Texto</mat-label>
|
|
@@ -832,10 +857,10 @@ class EffectRegistryService {
|
|
|
832
857
|
list() {
|
|
833
858
|
return this.plugins.slice();
|
|
834
859
|
}
|
|
835
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
836
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
860
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: EffectRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
861
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: EffectRegistryService, providedIn: 'root' });
|
|
837
862
|
}
|
|
838
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
863
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: EffectRegistryService, decorators: [{
|
|
839
864
|
type: Injectable,
|
|
840
865
|
args: [{ providedIn: 'root' }]
|
|
841
866
|
}] });
|
|
@@ -1183,10 +1208,10 @@ class RuleEffectsPanelComponent {
|
|
|
1183
1208
|
const parsed = Number(value);
|
|
1184
1209
|
return Number.isFinite(parsed) && parsed >= 0 ? Math.round(parsed) : undefined;
|
|
1185
1210
|
}
|
|
1186
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1187
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: RuleEffectsPanelComponent, isStandalone: true, selector: "praxis-rule-effects-panel", inputs: { scope: "scope", value: "value" }, outputs: { valueChange: "valueChange", apply: "apply", reset: "reset" }, ngImport: i0, template: "<div class=\"rulefx\">\n <header class=\"rulefx__header\">\n <h3 class=\"rulefx__title\">{{ t('panel.title') }}</h3>\n <p class=\"rulefx__subtitle\">{{ t('panel.subtitle') }}</p>\n <div class=\"rulefx__actions\">\n <button mat-stroked-button type=\"button\" [matMenuTriggerFor]=\"presetsMenu\" [attr.aria-label]=\"t('presets.label')\" (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">\n <mat-icon>bookmarks</mat-icon>\n {{ t('presets.label') }}\n </button>\n <mat-menu #presetsMenu=\"matMenu\">\n <button mat-menu-item type=\"button\" (click)=\"applyPreset('aprovado')\"><mat-icon>check_circle</mat-icon> Aprovado</button>\n <button mat-menu-item type=\"button\" (click)=\"applyPreset('alerta')\"><mat-icon>warning</mat-icon> Alerta</button>\n <button mat-menu-item type=\"button\" (click)=\"applyPreset('erro')\"><mat-icon>error</mat-icon> Erro</button>\n <button mat-menu-item type=\"button\" (click)=\"applyPreset('info')\"><mat-icon>info</mat-icon> Info</button>\n </mat-menu>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"$event.stopPropagation(); onApply()\" (mousedown)=\"$event.stopPropagation()\" [attr.aria-label]=\"t('actions.apply')\" [matTooltip]=\"t('actions.apply')\" matTooltipPosition=\"below\">\n <mat-icon>done</mat-icon>\n {{ t('actions.apply') }}\n </button>\n <button mat-stroked-button type=\"button\" (click)=\"$event.stopPropagation(); onReset()\" (mousedown)=\"$event.stopPropagation()\" [attr.aria-label]=\"t('actions.reset')\" [matTooltip]=\"t('actions.reset')\" matTooltipPosition=\"below\">\n <mat-icon>restart_alt</mat-icon>\n {{ t('actions.reset') }}\n </button>\n </div>\n </header>\n\n <!-- Ribbon com seis categorias -->\n <nav\n class=\"rulefx__ribbon\"\n aria-label=\"Categorias de efeitos\"\n role=\"tablist\"\n (keydown)=\"onTabsKeydown($event)\"\n >\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'estilo'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'estilo'\"\n [attr.tabindex]=\"activeTab === 'estilo' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('estilo')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.estilo')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">text_format</span>\n <span>{{ t('tabs.estilo') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'layout'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'layout'\"\n [attr.tabindex]=\"activeTab === 'layout' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('layout')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.layout')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">view_quilt</span>\n <span>{{ t('tabs.layout') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'icone'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'icone'\"\n [attr.tabindex]=\"activeTab === 'icone' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('icone')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.icone')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">verified</span>\n <span>{{ t('tabs.icone') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'fundo'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'fundo'\"\n [attr.tabindex]=\"activeTab === 'fundo' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('fundo')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.fundo')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">gradient</span>\n <span>{{ t('tabs.fundo') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'animacao'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'animacao'\"\n [attr.tabindex]=\"activeTab === 'animacao' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('animacao')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.animacao')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">animation</span>\n <span>{{ t('tabs.animacao') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'tooltip'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'tooltip'\"\n [attr.tabindex]=\"activeTab === 'tooltip' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('tooltip')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.tooltip')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">info</span>\n <span>{{ t('tabs.tooltip') }}</span>\n </button>\n </nav>\n\n <!-- Quickbar contextual -->\n <section class=\"rulefx__quickbar\" aria-live=\"polite\" *ngIf=\"effectsForm\">\n <ng-container [ngSwitch]=\"activeTab\">\n <ng-container *ngSwitchCase=\"'estilo'\">\n <praxis-effects-estilo-editor [group]=\"estiloGroup\"></praxis-effects-estilo-editor>\n </ng-container>\n <ng-container *ngSwitchCase=\"'layout'\">\n <praxis-effects-layout-editor [group]=\"layoutGroup\"></praxis-effects-layout-editor>\n </ng-container>\n <ng-container *ngSwitchCase=\"'icone'\">\n <praxis-effects-icone-badge-editor [group]=\"iconBadgeGroup\"></praxis-effects-icone-badge-editor>\n </ng-container>\n <ng-container *ngSwitchCase=\"'fundo'\">\n <praxis-effects-fundo-editor [group]=\"backgroundGroup\"></praxis-effects-fundo-editor>\n </ng-container>\n <ng-container *ngSwitchCase=\"'animacao'\">\n <praxis-effects-animacao-editor [group]=\"animationGroup\"></praxis-effects-animacao-editor>\n </ng-container>\n <ng-container *ngSwitchCase=\"'tooltip'\">\n <praxis-effects-tooltip-editor [group]=\"tooltipGroup\"></praxis-effects-tooltip-editor>\n </ng-container>\n </ng-container>\n </section>\n\n <!-- Pr\u00E9-visualiza\u00E7\u00E3o e se\u00E7\u00E3o avan\u00E7ada -->\n <section class=\"rulefx__body\">\n <div class=\"rulefx__preview\">\n <div class=\"preview__title\">{{ t('preview.title') }}</div>\n\n <div\n class=\"preview__cell\"\n [ngStyle]=\"computeCellStyle(formValue)\"\n [ngClass]=\"computeCellClass(formValue)\"\n (mouseenter)=\"onHoverPreview(true)\"\n (mouseleave)=\"onHoverPreview(false)\"\n >\n <span\n *ngIf=\"formValue.iconBadge?.icon && formValue.iconBadge?.iconPos === 'before'\"\n class=\"material-icons preview__icon\"\n [style.color]=\"formValue.iconBadge?.iconColor\"\n >\n {{ formValue.iconBadge?.icon }}\n </span>\n\n <span class=\"preview__text\" [ngStyle]=\"computeTextStyle(formValue)\">\n Joana Silva \u2014 Ativo desde 2019\n </span>\n\n <span\n *ngIf=\"formValue.iconBadge?.badgeText\"\n class=\"preview__badge\"\n [ngStyle]=\"{ 'background': badgeBackground(formValue), 'border-color': badgeBorder(formValue) }\"\n >\n {{ formValue.iconBadge?.badgeText }}\n </span>\n\n <span\n *ngIf=\"formValue.iconBadge?.icon && formValue.iconBadge?.iconPos === 'after'\"\n class=\"material-icons preview__icon\"\n [style.color]=\"formValue.iconBadge?.iconColor\"\n >\n {{ formValue.iconBadge?.icon }}\n </span>\n </div>\n\n <p class=\"preview__hint\">{{ t('preview.hint') }}</p>\n </div>\n\n <div class=\"rulefx__advanced\">\n <details class=\"advanced__section\">\n <summary (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">{{ t('advanced.title') }}</summary>\n <div class=\"advanced__grid\" [formGroup]=\"effectsForm\">\n <label class=\"textctl\">\n <span>{{ t('advanced.description') }}</span>\n <input type=\"text\" formControlName=\"description\" placeholder=\"ex.: Destacar pre\u00E7os altos\" />\n </label>\n <label class=\"textctl\">\n <span>Classe CSS</span>\n <input type=\"text\" formControlName=\"cssClass\" placeholder=\"ex.: praxis-cell--alert\" />\n </label>\n <label class=\"textctl\">\n <span>Estilo inline</span>\n <input type=\"text\" formControlName=\"inlineStyle\" placeholder=\"ex.: text-shadow: 0 0 8px rgba(0,255,163,.5)\" />\n </label>\n </div>\n </details>\n </div>\n </section>\n</div>\n", styles: [".rulefx{background:linear-gradient(180deg,#171b24,#1e2431);border-radius:14px;color:#e7ecf6;border:1px solid rgba(255,255,255,.08);box-shadow:0 6px 24px #00000047;padding:12px}.rulefx__header{display:grid;grid-template-columns:1fr auto;align-items:center;gap:8px;margin-bottom:8px}.rulefx__title{margin:0;font-size:1.05rem}.rulefx__subtitle{margin:0;opacity:.75;font-size:.9rem}.rulefx__actions{display:inline-flex;gap:8px;align-items:center}.rulefx__ribbon{display:flex;gap:6px;padding:8px;border-radius:10px;background:linear-gradient(180deg,#202636,#1c2230);margin-bottom:8px}.ribbon__tab{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:10px;background:transparent;color:#e7ecf6;cursor:pointer;border:none}.ribbon__tab.is-active{background:linear-gradient(180deg,#2a3550,#243149);box-shadow:inset 0 0 0 1px #ffffff0a}.rulefx__quickbar{border:1px solid rgba(255,255,255,.08);border-radius:12px;padding:10px;background:linear-gradient(180deg,#202637,#1c2230);margin-bottom:10px}.rulefx__body{display:grid;grid-template-columns:1fr 320px;gap:12px}.rulefx__preview{border:1px solid rgba(255,255,255,.08);border-radius:12px;padding:12px;background:linear-gradient(180deg,#202637,#1c2230)}.preview__title{font-weight:600;margin-bottom:8px}.preview__cell{display:inline-flex;align-items:center;gap:8px;padding:10px 12px;border-radius:12px;background:#35d07f14;border:1px solid rgba(53,208,127,.25)}.preview__icon{font-size:18px;line-height:1}.preview__badge{font-size:.75rem;border-radius:999px;padding:2px 8px;border:1px solid transparent}.preview__hint{opacity:.7;font-size:.85rem;margin:8px 0 0}.rulefx__advanced .advanced__grid{display:grid;grid-template-columns:1fr;gap:8px}.rulefx__advanced .textctl{display:grid;gap:6px}.rulefx__advanced input[type=text]{background:#151a24;color:#e7ecf6;border:1px solid rgba(255,255,255,.08);border-radius:8px;padding:8px 10px}.anim--once{animation-iteration-count:1}.anim--loop{animation-iteration-count:infinite}.anim--count{animation-iteration-count:3}.anim--subtle{--pfx-preview-scale-peak: 1.01;--pfx-preview-min-opacity: .7;--pfx-preview-slide-distance: 2px;--pfx-preview-border-strength: .18}.anim--normal{--pfx-preview-scale-peak: 1.03;--pfx-preview-min-opacity: .45;--pfx-preview-slide-distance: 6px;--pfx-preview-border-strength: .3}.anim--strong{--pfx-preview-scale-peak: 1.05;--pfx-preview-min-opacity: .25;--pfx-preview-slide-distance: 8px;--pfx-preview-border-strength: .42}.anim--pulse{animation-name:pfxPulse;animation-duration:.8s;animation-timing-function:ease-in-out}.anim--blink{animation-name:pfxBlink;animation-duration:.7s}.anim--grow{animation-name:pfxGrow;animation-duration:.4s}.anim--fade{animation-name:pfxFade;animation-duration:.6s}.anim--slide-in{animation-name:pfxSlideIn;animation-duration:.3s}.anim--border-pulse{animation-name:pfxBorderPulse;animation-duration:.9s}@keyframes pfxPulse{0%{transform:scale(1)}50%{transform:scale(var(--pfx-preview-scale-peak, 1.03))}to{transform:scale(1)}}@keyframes pfxBlink{0%,49%{opacity:1}50%,to{opacity:var(--pfx-preview-min-opacity, .25)}}@keyframes pfxGrow{0%{transform:scale(.96)}to{transform:scale(1)}}@keyframes pfxFade{0%{opacity:0}to{opacity:1}}@keyframes pfxSlideIn{0%{transform:translateY(var(--pfx-preview-slide-distance, 6px));opacity:0}to{transform:translateY(0);opacity:1}}@keyframes pfxBorderPulse{0%,to{box-shadow:inset 0 0 #d32f2f00}50%{box-shadow:inset 0 0 0 2px rgba(211,47,47,var(--pfx-preview-border-strength, .3))}}.icon--overlay{position:relative}.icon--overlay .preview__icon{position:absolute;left:6px;top:6px}@media(prefers-reduced-motion:reduce){.preview__cell{animation:none!important;transition:none!important}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i3$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i3$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4$1.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: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i7.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i7.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "component", type: EstiloEditorComponent, selector: "praxis-effects-estilo-editor", inputs: ["group"] }, { kind: "component", type: LayoutEditorComponent, selector: "praxis-effects-layout-editor", inputs: ["group"] }, { kind: "component", type: IconeBadgeEditorComponent, selector: "praxis-effects-icone-badge-editor", inputs: ["group"] }, { kind: "component", type: FundoEditorComponent, selector: "praxis-effects-fundo-editor", inputs: ["group"] }, { kind: "component", type: AnimacaoEditorComponent, selector: "praxis-effects-animacao-editor", inputs: ["group"] }, { kind: "component", type: TooltipEditorComponent, selector: "praxis-effects-tooltip-editor", inputs: ["group"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1211
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: RuleEffectsPanelComponent, deps: [{ token: i1.FormBuilder }, { token: EffectRegistryService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1212
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: RuleEffectsPanelComponent, isStandalone: true, selector: "praxis-rule-effects-panel", inputs: { scope: "scope", value: "value" }, outputs: { valueChange: "valueChange", apply: "apply", reset: "reset" }, ngImport: i0, template: "<div class=\"rulefx\">\n <header class=\"rulefx__header\">\n <h3 class=\"rulefx__title\">{{ t('panel.title') }}</h3>\n <p class=\"rulefx__subtitle\">{{ t('panel.subtitle') }}</p>\n <div class=\"rulefx__actions\">\n <button mat-stroked-button type=\"button\" [matMenuTriggerFor]=\"presetsMenu\" [attr.aria-label]=\"t('presets.label')\" (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">\n <mat-icon>bookmarks</mat-icon>\n {{ t('presets.label') }}\n </button>\n <mat-menu #presetsMenu=\"matMenu\">\n <button mat-menu-item type=\"button\" (click)=\"applyPreset('aprovado')\"><mat-icon>check_circle</mat-icon> Aprovado</button>\n <button mat-menu-item type=\"button\" (click)=\"applyPreset('alerta')\"><mat-icon>warning</mat-icon> Alerta</button>\n <button mat-menu-item type=\"button\" (click)=\"applyPreset('erro')\"><mat-icon>error</mat-icon> Erro</button>\n <button mat-menu-item type=\"button\" (click)=\"applyPreset('info')\"><mat-icon>info</mat-icon> Info</button>\n </mat-menu>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"$event.stopPropagation(); onApply()\" (mousedown)=\"$event.stopPropagation()\" [attr.aria-label]=\"t('actions.apply')\" [matTooltip]=\"t('actions.apply')\" matTooltipPosition=\"below\">\n <mat-icon>done</mat-icon>\n {{ t('actions.apply') }}\n </button>\n <button mat-stroked-button type=\"button\" (click)=\"$event.stopPropagation(); onReset()\" (mousedown)=\"$event.stopPropagation()\" [attr.aria-label]=\"t('actions.reset')\" [matTooltip]=\"t('actions.reset')\" matTooltipPosition=\"below\">\n <mat-icon>restart_alt</mat-icon>\n {{ t('actions.reset') }}\n </button>\n </div>\n </header>\n\n <!-- Ribbon com seis categorias -->\n <nav\n class=\"rulefx__ribbon\"\n aria-label=\"Categorias de efeitos\"\n role=\"tablist\"\n (keydown)=\"onTabsKeydown($event)\"\n >\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'estilo'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'estilo'\"\n [attr.tabindex]=\"activeTab === 'estilo' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('estilo')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.estilo')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">text_format</span>\n <span>{{ t('tabs.estilo') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'layout'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'layout'\"\n [attr.tabindex]=\"activeTab === 'layout' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('layout')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.layout')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">view_quilt</span>\n <span>{{ t('tabs.layout') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'icone'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'icone'\"\n [attr.tabindex]=\"activeTab === 'icone' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('icone')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.icone')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">verified</span>\n <span>{{ t('tabs.icone') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'fundo'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'fundo'\"\n [attr.tabindex]=\"activeTab === 'fundo' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('fundo')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.fundo')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">gradient</span>\n <span>{{ t('tabs.fundo') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'animacao'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'animacao'\"\n [attr.tabindex]=\"activeTab === 'animacao' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('animacao')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.animacao')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">animation</span>\n <span>{{ t('tabs.animacao') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'tooltip'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'tooltip'\"\n [attr.tabindex]=\"activeTab === 'tooltip' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('tooltip')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.tooltip')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">info</span>\n <span>{{ t('tabs.tooltip') }}</span>\n </button>\n </nav>\n\n <!-- Quickbar contextual -->\n @if (effectsForm) {\n <section class=\"rulefx__quickbar\" aria-live=\"polite\">\n @switch (activeTab) {\n @case ('estilo') {\n <praxis-effects-estilo-editor [group]=\"estiloGroup\"></praxis-effects-estilo-editor>\n }\n @case ('layout') {\n <praxis-effects-layout-editor [group]=\"layoutGroup\"></praxis-effects-layout-editor>\n }\n @case ('icone') {\n <praxis-effects-icone-badge-editor [group]=\"iconBadgeGroup\"></praxis-effects-icone-badge-editor>\n }\n @case ('fundo') {\n <praxis-effects-fundo-editor [group]=\"backgroundGroup\"></praxis-effects-fundo-editor>\n }\n @case ('animacao') {\n <praxis-effects-animacao-editor [group]=\"animationGroup\"></praxis-effects-animacao-editor>\n }\n @case ('tooltip') {\n <praxis-effects-tooltip-editor [group]=\"tooltipGroup\"></praxis-effects-tooltip-editor>\n }\n }\n </section>\n }\n\n <!-- Pr\u00E9-visualiza\u00E7\u00E3o e se\u00E7\u00E3o avan\u00E7ada -->\n <section class=\"rulefx__body\">\n <div class=\"rulefx__preview\">\n <div class=\"preview__title\">{{ t('preview.title') }}</div>\n\n <div\n class=\"preview__cell\"\n [ngStyle]=\"computeCellStyle(formValue)\"\n [ngClass]=\"computeCellClass(formValue)\"\n (mouseenter)=\"onHoverPreview(true)\"\n (mouseleave)=\"onHoverPreview(false)\"\n >\n @if (formValue.iconBadge?.icon && formValue.iconBadge?.iconPos === 'before') {\n <span\n class=\"material-icons preview__icon\"\n [style.color]=\"formValue.iconBadge?.iconColor\"\n >\n {{ formValue.iconBadge?.icon }}\n </span>\n }\n\n <span class=\"preview__text\" [ngStyle]=\"computeTextStyle(formValue)\">\n Joana Silva \u2014 Ativo desde 2019\n </span>\n\n @if (formValue.iconBadge?.badgeText) {\n <span\n class=\"preview__badge\"\n [ngStyle]=\"{ 'background': badgeBackground(formValue), 'border-color': badgeBorder(formValue) }\"\n >\n {{ formValue.iconBadge?.badgeText }}\n </span>\n }\n\n @if (formValue.iconBadge?.icon && formValue.iconBadge?.iconPos === 'after') {\n <span\n class=\"material-icons preview__icon\"\n [style.color]=\"formValue.iconBadge?.iconColor\"\n >\n {{ formValue.iconBadge?.icon }}\n </span>\n }\n </div>\n\n <p class=\"preview__hint\">{{ t('preview.hint') }}</p>\n </div>\n\n <div class=\"rulefx__advanced\">\n <details class=\"advanced__section\">\n <summary (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">{{ t('advanced.title') }}</summary>\n <div class=\"advanced__grid\" [formGroup]=\"effectsForm\">\n <label class=\"textctl\">\n <span>{{ t('advanced.description') }}</span>\n <input type=\"text\" formControlName=\"description\" placeholder=\"ex.: Destacar pre\u00E7os altos\" />\n </label>\n <label class=\"textctl\">\n <span>Classe CSS</span>\n <input type=\"text\" formControlName=\"cssClass\" placeholder=\"ex.: praxis-cell--alert\" />\n </label>\n <label class=\"textctl\">\n <span>Estilo inline</span>\n <input type=\"text\" formControlName=\"inlineStyle\" placeholder=\"ex.: text-shadow: 0 0 8px rgba(0,255,163,.5)\" />\n </label>\n </div>\n </details>\n </div>\n </section>\n</div>\n", styles: [".rulefx{background:linear-gradient(180deg,#171b24,#1e2431);border-radius:14px;color:#e7ecf6;border:1px solid rgba(255,255,255,.08);box-shadow:0 6px 24px #00000047;padding:12px}.rulefx__header{display:grid;grid-template-columns:1fr auto;align-items:center;gap:8px;margin-bottom:8px}.rulefx__title{margin:0;font-size:1.05rem}.rulefx__subtitle{margin:0;opacity:.75;font-size:.9rem}.rulefx__actions{display:inline-flex;gap:8px;align-items:center}.rulefx__ribbon{display:flex;gap:6px;padding:8px;border-radius:10px;background:linear-gradient(180deg,#202636,#1c2230);margin-bottom:8px}.ribbon__tab{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:10px;background:transparent;color:#e7ecf6;cursor:pointer;border:none}.ribbon__tab.is-active{background:linear-gradient(180deg,#2a3550,#243149);box-shadow:inset 0 0 0 1px #ffffff0a}.rulefx__quickbar{border:1px solid rgba(255,255,255,.08);border-radius:12px;padding:10px;background:linear-gradient(180deg,#202637,#1c2230);margin-bottom:10px}.rulefx__body{display:grid;grid-template-columns:1fr 320px;gap:12px}.rulefx__preview{border:1px solid rgba(255,255,255,.08);border-radius:12px;padding:12px;background:linear-gradient(180deg,#202637,#1c2230)}.preview__title{font-weight:600;margin-bottom:8px}.preview__cell{display:inline-flex;align-items:center;gap:8px;padding:10px 12px;border-radius:12px;background:#35d07f14;border:1px solid rgba(53,208,127,.25)}.preview__icon{font-size:18px;line-height:1}.preview__badge{font-size:.75rem;border-radius:999px;padding:2px 8px;border:1px solid transparent}.preview__hint{opacity:.7;font-size:.85rem;margin:8px 0 0}.rulefx__advanced .advanced__grid{display:grid;grid-template-columns:1fr;gap:8px}.rulefx__advanced .textctl{display:grid;gap:6px}.rulefx__advanced input[type=text]{background:#151a24;color:#e7ecf6;border:1px solid rgba(255,255,255,.08);border-radius:8px;padding:8px 10px}.anim--once{animation-iteration-count:1}.anim--loop{animation-iteration-count:infinite}.anim--count{animation-iteration-count:3}.anim--subtle{--pfx-preview-scale-peak: 1.01;--pfx-preview-min-opacity: .7;--pfx-preview-slide-distance: 2px;--pfx-preview-border-strength: .18}.anim--normal{--pfx-preview-scale-peak: 1.03;--pfx-preview-min-opacity: .45;--pfx-preview-slide-distance: 6px;--pfx-preview-border-strength: .3}.anim--strong{--pfx-preview-scale-peak: 1.05;--pfx-preview-min-opacity: .25;--pfx-preview-slide-distance: 8px;--pfx-preview-border-strength: .42}.anim--pulse{animation-name:pfxPulse;animation-duration:.8s;animation-timing-function:ease-in-out}.anim--blink{animation-name:pfxBlink;animation-duration:.7s}.anim--grow{animation-name:pfxGrow;animation-duration:.4s}.anim--fade{animation-name:pfxFade;animation-duration:.6s}.anim--slide-in{animation-name:pfxSlideIn;animation-duration:.3s}.anim--border-pulse{animation-name:pfxBorderPulse;animation-duration:.9s}@keyframes pfxPulse{0%{transform:scale(1)}50%{transform:scale(var(--pfx-preview-scale-peak, 1.03))}to{transform:scale(1)}}@keyframes pfxBlink{0%,49%{opacity:1}50%,to{opacity:var(--pfx-preview-min-opacity, .25)}}@keyframes pfxGrow{0%{transform:scale(.96)}to{transform:scale(1)}}@keyframes pfxFade{0%{opacity:0}to{opacity:1}}@keyframes pfxSlideIn{0%{transform:translateY(var(--pfx-preview-slide-distance, 6px));opacity:0}to{transform:translateY(0);opacity:1}}@keyframes pfxBorderPulse{0%,to{box-shadow:inset 0 0 #d32f2f00}50%{box-shadow:inset 0 0 0 2px rgba(211,47,47,var(--pfx-preview-border-strength, .3))}}.icon--overlay{position:relative}.icon--overlay .preview__icon{position:absolute;left:6px;top:6px}@media(prefers-reduced-motion:reduce){.preview__cell{animation:none!important;transition:none!important}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4$1.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: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i6$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i7.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i7.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "component", type: EstiloEditorComponent, selector: "praxis-effects-estilo-editor", inputs: ["group"] }, { kind: "component", type: LayoutEditorComponent, selector: "praxis-effects-layout-editor", inputs: ["group"] }, { kind: "component", type: IconeBadgeEditorComponent, selector: "praxis-effects-icone-badge-editor", inputs: ["group"] }, { kind: "component", type: FundoEditorComponent, selector: "praxis-effects-fundo-editor", inputs: ["group"] }, { kind: "component", type: AnimacaoEditorComponent, selector: "praxis-effects-animacao-editor", inputs: ["group"] }, { kind: "component", type: TooltipEditorComponent, selector: "praxis-effects-tooltip-editor", inputs: ["group"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1188
1213
|
}
|
|
1189
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1214
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: RuleEffectsPanelComponent, decorators: [{
|
|
1190
1215
|
type: Component,
|
|
1191
1216
|
args: [{ selector: 'praxis-rule-effects-panel', standalone: true, imports: [
|
|
1192
1217
|
CommonModule,
|
|
@@ -1204,7 +1229,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
1204
1229
|
FundoEditorComponent,
|
|
1205
1230
|
AnimacaoEditorComponent,
|
|
1206
1231
|
TooltipEditorComponent,
|
|
1207
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"rulefx\">\n <header class=\"rulefx__header\">\n <h3 class=\"rulefx__title\">{{ t('panel.title') }}</h3>\n <p class=\"rulefx__subtitle\">{{ t('panel.subtitle') }}</p>\n <div class=\"rulefx__actions\">\n <button mat-stroked-button type=\"button\" [matMenuTriggerFor]=\"presetsMenu\" [attr.aria-label]=\"t('presets.label')\" (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">\n <mat-icon>bookmarks</mat-icon>\n {{ t('presets.label') }}\n </button>\n <mat-menu #presetsMenu=\"matMenu\">\n <button mat-menu-item type=\"button\" (click)=\"applyPreset('aprovado')\"><mat-icon>check_circle</mat-icon> Aprovado</button>\n <button mat-menu-item type=\"button\" (click)=\"applyPreset('alerta')\"><mat-icon>warning</mat-icon> Alerta</button>\n <button mat-menu-item type=\"button\" (click)=\"applyPreset('erro')\"><mat-icon>error</mat-icon> Erro</button>\n <button mat-menu-item type=\"button\" (click)=\"applyPreset('info')\"><mat-icon>info</mat-icon> Info</button>\n </mat-menu>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"$event.stopPropagation(); onApply()\" (mousedown)=\"$event.stopPropagation()\" [attr.aria-label]=\"t('actions.apply')\" [matTooltip]=\"t('actions.apply')\" matTooltipPosition=\"below\">\n <mat-icon>done</mat-icon>\n {{ t('actions.apply') }}\n </button>\n <button mat-stroked-button type=\"button\" (click)=\"$event.stopPropagation(); onReset()\" (mousedown)=\"$event.stopPropagation()\" [attr.aria-label]=\"t('actions.reset')\" [matTooltip]=\"t('actions.reset')\" matTooltipPosition=\"below\">\n <mat-icon>restart_alt</mat-icon>\n {{ t('actions.reset') }}\n </button>\n </div>\n </header>\n\n <!-- Ribbon com seis categorias -->\n <nav\n class=\"rulefx__ribbon\"\n aria-label=\"Categorias de efeitos\"\n role=\"tablist\"\n (keydown)=\"onTabsKeydown($event)\"\n >\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'estilo'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'estilo'\"\n [attr.tabindex]=\"activeTab === 'estilo' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('estilo')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.estilo')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">text_format</span>\n <span>{{ t('tabs.estilo') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'layout'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'layout'\"\n [attr.tabindex]=\"activeTab === 'layout' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('layout')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.layout')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">view_quilt</span>\n <span>{{ t('tabs.layout') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'icone'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'icone'\"\n [attr.tabindex]=\"activeTab === 'icone' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('icone')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.icone')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">verified</span>\n <span>{{ t('tabs.icone') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'fundo'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'fundo'\"\n [attr.tabindex]=\"activeTab === 'fundo' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('fundo')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.fundo')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">gradient</span>\n <span>{{ t('tabs.fundo') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'animacao'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'animacao'\"\n [attr.tabindex]=\"activeTab === 'animacao' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('animacao')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.animacao')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">animation</span>\n <span>{{ t('tabs.animacao') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'tooltip'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'tooltip'\"\n [attr.tabindex]=\"activeTab === 'tooltip' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('tooltip')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.tooltip')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">info</span>\n <span>{{ t('tabs.tooltip') }}</span>\n </button>\n </nav>\n\n <!-- Quickbar contextual -->\n <section class=\"rulefx__quickbar\" aria-live=\"polite\" *ngIf=\"effectsForm\">\n <ng-container [ngSwitch]=\"activeTab\">\n <ng-container *ngSwitchCase=\"'estilo'\">\n <praxis-effects-estilo-editor [group]=\"estiloGroup\"></praxis-effects-estilo-editor>\n </ng-container>\n <ng-container *ngSwitchCase=\"'layout'\">\n <praxis-effects-layout-editor [group]=\"layoutGroup\"></praxis-effects-layout-editor>\n </ng-container>\n <ng-container *ngSwitchCase=\"'icone'\">\n <praxis-effects-icone-badge-editor [group]=\"iconBadgeGroup\"></praxis-effects-icone-badge-editor>\n </ng-container>\n <ng-container *ngSwitchCase=\"'fundo'\">\n <praxis-effects-fundo-editor [group]=\"backgroundGroup\"></praxis-effects-fundo-editor>\n </ng-container>\n <ng-container *ngSwitchCase=\"'animacao'\">\n <praxis-effects-animacao-editor [group]=\"animationGroup\"></praxis-effects-animacao-editor>\n </ng-container>\n <ng-container *ngSwitchCase=\"'tooltip'\">\n <praxis-effects-tooltip-editor [group]=\"tooltipGroup\"></praxis-effects-tooltip-editor>\n </ng-container>\n </ng-container>\n </section>\n\n <!-- Pr\u00E9-visualiza\u00E7\u00E3o e se\u00E7\u00E3o avan\u00E7ada -->\n <section class=\"rulefx__body\">\n <div class=\"rulefx__preview\">\n <div class=\"preview__title\">{{ t('preview.title') }}</div>\n\n <div\n class=\"preview__cell\"\n [ngStyle]=\"computeCellStyle(formValue)\"\n [ngClass]=\"computeCellClass(formValue)\"\n (mouseenter)=\"onHoverPreview(true)\"\n (mouseleave)=\"onHoverPreview(false)\"\n >\n <span\n *ngIf=\"formValue.iconBadge?.icon && formValue.iconBadge?.iconPos === 'before'\"\n class=\"material-icons preview__icon\"\n [style.color]=\"formValue.iconBadge?.iconColor\"\n >\n {{ formValue.iconBadge?.icon }}\n </span>\n\n <span class=\"preview__text\" [ngStyle]=\"computeTextStyle(formValue)\">\n Joana Silva \u2014 Ativo desde 2019\n </span>\n\n <span\n *ngIf=\"formValue.iconBadge?.badgeText\"\n class=\"preview__badge\"\n [ngStyle]=\"{ 'background': badgeBackground(formValue), 'border-color': badgeBorder(formValue) }\"\n >\n {{ formValue.iconBadge?.badgeText }}\n </span>\n\n <span\n *ngIf=\"formValue.iconBadge?.icon && formValue.iconBadge?.iconPos === 'after'\"\n class=\"material-icons preview__icon\"\n [style.color]=\"formValue.iconBadge?.iconColor\"\n >\n {{ formValue.iconBadge?.icon }}\n </span>\n </div>\n\n <p class=\"preview__hint\">{{ t('preview.hint') }}</p>\n </div>\n\n <div class=\"rulefx__advanced\">\n <details class=\"advanced__section\">\n <summary (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">{{ t('advanced.title') }}</summary>\n <div class=\"advanced__grid\" [formGroup]=\"effectsForm\">\n <label class=\"textctl\">\n <span>{{ t('advanced.description') }}</span>\n <input type=\"text\" formControlName=\"description\" placeholder=\"ex.: Destacar pre\u00E7os altos\" />\n </label>\n <label class=\"textctl\">\n <span>Classe CSS</span>\n <input type=\"text\" formControlName=\"cssClass\" placeholder=\"ex.: praxis-cell--alert\" />\n </label>\n <label class=\"textctl\">\n <span>Estilo inline</span>\n <input type=\"text\" formControlName=\"inlineStyle\" placeholder=\"ex.: text-shadow: 0 0 8px rgba(0,255,163,.5)\" />\n </label>\n </div>\n </details>\n </div>\n </section>\n</div>\n", styles: [".rulefx{background:linear-gradient(180deg,#171b24,#1e2431);border-radius:14px;color:#e7ecf6;border:1px solid rgba(255,255,255,.08);box-shadow:0 6px 24px #00000047;padding:12px}.rulefx__header{display:grid;grid-template-columns:1fr auto;align-items:center;gap:8px;margin-bottom:8px}.rulefx__title{margin:0;font-size:1.05rem}.rulefx__subtitle{margin:0;opacity:.75;font-size:.9rem}.rulefx__actions{display:inline-flex;gap:8px;align-items:center}.rulefx__ribbon{display:flex;gap:6px;padding:8px;border-radius:10px;background:linear-gradient(180deg,#202636,#1c2230);margin-bottom:8px}.ribbon__tab{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:10px;background:transparent;color:#e7ecf6;cursor:pointer;border:none}.ribbon__tab.is-active{background:linear-gradient(180deg,#2a3550,#243149);box-shadow:inset 0 0 0 1px #ffffff0a}.rulefx__quickbar{border:1px solid rgba(255,255,255,.08);border-radius:12px;padding:10px;background:linear-gradient(180deg,#202637,#1c2230);margin-bottom:10px}.rulefx__body{display:grid;grid-template-columns:1fr 320px;gap:12px}.rulefx__preview{border:1px solid rgba(255,255,255,.08);border-radius:12px;padding:12px;background:linear-gradient(180deg,#202637,#1c2230)}.preview__title{font-weight:600;margin-bottom:8px}.preview__cell{display:inline-flex;align-items:center;gap:8px;padding:10px 12px;border-radius:12px;background:#35d07f14;border:1px solid rgba(53,208,127,.25)}.preview__icon{font-size:18px;line-height:1}.preview__badge{font-size:.75rem;border-radius:999px;padding:2px 8px;border:1px solid transparent}.preview__hint{opacity:.7;font-size:.85rem;margin:8px 0 0}.rulefx__advanced .advanced__grid{display:grid;grid-template-columns:1fr;gap:8px}.rulefx__advanced .textctl{display:grid;gap:6px}.rulefx__advanced input[type=text]{background:#151a24;color:#e7ecf6;border:1px solid rgba(255,255,255,.08);border-radius:8px;padding:8px 10px}.anim--once{animation-iteration-count:1}.anim--loop{animation-iteration-count:infinite}.anim--count{animation-iteration-count:3}.anim--subtle{--pfx-preview-scale-peak: 1.01;--pfx-preview-min-opacity: .7;--pfx-preview-slide-distance: 2px;--pfx-preview-border-strength: .18}.anim--normal{--pfx-preview-scale-peak: 1.03;--pfx-preview-min-opacity: .45;--pfx-preview-slide-distance: 6px;--pfx-preview-border-strength: .3}.anim--strong{--pfx-preview-scale-peak: 1.05;--pfx-preview-min-opacity: .25;--pfx-preview-slide-distance: 8px;--pfx-preview-border-strength: .42}.anim--pulse{animation-name:pfxPulse;animation-duration:.8s;animation-timing-function:ease-in-out}.anim--blink{animation-name:pfxBlink;animation-duration:.7s}.anim--grow{animation-name:pfxGrow;animation-duration:.4s}.anim--fade{animation-name:pfxFade;animation-duration:.6s}.anim--slide-in{animation-name:pfxSlideIn;animation-duration:.3s}.anim--border-pulse{animation-name:pfxBorderPulse;animation-duration:.9s}@keyframes pfxPulse{0%{transform:scale(1)}50%{transform:scale(var(--pfx-preview-scale-peak, 1.03))}to{transform:scale(1)}}@keyframes pfxBlink{0%,49%{opacity:1}50%,to{opacity:var(--pfx-preview-min-opacity, .25)}}@keyframes pfxGrow{0%{transform:scale(.96)}to{transform:scale(1)}}@keyframes pfxFade{0%{opacity:0}to{opacity:1}}@keyframes pfxSlideIn{0%{transform:translateY(var(--pfx-preview-slide-distance, 6px));opacity:0}to{transform:translateY(0);opacity:1}}@keyframes pfxBorderPulse{0%,to{box-shadow:inset 0 0 #d32f2f00}50%{box-shadow:inset 0 0 0 2px rgba(211,47,47,var(--pfx-preview-border-strength, .3))}}.icon--overlay{position:relative}.icon--overlay .preview__icon{position:absolute;left:6px;top:6px}@media(prefers-reduced-motion:reduce){.preview__cell{animation:none!important;transition:none!important}}\n"] }]
|
|
1232
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"rulefx\">\n <header class=\"rulefx__header\">\n <h3 class=\"rulefx__title\">{{ t('panel.title') }}</h3>\n <p class=\"rulefx__subtitle\">{{ t('panel.subtitle') }}</p>\n <div class=\"rulefx__actions\">\n <button mat-stroked-button type=\"button\" [matMenuTriggerFor]=\"presetsMenu\" [attr.aria-label]=\"t('presets.label')\" (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">\n <mat-icon>bookmarks</mat-icon>\n {{ t('presets.label') }}\n </button>\n <mat-menu #presetsMenu=\"matMenu\">\n <button mat-menu-item type=\"button\" (click)=\"applyPreset('aprovado')\"><mat-icon>check_circle</mat-icon> Aprovado</button>\n <button mat-menu-item type=\"button\" (click)=\"applyPreset('alerta')\"><mat-icon>warning</mat-icon> Alerta</button>\n <button mat-menu-item type=\"button\" (click)=\"applyPreset('erro')\"><mat-icon>error</mat-icon> Erro</button>\n <button mat-menu-item type=\"button\" (click)=\"applyPreset('info')\"><mat-icon>info</mat-icon> Info</button>\n </mat-menu>\n <button mat-flat-button color=\"primary\" type=\"button\" (click)=\"$event.stopPropagation(); onApply()\" (mousedown)=\"$event.stopPropagation()\" [attr.aria-label]=\"t('actions.apply')\" [matTooltip]=\"t('actions.apply')\" matTooltipPosition=\"below\">\n <mat-icon>done</mat-icon>\n {{ t('actions.apply') }}\n </button>\n <button mat-stroked-button type=\"button\" (click)=\"$event.stopPropagation(); onReset()\" (mousedown)=\"$event.stopPropagation()\" [attr.aria-label]=\"t('actions.reset')\" [matTooltip]=\"t('actions.reset')\" matTooltipPosition=\"below\">\n <mat-icon>restart_alt</mat-icon>\n {{ t('actions.reset') }}\n </button>\n </div>\n </header>\n\n <!-- Ribbon com seis categorias -->\n <nav\n class=\"rulefx__ribbon\"\n aria-label=\"Categorias de efeitos\"\n role=\"tablist\"\n (keydown)=\"onTabsKeydown($event)\"\n >\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'estilo'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'estilo'\"\n [attr.tabindex]=\"activeTab === 'estilo' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('estilo')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.estilo')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">text_format</span>\n <span>{{ t('tabs.estilo') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'layout'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'layout'\"\n [attr.tabindex]=\"activeTab === 'layout' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('layout')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.layout')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">view_quilt</span>\n <span>{{ t('tabs.layout') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'icone'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'icone'\"\n [attr.tabindex]=\"activeTab === 'icone' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('icone')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.icone')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">verified</span>\n <span>{{ t('tabs.icone') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'fundo'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'fundo'\"\n [attr.tabindex]=\"activeTab === 'fundo' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('fundo')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.fundo')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">gradient</span>\n <span>{{ t('tabs.fundo') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'animacao'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'animacao'\"\n [attr.tabindex]=\"activeTab === 'animacao' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('animacao')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.animacao')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">animation</span>\n <span>{{ t('tabs.animacao') }}</span>\n </button>\n <button\n class=\"ribbon__tab\"\n [class.is-active]=\"activeTab === 'tooltip'\"\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'tooltip'\"\n [attr.tabindex]=\"activeTab === 'tooltip' ? 0 : -1\"\n (click)=\"$event.stopPropagation(); setTab('tooltip')\"\n (mousedown)=\"$event.stopPropagation()\"\n [matTooltip]=\"t('tabs.tooltip')\"\n matTooltipPosition=\"below\"\n >\n <span class=\"material-icons\">info</span>\n <span>{{ t('tabs.tooltip') }}</span>\n </button>\n </nav>\n\n <!-- Quickbar contextual -->\n @if (effectsForm) {\n <section class=\"rulefx__quickbar\" aria-live=\"polite\">\n @switch (activeTab) {\n @case ('estilo') {\n <praxis-effects-estilo-editor [group]=\"estiloGroup\"></praxis-effects-estilo-editor>\n }\n @case ('layout') {\n <praxis-effects-layout-editor [group]=\"layoutGroup\"></praxis-effects-layout-editor>\n }\n @case ('icone') {\n <praxis-effects-icone-badge-editor [group]=\"iconBadgeGroup\"></praxis-effects-icone-badge-editor>\n }\n @case ('fundo') {\n <praxis-effects-fundo-editor [group]=\"backgroundGroup\"></praxis-effects-fundo-editor>\n }\n @case ('animacao') {\n <praxis-effects-animacao-editor [group]=\"animationGroup\"></praxis-effects-animacao-editor>\n }\n @case ('tooltip') {\n <praxis-effects-tooltip-editor [group]=\"tooltipGroup\"></praxis-effects-tooltip-editor>\n }\n }\n </section>\n }\n\n <!-- Pr\u00E9-visualiza\u00E7\u00E3o e se\u00E7\u00E3o avan\u00E7ada -->\n <section class=\"rulefx__body\">\n <div class=\"rulefx__preview\">\n <div class=\"preview__title\">{{ t('preview.title') }}</div>\n\n <div\n class=\"preview__cell\"\n [ngStyle]=\"computeCellStyle(formValue)\"\n [ngClass]=\"computeCellClass(formValue)\"\n (mouseenter)=\"onHoverPreview(true)\"\n (mouseleave)=\"onHoverPreview(false)\"\n >\n @if (formValue.iconBadge?.icon && formValue.iconBadge?.iconPos === 'before') {\n <span\n class=\"material-icons preview__icon\"\n [style.color]=\"formValue.iconBadge?.iconColor\"\n >\n {{ formValue.iconBadge?.icon }}\n </span>\n }\n\n <span class=\"preview__text\" [ngStyle]=\"computeTextStyle(formValue)\">\n Joana Silva \u2014 Ativo desde 2019\n </span>\n\n @if (formValue.iconBadge?.badgeText) {\n <span\n class=\"preview__badge\"\n [ngStyle]=\"{ 'background': badgeBackground(formValue), 'border-color': badgeBorder(formValue) }\"\n >\n {{ formValue.iconBadge?.badgeText }}\n </span>\n }\n\n @if (formValue.iconBadge?.icon && formValue.iconBadge?.iconPos === 'after') {\n <span\n class=\"material-icons preview__icon\"\n [style.color]=\"formValue.iconBadge?.iconColor\"\n >\n {{ formValue.iconBadge?.icon }}\n </span>\n }\n </div>\n\n <p class=\"preview__hint\">{{ t('preview.hint') }}</p>\n </div>\n\n <div class=\"rulefx__advanced\">\n <details class=\"advanced__section\">\n <summary (click)=\"$event.stopPropagation()\" (mousedown)=\"$event.stopPropagation()\">{{ t('advanced.title') }}</summary>\n <div class=\"advanced__grid\" [formGroup]=\"effectsForm\">\n <label class=\"textctl\">\n <span>{{ t('advanced.description') }}</span>\n <input type=\"text\" formControlName=\"description\" placeholder=\"ex.: Destacar pre\u00E7os altos\" />\n </label>\n <label class=\"textctl\">\n <span>Classe CSS</span>\n <input type=\"text\" formControlName=\"cssClass\" placeholder=\"ex.: praxis-cell--alert\" />\n </label>\n <label class=\"textctl\">\n <span>Estilo inline</span>\n <input type=\"text\" formControlName=\"inlineStyle\" placeholder=\"ex.: text-shadow: 0 0 8px rgba(0,255,163,.5)\" />\n </label>\n </div>\n </details>\n </div>\n </section>\n</div>\n", styles: [".rulefx{background:linear-gradient(180deg,#171b24,#1e2431);border-radius:14px;color:#e7ecf6;border:1px solid rgba(255,255,255,.08);box-shadow:0 6px 24px #00000047;padding:12px}.rulefx__header{display:grid;grid-template-columns:1fr auto;align-items:center;gap:8px;margin-bottom:8px}.rulefx__title{margin:0;font-size:1.05rem}.rulefx__subtitle{margin:0;opacity:.75;font-size:.9rem}.rulefx__actions{display:inline-flex;gap:8px;align-items:center}.rulefx__ribbon{display:flex;gap:6px;padding:8px;border-radius:10px;background:linear-gradient(180deg,#202636,#1c2230);margin-bottom:8px}.ribbon__tab{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:10px;background:transparent;color:#e7ecf6;cursor:pointer;border:none}.ribbon__tab.is-active{background:linear-gradient(180deg,#2a3550,#243149);box-shadow:inset 0 0 0 1px #ffffff0a}.rulefx__quickbar{border:1px solid rgba(255,255,255,.08);border-radius:12px;padding:10px;background:linear-gradient(180deg,#202637,#1c2230);margin-bottom:10px}.rulefx__body{display:grid;grid-template-columns:1fr 320px;gap:12px}.rulefx__preview{border:1px solid rgba(255,255,255,.08);border-radius:12px;padding:12px;background:linear-gradient(180deg,#202637,#1c2230)}.preview__title{font-weight:600;margin-bottom:8px}.preview__cell{display:inline-flex;align-items:center;gap:8px;padding:10px 12px;border-radius:12px;background:#35d07f14;border:1px solid rgba(53,208,127,.25)}.preview__icon{font-size:18px;line-height:1}.preview__badge{font-size:.75rem;border-radius:999px;padding:2px 8px;border:1px solid transparent}.preview__hint{opacity:.7;font-size:.85rem;margin:8px 0 0}.rulefx__advanced .advanced__grid{display:grid;grid-template-columns:1fr;gap:8px}.rulefx__advanced .textctl{display:grid;gap:6px}.rulefx__advanced input[type=text]{background:#151a24;color:#e7ecf6;border:1px solid rgba(255,255,255,.08);border-radius:8px;padding:8px 10px}.anim--once{animation-iteration-count:1}.anim--loop{animation-iteration-count:infinite}.anim--count{animation-iteration-count:3}.anim--subtle{--pfx-preview-scale-peak: 1.01;--pfx-preview-min-opacity: .7;--pfx-preview-slide-distance: 2px;--pfx-preview-border-strength: .18}.anim--normal{--pfx-preview-scale-peak: 1.03;--pfx-preview-min-opacity: .45;--pfx-preview-slide-distance: 6px;--pfx-preview-border-strength: .3}.anim--strong{--pfx-preview-scale-peak: 1.05;--pfx-preview-min-opacity: .25;--pfx-preview-slide-distance: 8px;--pfx-preview-border-strength: .42}.anim--pulse{animation-name:pfxPulse;animation-duration:.8s;animation-timing-function:ease-in-out}.anim--blink{animation-name:pfxBlink;animation-duration:.7s}.anim--grow{animation-name:pfxGrow;animation-duration:.4s}.anim--fade{animation-name:pfxFade;animation-duration:.6s}.anim--slide-in{animation-name:pfxSlideIn;animation-duration:.3s}.anim--border-pulse{animation-name:pfxBorderPulse;animation-duration:.9s}@keyframes pfxPulse{0%{transform:scale(1)}50%{transform:scale(var(--pfx-preview-scale-peak, 1.03))}to{transform:scale(1)}}@keyframes pfxBlink{0%,49%{opacity:1}50%,to{opacity:var(--pfx-preview-min-opacity, .25)}}@keyframes pfxGrow{0%{transform:scale(.96)}to{transform:scale(1)}}@keyframes pfxFade{0%{opacity:0}to{opacity:1}}@keyframes pfxSlideIn{0%{transform:translateY(var(--pfx-preview-slide-distance, 6px));opacity:0}to{transform:translateY(0);opacity:1}}@keyframes pfxBorderPulse{0%,to{box-shadow:inset 0 0 #d32f2f00}50%{box-shadow:inset 0 0 0 2px rgba(211,47,47,var(--pfx-preview-border-strength, .3))}}.icon--overlay{position:relative}.icon--overlay .preview__icon{position:absolute;left:6px;top:6px}@media(prefers-reduced-motion:reduce){.preview__cell{animation:none!important;transition:none!important}}\n"] }]
|
|
1208
1233
|
}], ctorParameters: () => [{ type: i1.FormBuilder }, { type: EffectRegistryService }], propDecorators: { scope: [{
|
|
1209
1234
|
type: Input
|
|
1210
1235
|
}], value: [{
|
|
@@ -1306,8 +1331,408 @@ function toCellClassAndStyle(effect, options) {
|
|
|
1306
1331
|
return { classList, style };
|
|
1307
1332
|
}
|
|
1308
1333
|
|
|
1334
|
+
const ruleAddSchema = {
|
|
1335
|
+
type: 'object',
|
|
1336
|
+
required: ['ruleId', 'scope'],
|
|
1337
|
+
properties: {
|
|
1338
|
+
ruleId: { type: 'string' },
|
|
1339
|
+
scope: { enum: ['cell', 'row', 'column', 'table'] },
|
|
1340
|
+
columnKey: { type: 'string' },
|
|
1341
|
+
condition: { type: 'object' },
|
|
1342
|
+
effect: { type: 'object' },
|
|
1343
|
+
insertAfterRuleId: { type: 'string' },
|
|
1344
|
+
},
|
|
1345
|
+
};
|
|
1346
|
+
const ruleRemoveSchema = {
|
|
1347
|
+
type: 'object',
|
|
1348
|
+
required: ['ruleId'],
|
|
1349
|
+
properties: {
|
|
1350
|
+
ruleId: { type: 'string' },
|
|
1351
|
+
removeEffects: { type: 'boolean' },
|
|
1352
|
+
preserveCondition: { type: 'boolean' },
|
|
1353
|
+
},
|
|
1354
|
+
};
|
|
1355
|
+
const conditionSetSchema = {
|
|
1356
|
+
type: 'object',
|
|
1357
|
+
required: ['ruleId', 'condition'],
|
|
1358
|
+
properties: {
|
|
1359
|
+
ruleId: { type: 'string' },
|
|
1360
|
+
condition: { type: 'object' },
|
|
1361
|
+
scope: { enum: ['cell', 'row', 'column', 'table'] },
|
|
1362
|
+
columnKey: { type: 'string' },
|
|
1363
|
+
mode: { enum: ['replace', 'merge'] },
|
|
1364
|
+
},
|
|
1365
|
+
};
|
|
1366
|
+
const effectAddSchema = {
|
|
1367
|
+
type: 'object',
|
|
1368
|
+
required: ['ruleId', 'effectId', 'effectType'],
|
|
1369
|
+
properties: {
|
|
1370
|
+
ruleId: { type: 'string' },
|
|
1371
|
+
effectId: { type: 'string' },
|
|
1372
|
+
effectType: {
|
|
1373
|
+
enum: ['estilo', 'layout', 'icone', 'fundo', 'animacao', 'tooltip'],
|
|
1374
|
+
},
|
|
1375
|
+
payload: { type: 'object' },
|
|
1376
|
+
},
|
|
1377
|
+
};
|
|
1378
|
+
const effectUpdateSchema = {
|
|
1379
|
+
type: 'object',
|
|
1380
|
+
required: ['ruleId', 'effectId', 'payload'],
|
|
1381
|
+
properties: {
|
|
1382
|
+
ruleId: { type: 'string' },
|
|
1383
|
+
effectId: { type: 'string' },
|
|
1384
|
+
payload: { type: 'object' },
|
|
1385
|
+
mode: { enum: ['replace', 'merge'] },
|
|
1386
|
+
},
|
|
1387
|
+
};
|
|
1388
|
+
const effectRemoveSchema = {
|
|
1389
|
+
type: 'object',
|
|
1390
|
+
required: ['ruleId', 'effectId'],
|
|
1391
|
+
properties: {
|
|
1392
|
+
ruleId: { type: 'string' },
|
|
1393
|
+
effectId: { type: 'string' },
|
|
1394
|
+
removeEmptyRule: { type: 'boolean' },
|
|
1395
|
+
},
|
|
1396
|
+
};
|
|
1397
|
+
const presetApplySchema = {
|
|
1398
|
+
type: 'object',
|
|
1399
|
+
required: ['ruleId', 'presetKey'],
|
|
1400
|
+
properties: {
|
|
1401
|
+
ruleId: { type: 'string' },
|
|
1402
|
+
presetKey: { enum: ['aprovado', 'alerta', 'erro', 'info'] },
|
|
1403
|
+
scope: { enum: ['cell', 'row', 'column', 'table'] },
|
|
1404
|
+
mergeWithExisting: { type: 'boolean' },
|
|
1405
|
+
},
|
|
1406
|
+
};
|
|
1407
|
+
const animationSetSchema = {
|
|
1408
|
+
type: 'object',
|
|
1409
|
+
required: ['ruleId', 'animation'],
|
|
1410
|
+
properties: {
|
|
1411
|
+
ruleId: { type: 'string' },
|
|
1412
|
+
effectId: { type: 'string' },
|
|
1413
|
+
animation: {
|
|
1414
|
+
type: 'object',
|
|
1415
|
+
properties: {
|
|
1416
|
+
enabled: { type: 'boolean' },
|
|
1417
|
+
preset: {
|
|
1418
|
+
enum: [
|
|
1419
|
+
'info-soft',
|
|
1420
|
+
'success-confirm',
|
|
1421
|
+
'warning-attention',
|
|
1422
|
+
'critical-alert',
|
|
1423
|
+
'audit-review',
|
|
1424
|
+
'sync-pending',
|
|
1425
|
+
'sla-warning',
|
|
1426
|
+
'sla-breach',
|
|
1427
|
+
'risk-elevated',
|
|
1428
|
+
'risk-critical',
|
|
1429
|
+
'audit-warning',
|
|
1430
|
+
'sync-warning',
|
|
1431
|
+
],
|
|
1432
|
+
},
|
|
1433
|
+
type: { enum: ['pulse', 'blink', 'grow', 'fade', 'slide-in', 'border-pulse'] },
|
|
1434
|
+
trigger: {
|
|
1435
|
+
enum: [
|
|
1436
|
+
'onChange',
|
|
1437
|
+
'onAppear',
|
|
1438
|
+
'onHover',
|
|
1439
|
+
'onConditionEnter',
|
|
1440
|
+
'onConditionExit',
|
|
1441
|
+
'onDataRefresh',
|
|
1442
|
+
],
|
|
1443
|
+
},
|
|
1444
|
+
repeat: {},
|
|
1445
|
+
durationMs: { type: 'number' },
|
|
1446
|
+
delayMs: { type: 'number' },
|
|
1447
|
+
intensity: { enum: ['subtle', 'normal', 'strong'] },
|
|
1448
|
+
},
|
|
1449
|
+
},
|
|
1450
|
+
},
|
|
1451
|
+
};
|
|
1452
|
+
const tableDelegateSchema = {
|
|
1453
|
+
type: 'object',
|
|
1454
|
+
required: ['tableOperationId', 'reason'],
|
|
1455
|
+
properties: {
|
|
1456
|
+
tableOperationId: { type: 'string' },
|
|
1457
|
+
reason: { type: 'string' },
|
|
1458
|
+
tableTarget: { type: 'object' },
|
|
1459
|
+
tableParams: { type: 'object' },
|
|
1460
|
+
},
|
|
1461
|
+
};
|
|
1462
|
+
const PRAXIS_TABLE_RULE_BUILDER_AUTHORING_MANIFEST = {
|
|
1463
|
+
schemaVersion: '1.0.0',
|
|
1464
|
+
componentId: 'praxis-table-rule-builder',
|
|
1465
|
+
ownerPackage: '@praxisui/table-rule-builder',
|
|
1466
|
+
configSchemaId: 'RuleEffectDefinition',
|
|
1467
|
+
manifestVersion: '1.0.0',
|
|
1468
|
+
runtimeInputs: [
|
|
1469
|
+
{ name: 'scope', type: 'RuleScope', description: 'Effect scope: cell, row, column or table.' },
|
|
1470
|
+
{ name: 'value', type: 'RuleEffectDefinition | undefined', description: 'Initial effect definition hydrated into the panel form.' },
|
|
1471
|
+
{ name: 'valueChange', type: 'RuleEffectDefinition', description: 'Debounced normalized effect payload emitted by the editor.' },
|
|
1472
|
+
{ name: 'apply', type: 'void', description: 'Emitted when the user applies the current effect payload.' },
|
|
1473
|
+
{ name: 'reset', type: 'void', description: 'Emitted when the user resets the panel form.' },
|
|
1474
|
+
],
|
|
1475
|
+
editableTargets: [
|
|
1476
|
+
{ kind: 'rule', resolver: 'table-rule-by-stable-id', description: 'Table conditional rule entry keyed by stable rule id before it is passed to praxis-table.' },
|
|
1477
|
+
{ kind: 'condition', resolver: 'table-rule-condition-by-rule-id', description: 'Structured condition payload evaluated against table row/column context.' },
|
|
1478
|
+
{ kind: 'effect', resolver: 'rule-effect-by-rule-and-effect-id', description: 'Visual effect payload inside a rule, mapped to RuleEffectDefinition.' },
|
|
1479
|
+
{ kind: 'preset', resolver: 'default-effect-preset-by-key', description: 'Built-in semantic effect preset from DEFAULT_EFFECT_PRESETS.' },
|
|
1480
|
+
{ kind: 'animation', resolver: 'rule-animation-by-rule-and-effect-id', description: 'Animation preset, alias or override resolved through animation-presets.' },
|
|
1481
|
+
{ kind: 'tableDelegation', resolver: 'praxis-table-authoring-operation', description: 'Explicit delegation boundary for table-owned configuration changes.' },
|
|
1482
|
+
],
|
|
1483
|
+
operations: [
|
|
1484
|
+
{
|
|
1485
|
+
operationId: 'rule.add',
|
|
1486
|
+
title: 'Add table visual rule',
|
|
1487
|
+
scope: 'rule',
|
|
1488
|
+
targetKind: 'rule',
|
|
1489
|
+
target: { kind: 'rule', resolver: 'table-rule-by-stable-id', ambiguityPolicy: 'fail', required: true },
|
|
1490
|
+
inputSchema: ruleAddSchema,
|
|
1491
|
+
effects: [{ kind: 'compile-domain-patch', handler: 'table-rule-builder-rule-add', handlerContract: {
|
|
1492
|
+
reads: ['RuleEffectsPanelComponent.scope', 'RuleEffectDefinition', 'praxis-table rowConditionalRenderers', 'praxis-table columns[].conditionalRenderers'],
|
|
1493
|
+
writes: ['delegatedAuthoringOperations', 'RuleEffectDefinition'],
|
|
1494
|
+
identityKeys: ['ruleId'],
|
|
1495
|
+
inputSchema: ruleAddSchema,
|
|
1496
|
+
failureModes: ['duplicate-rule-id', 'unsupported-scope', 'column-not-found', 'condition-invalid', 'effect-registry-miss'],
|
|
1497
|
+
description: 'Creates a stable table visual rule and keeps table-owned renderer placement delegated to praxis-table.',
|
|
1498
|
+
} }],
|
|
1499
|
+
validators: ['rule-id-unique', 'scope-supported', 'condition-table-context-valid', 'effect-registry-supported', 'table-owned-config-delegated'],
|
|
1500
|
+
affectedPaths: ['delegatedAuthoringOperations', 'RuleEffectDefinition'],
|
|
1501
|
+
submissionImpact: 'config-only',
|
|
1502
|
+
preconditions: ['rule-effects-panel-loaded', 'table-authoring-context-known'],
|
|
1503
|
+
destructive: false,
|
|
1504
|
+
requiresConfirmation: false,
|
|
1505
|
+
},
|
|
1506
|
+
{
|
|
1507
|
+
operationId: 'rule.remove',
|
|
1508
|
+
title: 'Remove table visual rule',
|
|
1509
|
+
scope: 'rule',
|
|
1510
|
+
targetKind: 'rule',
|
|
1511
|
+
target: { kind: 'rule', resolver: 'table-rule-by-stable-id', ambiguityPolicy: 'fail', required: true },
|
|
1512
|
+
inputSchema: ruleRemoveSchema,
|
|
1513
|
+
effects: [{ kind: 'compile-domain-patch', handler: 'table-rule-builder-rule-remove', handlerContract: {
|
|
1514
|
+
reads: ['ruleEffects.rules', 'ruleEffects.rules[].effect', 'ruleEffects.rules[].condition'],
|
|
1515
|
+
writes: ['delegatedAuthoringOperations'],
|
|
1516
|
+
identityKeys: ['ruleId'],
|
|
1517
|
+
inputSchema: ruleRemoveSchema,
|
|
1518
|
+
failureModes: ['rule-not-found', 'destructive-removal-not-confirmed', 'orphaned-table-renderer', 'condition-preserve-not-supported'],
|
|
1519
|
+
description: 'Removes a governed visual rule by id with confirmation because conditions and effects can be lost.',
|
|
1520
|
+
} }],
|
|
1521
|
+
destructive: true,
|
|
1522
|
+
requiresConfirmation: true,
|
|
1523
|
+
validators: ['rule-exists', 'destructive-removal-confirmed', 'table-renderer-references-clean', 'table-owned-config-delegated'],
|
|
1524
|
+
affectedPaths: ['delegatedAuthoringOperations'],
|
|
1525
|
+
submissionImpact: 'config-only',
|
|
1526
|
+
preconditions: ['rule-effects-panel-loaded', 'explicit-confirmation-provided'],
|
|
1527
|
+
},
|
|
1528
|
+
{
|
|
1529
|
+
operationId: 'condition.set',
|
|
1530
|
+
title: 'Set table rule condition',
|
|
1531
|
+
scope: 'rule',
|
|
1532
|
+
targetKind: 'condition',
|
|
1533
|
+
target: { kind: 'condition', resolver: 'table-rule-condition-by-rule-id', ambiguityPolicy: 'fail', required: true },
|
|
1534
|
+
inputSchema: conditionSetSchema,
|
|
1535
|
+
effects: [{ kind: 'compile-domain-patch', handler: 'table-rule-builder-condition-set', handlerContract: {
|
|
1536
|
+
reads: ['ruleEffects.rules', 'praxis-table dataSource fields', 'praxis-table columns'],
|
|
1537
|
+
writes: ['delegatedAuthoringOperations'],
|
|
1538
|
+
identityKeys: ['ruleId'],
|
|
1539
|
+
inputSchema: conditionSetSchema,
|
|
1540
|
+
failureModes: ['rule-not-found', 'condition-invalid', 'field-not-in-table-context', 'column-not-found'],
|
|
1541
|
+
description: 'Applies a structured table row/column condition without creating a parallel table DSL.',
|
|
1542
|
+
} }],
|
|
1543
|
+
validators: ['rule-exists', 'condition-table-context-valid', 'condition-fields-known', 'condition-operators-supported'],
|
|
1544
|
+
affectedPaths: ['delegatedAuthoringOperations'],
|
|
1545
|
+
submissionImpact: 'config-only',
|
|
1546
|
+
preconditions: ['rule-effects-panel-loaded', 'table-authoring-context-known'],
|
|
1547
|
+
destructive: false,
|
|
1548
|
+
requiresConfirmation: false,
|
|
1549
|
+
},
|
|
1550
|
+
{
|
|
1551
|
+
operationId: 'effect.add',
|
|
1552
|
+
title: 'Add visual effect to rule',
|
|
1553
|
+
scope: 'skin',
|
|
1554
|
+
targetKind: 'effect',
|
|
1555
|
+
target: { kind: 'effect', resolver: 'rule-effect-by-rule-and-effect-id', ambiguityPolicy: 'fail', required: true },
|
|
1556
|
+
inputSchema: effectAddSchema,
|
|
1557
|
+
effects: [{ kind: 'compile-domain-patch', handler: 'table-rule-builder-effect-add', handlerContract: {
|
|
1558
|
+
reads: ['EffectRegistryService.list', 'RuleEffectDefinition', 'toCellClassAndStyle'],
|
|
1559
|
+
writes: ['RuleEffectDefinition'],
|
|
1560
|
+
identityKeys: ['ruleId', 'effectId'],
|
|
1561
|
+
inputSchema: effectAddSchema,
|
|
1562
|
+
failureModes: ['rule-not-found', 'duplicate-effect-id', 'unsupported-effect-type', 'unsafe-style-value'],
|
|
1563
|
+
description: 'Adds a governed visual effect whose type is backed by the effect registry and RuleEffectDefinition.',
|
|
1564
|
+
} }],
|
|
1565
|
+
validators: ['rule-exists', 'effect-id-unique', 'effect-registry-supported', 'style-values-safe', 'preview-class-not-persisted'],
|
|
1566
|
+
affectedPaths: ['RuleEffectDefinition'],
|
|
1567
|
+
submissionImpact: 'visual-only',
|
|
1568
|
+
preconditions: ['rule-effects-panel-loaded', 'effect-registry-initialized'],
|
|
1569
|
+
destructive: false,
|
|
1570
|
+
requiresConfirmation: false,
|
|
1571
|
+
},
|
|
1572
|
+
{
|
|
1573
|
+
operationId: 'effect.update',
|
|
1574
|
+
title: 'Update visual effect payload',
|
|
1575
|
+
scope: 'skin',
|
|
1576
|
+
targetKind: 'effect',
|
|
1577
|
+
target: { kind: 'effect', resolver: 'rule-effect-by-rule-and-effect-id', ambiguityPolicy: 'fail', required: true },
|
|
1578
|
+
inputSchema: effectUpdateSchema,
|
|
1579
|
+
effects: [{ kind: 'compile-domain-patch', handler: 'table-rule-builder-effect-update', handlerContract: {
|
|
1580
|
+
reads: ['ruleEffects.rules[].effect', 'EffectRegistryService.list', 'toCellClassAndStyle'],
|
|
1581
|
+
writes: ['RuleEffectDefinition'],
|
|
1582
|
+
identityKeys: ['ruleId', 'effectId'],
|
|
1583
|
+
inputSchema: effectUpdateSchema,
|
|
1584
|
+
failureModes: ['rule-not-found', 'effect-not-found', 'unsupported-effect-type', 'unsafe-style-value'],
|
|
1585
|
+
description: 'Updates a visual effect payload while preserving its stable effect id and registry-backed type.',
|
|
1586
|
+
} }],
|
|
1587
|
+
validators: ['rule-exists', 'effect-exists', 'effect-registry-supported', 'style-values-safe', 'runtime-effect-compilable'],
|
|
1588
|
+
affectedPaths: ['RuleEffectDefinition'],
|
|
1589
|
+
submissionImpact: 'visual-only',
|
|
1590
|
+
preconditions: ['rule-effects-panel-loaded', 'effect-registry-initialized'],
|
|
1591
|
+
destructive: false,
|
|
1592
|
+
requiresConfirmation: false,
|
|
1593
|
+
},
|
|
1594
|
+
{
|
|
1595
|
+
operationId: 'effect.remove',
|
|
1596
|
+
title: 'Remove visual effect from rule',
|
|
1597
|
+
scope: 'skin',
|
|
1598
|
+
targetKind: 'effect',
|
|
1599
|
+
target: { kind: 'effect', resolver: 'rule-effect-by-rule-and-effect-id', ambiguityPolicy: 'fail', required: true },
|
|
1600
|
+
inputSchema: effectRemoveSchema,
|
|
1601
|
+
effects: [{ kind: 'compile-domain-patch', handler: 'table-rule-builder-effect-remove', handlerContract: {
|
|
1602
|
+
reads: ['ruleEffects.rules', 'ruleEffects.rules[].effect'],
|
|
1603
|
+
writes: ['RuleEffectDefinition', 'delegatedAuthoringOperations'],
|
|
1604
|
+
identityKeys: ['ruleId', 'effectId'],
|
|
1605
|
+
inputSchema: effectRemoveSchema,
|
|
1606
|
+
failureModes: ['rule-not-found', 'effect-not-found', 'destructive-removal-not-confirmed', 'empty-rule-created'],
|
|
1607
|
+
description: 'Removes one visual effect and optionally removes the empty rule, requiring confirmation for destructive cleanup.',
|
|
1608
|
+
} }],
|
|
1609
|
+
destructive: true,
|
|
1610
|
+
requiresConfirmation: true,
|
|
1611
|
+
validators: ['rule-exists', 'effect-exists', 'destructive-removal-confirmed', 'empty-rule-policy-valid'],
|
|
1612
|
+
affectedPaths: ['RuleEffectDefinition', 'delegatedAuthoringOperations'],
|
|
1613
|
+
submissionImpact: 'visual-only',
|
|
1614
|
+
preconditions: ['rule-effects-panel-loaded', 'explicit-confirmation-provided'],
|
|
1615
|
+
},
|
|
1616
|
+
{
|
|
1617
|
+
operationId: 'preset.apply',
|
|
1618
|
+
title: 'Apply semantic effect preset',
|
|
1619
|
+
scope: 'skin',
|
|
1620
|
+
targetKind: 'preset',
|
|
1621
|
+
target: { kind: 'preset', resolver: 'default-effect-preset-by-key', ambiguityPolicy: 'fail', required: true },
|
|
1622
|
+
inputSchema: presetApplySchema,
|
|
1623
|
+
effects: [{ kind: 'compile-domain-patch', handler: 'table-rule-builder-preset-apply', handlerContract: {
|
|
1624
|
+
reads: ['DEFAULT_EFFECT_PRESETS', 'RuleEffectsPanelComponent.applyPreset', 'RuleEffectDefinition'],
|
|
1625
|
+
writes: ['RuleEffectDefinition', 'RuleEffectsPanelComponent.effectsForm', 'valueChange'],
|
|
1626
|
+
identityKeys: ['ruleId', 'presetKey'],
|
|
1627
|
+
inputSchema: presetApplySchema,
|
|
1628
|
+
failureModes: ['rule-not-found', 'preset-not-found', 'scope-override-invalid', 'preset-effect-not-compilable'],
|
|
1629
|
+
description: 'Applies a built-in semantic preset and normalizes its scope through the rule effects panel.',
|
|
1630
|
+
} }],
|
|
1631
|
+
validators: ['rule-exists', 'preset-key-known', 'preset-effect-compilable', 'scope-supported'],
|
|
1632
|
+
affectedPaths: ['RuleEffectDefinition', 'RuleEffectsPanelComponent.effectsForm', 'valueChange'],
|
|
1633
|
+
submissionImpact: 'visual-only',
|
|
1634
|
+
preconditions: ['rule-effects-panel-loaded', 'default-presets-loaded'],
|
|
1635
|
+
destructive: false,
|
|
1636
|
+
requiresConfirmation: false,
|
|
1637
|
+
},
|
|
1638
|
+
{
|
|
1639
|
+
operationId: 'animation.set',
|
|
1640
|
+
title: 'Set rule animation',
|
|
1641
|
+
scope: 'skin',
|
|
1642
|
+
targetKind: 'animation',
|
|
1643
|
+
target: { kind: 'animation', resolver: 'rule-animation-by-rule-and-effect-id', ambiguityPolicy: 'fail', required: true },
|
|
1644
|
+
inputSchema: animationSetSchema,
|
|
1645
|
+
effects: [{ kind: 'compile-domain-patch', handler: 'table-rule-builder-animation-set', handlerContract: {
|
|
1646
|
+
reads: ['RULE_ANIMATION_PRESETS', 'RULE_ANIMATION_PRESET_ALIASES', 'resolveRuleAnimationConfig', 'RuleEffectDefinition.animation'],
|
|
1647
|
+
writes: ['RuleEffectDefinition.animation', 'RuleEffectsPanelComponent.effectsForm.animation', 'valueChange'],
|
|
1648
|
+
identityKeys: ['ruleId', 'effectId'],
|
|
1649
|
+
inputSchema: animationSetSchema,
|
|
1650
|
+
failureModes: ['rule-not-found', 'effect-not-found', 'animation-preset-unknown', 'animation-override-invalid', 'reduced-motion-policy-violated'],
|
|
1651
|
+
description: 'Sets a semantic animation preset or override that resolves fail-closed through the animation preset catalog.',
|
|
1652
|
+
} }],
|
|
1653
|
+
validators: ['rule-exists', 'animation-preset-known', 'animation-alias-known', 'animation-override-valid', 'animation-runtime-supported'],
|
|
1654
|
+
affectedPaths: ['RuleEffectDefinition.animation', 'RuleEffectsPanelComponent.effectsForm.animation', 'valueChange'],
|
|
1655
|
+
submissionImpact: 'visual-only',
|
|
1656
|
+
preconditions: ['rule-effects-panel-loaded', 'animation-presets-loaded'],
|
|
1657
|
+
destructive: false,
|
|
1658
|
+
requiresConfirmation: false,
|
|
1659
|
+
},
|
|
1660
|
+
{
|
|
1661
|
+
operationId: 'tableIntegration.delegate',
|
|
1662
|
+
title: 'Delegate table-owned configuration',
|
|
1663
|
+
scope: 'global',
|
|
1664
|
+
targetKind: 'tableDelegation',
|
|
1665
|
+
target: { kind: 'tableDelegation', resolver: 'praxis-table-authoring-operation', ambiguityPolicy: 'fail', required: false },
|
|
1666
|
+
inputSchema: tableDelegateSchema,
|
|
1667
|
+
effects: [{ kind: 'compile-domain-patch', handler: 'table-rule-builder-table-delegate', handlerContract: {
|
|
1668
|
+
reads: ['PRAXIS_TABLE_AUTHORING_MANIFEST', 'TableConfigV2', 'tableOperationId'],
|
|
1669
|
+
writes: ['delegatedAuthoringOperations'],
|
|
1670
|
+
identityKeys: ['tableOperationId'],
|
|
1671
|
+
inputSchema: tableDelegateSchema,
|
|
1672
|
+
failureModes: ['table-operation-not-found', 'table-target-invalid', 'attempted-local-table-config-write'],
|
|
1673
|
+
description: 'Records that table-owned config such as renderer placement, columns, ordering or data binding must route through praxis-table.',
|
|
1674
|
+
} }],
|
|
1675
|
+
validators: ['table-manifest-operation-known', 'table-target-valid', 'no-local-table-config-write', 'table-owned-config-delegated'],
|
|
1676
|
+
affectedPaths: ['delegatedAuthoringOperations'],
|
|
1677
|
+
submissionImpact: 'none',
|
|
1678
|
+
preconditions: ['praxis-table-manifest-available'],
|
|
1679
|
+
destructive: false,
|
|
1680
|
+
requiresConfirmation: false,
|
|
1681
|
+
},
|
|
1682
|
+
],
|
|
1683
|
+
validators: [
|
|
1684
|
+
{ validatorId: 'rule-id-unique', level: 'error', code: 'TABLE_RULE_ID_UNIQUE', description: 'Rule ids must be unique and stable.' },
|
|
1685
|
+
{ validatorId: 'scope-supported', level: 'error', code: 'TABLE_RULE_SCOPE_SUPPORTED', description: 'Rule scope must be one of cell, row, column or table.' },
|
|
1686
|
+
{ validatorId: 'condition-table-context-valid', level: 'error', code: 'TABLE_RULE_CONDITION_CONTEXT_VALID', description: 'Conditions must reference valid table row or column context.' },
|
|
1687
|
+
{ validatorId: 'effect-registry-supported', level: 'error', code: 'TABLE_RULE_EFFECT_REGISTRY_SUPPORTED', description: 'Effects must be backed by EffectRegistryService editor categories.' },
|
|
1688
|
+
{ validatorId: 'table-owned-config-delegated', level: 'error', code: 'TABLE_RULE_TABLE_CONFIG_DELEGATED', description: 'Table-owned configuration changes must delegate to praxis-table.' },
|
|
1689
|
+
{ validatorId: 'rule-exists', level: 'error', code: 'TABLE_RULE_EXISTS', description: 'The targeted rule must exist.' },
|
|
1690
|
+
{ validatorId: 'destructive-removal-confirmed', level: 'error', code: 'TABLE_RULE_DESTRUCTIVE_CONFIRMED', description: 'Destructive rule or effect removal requires explicit confirmation.' },
|
|
1691
|
+
{ validatorId: 'table-renderer-references-clean', level: 'error', code: 'TABLE_RULE_RENDERER_REFERENCES_CLEAN', description: 'Removing a rule must not leave stale table renderer references.' },
|
|
1692
|
+
{ validatorId: 'condition-fields-known', level: 'error', code: 'TABLE_RULE_CONDITION_FIELDS_KNOWN', description: 'Condition fields must exist in table row data or column metadata.' },
|
|
1693
|
+
{ validatorId: 'condition-operators-supported', level: 'error', code: 'TABLE_RULE_CONDITION_OPERATORS_SUPPORTED', description: 'Condition operators must be supported by table rule semantics.' },
|
|
1694
|
+
{ validatorId: 'effect-id-unique', level: 'error', code: 'TABLE_RULE_EFFECT_ID_UNIQUE', description: 'Effect ids must be unique within a rule.' },
|
|
1695
|
+
{ validatorId: 'style-values-safe', level: 'error', code: 'TABLE_RULE_STYLE_VALUES_SAFE', description: 'CSS class and style values must be safe for runtime rendering.' },
|
|
1696
|
+
{ validatorId: 'preview-class-not-persisted', level: 'error', code: 'TABLE_RULE_PREVIEW_CLASS_NOT_PERSISTED', description: 'Preview-only animation classes must not leak into persisted payload mapping.' },
|
|
1697
|
+
{ validatorId: 'effect-exists', level: 'error', code: 'TABLE_RULE_EFFECT_EXISTS', description: 'The targeted effect must exist.' },
|
|
1698
|
+
{ validatorId: 'runtime-effect-compilable', level: 'error', code: 'TABLE_RULE_RUNTIME_EFFECT_COMPILABLE', description: 'Effect payload must compile through toCellClassAndStyle or table renderer semantics.' },
|
|
1699
|
+
{ validatorId: 'empty-rule-policy-valid', level: 'warning', code: 'TABLE_RULE_EMPTY_RULE_POLICY_VALID', description: 'Removing the last effect must follow the requested empty-rule policy.' },
|
|
1700
|
+
{ validatorId: 'preset-key-known', level: 'error', code: 'TABLE_RULE_PRESET_KEY_KNOWN', description: 'Preset key must exist in DEFAULT_EFFECT_PRESETS.' },
|
|
1701
|
+
{ validatorId: 'preset-effect-compilable', level: 'error', code: 'TABLE_RULE_PRESET_EFFECT_COMPILABLE', description: 'Preset payload must compile to RuleEffectDefinition.' },
|
|
1702
|
+
{ validatorId: 'animation-preset-known', level: 'error', code: 'TABLE_RULE_ANIMATION_PRESET_KNOWN', description: 'Animation preset must be canonical or explicitly aliased.' },
|
|
1703
|
+
{ validatorId: 'animation-alias-known', level: 'error', code: 'TABLE_RULE_ANIMATION_ALIAS_KNOWN', description: 'Animation aliases must resolve to canonical presets.' },
|
|
1704
|
+
{ validatorId: 'animation-override-valid', level: 'error', code: 'TABLE_RULE_ANIMATION_OVERRIDE_VALID', description: 'Animation overrides must normalize to supported type, trigger, repeat and intensity values.' },
|
|
1705
|
+
{ validatorId: 'animation-runtime-supported', level: 'error', code: 'TABLE_RULE_ANIMATION_RUNTIME_SUPPORTED', description: 'Animation payload must be supported by row and column conditional renderers.' },
|
|
1706
|
+
{ validatorId: 'table-manifest-operation-known', level: 'error', code: 'TABLE_RULE_TABLE_OPERATION_KNOWN', description: 'Delegated table operation must exist in the praxis-table authoring manifest.' },
|
|
1707
|
+
{ validatorId: 'table-target-valid', level: 'error', code: 'TABLE_RULE_TABLE_TARGET_VALID', description: 'Delegated table target must be resolvable by praxis-table.' },
|
|
1708
|
+
{ validatorId: 'no-local-table-config-write', level: 'error', code: 'TABLE_RULE_NO_LOCAL_TABLE_CONFIG_WRITE', description: 'Rule builder operations must not write TableConfig directly.' },
|
|
1709
|
+
],
|
|
1710
|
+
roundTripRequirements: [
|
|
1711
|
+
'RuleEffectDefinition is the local source of truth for the effects panel.',
|
|
1712
|
+
'Rules that affect rowConditionalRenderers or columns[].conditionalRenderers must delegate table-owned placement to praxis-table.',
|
|
1713
|
+
'Rule and effect identity must use stable ruleId/effectId keys; array indexes are not canonical identities.',
|
|
1714
|
+
'Animation presets and aliases must resolve through RULE_ANIMATION_PRESETS and RULE_ANIMATION_PRESET_ALIASES before persistence.',
|
|
1715
|
+
'Preview-only animation classes must be omitted from persisted table payload mapping by using includeAnimationPreview: false.',
|
|
1716
|
+
'Preset application must preserve the selected scope and emit a normalized RuleEffectDefinition through valueChange.',
|
|
1717
|
+
],
|
|
1718
|
+
examples: [
|
|
1719
|
+
{ id: 'table-rule-add-row-warning', request: 'Add a row warning rule for overdue invoices.', operationId: 'rule.add', target: 'rule:overdue-warning', params: { ruleId: 'overdue-warning', scope: 'row', condition: { field: 'dueDate', operator: 'beforeToday' }, effect: { background: { color: 'rgba(255,193,7,0.12)' } } }, isPositive: true },
|
|
1720
|
+
{ id: 'table-rule-remove-obsolete', request: 'Remove the obsolete archived row rule.', operationId: 'rule.remove', target: 'rule:archived-obsolete', params: { ruleId: 'archived-obsolete', removeEffects: true }, isPositive: true },
|
|
1721
|
+
{ id: 'table-rule-condition-status-error', request: 'Make the rule apply when status is error.', operationId: 'condition.set', target: 'condition:status-error', params: { ruleId: 'status-error', condition: { field: 'status', operator: 'equals', value: 'error' } }, isPositive: true },
|
|
1722
|
+
{ id: 'table-rule-add-badge-effect', request: 'Add a warning badge to the status rule.', operationId: 'effect.add', target: 'effect:status-warning/badge', params: { ruleId: 'status-warning', effectId: 'badge', effectType: 'icone', payload: { icon: 'warning', badgeText: 'Attention' } }, isPositive: true },
|
|
1723
|
+
{ id: 'table-rule-update-background', request: 'Change the risk rule background color.', operationId: 'effect.update', target: 'effect:risk/background', params: { ruleId: 'risk', effectId: 'background', payload: { background: { color: 'rgba(239,83,80,0.10)' } }, mode: 'merge' }, isPositive: true },
|
|
1724
|
+
{ id: 'table-rule-remove-tooltip', request: 'Remove the tooltip effect from the audit rule.', operationId: 'effect.remove', target: 'effect:audit/tooltip', params: { ruleId: 'audit', effectId: 'tooltip' }, isPositive: true },
|
|
1725
|
+
{ id: 'table-rule-apply-alerta', request: 'Use the alerta preset on the SLA rule.', operationId: 'preset.apply', target: 'preset:alerta', params: { ruleId: 'sla', presetKey: 'alerta', scope: 'row', mergeWithExisting: true }, isPositive: true },
|
|
1726
|
+
{ id: 'table-rule-animation-critical', request: 'Make the SLA breach animation critical.', operationId: 'animation.set', target: 'animation:sla-breach', params: { ruleId: 'sla-breach', effectId: 'animation', animation: { preset: 'critical-alert' } }, isPositive: true },
|
|
1727
|
+
{ id: 'table-rule-delegate-column-renderer', request: 'Move this effect to the status column renderer.', operationId: 'tableIntegration.delegate', target: 'praxis-table:column-renderer', params: { tableOperationId: 'column.conditionalRenderer.set', reason: 'column renderer placement is owned by praxis-table', tableTarget: { columnKey: 'status' } }, isPositive: true },
|
|
1728
|
+
{ id: 'table-rule-reject-direct-table-column', request: 'Add a new table column from the rule builder.', operationId: 'tableIntegration.delegate', target: 'praxis-table:column.add', params: { tableOperationId: 'column.add', reason: 'column authoring belongs to praxis-table' }, isPositive: false },
|
|
1729
|
+
{ id: 'table-rule-reject-unknown-effect', request: 'Add a sparkle shader effect to rows.', operationId: 'effect.add', target: 'effect:sparkle', params: { ruleId: 'risk', effectId: 'sparkle', effectType: 'shader', payload: {} }, isPositive: false },
|
|
1730
|
+
{ id: 'table-rule-reject-unknown-animation', request: 'Use the earthquake animation preset.', operationId: 'animation.set', target: 'animation:earthquake', params: { ruleId: 'risk', effectId: 'animation', animation: { preset: 'earthquake' } }, isPositive: false },
|
|
1731
|
+
],
|
|
1732
|
+
};
|
|
1733
|
+
|
|
1309
1734
|
/**
|
|
1310
1735
|
* Generated bundle index. Do not edit.
|
|
1311
1736
|
*/
|
|
1312
1737
|
|
|
1313
|
-
export { AnimacaoEditorComponent, DEFAULT_EFFECT_PRESETS, EffectRegistryService, EstiloEditorComponent, FundoEditorComponent, IconeBadgeEditorComponent, LayoutEditorComponent, RuleEffectsPanelComponent, TooltipEditorComponent, toCellClassAndStyle };
|
|
1738
|
+
export { AnimacaoEditorComponent, DEFAULT_EFFECT_PRESETS, EffectRegistryService, EstiloEditorComponent, FundoEditorComponent, IconeBadgeEditorComponent, LayoutEditorComponent, PRAXIS_TABLE_RULE_BUILDER_AUTHORING_MANIFEST, RuleEffectsPanelComponent, TooltipEditorComponent, toCellClassAndStyle };
|
package/package.json
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisui/table-rule-builder",
|
|
3
|
-
"version": "8.0.0-beta.
|
|
3
|
+
"version": "8.0.0-beta.91",
|
|
4
4
|
"description": "Praxis Table Rule Builder: UI components and engine utils for table rules",
|
|
5
5
|
"peerDependencies": {
|
|
6
|
-
"@angular/common": "^
|
|
7
|
-
"@angular/core": "^
|
|
8
|
-
"@angular/forms": "^
|
|
9
|
-
"@angular/material": "^
|
|
6
|
+
"@angular/common": "^21.0.0",
|
|
7
|
+
"@angular/core": "^21.0.0",
|
|
8
|
+
"@angular/forms": "^21.0.0",
|
|
9
|
+
"@angular/material": "^21.0.0",
|
|
10
|
+
"@praxisui/ai": "^8.0.0-beta.91",
|
|
11
|
+
"@praxisui/core": "^8.0.0-beta.91",
|
|
12
|
+
"@praxisui/dynamic-fields": "^8.0.0-beta.91",
|
|
13
|
+
"rxjs": "~7.8.0"
|
|
10
14
|
},
|
|
11
15
|
"dependencies": {
|
|
12
16
|
"tslib": "^2.3.0"
|
|
@@ -33,14 +37,15 @@
|
|
|
33
37
|
],
|
|
34
38
|
"sideEffects": false,
|
|
35
39
|
"module": "fesm2022/praxisui-table-rule-builder.mjs",
|
|
36
|
-
"typings": "
|
|
40
|
+
"typings": "types/praxisui-table-rule-builder.d.ts",
|
|
37
41
|
"exports": {
|
|
38
42
|
"./package.json": {
|
|
39
43
|
"default": "./package.json"
|
|
40
44
|
},
|
|
41
45
|
".": {
|
|
42
|
-
"types": "./
|
|
46
|
+
"types": "./types/praxisui-table-rule-builder.d.ts",
|
|
43
47
|
"default": "./fesm2022/praxisui-table-rule-builder.mjs"
|
|
44
48
|
}
|
|
45
|
-
}
|
|
49
|
+
},
|
|
50
|
+
"type": "module"
|
|
46
51
|
}
|
|
@@ -2,6 +2,7 @@ import * as i0 from '@angular/core';
|
|
|
2
2
|
import { OnInit, OnDestroy, EventEmitter } from '@angular/core';
|
|
3
3
|
import { FormGroup, FormBuilder } from '@angular/forms';
|
|
4
4
|
import { Subject } from 'rxjs';
|
|
5
|
+
import { ComponentAuthoringManifest } from '@praxisui/core';
|
|
5
6
|
|
|
6
7
|
type RuleScope = 'cell' | 'row' | 'column' | 'table';
|
|
7
8
|
type RuleAnimationPreset = 'info-soft' | 'success-confirm' | 'warning-attention' | 'critical-alert' | 'audit-review' | 'sync-pending' | 'sla-warning' | 'sla-breach' | 'risk-elevated' | 'risk-critical' | 'audit-warning' | 'sync-warning';
|
|
@@ -175,5 +176,7 @@ declare class TooltipEditorComponent {
|
|
|
175
176
|
static ɵcmp: i0.ɵɵComponentDeclaration<TooltipEditorComponent, "praxis-effects-tooltip-editor", never, { "group": { "alias": "group"; "required": false; }; }, {}, never, never, true, never>;
|
|
176
177
|
}
|
|
177
178
|
|
|
178
|
-
|
|
179
|
+
declare const PRAXIS_TABLE_RULE_BUILDER_AUTHORING_MANIFEST: ComponentAuthoringManifest;
|
|
180
|
+
|
|
181
|
+
export { AnimacaoEditorComponent, DEFAULT_EFFECT_PRESETS, EffectRegistryService, EstiloEditorComponent, FundoEditorComponent, IconeBadgeEditorComponent, LayoutEditorComponent, PRAXIS_TABLE_RULE_BUILDER_AUTHORING_MANIFEST, RuleEffectsPanelComponent, TooltipEditorComponent, toCellClassAndStyle };
|
|
179
182
|
export type { EffectEditorPlugin, RuleAnimationIntensity, RuleAnimationPreset, RuleAnimationRepeat, RuleAnimationTrigger, RuleAnimationType, RuleEffectDefinition, RuleScope };
|