@praxisui/page-builder 0.0.1
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/LICENSE +7 -0
- package/README.md +102 -0
- package/fesm2022/praxisui-page-builder-connection-graph.component-C6x--6--.mjs +1129 -0
- package/fesm2022/praxisui-page-builder-connection-graph.component-C6x--6--.mjs.map +1 -0
- package/fesm2022/praxisui-page-builder.mjs +620 -0
- package/fesm2022/praxisui-page-builder.mjs.map +1 -0
- package/index.d.ts +134 -0
- package/package.json +41 -0
|
@@ -0,0 +1,620 @@
|
|
|
1
|
+
import * as i3$2 from '@angular/common';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import * as i0 from '@angular/core';
|
|
4
|
+
import { Inject, ChangeDetectionStrategy, Component, EventEmitter, Output, Input, signal, computed, effect } from '@angular/core';
|
|
5
|
+
import * as i2 from '@angular/material/button';
|
|
6
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
7
|
+
import * as i1 from '@angular/material/dialog';
|
|
8
|
+
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
|
9
|
+
import * as i3 from '@angular/material/icon';
|
|
10
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
11
|
+
import * as i2$1 from '@praxisui/core';
|
|
12
|
+
import { PraxisIconDirective } from '@praxisui/core';
|
|
13
|
+
import * as i3$1 from '@angular/material/tooltip';
|
|
14
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
15
|
+
import * as i6 from '@angular/material/form-field';
|
|
16
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
17
|
+
import * as i7 from '@angular/material/input';
|
|
18
|
+
import { MatInputModule } from '@angular/material/input';
|
|
19
|
+
import * as i4 from '@angular/forms';
|
|
20
|
+
import { FormsModule } from '@angular/forms';
|
|
21
|
+
import * as i9 from '@angular/material/select';
|
|
22
|
+
import { MatSelectModule } from '@angular/material/select';
|
|
23
|
+
import * as i12 from '@angular/material/list';
|
|
24
|
+
import { MatListModule } from '@angular/material/list';
|
|
25
|
+
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
|
26
|
+
import { MatMenuModule } from '@angular/material/menu';
|
|
27
|
+
import * as i3$3 from '@angular/material/snack-bar';
|
|
28
|
+
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
|
29
|
+
import { MatTabsModule } from '@angular/material/tabs';
|
|
30
|
+
import * as i8 from '@angular/cdk/scrolling';
|
|
31
|
+
import { ScrollingModule } from '@angular/cdk/scrolling';
|
|
32
|
+
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
33
|
+
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
34
|
+
|
|
35
|
+
const PLACEHOLDER = 1;
|
|
36
|
+
|
|
37
|
+
class ConfirmDialogComponent {
|
|
38
|
+
data;
|
|
39
|
+
ref;
|
|
40
|
+
constructor(data, ref) {
|
|
41
|
+
this.data = data;
|
|
42
|
+
this.ref = ref;
|
|
43
|
+
}
|
|
44
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ConfirmDialogComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.MatDialogRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
45
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: ConfirmDialogComponent, isStandalone: true, selector: "praxis-confirm-dialog", ngImport: i0, template: `
|
|
46
|
+
<h2 mat-dialog-title>
|
|
47
|
+
<mat-icon aria-hidden="true" style="vertical-align: middle; margin-right: 8px;" [praxisIcon]="data.icon || 'warning'"></mat-icon>
|
|
48
|
+
{{ data.title || 'Confirmar ação' }}
|
|
49
|
+
</h2>
|
|
50
|
+
<div mat-dialog-content>
|
|
51
|
+
<p>{{ data.message || 'Tem certeza que deseja prosseguir?' }}</p>
|
|
52
|
+
</div>
|
|
53
|
+
<div mat-dialog-actions align="end">
|
|
54
|
+
<button mat-button mat-dialog-close>{{ data.cancelLabel || 'Cancelar' }}</button>
|
|
55
|
+
<button mat-raised-button color="warn" [mat-dialog-close]="true">{{ data.confirmLabel || 'Excluir' }}</button>
|
|
56
|
+
</div>
|
|
57
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
58
|
+
}
|
|
59
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ConfirmDialogComponent, decorators: [{
|
|
60
|
+
type: Component,
|
|
61
|
+
args: [{
|
|
62
|
+
selector: 'praxis-confirm-dialog',
|
|
63
|
+
standalone: true,
|
|
64
|
+
imports: [CommonModule, MatDialogModule, MatButtonModule, MatIconModule, PraxisIconDirective],
|
|
65
|
+
template: `
|
|
66
|
+
<h2 mat-dialog-title>
|
|
67
|
+
<mat-icon aria-hidden="true" style="vertical-align: middle; margin-right: 8px;" [praxisIcon]="data.icon || 'warning'"></mat-icon>
|
|
68
|
+
{{ data.title || 'Confirmar ação' }}
|
|
69
|
+
</h2>
|
|
70
|
+
<div mat-dialog-content>
|
|
71
|
+
<p>{{ data.message || 'Tem certeza que deseja prosseguir?' }}</p>
|
|
72
|
+
</div>
|
|
73
|
+
<div mat-dialog-actions align="end">
|
|
74
|
+
<button mat-button mat-dialog-close>{{ data.cancelLabel || 'Cancelar' }}</button>
|
|
75
|
+
<button mat-raised-button color="warn" [mat-dialog-close]="true">{{ data.confirmLabel || 'Excluir' }}</button>
|
|
76
|
+
</div>
|
|
77
|
+
`,
|
|
78
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
79
|
+
}]
|
|
80
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
81
|
+
type: Inject,
|
|
82
|
+
args: [MAT_DIALOG_DATA]
|
|
83
|
+
}] }, { type: i1.MatDialogRef }] });
|
|
84
|
+
|
|
85
|
+
class TileToolbarComponent {
|
|
86
|
+
selected = false;
|
|
87
|
+
widgetType = null;
|
|
88
|
+
remove = new EventEmitter();
|
|
89
|
+
settings = new EventEmitter();
|
|
90
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: TileToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
91
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: TileToolbarComponent, isStandalone: true, selector: "praxis-tile-toolbar", inputs: { selected: "selected", widgetType: "widgetType" }, outputs: { remove: "remove", settings: "settings" }, ngImport: i0, template: `
|
|
92
|
+
<div class="pdx-tile-toolbar" [class.always-visible]="selected" role="toolbar" aria-label="Ações do widget">
|
|
93
|
+
<button
|
|
94
|
+
mat-mini-fab
|
|
95
|
+
(click)="settings.emit()"
|
|
96
|
+
[matTooltip]="'Configurar widget'"
|
|
97
|
+
aria-label="Configurar widget"
|
|
98
|
+
>
|
|
99
|
+
<mat-icon [praxisIcon]="'settings'"></mat-icon>
|
|
100
|
+
</button>
|
|
101
|
+
<button
|
|
102
|
+
mat-mini-fab
|
|
103
|
+
color="primary"
|
|
104
|
+
class="pdx-drag-handle"
|
|
105
|
+
[matTooltip]="'Arrastar tile'"
|
|
106
|
+
aria-label="Arrastar tile"
|
|
107
|
+
>
|
|
108
|
+
<mat-icon [praxisIcon]="'drag_indicator'"></mat-icon>
|
|
109
|
+
</button>
|
|
110
|
+
<button
|
|
111
|
+
mat-mini-fab
|
|
112
|
+
color="warn"
|
|
113
|
+
(click)="remove.emit()"
|
|
114
|
+
[matTooltip]="'Excluir widget'"
|
|
115
|
+
aria-label="Excluir widget"
|
|
116
|
+
>
|
|
117
|
+
<mat-icon [praxisIcon]="'delete'"></mat-icon>
|
|
118
|
+
</button>
|
|
119
|
+
</div>
|
|
120
|
+
`, isInline: true, styles: [":host{position:absolute;inset:0;pointer-events:none}.pdx-tile-toolbar{position:absolute;right:6px;top:-18px;display:flex;gap:6px;z-index:5;opacity:0;transition:opacity .12s ease-in-out;pointer-events:auto;background:color-mix(in oklab,var(--md-sys-color-surface) 92%,transparent);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);border-radius:999px;padding:4px;box-shadow:var(--mat-elevation-level3, 0 4px 8px rgba(0,0,0,.2))}.pdx-tile-toolbar.always-visible{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
121
|
+
}
|
|
122
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: TileToolbarComponent, decorators: [{
|
|
123
|
+
type: Component,
|
|
124
|
+
args: [{ selector: 'praxis-tile-toolbar', standalone: true, imports: [CommonModule, MatButtonModule, MatIconModule, MatTooltipModule, PraxisIconDirective], template: `
|
|
125
|
+
<div class="pdx-tile-toolbar" [class.always-visible]="selected" role="toolbar" aria-label="Ações do widget">
|
|
126
|
+
<button
|
|
127
|
+
mat-mini-fab
|
|
128
|
+
(click)="settings.emit()"
|
|
129
|
+
[matTooltip]="'Configurar widget'"
|
|
130
|
+
aria-label="Configurar widget"
|
|
131
|
+
>
|
|
132
|
+
<mat-icon [praxisIcon]="'settings'"></mat-icon>
|
|
133
|
+
</button>
|
|
134
|
+
<button
|
|
135
|
+
mat-mini-fab
|
|
136
|
+
color="primary"
|
|
137
|
+
class="pdx-drag-handle"
|
|
138
|
+
[matTooltip]="'Arrastar tile'"
|
|
139
|
+
aria-label="Arrastar tile"
|
|
140
|
+
>
|
|
141
|
+
<mat-icon [praxisIcon]="'drag_indicator'"></mat-icon>
|
|
142
|
+
</button>
|
|
143
|
+
<button
|
|
144
|
+
mat-mini-fab
|
|
145
|
+
color="warn"
|
|
146
|
+
(click)="remove.emit()"
|
|
147
|
+
[matTooltip]="'Excluir widget'"
|
|
148
|
+
aria-label="Excluir widget"
|
|
149
|
+
>
|
|
150
|
+
<mat-icon [praxisIcon]="'delete'"></mat-icon>
|
|
151
|
+
</button>
|
|
152
|
+
</div>
|
|
153
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{position:absolute;inset:0;pointer-events:none}.pdx-tile-toolbar{position:absolute;right:6px;top:-18px;display:flex;gap:6px;z-index:5;opacity:0;transition:opacity .12s ease-in-out;pointer-events:auto;background:color-mix(in oklab,var(--md-sys-color-surface) 92%,transparent);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);border-radius:999px;padding:4px;box-shadow:var(--mat-elevation-level3, 0 4px 8px rgba(0,0,0,.2))}.pdx-tile-toolbar.always-visible{opacity:1}\n"] }]
|
|
154
|
+
}], propDecorators: { selected: [{
|
|
155
|
+
type: Input
|
|
156
|
+
}], widgetType: [{
|
|
157
|
+
type: Input
|
|
158
|
+
}], remove: [{
|
|
159
|
+
type: Output
|
|
160
|
+
}], settings: [{
|
|
161
|
+
type: Output
|
|
162
|
+
}] } });
|
|
163
|
+
|
|
164
|
+
class FloatingToolbarComponent {
|
|
165
|
+
visible = false;
|
|
166
|
+
canUndo = false;
|
|
167
|
+
canRedo = false;
|
|
168
|
+
add = new EventEmitter();
|
|
169
|
+
undo = new EventEmitter();
|
|
170
|
+
redo = new EventEmitter();
|
|
171
|
+
settings = new EventEmitter();
|
|
172
|
+
preview = new EventEmitter();
|
|
173
|
+
connections = new EventEmitter();
|
|
174
|
+
connectionsEdit = new EventEmitter();
|
|
175
|
+
connectionsVisual = new EventEmitter();
|
|
176
|
+
save = new EventEmitter();
|
|
177
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: FloatingToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
178
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: FloatingToolbarComponent, isStandalone: true, selector: "praxis-floating-toolbar", inputs: { visible: "visible", canUndo: "canUndo", canRedo: "canRedo" }, outputs: { add: "add", undo: "undo", redo: "redo", settings: "settings", preview: "preview", connections: "connections", connectionsEdit: "connectionsEdit", connectionsVisual: "connectionsVisual", save: "save" }, ngImport: i0, template: `
|
|
179
|
+
<div class="pdx-floating-toolbar" *ngIf="visible">
|
|
180
|
+
<button mat-fab color="primary" class="pdx-fab" [matTooltip]="'Ações rápidas'">
|
|
181
|
+
<mat-icon [praxisIcon]="'build'"></mat-icon>
|
|
182
|
+
</button>
|
|
183
|
+
<div class="pdx-actions">
|
|
184
|
+
<button mat-mini-fab color="primary" (click)="add.emit()" [matTooltip]="'Inserir componente'" aria-label="Inserir componente">
|
|
185
|
+
<mat-icon [praxisIcon]="'add'"></mat-icon>
|
|
186
|
+
</button>
|
|
187
|
+
<button mat-mini-fab (click)="connections.emit()" [matTooltip]="'Visualizar conexões (Diagrama)'" aria-label="Visualizar conexões (Diagrama)">
|
|
188
|
+
<mat-icon [praxisIcon]="'device_hub'"></mat-icon>
|
|
189
|
+
</button>
|
|
190
|
+
<button mat-mini-fab (click)="connectionsVisual.emit()" [matTooltip]="'Editor Visual (beta)'" aria-label="Editor Visual (beta)">
|
|
191
|
+
<mat-icon [praxisIcon]="'schema'"></mat-icon>
|
|
192
|
+
</button>
|
|
193
|
+
<button mat-mini-fab (click)="connectionsEdit.emit()" [matTooltip]="'Editar conexões (Builder)'" aria-label="Editar conexões (Builder)">
|
|
194
|
+
<mat-icon [praxisIcon]="'tune'"></mat-icon>
|
|
195
|
+
</button>
|
|
196
|
+
<button mat-mini-fab color="accent" (click)="save.emit()" [matTooltip]="'Salvar página'" aria-label="Salvar página">
|
|
197
|
+
<mat-icon [praxisIcon]="'save'"></mat-icon>
|
|
198
|
+
</button>
|
|
199
|
+
<button mat-mini-fab (click)="undo.emit()" [disabled]="!canUndo" [matTooltip]="'Desfazer'" aria-label="Desfazer">
|
|
200
|
+
<mat-icon [praxisIcon]="'undo'"></mat-icon>
|
|
201
|
+
</button>
|
|
202
|
+
<button mat-mini-fab (click)="redo.emit()" [disabled]="!canRedo" [matTooltip]="'Refazer'" aria-label="Refazer">
|
|
203
|
+
<mat-icon [praxisIcon]="'redo'"></mat-icon>
|
|
204
|
+
</button>
|
|
205
|
+
<button mat-mini-fab (click)="settings.emit()" [matTooltip]="'Configurações da página'" aria-label="Configurações da página">
|
|
206
|
+
<mat-icon [praxisIcon]="'settings'"></mat-icon>
|
|
207
|
+
</button>
|
|
208
|
+
<button mat-mini-fab (click)="preview.emit()" [matTooltip]="'Pré-visualizar'" aria-label="Pré-visualizar">
|
|
209
|
+
<mat-icon [praxisIcon]="'visibility'"></mat-icon>
|
|
210
|
+
</button>
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
`, isInline: true, styles: [":host{position:absolute;inset:0;pointer-events:none}.pdx-floating-toolbar{position:absolute;right:16px;bottom:16px;display:flex;gap:8px;align-items:center;pointer-events:auto}.pdx-actions{display:flex;gap:8px}.pdx-fab{box-shadow:var(--mat-elevation-transition),var(--mat-elevation-level6, 0 6px 12px rgba(0,0,0,.24))}@media (max-width: 720px){.pdx-actions{gap:6px}.pdx-floating-toolbar{right:12px;bottom:12px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
214
|
+
}
|
|
215
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: FloatingToolbarComponent, decorators: [{
|
|
216
|
+
type: Component,
|
|
217
|
+
args: [{ selector: 'praxis-floating-toolbar', standalone: true, imports: [CommonModule, MatButtonModule, MatIconModule, MatTooltipModule, PraxisIconDirective], template: `
|
|
218
|
+
<div class="pdx-floating-toolbar" *ngIf="visible">
|
|
219
|
+
<button mat-fab color="primary" class="pdx-fab" [matTooltip]="'Ações rápidas'">
|
|
220
|
+
<mat-icon [praxisIcon]="'build'"></mat-icon>
|
|
221
|
+
</button>
|
|
222
|
+
<div class="pdx-actions">
|
|
223
|
+
<button mat-mini-fab color="primary" (click)="add.emit()" [matTooltip]="'Inserir componente'" aria-label="Inserir componente">
|
|
224
|
+
<mat-icon [praxisIcon]="'add'"></mat-icon>
|
|
225
|
+
</button>
|
|
226
|
+
<button mat-mini-fab (click)="connections.emit()" [matTooltip]="'Visualizar conexões (Diagrama)'" aria-label="Visualizar conexões (Diagrama)">
|
|
227
|
+
<mat-icon [praxisIcon]="'device_hub'"></mat-icon>
|
|
228
|
+
</button>
|
|
229
|
+
<button mat-mini-fab (click)="connectionsVisual.emit()" [matTooltip]="'Editor Visual (beta)'" aria-label="Editor Visual (beta)">
|
|
230
|
+
<mat-icon [praxisIcon]="'schema'"></mat-icon>
|
|
231
|
+
</button>
|
|
232
|
+
<button mat-mini-fab (click)="connectionsEdit.emit()" [matTooltip]="'Editar conexões (Builder)'" aria-label="Editar conexões (Builder)">
|
|
233
|
+
<mat-icon [praxisIcon]="'tune'"></mat-icon>
|
|
234
|
+
</button>
|
|
235
|
+
<button mat-mini-fab color="accent" (click)="save.emit()" [matTooltip]="'Salvar página'" aria-label="Salvar página">
|
|
236
|
+
<mat-icon [praxisIcon]="'save'"></mat-icon>
|
|
237
|
+
</button>
|
|
238
|
+
<button mat-mini-fab (click)="undo.emit()" [disabled]="!canUndo" [matTooltip]="'Desfazer'" aria-label="Desfazer">
|
|
239
|
+
<mat-icon [praxisIcon]="'undo'"></mat-icon>
|
|
240
|
+
</button>
|
|
241
|
+
<button mat-mini-fab (click)="redo.emit()" [disabled]="!canRedo" [matTooltip]="'Refazer'" aria-label="Refazer">
|
|
242
|
+
<mat-icon [praxisIcon]="'redo'"></mat-icon>
|
|
243
|
+
</button>
|
|
244
|
+
<button mat-mini-fab (click)="settings.emit()" [matTooltip]="'Configurações da página'" aria-label="Configurações da página">
|
|
245
|
+
<mat-icon [praxisIcon]="'settings'"></mat-icon>
|
|
246
|
+
</button>
|
|
247
|
+
<button mat-mini-fab (click)="preview.emit()" [matTooltip]="'Pré-visualizar'" aria-label="Pré-visualizar">
|
|
248
|
+
<mat-icon [praxisIcon]="'visibility'"></mat-icon>
|
|
249
|
+
</button>
|
|
250
|
+
</div>
|
|
251
|
+
</div>
|
|
252
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{position:absolute;inset:0;pointer-events:none}.pdx-floating-toolbar{position:absolute;right:16px;bottom:16px;display:flex;gap:8px;align-items:center;pointer-events:auto}.pdx-actions{display:flex;gap:8px}.pdx-fab{box-shadow:var(--mat-elevation-transition),var(--mat-elevation-level6, 0 6px 12px rgba(0,0,0,.24))}@media (max-width: 720px){.pdx-actions{gap:6px}.pdx-floating-toolbar{right:12px;bottom:12px}}\n"] }]
|
|
253
|
+
}], propDecorators: { visible: [{
|
|
254
|
+
type: Input
|
|
255
|
+
}], canUndo: [{
|
|
256
|
+
type: Input
|
|
257
|
+
}], canRedo: [{
|
|
258
|
+
type: Input
|
|
259
|
+
}], add: [{
|
|
260
|
+
type: Output
|
|
261
|
+
}], undo: [{
|
|
262
|
+
type: Output
|
|
263
|
+
}], redo: [{
|
|
264
|
+
type: Output
|
|
265
|
+
}], settings: [{
|
|
266
|
+
type: Output
|
|
267
|
+
}], preview: [{
|
|
268
|
+
type: Output
|
|
269
|
+
}], connections: [{
|
|
270
|
+
type: Output
|
|
271
|
+
}], connectionsEdit: [{
|
|
272
|
+
type: Output
|
|
273
|
+
}], connectionsVisual: [{
|
|
274
|
+
type: Output
|
|
275
|
+
}], save: [{
|
|
276
|
+
type: Output
|
|
277
|
+
}] } });
|
|
278
|
+
|
|
279
|
+
class ComponentPaletteDialogComponent {
|
|
280
|
+
dialogRef;
|
|
281
|
+
registry;
|
|
282
|
+
data;
|
|
283
|
+
query = '';
|
|
284
|
+
all = signal([], ...(ngDevMode ? [{ debugName: "all" }] : []));
|
|
285
|
+
filtered = computed(() => this.applyFilters(), ...(ngDevMode ? [{ debugName: "filtered" }] : []));
|
|
286
|
+
density = computed(() => {
|
|
287
|
+
const n = this.filtered().length;
|
|
288
|
+
if (n <= 4)
|
|
289
|
+
return 'roomy';
|
|
290
|
+
if (n > 12)
|
|
291
|
+
return 'dense';
|
|
292
|
+
return 'normal';
|
|
293
|
+
}, ...(ngDevMode ? [{ debugName: "density" }] : []));
|
|
294
|
+
constructor(dialogRef, registry, data) {
|
|
295
|
+
this.dialogRef = dialogRef;
|
|
296
|
+
this.registry = registry;
|
|
297
|
+
this.data = data;
|
|
298
|
+
}
|
|
299
|
+
ngOnInit() {
|
|
300
|
+
this.all.set(this.registry.getAll());
|
|
301
|
+
}
|
|
302
|
+
select(id) {
|
|
303
|
+
this.dialogRef.close(id);
|
|
304
|
+
}
|
|
305
|
+
trackById = (_, m) => m.id;
|
|
306
|
+
getPreview(m) {
|
|
307
|
+
return (m.description || m.selector || m.friendlyName || m.id || '').toString();
|
|
308
|
+
}
|
|
309
|
+
// Create effect in injection context (field initializer is allowed)
|
|
310
|
+
_adjustSizeEffect = effect(() => {
|
|
311
|
+
const n = this.filtered().length;
|
|
312
|
+
let width = '720px';
|
|
313
|
+
if (n <= 4)
|
|
314
|
+
width = '560px';
|
|
315
|
+
else if (n <= 8)
|
|
316
|
+
width = '680px';
|
|
317
|
+
const container = this.dialogRef._containerInstance;
|
|
318
|
+
if (container && container._config) {
|
|
319
|
+
container._config.width = width;
|
|
320
|
+
}
|
|
321
|
+
}, ...(ngDevMode ? [{ debugName: "_adjustSizeEffect" }] : []));
|
|
322
|
+
applyFilters() {
|
|
323
|
+
const list = (this.all() || []);
|
|
324
|
+
const q = (this.query || '').toLowerCase();
|
|
325
|
+
const allowIds = new Set((this.data?.allowedWidgetIds || []).map((s) => s.toLowerCase()));
|
|
326
|
+
const allowTags = new Set((this.data?.allowedWidgetTags || []).map((s) => s.toLowerCase()));
|
|
327
|
+
return list.filter((m) => {
|
|
328
|
+
if (q) {
|
|
329
|
+
const hay = `${m.id} ${m.friendlyName || ''} ${m.description || ''} ${m.selector || ''}`.toLowerCase();
|
|
330
|
+
if (!hay.includes(q))
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
if (allowIds.size > 0 && !allowIds.has((m.id || '').toLowerCase()))
|
|
334
|
+
return false;
|
|
335
|
+
if (allowTags.size > 0 && !m.tags?.some(t => allowTags.has(t.toLowerCase())))
|
|
336
|
+
return false;
|
|
337
|
+
if (typeof this.data?.predicate === 'function' && !this.data.predicate(m))
|
|
338
|
+
return false;
|
|
339
|
+
return true;
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ComponentPaletteDialogComponent, deps: [{ token: i1.MatDialogRef }, { token: i2$1.ComponentMetadataRegistry }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
|
|
343
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: ComponentPaletteDialogComponent, isStandalone: true, selector: "praxis-component-palette-dialog", ngImport: i0, template: `
|
|
344
|
+
<h2 mat-dialog-title>
|
|
345
|
+
<div class="dlg-title">
|
|
346
|
+
<mat-icon class="dlg-icon" [praxisIcon]="'widgets'"></mat-icon>
|
|
347
|
+
<div class="dlg-texts">
|
|
348
|
+
<div class="dlg-head">{{ data?.title || 'Inserir componente' }}</div>
|
|
349
|
+
<div class="dlg-sub">Escolha um componente para adicionar à página · {{ filtered().length }} disponíveis</div>
|
|
350
|
+
</div>
|
|
351
|
+
</div>
|
|
352
|
+
</h2>
|
|
353
|
+
<div mat-dialog-content class="pdx-palette-content">
|
|
354
|
+
<div class="pdx-grid" [ngClass]="density()" *ngIf="filtered().length; else emptyState">
|
|
355
|
+
<div
|
|
356
|
+
*ngFor="let m of filtered(); trackBy: trackById"
|
|
357
|
+
class="pdx-card mat-elevation-z2"
|
|
358
|
+
tabindex="0"
|
|
359
|
+
role="button"
|
|
360
|
+
[attr.aria-label]="'Adicionar ' + (m.friendlyName || m.id)"
|
|
361
|
+
(click)="select(m.id)"
|
|
362
|
+
(keydown.enter)="select(m.id)"
|
|
363
|
+
(keydown.space)="select(m.id)"
|
|
364
|
+
>
|
|
365
|
+
<div class="pdx-card-icon">
|
|
366
|
+
<mat-icon [praxisIcon]="m.icon || 'widgets'"></mat-icon>
|
|
367
|
+
</div>
|
|
368
|
+
<div class="pdx-card-body">
|
|
369
|
+
<div class="pdx-card-title">{{ m.friendlyName || m.id }}</div>
|
|
370
|
+
<div class="pdx-card-desc">{{ m.description || m.selector }}</div>
|
|
371
|
+
</div>
|
|
372
|
+
</div>
|
|
373
|
+
</div>
|
|
374
|
+
|
|
375
|
+
<ng-template #emptyState>
|
|
376
|
+
<div class="pdx-empty">
|
|
377
|
+
<mat-icon [praxisIcon]="'sentiment_dissatisfied'"></mat-icon>
|
|
378
|
+
<div>Nenhum componente disponível</div>
|
|
379
|
+
</div>
|
|
380
|
+
</ng-template>
|
|
381
|
+
</div>
|
|
382
|
+
<div mat-dialog-actions align="end">
|
|
383
|
+
<button mat-stroked-button color="primary" mat-dialog-close>Cancelar</button>
|
|
384
|
+
</div>
|
|
385
|
+
`, isInline: true, styles: [":host{display:block}h2[mat-dialog-title]{margin:0;padding:12px 24px 10px;border-bottom:1px solid var(--md-sys-color-outline-variant, rgba(0,0,0,.12))}.dlg-title{display:flex;align-items:center;gap:10px}.dlg-icon{color:var(--md-sys-color-primary, #3f51b5)}.dlg-head{font-size:18px;font-weight:600;line-height:1.2}.dlg-sub{font-size:12px;opacity:.85;color:var(--md-sys-color-on-surface-variant, rgba(0,0,0,.62))}.pdx-palette-content{min-width:480px;max-width:920px;padding-top:8px}.pdx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:14px}.pdx-grid.dense{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.pdx-grid.roomy{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px}.pdx-card{position:relative;display:grid;grid-template-columns:44px 1fr;grid-template-rows:auto auto;gap:10px;padding:14px;border:1px solid transparent;border-radius:14px;cursor:pointer;outline:none;min-height:92px;background:linear-gradient(var(--md-sys-color-surface),var(--md-sys-color-surface)) padding-box,linear-gradient(135deg,color-mix(in oklab,var(--md-sys-color-primary, #3f51b5) 55%,transparent),color-mix(in oklab,var(--md-sys-color-secondary, #ff4081) 45%,transparent)) border-box;transition:box-shadow .2s ease,background .25s ease,transform .06s ease}.pdx-grid.dense .pdx-card{padding:10px;border-radius:12px;min-height:84px}.pdx-grid.roomy .pdx-card{padding:16px;border-radius:16px;min-height:100px}.pdx-card:focus,.pdx-card:hover{box-shadow:var(--mat-elevation-transition),var(--mat-elevation-level6, 0 6px 12px rgba(0,0,0,.22));background:linear-gradient(var(--md-sys-color-surface),var(--md-sys-color-surface)) padding-box,linear-gradient(135deg,color-mix(in oklab,var(--md-sys-color-primary) 70%,transparent),color-mix(in oklab,var(--md-sys-color-secondary) 55%,transparent)) border-box}.pdx-card:active{transform:translateY(1px)}.pdx-card-icon{grid-row:span 2;display:flex;align-items:center;justify-content:center;color:color-mix(in oklab,var(--md-sys-color-primary) 70%,#666)}.pdx-card-title{font-weight:600;line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pdx-card-desc{color:#000000b3;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}.pdx-empty{padding:24px;display:grid;place-items:center;color:#0009;gap:8px}@media (max-width: 600px){.pdx-palette-content{min-width:320px}.pdx-grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
386
|
+
}
|
|
387
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ComponentPaletteDialogComponent, decorators: [{
|
|
388
|
+
type: Component,
|
|
389
|
+
args: [{ selector: 'praxis-component-palette-dialog', standalone: true, imports: [CommonModule, FormsModule, MatDialogModule, MatFormFieldModule, MatInputModule, MatIconModule, MatButtonModule, PraxisIconDirective], template: `
|
|
390
|
+
<h2 mat-dialog-title>
|
|
391
|
+
<div class="dlg-title">
|
|
392
|
+
<mat-icon class="dlg-icon" [praxisIcon]="'widgets'"></mat-icon>
|
|
393
|
+
<div class="dlg-texts">
|
|
394
|
+
<div class="dlg-head">{{ data?.title || 'Inserir componente' }}</div>
|
|
395
|
+
<div class="dlg-sub">Escolha um componente para adicionar à página · {{ filtered().length }} disponíveis</div>
|
|
396
|
+
</div>
|
|
397
|
+
</div>
|
|
398
|
+
</h2>
|
|
399
|
+
<div mat-dialog-content class="pdx-palette-content">
|
|
400
|
+
<div class="pdx-grid" [ngClass]="density()" *ngIf="filtered().length; else emptyState">
|
|
401
|
+
<div
|
|
402
|
+
*ngFor="let m of filtered(); trackBy: trackById"
|
|
403
|
+
class="pdx-card mat-elevation-z2"
|
|
404
|
+
tabindex="0"
|
|
405
|
+
role="button"
|
|
406
|
+
[attr.aria-label]="'Adicionar ' + (m.friendlyName || m.id)"
|
|
407
|
+
(click)="select(m.id)"
|
|
408
|
+
(keydown.enter)="select(m.id)"
|
|
409
|
+
(keydown.space)="select(m.id)"
|
|
410
|
+
>
|
|
411
|
+
<div class="pdx-card-icon">
|
|
412
|
+
<mat-icon [praxisIcon]="m.icon || 'widgets'"></mat-icon>
|
|
413
|
+
</div>
|
|
414
|
+
<div class="pdx-card-body">
|
|
415
|
+
<div class="pdx-card-title">{{ m.friendlyName || m.id }}</div>
|
|
416
|
+
<div class="pdx-card-desc">{{ m.description || m.selector }}</div>
|
|
417
|
+
</div>
|
|
418
|
+
</div>
|
|
419
|
+
</div>
|
|
420
|
+
|
|
421
|
+
<ng-template #emptyState>
|
|
422
|
+
<div class="pdx-empty">
|
|
423
|
+
<mat-icon [praxisIcon]="'sentiment_dissatisfied'"></mat-icon>
|
|
424
|
+
<div>Nenhum componente disponível</div>
|
|
425
|
+
</div>
|
|
426
|
+
</ng-template>
|
|
427
|
+
</div>
|
|
428
|
+
<div mat-dialog-actions align="end">
|
|
429
|
+
<button mat-stroked-button color="primary" mat-dialog-close>Cancelar</button>
|
|
430
|
+
</div>
|
|
431
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}h2[mat-dialog-title]{margin:0;padding:12px 24px 10px;border-bottom:1px solid var(--md-sys-color-outline-variant, rgba(0,0,0,.12))}.dlg-title{display:flex;align-items:center;gap:10px}.dlg-icon{color:var(--md-sys-color-primary, #3f51b5)}.dlg-head{font-size:18px;font-weight:600;line-height:1.2}.dlg-sub{font-size:12px;opacity:.85;color:var(--md-sys-color-on-surface-variant, rgba(0,0,0,.62))}.pdx-palette-content{min-width:480px;max-width:920px;padding-top:8px}.pdx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:14px}.pdx-grid.dense{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}.pdx-grid.roomy{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px}.pdx-card{position:relative;display:grid;grid-template-columns:44px 1fr;grid-template-rows:auto auto;gap:10px;padding:14px;border:1px solid transparent;border-radius:14px;cursor:pointer;outline:none;min-height:92px;background:linear-gradient(var(--md-sys-color-surface),var(--md-sys-color-surface)) padding-box,linear-gradient(135deg,color-mix(in oklab,var(--md-sys-color-primary, #3f51b5) 55%,transparent),color-mix(in oklab,var(--md-sys-color-secondary, #ff4081) 45%,transparent)) border-box;transition:box-shadow .2s ease,background .25s ease,transform .06s ease}.pdx-grid.dense .pdx-card{padding:10px;border-radius:12px;min-height:84px}.pdx-grid.roomy .pdx-card{padding:16px;border-radius:16px;min-height:100px}.pdx-card:focus,.pdx-card:hover{box-shadow:var(--mat-elevation-transition),var(--mat-elevation-level6, 0 6px 12px rgba(0,0,0,.22));background:linear-gradient(var(--md-sys-color-surface),var(--md-sys-color-surface)) padding-box,linear-gradient(135deg,color-mix(in oklab,var(--md-sys-color-primary) 70%,transparent),color-mix(in oklab,var(--md-sys-color-secondary) 55%,transparent)) border-box}.pdx-card:active{transform:translateY(1px)}.pdx-card-icon{grid-row:span 2;display:flex;align-items:center;justify-content:center;color:color-mix(in oklab,var(--md-sys-color-primary) 70%,#666)}.pdx-card-title{font-weight:600;line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pdx-card-desc{color:#000000b3;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}.pdx-empty{padding:24px;display:grid;place-items:center;color:#0009;gap:8px}@media (max-width: 600px){.pdx-palette-content{min-width:320px}.pdx-grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}}\n"] }]
|
|
432
|
+
}], ctorParameters: () => [{ type: i1.MatDialogRef }, { type: i2$1.ComponentMetadataRegistry }, { type: undefined, decorators: [{
|
|
433
|
+
type: Inject,
|
|
434
|
+
args: [MAT_DIALOG_DATA]
|
|
435
|
+
}] }] });
|
|
436
|
+
|
|
437
|
+
class ConnectionBuilderComponent {
|
|
438
|
+
dialog;
|
|
439
|
+
registry;
|
|
440
|
+
snack;
|
|
441
|
+
page;
|
|
442
|
+
widgets;
|
|
443
|
+
pageChange = new EventEmitter();
|
|
444
|
+
// State
|
|
445
|
+
originalSnapshot = '';
|
|
446
|
+
showOnlyIssues = false;
|
|
447
|
+
showFriendly = true;
|
|
448
|
+
filterText = '';
|
|
449
|
+
groupBy = 'none';
|
|
450
|
+
sortBy = 'from';
|
|
451
|
+
// Move braces-containing placeholder into TS (AGENTS.md policy)
|
|
452
|
+
mapPlaceholder = 'payload | payload.id | ${payload.id}';
|
|
453
|
+
// Signals
|
|
454
|
+
connections = signal([], ...(ngDevMode ? [{ debugName: "connections" }] : []));
|
|
455
|
+
selectedIndex = signal(-1, ...(ngDevMode ? [{ debugName: "selectedIndex" }] : []));
|
|
456
|
+
// Derived lists
|
|
457
|
+
filteredConnections = computed(() => this.applyFilters(this.connections()), ...(ngDevMode ? [{ debugName: "filteredConnections" }] : []));
|
|
458
|
+
groupedConnections = computed(() => this.applyGrouping(this.filteredConnections()), ...(ngDevMode ? [{ debugName: "groupedConnections" }] : []));
|
|
459
|
+
constructor(dialog, registry, snack) {
|
|
460
|
+
this.dialog = dialog;
|
|
461
|
+
this.registry = registry;
|
|
462
|
+
this.snack = snack;
|
|
463
|
+
}
|
|
464
|
+
ngOnInit() {
|
|
465
|
+
const p = this.parsePage(this.page);
|
|
466
|
+
const ws = this.widgets || p?.widgets || [];
|
|
467
|
+
this.widgets = ws;
|
|
468
|
+
const conns = [...(p?.connections || [])];
|
|
469
|
+
this.connections.set(conns);
|
|
470
|
+
this.originalSnapshot = JSON.stringify(conns);
|
|
471
|
+
}
|
|
472
|
+
ngOnChanges(changes) {
|
|
473
|
+
if (changes['page'] || changes['widgets']) {
|
|
474
|
+
const p = this.parsePage(this.page);
|
|
475
|
+
this.widgets = this.widgets || p?.widgets || [];
|
|
476
|
+
const next = [...(p?.connections || [])];
|
|
477
|
+
this.connections.set(next);
|
|
478
|
+
this.originalSnapshot = JSON.stringify(next);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
// UI helpers
|
|
482
|
+
isExpanded(i) { return i === this.selectedIndex(); }
|
|
483
|
+
toggleExpanded(i, ev) { if (ev)
|
|
484
|
+
ev.stopPropagation(); this.selectedIndex.set(this.selectedIndex() === i ? -1 : i); }
|
|
485
|
+
setSortBy(v) { this.sortBy = v; this.connections.set(this.sortList([...this.connections()])); }
|
|
486
|
+
onGroupByChange() { }
|
|
487
|
+
toggleShowOnlyIssues() { this.showOnlyIssues = !this.showOnlyIssues; }
|
|
488
|
+
toggleFriendly() { this.showFriendly = !this.showFriendly; }
|
|
489
|
+
trackByIndex = (i) => i;
|
|
490
|
+
// Labels
|
|
491
|
+
fromLabel(c) { return `${c.from.widget}.${c.from.output}`; }
|
|
492
|
+
toLabel(c) { return `${c.to.widget}.${c.to.input}`; }
|
|
493
|
+
fromFriendly(c) { return `${this.widgetFriendlyNameForKey(c.from.widget)}.${c.from.output}`; }
|
|
494
|
+
toFriendly(c) { return `${this.widgetFriendlyNameForKey(c.to.widget)}.${c.to.input}`; }
|
|
495
|
+
outputDescription(c) { return this.registry.get(this.widgetTypeByKey(c.from.widget))?.outputs?.find(o => o.name === c.from.output)?.description || ''; }
|
|
496
|
+
inputDescription(c) { return this.registry.get(this.widgetTypeByKey(c.to.widget))?.inputs?.find(i => i.name === c.to.input)?.description || ''; }
|
|
497
|
+
widgetFriendlyNameForKey(key) { const id = this.widgetTypeByKey(key); return this.registry.get(id)?.friendlyName || id; }
|
|
498
|
+
componentIconForKey(key) { const id = this.widgetTypeByKey(key); return this.registry.get(id)?.icon || 'widgets'; }
|
|
499
|
+
widgetTypeByKey(key) { return this.widgets?.find(w => w.key === key)?.definition?.id || key; }
|
|
500
|
+
applyFilters(list) {
|
|
501
|
+
const q = (this.filterText || '').toLowerCase();
|
|
502
|
+
const arr = list.filter((c) => {
|
|
503
|
+
if (this.showOnlyIssues && this.connectionStatus(c) === 'ok')
|
|
504
|
+
return false;
|
|
505
|
+
if (!q)
|
|
506
|
+
return true;
|
|
507
|
+
const hay = `${c.from.widget}.${c.from.output} ${c.to.widget}.${c.to.input} ${c.map || ''}`.toLowerCase();
|
|
508
|
+
return hay.includes(q);
|
|
509
|
+
});
|
|
510
|
+
return this.sortList(arr);
|
|
511
|
+
}
|
|
512
|
+
applyGrouping(list) {
|
|
513
|
+
switch (this.groupBy) {
|
|
514
|
+
case 'from': return this.groupByKey(list, c => `${c.from.widget}.${c.from.output}`);
|
|
515
|
+
case 'to': return this.groupByKey(list, c => `${c.to.widget}.${c.to.input}`);
|
|
516
|
+
case 'event': return this.groupByKey(list, c => `${c.from.output}`);
|
|
517
|
+
default: return [{ label: 'Todas', list }];
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
groupByKey(list, keyFn) {
|
|
521
|
+
const map = new Map();
|
|
522
|
+
for (const c of list) {
|
|
523
|
+
const k = keyFn(c);
|
|
524
|
+
const arr = map.get(k) || [];
|
|
525
|
+
arr.push(c);
|
|
526
|
+
map.set(k, arr);
|
|
527
|
+
}
|
|
528
|
+
return Array.from(map.entries()).map(([k, v]) => ({ label: k, list: v }));
|
|
529
|
+
}
|
|
530
|
+
sortList(list) {
|
|
531
|
+
return [...list].sort((a, b) => {
|
|
532
|
+
if (this.sortBy === 'from')
|
|
533
|
+
return this.fromLabel(a).localeCompare(this.fromLabel(b));
|
|
534
|
+
return this.toLabel(a).localeCompare(this.toLabel(b));
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
// Editing
|
|
538
|
+
createNew() {
|
|
539
|
+
const fromKey = this.widgets?.[0]?.key || '';
|
|
540
|
+
const toKey = this.widgets?.[1]?.key || '';
|
|
541
|
+
const conn = { from: { widget: fromKey, output: 'submit' }, to: { widget: toKey, input: 'context' } };
|
|
542
|
+
this.connections.set([conn, ...this.connections()]);
|
|
543
|
+
}
|
|
544
|
+
startEdit(index, _c) { this.selectedIndex.set(index); }
|
|
545
|
+
startEditByConn(c) { const i = this.connections().indexOf(c); if (i >= 0)
|
|
546
|
+
this.startEdit(i, c); }
|
|
547
|
+
duplicateConnection(index) { const next = [...this.connections()]; const c = next[index]; if (!c)
|
|
548
|
+
return; next.splice(index + 1, 0, { ...c }); this.connections.set(next); }
|
|
549
|
+
removeConnection(index) { const next = [...this.connections()]; if (index < 0 || index >= next.length)
|
|
550
|
+
return; next.splice(index, 1); this.connections.set(next); }
|
|
551
|
+
// Validation
|
|
552
|
+
connectionStatus(c) {
|
|
553
|
+
if (!c.from?.widget || !c.from?.output || !c.to?.widget || !c.to?.input)
|
|
554
|
+
return 'err';
|
|
555
|
+
const wFrom = this.widgetTypeByKey(c.from.widget);
|
|
556
|
+
const wTo = this.widgetTypeByKey(c.to.widget);
|
|
557
|
+
const outOk = !!this.registry.get(wFrom)?.outputs?.some(o => o.name === c.from.output);
|
|
558
|
+
const inOk = !!this.registry.get(wTo)?.inputs?.some(i => i.name === c.to.input);
|
|
559
|
+
if (!outOk || !inOk)
|
|
560
|
+
return 'warn';
|
|
561
|
+
return 'ok';
|
|
562
|
+
}
|
|
563
|
+
// Persist/apply
|
|
564
|
+
onSave() {
|
|
565
|
+
const p = this.parsePage(this.page) || {};
|
|
566
|
+
const next = { ...p, connections: this.connections() };
|
|
567
|
+
this.page = next;
|
|
568
|
+
this.pageChange.emit(next);
|
|
569
|
+
this.snack.open('Conexões salvas', undefined, { duration: 1000 });
|
|
570
|
+
this.originalSnapshot = JSON.stringify(this.connections());
|
|
571
|
+
}
|
|
572
|
+
// Diagram helpers
|
|
573
|
+
openDiagramFor(_c) {
|
|
574
|
+
import('./praxisui-page-builder-connection-graph.component-C6x--6--.mjs').then(m => {
|
|
575
|
+
this.dialog.open(m.ConnectionGraphComponent, { width: '95vw', height: '80vh', maxWidth: '100vw', panelClass: 'praxis-conn-graph-dialog' });
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
openDiagramFullscreen() {
|
|
579
|
+
import('./praxisui-page-builder-connection-graph.component-C6x--6--.mjs').then(m => {
|
|
580
|
+
this.dialog.open(m.ConnectionGraphComponent, { width: '95vw', height: '95vh', maxWidth: '100vw', panelClass: 'praxis-conn-graph-dialog', autoFocus: false, restoreFocus: false });
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
parsePage(input) {
|
|
584
|
+
if (!input)
|
|
585
|
+
return undefined;
|
|
586
|
+
if (typeof input === 'string') {
|
|
587
|
+
try {
|
|
588
|
+
return JSON.parse(input);
|
|
589
|
+
}
|
|
590
|
+
catch {
|
|
591
|
+
return undefined;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
return input;
|
|
595
|
+
}
|
|
596
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ConnectionBuilderComponent, deps: [{ token: i1.MatDialog }, { token: i2$1.ComponentMetadataRegistry }, { token: i3$3.MatSnackBar }], target: i0.ɵɵFactoryTarget.Component });
|
|
597
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: ConnectionBuilderComponent, isStandalone: true, selector: "praxis-connection-builder", inputs: { page: "page", widgets: "widgets" }, outputs: { pageChange: "pageChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"pdx-conn-root\" role=\"region\" aria-label=\"Construtor de Conex\u00F5es\">\n <div class=\"pdx-conn-head\">\n <span class=\"pdx-conn-title\">Conex\u00F5es</span>\n <span class=\"pdx-conn-count\" aria-label=\"Conex\u00F5es filtradas e total\">{{ filteredConnections().length }} / {{ connections().length }}</span>\n <mat-form-field appearance=\"outline\" class=\"pdx-conn-search\">\n <mat-label>Buscar</mat-label>\n <input matInput [(ngModel)]=\"filterText\" placeholder=\"Origem, Destino, Input, Map...\" />\n <button mat-icon-button matSuffix *ngIf=\"filterText\" (click)=\"filterText='';\" aria-label=\"Limpar busca\"><mat-icon [praxisIcon]=\"'close'\"></mat-icon></button>\n </mat-form-field>\n <span class=\"pdx-spacer\"></span>\n <button mat-button (click)=\"toggleShowOnlyIssues()\" [color]=\"showOnlyIssues ? 'primary': undefined\" aria-label=\"Somente avisos/erros\"><mat-icon [praxisIcon]=\"'report_problem'\"></mat-icon> Issues</button>\n <mat-form-field appearance=\"outline\" style=\"width: 160px;\">\n <mat-label>Ordenar por</mat-label>\n <mat-select [(ngModel)]=\"sortBy\" (ngModelChange)=\"setSortBy($event)\">\n <mat-option value=\"from\">Origem</mat-option>\n <mat-option value=\"to\">Destino</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" style=\"width: 170px;\">\n <mat-label>Agrupar por</mat-label>\n <mat-select [(ngModel)]=\"groupBy\" (ngModelChange)=\"onGroupByChange()\">\n <mat-option value=\"none\">Nenhum</mat-option>\n <mat-option value=\"from\">Origem</mat-option>\n <mat-option value=\"to\">Destino</mat-option>\n <mat-option value=\"event\">Evento</mat-option>\n </mat-select>\n </mat-form-field>\n <button mat-icon-button [color]=\"showFriendly ? 'primary' : undefined\" (click)=\"toggleFriendly()\" aria-label=\"Alternar nome amig\u00E1vel/t\u00E9cnico\"><mat-icon [praxisIcon]=\"'translate'\"></mat-icon></button>\n <button mat-stroked-button (click)=\"createNew()\" aria-label=\"Nova conex\u00E3o\"><mat-icon [praxisIcon]=\"'add'\"></mat-icon> Nova Conex\u00E3o</button>\n <button mat-flat-button color=\"accent\" class=\"pdx-diagram-cta\" (click)=\"openDiagramFullscreen()\" aria-label=\"Abrir diagrama em tela cheia\" matTooltip=\"Visualizar conex\u00F5es em grafo\"><mat-icon [praxisIcon]=\"'schema'\"></mat-icon><span>Diagrama</span></button>\n </div>\n\n <div class=\"pdx-conn-grid\">\n <!-- Left: read-only list -->\n <div class=\"pdx-conn-list\" role=\"list\" aria-label=\"Lista de conex\u00F5es\" cdkScrollable>\n <mat-list *ngIf=\"filteredConnections().length; else noConns\">\n <ng-container *ngIf=\"groupBy!=='none'; else flatList\">\n <div class=\"group-block\" *ngFor=\"let g of groupedConnections(); let gi = index\">\n <div class=\"group-header\">\n <span class=\"group-title\">{{ g.label }}</span>\n <span class=\"group-count\">{{ g.list.length }}</span>\n </div>\n <mat-divider></mat-divider>\n <div class=\"group-list\">\n <ng-container *ngFor=\"let c of g.list; let i = index\">\n <mat-list-item role=\"listitem\" (click)=\"startEdit(i, c)\" [class.selected]=\"selectedIndex()===i\">\n <div class=\"card-head\" matListItemTitle [matTooltip]=\"showFriendly ? (c.from.widget + '.' + c.from.output + ' \u2192 ' + (c.to.widget + '.' + c.to.input)) : ''\">\n <mat-icon class=\"comp-icon from\" [matTooltip]=\"widgetFriendlyNameForKey(c.from.widget)\">{{ componentIconForKey(c.from.widget) }}</mat-icon>\n <span class=\"pdx-badge from\" aria-hidden=\"true\"></span>\n <span class=\"from\">{{ showFriendly ? fromFriendly(c) : fromLabel(c) }}</span>\n <span class=\"arrow\">\u2192</span>\n <mat-icon class=\"comp-icon to\" [matTooltip]=\"widgetFriendlyNameForKey(c.to.widget)\">{{ componentIconForKey(c.to.widget) }}</mat-icon>\n <span class=\"pdx-badge to\" aria-hidden=\"true\"></span>\n <span class=\"to\">{{ showFriendly ? toFriendly(c) : toLabel(c) }}</span>\n <span class=\"spacer\"></span>\n <span class=\"status-pill\" [class.ok]=\"connectionStatus(c)==='ok'\" [class.warn]=\"connectionStatus(c)==='warn'\" [class.err]=\"connectionStatus(c)==='err'\">\n <mat-icon *ngIf=\"connectionStatus(c)==='ok'\">check_circle</mat-icon>\n <mat-icon *ngIf=\"connectionStatus(c)==='warn'\">warning</mat-icon>\n <mat-icon *ngIf=\"connectionStatus(c)==='err'\">error</mat-icon>\n </span>\n <button mat-icon-button class=\"expand-btn\" [attr.aria-expanded]=\"isExpanded(i)\" (click)=\"toggleExpanded(i, $event)\" [matTooltip]=\"isExpanded(i) ? 'Recolher detalhes' : 'Expandir detalhes'\">\n <mat-icon>{{ isExpanded(i) ? 'expand_less' : 'expand_more' }}</mat-icon>\n </button>\n </div>\n <div class=\"meta\" *ngIf=\"showFriendly\" matListItemLine>\n <span class=\"hint\">{{ outputDescription(c) }}</span>\n <span class=\"sep\" *ngIf=\"outputDescription(c) && inputDescription(c)\">\u2022</span>\n <span class=\"hint\">{{ inputDescription(c) }}</span>\n </div>\n <div class=\"map-chip\" *ngIf=\"c.map\" [matTooltip]=\"c.map || ''\" matListItemLine (click)=\"startEditByConn(c)\" title=\"Clique para editar Map\">\n <span class=\"pdx-badge map\" aria-hidden=\"true\"></span>\n <mat-icon class=\"map-icon\" inline>bolt</mat-icon>\n <span class=\"mono\">{{ c.map }}</span>\n </div>\n <div class=\"card-actions\" matListItemLine (click)=\"$event.stopPropagation()\">\n <span class=\"action-group\">\n <button mat-icon-button (click)=\"startEdit(i, c)\" matTooltip=\"Editar\"><mat-icon>settings</mat-icon></button>\n <button mat-icon-button (click)=\"duplicateConnection(i)\" matTooltip=\"Duplicar\"><mat-icon>content_copy</mat-icon></button>\n </span>\n <span class=\"action-group\">\n <button mat-stroked-button color=\"primary\" (click)=\"openDiagramFor(c)\" matTooltip=\"Ver rela\u00E7\u00E3o no diagrama\"><mat-icon>schema</mat-icon><span>Diagrama</span></button>\n </span>\n <span class=\"spacer\"></span>\n <span class=\"action-group\">\n <button mat-icon-button color=\"warn\" (click)=\"removeConnection(i)\" matTooltip=\"Remover\"><mat-icon>delete</mat-icon></button>\n </span>\n </div>\n <div class=\"card-details\" matListItemLine [class.expanded]=\"isExpanded(i)\" [style.maxHeight]=\"isExpanded(i) ? '240px' : '0px'\" [style.opacity]=\"isExpanded(i) ? 1 : 0\" [style.pointerEvents]=\"isExpanded(i) ? 'auto' : 'none'\">\n <div class=\"stepper\">\n <div class=\"step from-step\">\n <div class=\"dot from\"></div>\n <div class=\"content\">\n <div class=\"label\">De</div>\n <div class=\"value\">{{ showFriendly ? fromFriendly(c) : fromLabel(c) }}</div>\n </div>\n </div>\n <div class=\"step to-step\">\n <div class=\"dot to\"></div>\n <div class=\"content\">\n <div class=\"label\">Para</div>\n <div class=\"value\">{{ showFriendly ? toFriendly(c) : toLabel(c) }}</div>\n </div>\n </div>\n <div class=\"step map-step\" *ngIf=\"c.map\">\n <div class=\"dot map\"></div>\n <div class=\"content\">\n <div class=\"label\">Map</div>\n <div class=\"value mono\">{{ c.map }}</div>\n </div>\n </div>\n </div>\n </div>\n </mat-list-item>\n </ng-container>\n </div>\n </div>\n </ng-container>\n <ng-template #flatList>\n <ng-container *ngFor=\"let c of filteredConnections(); let i = index\">\n <mat-list-item role=\"listitem\" (click)=\"startEdit(i, c)\" [class.selected]=\"selectedIndex()===i\">\n <div class=\"card-head\" matListItemTitle [matTooltip]=\"showFriendly ? (c.from.widget + '.' + c.from.output + ' \u2192 ' + (c.to.widget + '.' + c.to.input)) : ''\">\n <mat-icon class=\"comp-icon from\" [matTooltip]=\"widgetFriendlyNameForKey(c.from.widget)\">{{ componentIconForKey(c.from.widget) }}</mat-icon>\n <span class=\"pdx-badge from\" aria-hidden=\"true\"></span>\n <span class=\"from\">{{ showFriendly ? fromFriendly(c) : fromLabel(c) }}</span>\n <span class=\"arrow\">\u2192</span>\n <mat-icon class=\"comp-icon to\" [matTooltip]=\"widgetFriendlyNameForKey(c.to.widget)\">{{ componentIconForKey(c.to.widget) }}</mat-icon>\n <span class=\"pdx-badge to\" aria-hidden=\"true\"></span>\n <span class=\"to\">{{ showFriendly ? toFriendly(c) : toLabel(c) }}</span>\n <span class=\"spacer\"></span>\n <span class=\"status-pill\" [class.ok]=\"connectionStatus(c)==='ok'\" [class.warn]=\"connectionStatus(c)==='warn'\" [class.err]=\"connectionStatus(c)==='err'\">\n <mat-icon *ngIf=\"connectionStatus(c)==='ok'\">check_circle</mat-icon>\n <mat-icon *ngIf=\"connectionStatus(c)==='warn'\">warning</mat-icon>\n <mat-icon *ngIf=\"connectionStatus(c)==='err'\">error</mat-icon>\n </span>\n <button mat-icon-button class=\"expand-btn\" [attr.aria-expanded]=\"isExpanded(i)\" (click)=\"toggleExpanded(i, $event)\" [matTooltip]=\"isExpanded(i) ? 'Recolher detalhes' : 'Expandir detalhes'\">\n <mat-icon>{{ isExpanded(i) ? 'expand_less' : 'expand_more' }}</mat-icon>\n </button>\n </div>\n <div class=\"meta\" *ngIf=\"showFriendly\" matListItemLine>\n <span class=\"hint\">{{ outputDescription(c) }}</span>\n <span class=\"sep\" *ngIf=\"outputDescription(c) && inputDescription(c)\">\u2022</span>\n <span class=\"hint\">{{ inputDescription(c) }}</span>\n </div>\n <div class=\"map-chip\" *ngIf=\"c.map\" [matTooltip]=\"c.map || ''\" matListItemLine (click)=\"startEditByConn(c)\" title=\"Clique para editar Map\">\n <span class=\"pdx-badge map\" aria-hidden=\"true\"></span>\n <mat-icon class=\"map-icon\" inline>bolt</mat-icon>\n <span class=\"mono\">{{ c.map }}</span>\n </div>\n <div class=\"card-actions\" matListItemLine (click)=\"$event.stopPropagation()\">\n <span class=\"action-group\">\n <button mat-icon-button (click)=\"startEdit(i, c)\" matTooltip=\"Editar\"><mat-icon>settings</mat-icon></button>\n <button mat-icon-button (click)=\"duplicateConnection(i)\" matTooltip=\"Duplicar\"><mat-icon>content_copy</mat-icon></button>\n </span>\n <span class=\"action-group\">\n <button mat-stroked-button color=\"primary\" (click)=\"openDiagramFor(c)\" matTooltip=\"Ver rela\u00E7\u00E3o no diagrama\"><mat-icon>schema</mat-icon><span>Diagrama</span></button>\n </span>\n <span class=\"spacer\"></span>\n <span class=\"action-group\">\n <button mat-icon-button color=\"warn\" (click)=\"removeConnection(i)\" matTooltip=\"Remover\"><mat-icon>delete</mat-icon></button>\n </span>\n </div>\n <div class=\"card-details\" matListItemLine [class.expanded]=\"isExpanded(i)\" [style.maxHeight]=\"isExpanded(i) ? '240px' : '0px'\" [style.opacity]=\"isExpanded(i) ? 1 : 0\" [style.pointerEvents]=\"isExpanded(i) ? 'auto' : 'none'\">\n <div class=\"stepper\">\n <div class=\"step from-step\">\n <div class=\"dot from\"></div>\n <div class=\"content\">\n <div class=\"label\">De</div>\n <div class=\"value\">{{ showFriendly ? fromFriendly(c) : fromLabel(c) }}</div>\n </div>\n </div>\n <div class=\"step to-step\">\n <div class=\"dot to\"></div>\n <div class=\"content\">\n <div class=\"label\">Para</div>\n <div class=\"value\">{{ showFriendly ? toFriendly(c) : toLabel(c) }}</div>\n </div>\n </div>\n <div class=\"step map-step\" *ngIf=\"c.map\">\n <div class=\"dot map\"></div>\n <div class=\"content\">\n <div class=\"label\">Map</div>\n <div class=\"value mono\">{{ c.map }}</div>\n </div>\n </div>\n </div>\n </div>\n </mat-list-item>\n </ng-container>\n </ng-template>\n </mat-list>\n <ng-template #noConns>\n <div class=\"pdx-empty-list\" role=\"status\" aria-live=\"polite\">\n <mat-icon>link_off</mat-icon>\n <div>Nenhuma conex\u00E3o definida. Use \u201CNova Conex\u00E3o\u201D.</div>\n </div>\n </ng-template>\n </div>\n\n <!-- Right: editor form -->\n <div class=\"pdx-conn-editor\" role=\"form\" aria-label=\"Editor de conex\u00E3o\">\n <ng-container *ngIf=\"selectedIndex() >= 0; else emptyEditor\">\n <div class=\"form-grid\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Origem (widget.key)</mat-label>\n <input matInput [(ngModel)]=\"connections()[selectedIndex()].from.widget\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Evento (output)</mat-label>\n <input matInput [(ngModel)]=\"connections()[selectedIndex()].from.output\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Destino (widget.key)</mat-label>\n <input matInput [(ngModel)]=\"connections()[selectedIndex()].to.widget\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Input</mat-label>\n <input matInput [(ngModel)]=\"connections()[selectedIndex()].to.input\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"full-span\">\n <mat-label>Map (opcional)</mat-label>\n <input matInput [(ngModel)]=\"connections()[selectedIndex()].map\" [placeholder]=\"mapPlaceholder\" />\n </mat-form-field>\n <div class=\"full-span\">\n <button mat-flat-button color=\"primary\" (click)=\"onSave()\"><mat-icon [praxisIcon]=\"'save'\"></mat-icon>Salvar</button>\n </div>\n </div>\n </ng-container>\n <ng-template #emptyEditor>\n <div class=\"pdx-empty-editor\">Selecione uma conex\u00E3o para editar.</div>\n </ng-template>\n </div>\n </div>\n</div>\n", styles: [".pdx-conn-root{display:grid;gap:12px}.pdx-conn-head{display:flex;align-items:center;gap:8px}.pdx-conn-title{font-weight:600}.pdx-conn-count{opacity:.8}.pdx-conn-search{width:260px}.pdx-spacer{flex:1}.pdx-diagram-cta span{margin-left:6px}.pdx-conn-grid{display:grid;grid-template-columns:1.4fr 1fr;gap:12px}.pdx-conn-list{height:540px;overflow:auto;padding:8px 0}.pdx-conn-list .mat-mdc-list-item.mdc-list-item{height:auto;padding:10px 8px 8px}.card-head{display:flex;align-items:center;gap:6px}.card-head .spacer{flex:1}.card-head .comp-icon{opacity:.85}.card-head .expand-btn{margin-left:4px}.status-pill{display:inline-flex;align-items:center;gap:4px;border-radius:999px;padding:2px 8px}.status-pill.ok{background:color-mix(in oklab,var(--md-sys-color-primary) 15%,transparent);color:color-mix(in oklab,var(--md-sys-color-primary) 60%,#0a0)}.status-pill.warn{background:color-mix(in oklab,var(--md-sys-color-tertiary) 15%,transparent);color:color-mix(in oklab,var(--md-sys-color-tertiary) 60%,#aa0)}.status-pill.err{background:color-mix(in oklab,var(--md-sys-color-error) 15%,transparent);color:color-mix(in oklab,var(--md-sys-color-error) 60%,#a00)}.map-chip{display:inline-flex;align-items:center;gap:6px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.map-chip .map-icon{font-size:16px}.pdx-conn-editor{min-height:540px;padding:8px;border-left:1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, .12))}.pdx-empty-list{padding:16px;display:grid;place-items:center;gap:6px;opacity:.8}.pdx-empty-editor{padding:16px;opacity:.75}.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;align-content:start}.full-span{grid-column:1/-1}.stepper{display:grid;grid-template-columns:1fr 1fr 1fr;gap:16px;padding:8px 0}.step{display:grid;grid-template-columns:12px 1fr;gap:8px;align-items:start}.dot{width:12px;height:12px;border-radius:50%;margin-top:5px}.dot.from{background:color-mix(in oklab,var(--md-sys-color-primary) 70%,transparent)}.dot.to{background:color-mix(in oklab,var(--md-sys-color-secondary) 70%,transparent)}.dot.map{background:color-mix(in oklab,var(--md-sys-color-tertiary) 70%,transparent)}.group-block{padding:6px 6px 10px}.group-header{display:flex;gap:8px;align-items:center;padding:8px 0}.group-title{font-weight:600}.group-count{opacity:.75}.group-list{display:grid;gap:6px}.pdx-badge{width:10px;height:10px;border-radius:50%;display:inline-block}.pdx-badge.from{background:color-mix(in oklab,var(--md-sys-color-primary) 50%,transparent)}.pdx-badge.to{background:color-mix(in oklab,var(--md-sys-color-secondary) 50%,transparent)}.pdx-badge.map{background:color-mix(in oklab,var(--md-sys-color-tertiary) 50%,transparent)}.mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:12px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.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: MatSelectModule }, { kind: "directive", type: i8.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "component", type: i9.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i9.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i12.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i12.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "component", type: i12.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i12.MatListItemLine, selector: "[matListItemLine]" }, { kind: "directive", type: i12.MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
598
|
+
}
|
|
599
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ConnectionBuilderComponent, decorators: [{
|
|
600
|
+
type: Component,
|
|
601
|
+
args: [{ selector: 'praxis-connection-builder', standalone: true, imports: [CommonModule, FormsModule, MatFormFieldModule, MatInputModule, MatSelectModule, MatButtonModule, MatIconModule, MatListModule, MatDialogModule, MatAutocompleteModule, MatMenuModule, MatTabsModule, MatTooltipModule, MatProgressBarModule, MatCheckboxModule, MatSnackBarModule, ScrollingModule, PraxisIconDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"pdx-conn-root\" role=\"region\" aria-label=\"Construtor de Conex\u00F5es\">\n <div class=\"pdx-conn-head\">\n <span class=\"pdx-conn-title\">Conex\u00F5es</span>\n <span class=\"pdx-conn-count\" aria-label=\"Conex\u00F5es filtradas e total\">{{ filteredConnections().length }} / {{ connections().length }}</span>\n <mat-form-field appearance=\"outline\" class=\"pdx-conn-search\">\n <mat-label>Buscar</mat-label>\n <input matInput [(ngModel)]=\"filterText\" placeholder=\"Origem, Destino, Input, Map...\" />\n <button mat-icon-button matSuffix *ngIf=\"filterText\" (click)=\"filterText='';\" aria-label=\"Limpar busca\"><mat-icon [praxisIcon]=\"'close'\"></mat-icon></button>\n </mat-form-field>\n <span class=\"pdx-spacer\"></span>\n <button mat-button (click)=\"toggleShowOnlyIssues()\" [color]=\"showOnlyIssues ? 'primary': undefined\" aria-label=\"Somente avisos/erros\"><mat-icon [praxisIcon]=\"'report_problem'\"></mat-icon> Issues</button>\n <mat-form-field appearance=\"outline\" style=\"width: 160px;\">\n <mat-label>Ordenar por</mat-label>\n <mat-select [(ngModel)]=\"sortBy\" (ngModelChange)=\"setSortBy($event)\">\n <mat-option value=\"from\">Origem</mat-option>\n <mat-option value=\"to\">Destino</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" style=\"width: 170px;\">\n <mat-label>Agrupar por</mat-label>\n <mat-select [(ngModel)]=\"groupBy\" (ngModelChange)=\"onGroupByChange()\">\n <mat-option value=\"none\">Nenhum</mat-option>\n <mat-option value=\"from\">Origem</mat-option>\n <mat-option value=\"to\">Destino</mat-option>\n <mat-option value=\"event\">Evento</mat-option>\n </mat-select>\n </mat-form-field>\n <button mat-icon-button [color]=\"showFriendly ? 'primary' : undefined\" (click)=\"toggleFriendly()\" aria-label=\"Alternar nome amig\u00E1vel/t\u00E9cnico\"><mat-icon [praxisIcon]=\"'translate'\"></mat-icon></button>\n <button mat-stroked-button (click)=\"createNew()\" aria-label=\"Nova conex\u00E3o\"><mat-icon [praxisIcon]=\"'add'\"></mat-icon> Nova Conex\u00E3o</button>\n <button mat-flat-button color=\"accent\" class=\"pdx-diagram-cta\" (click)=\"openDiagramFullscreen()\" aria-label=\"Abrir diagrama em tela cheia\" matTooltip=\"Visualizar conex\u00F5es em grafo\"><mat-icon [praxisIcon]=\"'schema'\"></mat-icon><span>Diagrama</span></button>\n </div>\n\n <div class=\"pdx-conn-grid\">\n <!-- Left: read-only list -->\n <div class=\"pdx-conn-list\" role=\"list\" aria-label=\"Lista de conex\u00F5es\" cdkScrollable>\n <mat-list *ngIf=\"filteredConnections().length; else noConns\">\n <ng-container *ngIf=\"groupBy!=='none'; else flatList\">\n <div class=\"group-block\" *ngFor=\"let g of groupedConnections(); let gi = index\">\n <div class=\"group-header\">\n <span class=\"group-title\">{{ g.label }}</span>\n <span class=\"group-count\">{{ g.list.length }}</span>\n </div>\n <mat-divider></mat-divider>\n <div class=\"group-list\">\n <ng-container *ngFor=\"let c of g.list; let i = index\">\n <mat-list-item role=\"listitem\" (click)=\"startEdit(i, c)\" [class.selected]=\"selectedIndex()===i\">\n <div class=\"card-head\" matListItemTitle [matTooltip]=\"showFriendly ? (c.from.widget + '.' + c.from.output + ' \u2192 ' + (c.to.widget + '.' + c.to.input)) : ''\">\n <mat-icon class=\"comp-icon from\" [matTooltip]=\"widgetFriendlyNameForKey(c.from.widget)\">{{ componentIconForKey(c.from.widget) }}</mat-icon>\n <span class=\"pdx-badge from\" aria-hidden=\"true\"></span>\n <span class=\"from\">{{ showFriendly ? fromFriendly(c) : fromLabel(c) }}</span>\n <span class=\"arrow\">\u2192</span>\n <mat-icon class=\"comp-icon to\" [matTooltip]=\"widgetFriendlyNameForKey(c.to.widget)\">{{ componentIconForKey(c.to.widget) }}</mat-icon>\n <span class=\"pdx-badge to\" aria-hidden=\"true\"></span>\n <span class=\"to\">{{ showFriendly ? toFriendly(c) : toLabel(c) }}</span>\n <span class=\"spacer\"></span>\n <span class=\"status-pill\" [class.ok]=\"connectionStatus(c)==='ok'\" [class.warn]=\"connectionStatus(c)==='warn'\" [class.err]=\"connectionStatus(c)==='err'\">\n <mat-icon *ngIf=\"connectionStatus(c)==='ok'\">check_circle</mat-icon>\n <mat-icon *ngIf=\"connectionStatus(c)==='warn'\">warning</mat-icon>\n <mat-icon *ngIf=\"connectionStatus(c)==='err'\">error</mat-icon>\n </span>\n <button mat-icon-button class=\"expand-btn\" [attr.aria-expanded]=\"isExpanded(i)\" (click)=\"toggleExpanded(i, $event)\" [matTooltip]=\"isExpanded(i) ? 'Recolher detalhes' : 'Expandir detalhes'\">\n <mat-icon>{{ isExpanded(i) ? 'expand_less' : 'expand_more' }}</mat-icon>\n </button>\n </div>\n <div class=\"meta\" *ngIf=\"showFriendly\" matListItemLine>\n <span class=\"hint\">{{ outputDescription(c) }}</span>\n <span class=\"sep\" *ngIf=\"outputDescription(c) && inputDescription(c)\">\u2022</span>\n <span class=\"hint\">{{ inputDescription(c) }}</span>\n </div>\n <div class=\"map-chip\" *ngIf=\"c.map\" [matTooltip]=\"c.map || ''\" matListItemLine (click)=\"startEditByConn(c)\" title=\"Clique para editar Map\">\n <span class=\"pdx-badge map\" aria-hidden=\"true\"></span>\n <mat-icon class=\"map-icon\" inline>bolt</mat-icon>\n <span class=\"mono\">{{ c.map }}</span>\n </div>\n <div class=\"card-actions\" matListItemLine (click)=\"$event.stopPropagation()\">\n <span class=\"action-group\">\n <button mat-icon-button (click)=\"startEdit(i, c)\" matTooltip=\"Editar\"><mat-icon>settings</mat-icon></button>\n <button mat-icon-button (click)=\"duplicateConnection(i)\" matTooltip=\"Duplicar\"><mat-icon>content_copy</mat-icon></button>\n </span>\n <span class=\"action-group\">\n <button mat-stroked-button color=\"primary\" (click)=\"openDiagramFor(c)\" matTooltip=\"Ver rela\u00E7\u00E3o no diagrama\"><mat-icon>schema</mat-icon><span>Diagrama</span></button>\n </span>\n <span class=\"spacer\"></span>\n <span class=\"action-group\">\n <button mat-icon-button color=\"warn\" (click)=\"removeConnection(i)\" matTooltip=\"Remover\"><mat-icon>delete</mat-icon></button>\n </span>\n </div>\n <div class=\"card-details\" matListItemLine [class.expanded]=\"isExpanded(i)\" [style.maxHeight]=\"isExpanded(i) ? '240px' : '0px'\" [style.opacity]=\"isExpanded(i) ? 1 : 0\" [style.pointerEvents]=\"isExpanded(i) ? 'auto' : 'none'\">\n <div class=\"stepper\">\n <div class=\"step from-step\">\n <div class=\"dot from\"></div>\n <div class=\"content\">\n <div class=\"label\">De</div>\n <div class=\"value\">{{ showFriendly ? fromFriendly(c) : fromLabel(c) }}</div>\n </div>\n </div>\n <div class=\"step to-step\">\n <div class=\"dot to\"></div>\n <div class=\"content\">\n <div class=\"label\">Para</div>\n <div class=\"value\">{{ showFriendly ? toFriendly(c) : toLabel(c) }}</div>\n </div>\n </div>\n <div class=\"step map-step\" *ngIf=\"c.map\">\n <div class=\"dot map\"></div>\n <div class=\"content\">\n <div class=\"label\">Map</div>\n <div class=\"value mono\">{{ c.map }}</div>\n </div>\n </div>\n </div>\n </div>\n </mat-list-item>\n </ng-container>\n </div>\n </div>\n </ng-container>\n <ng-template #flatList>\n <ng-container *ngFor=\"let c of filteredConnections(); let i = index\">\n <mat-list-item role=\"listitem\" (click)=\"startEdit(i, c)\" [class.selected]=\"selectedIndex()===i\">\n <div class=\"card-head\" matListItemTitle [matTooltip]=\"showFriendly ? (c.from.widget + '.' + c.from.output + ' \u2192 ' + (c.to.widget + '.' + c.to.input)) : ''\">\n <mat-icon class=\"comp-icon from\" [matTooltip]=\"widgetFriendlyNameForKey(c.from.widget)\">{{ componentIconForKey(c.from.widget) }}</mat-icon>\n <span class=\"pdx-badge from\" aria-hidden=\"true\"></span>\n <span class=\"from\">{{ showFriendly ? fromFriendly(c) : fromLabel(c) }}</span>\n <span class=\"arrow\">\u2192</span>\n <mat-icon class=\"comp-icon to\" [matTooltip]=\"widgetFriendlyNameForKey(c.to.widget)\">{{ componentIconForKey(c.to.widget) }}</mat-icon>\n <span class=\"pdx-badge to\" aria-hidden=\"true\"></span>\n <span class=\"to\">{{ showFriendly ? toFriendly(c) : toLabel(c) }}</span>\n <span class=\"spacer\"></span>\n <span class=\"status-pill\" [class.ok]=\"connectionStatus(c)==='ok'\" [class.warn]=\"connectionStatus(c)==='warn'\" [class.err]=\"connectionStatus(c)==='err'\">\n <mat-icon *ngIf=\"connectionStatus(c)==='ok'\">check_circle</mat-icon>\n <mat-icon *ngIf=\"connectionStatus(c)==='warn'\">warning</mat-icon>\n <mat-icon *ngIf=\"connectionStatus(c)==='err'\">error</mat-icon>\n </span>\n <button mat-icon-button class=\"expand-btn\" [attr.aria-expanded]=\"isExpanded(i)\" (click)=\"toggleExpanded(i, $event)\" [matTooltip]=\"isExpanded(i) ? 'Recolher detalhes' : 'Expandir detalhes'\">\n <mat-icon>{{ isExpanded(i) ? 'expand_less' : 'expand_more' }}</mat-icon>\n </button>\n </div>\n <div class=\"meta\" *ngIf=\"showFriendly\" matListItemLine>\n <span class=\"hint\">{{ outputDescription(c) }}</span>\n <span class=\"sep\" *ngIf=\"outputDescription(c) && inputDescription(c)\">\u2022</span>\n <span class=\"hint\">{{ inputDescription(c) }}</span>\n </div>\n <div class=\"map-chip\" *ngIf=\"c.map\" [matTooltip]=\"c.map || ''\" matListItemLine (click)=\"startEditByConn(c)\" title=\"Clique para editar Map\">\n <span class=\"pdx-badge map\" aria-hidden=\"true\"></span>\n <mat-icon class=\"map-icon\" inline>bolt</mat-icon>\n <span class=\"mono\">{{ c.map }}</span>\n </div>\n <div class=\"card-actions\" matListItemLine (click)=\"$event.stopPropagation()\">\n <span class=\"action-group\">\n <button mat-icon-button (click)=\"startEdit(i, c)\" matTooltip=\"Editar\"><mat-icon>settings</mat-icon></button>\n <button mat-icon-button (click)=\"duplicateConnection(i)\" matTooltip=\"Duplicar\"><mat-icon>content_copy</mat-icon></button>\n </span>\n <span class=\"action-group\">\n <button mat-stroked-button color=\"primary\" (click)=\"openDiagramFor(c)\" matTooltip=\"Ver rela\u00E7\u00E3o no diagrama\"><mat-icon>schema</mat-icon><span>Diagrama</span></button>\n </span>\n <span class=\"spacer\"></span>\n <span class=\"action-group\">\n <button mat-icon-button color=\"warn\" (click)=\"removeConnection(i)\" matTooltip=\"Remover\"><mat-icon>delete</mat-icon></button>\n </span>\n </div>\n <div class=\"card-details\" matListItemLine [class.expanded]=\"isExpanded(i)\" [style.maxHeight]=\"isExpanded(i) ? '240px' : '0px'\" [style.opacity]=\"isExpanded(i) ? 1 : 0\" [style.pointerEvents]=\"isExpanded(i) ? 'auto' : 'none'\">\n <div class=\"stepper\">\n <div class=\"step from-step\">\n <div class=\"dot from\"></div>\n <div class=\"content\">\n <div class=\"label\">De</div>\n <div class=\"value\">{{ showFriendly ? fromFriendly(c) : fromLabel(c) }}</div>\n </div>\n </div>\n <div class=\"step to-step\">\n <div class=\"dot to\"></div>\n <div class=\"content\">\n <div class=\"label\">Para</div>\n <div class=\"value\">{{ showFriendly ? toFriendly(c) : toLabel(c) }}</div>\n </div>\n </div>\n <div class=\"step map-step\" *ngIf=\"c.map\">\n <div class=\"dot map\"></div>\n <div class=\"content\">\n <div class=\"label\">Map</div>\n <div class=\"value mono\">{{ c.map }}</div>\n </div>\n </div>\n </div>\n </div>\n </mat-list-item>\n </ng-container>\n </ng-template>\n </mat-list>\n <ng-template #noConns>\n <div class=\"pdx-empty-list\" role=\"status\" aria-live=\"polite\">\n <mat-icon>link_off</mat-icon>\n <div>Nenhuma conex\u00E3o definida. Use \u201CNova Conex\u00E3o\u201D.</div>\n </div>\n </ng-template>\n </div>\n\n <!-- Right: editor form -->\n <div class=\"pdx-conn-editor\" role=\"form\" aria-label=\"Editor de conex\u00E3o\">\n <ng-container *ngIf=\"selectedIndex() >= 0; else emptyEditor\">\n <div class=\"form-grid\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Origem (widget.key)</mat-label>\n <input matInput [(ngModel)]=\"connections()[selectedIndex()].from.widget\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Evento (output)</mat-label>\n <input matInput [(ngModel)]=\"connections()[selectedIndex()].from.output\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Destino (widget.key)</mat-label>\n <input matInput [(ngModel)]=\"connections()[selectedIndex()].to.widget\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Input</mat-label>\n <input matInput [(ngModel)]=\"connections()[selectedIndex()].to.input\" />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"full-span\">\n <mat-label>Map (opcional)</mat-label>\n <input matInput [(ngModel)]=\"connections()[selectedIndex()].map\" [placeholder]=\"mapPlaceholder\" />\n </mat-form-field>\n <div class=\"full-span\">\n <button mat-flat-button color=\"primary\" (click)=\"onSave()\"><mat-icon [praxisIcon]=\"'save'\"></mat-icon>Salvar</button>\n </div>\n </div>\n </ng-container>\n <ng-template #emptyEditor>\n <div class=\"pdx-empty-editor\">Selecione uma conex\u00E3o para editar.</div>\n </ng-template>\n </div>\n </div>\n</div>\n", styles: [".pdx-conn-root{display:grid;gap:12px}.pdx-conn-head{display:flex;align-items:center;gap:8px}.pdx-conn-title{font-weight:600}.pdx-conn-count{opacity:.8}.pdx-conn-search{width:260px}.pdx-spacer{flex:1}.pdx-diagram-cta span{margin-left:6px}.pdx-conn-grid{display:grid;grid-template-columns:1.4fr 1fr;gap:12px}.pdx-conn-list{height:540px;overflow:auto;padding:8px 0}.pdx-conn-list .mat-mdc-list-item.mdc-list-item{height:auto;padding:10px 8px 8px}.card-head{display:flex;align-items:center;gap:6px}.card-head .spacer{flex:1}.card-head .comp-icon{opacity:.85}.card-head .expand-btn{margin-left:4px}.status-pill{display:inline-flex;align-items:center;gap:4px;border-radius:999px;padding:2px 8px}.status-pill.ok{background:color-mix(in oklab,var(--md-sys-color-primary) 15%,transparent);color:color-mix(in oklab,var(--md-sys-color-primary) 60%,#0a0)}.status-pill.warn{background:color-mix(in oklab,var(--md-sys-color-tertiary) 15%,transparent);color:color-mix(in oklab,var(--md-sys-color-tertiary) 60%,#aa0)}.status-pill.err{background:color-mix(in oklab,var(--md-sys-color-error) 15%,transparent);color:color-mix(in oklab,var(--md-sys-color-error) 60%,#a00)}.map-chip{display:inline-flex;align-items:center;gap:6px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.map-chip .map-icon{font-size:16px}.pdx-conn-editor{min-height:540px;padding:8px;border-left:1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, .12))}.pdx-empty-list{padding:16px;display:grid;place-items:center;gap:6px;opacity:.8}.pdx-empty-editor{padding:16px;opacity:.75}.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;align-content:start}.full-span{grid-column:1/-1}.stepper{display:grid;grid-template-columns:1fr 1fr 1fr;gap:16px;padding:8px 0}.step{display:grid;grid-template-columns:12px 1fr;gap:8px;align-items:start}.dot{width:12px;height:12px;border-radius:50%;margin-top:5px}.dot.from{background:color-mix(in oklab,var(--md-sys-color-primary) 70%,transparent)}.dot.to{background:color-mix(in oklab,var(--md-sys-color-secondary) 70%,transparent)}.dot.map{background:color-mix(in oklab,var(--md-sys-color-tertiary) 70%,transparent)}.group-block{padding:6px 6px 10px}.group-header{display:flex;gap:8px;align-items:center;padding:8px 0}.group-title{font-weight:600}.group-count{opacity:.75}.group-list{display:grid;gap:6px}.pdx-badge{width:10px;height:10px;border-radius:50%;display:inline-block}.pdx-badge.from{background:color-mix(in oklab,var(--md-sys-color-primary) 50%,transparent)}.pdx-badge.to{background:color-mix(in oklab,var(--md-sys-color-secondary) 50%,transparent)}.pdx-badge.map{background:color-mix(in oklab,var(--md-sys-color-tertiary) 50%,transparent)}.mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:12px}\n"] }]
|
|
602
|
+
}], ctorParameters: () => [{ type: i1.MatDialog }, { type: i2$1.ComponentMetadataRegistry }, { type: i3$3.MatSnackBar }], propDecorators: { page: [{
|
|
603
|
+
type: Input
|
|
604
|
+
}], widgets: [{
|
|
605
|
+
type: Input
|
|
606
|
+
}], pageChange: [{
|
|
607
|
+
type: Output
|
|
608
|
+
}] } });
|
|
609
|
+
|
|
610
|
+
/*
|
|
611
|
+
* Public API Surface of @praxisui/page-builder
|
|
612
|
+
*/
|
|
613
|
+
// Temporary minimal export for build isolation
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Generated bundle index. Do not edit.
|
|
617
|
+
*/
|
|
618
|
+
|
|
619
|
+
export { ComponentPaletteDialogComponent, ConfirmDialogComponent, ConnectionBuilderComponent, FloatingToolbarComponent, PLACEHOLDER, TileToolbarComponent };
|
|
620
|
+
//# sourceMappingURL=praxisui-page-builder.mjs.map
|