@praxisui/core 3.0.0-beta.5 → 3.0.0-beta.7
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 +18 -0
- package/fesm2022/praxisui-core.mjs +2966 -116
- package/fesm2022/praxisui-core.mjs.map +1 -1
- package/index.d.ts +733 -324
- package/package.json +1 -1
|
@@ -1,35 +1,39 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component, InjectionToken, Injectable, inject, Inject, makeEnvironmentProviders, Optional, ENVIRONMENT_INITIALIZER, ErrorHandler, APP_INITIALIZER, Input, ChangeDetectionStrategy, Directive, SecurityContext,
|
|
2
|
+
import { Component, InjectionToken, Injectable, inject, Inject, makeEnvironmentProviders, Optional, ENVIRONMENT_INITIALIZER, ErrorHandler, APP_INITIALIZER, EventEmitter, Output, Input, ChangeDetectionStrategy, Directive, SecurityContext, ViewContainerRef, ContentChild, signal, HostListener, computed, ViewChild } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common/http';
|
|
4
|
-
import { HttpHeaders, HttpClient, HttpParams, HttpContextToken, HTTP_INTERCEPTORS, withInterceptors } from '@angular/common/http';
|
|
4
|
+
import { HttpHeaders, HttpClient, HttpParams, HttpResponse, HttpContextToken, HTTP_INTERCEPTORS, withInterceptors } from '@angular/common/http';
|
|
5
5
|
import { of, defer, throwError, from, EMPTY, BehaviorSubject, firstValueFrom, Subject } from 'rxjs';
|
|
6
6
|
import { switchMap, take, map, catchError, concatMap, tap, shareReplay, takeUntil, toArray, finalize } from 'rxjs/operators';
|
|
7
|
-
import * as i1$
|
|
7
|
+
import * as i1$2 from '@angular/common';
|
|
8
8
|
import { Location, CommonModule } from '@angular/common';
|
|
9
9
|
import { Router, ActivatedRoute } from '@angular/router';
|
|
10
|
-
import * as
|
|
10
|
+
import * as i1$1 from '@angular/forms';
|
|
11
11
|
import { Validators, FormGroup, FormControl, FormsModule } from '@angular/forms';
|
|
12
12
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
|
13
|
+
import * as i2 from '@angular/material/button';
|
|
14
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
15
|
+
import * as i3 from '@angular/material/form-field';
|
|
16
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
13
17
|
import * as i4 from '@angular/material/icon';
|
|
14
18
|
import { MatIconModule } from '@angular/material/icon';
|
|
19
|
+
import * as i5 from '@angular/material/input';
|
|
20
|
+
import { MatInputModule } from '@angular/material/input';
|
|
21
|
+
import * as i6 from '@angular/material/select';
|
|
22
|
+
import { MatSelectModule } from '@angular/material/select';
|
|
23
|
+
import * as i7 from '@angular/material/slide-toggle';
|
|
24
|
+
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|
25
|
+
import * as i5$1 from '@angular/material/tooltip';
|
|
26
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
15
27
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
16
|
-
import * as i2 from '@angular/material/button';
|
|
17
|
-
import { MatButtonModule } from '@angular/material/button';
|
|
18
28
|
import * as i4$1 from '@angular/material/menu';
|
|
19
29
|
import { MatMenuModule } from '@angular/material/menu';
|
|
20
|
-
import * as
|
|
21
|
-
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
22
|
-
import * as i3 from '@angular/material/card';
|
|
30
|
+
import * as i3$1 from '@angular/material/card';
|
|
23
31
|
import { MatCardModule } from '@angular/material/card';
|
|
24
|
-
import * as i3$1 from '@angular/material/form-field';
|
|
25
|
-
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
26
|
-
import * as i4$2 from '@angular/material/input';
|
|
27
|
-
import { MatInputModule } from '@angular/material/input';
|
|
28
32
|
import * as i8 from '@angular/material/chips';
|
|
29
33
|
import { MatChipsModule } from '@angular/material/chips';
|
|
30
|
-
import * as i1$
|
|
34
|
+
import * as i1$3 from '@angular/material/dialog';
|
|
31
35
|
import { MAT_DIALOG_DATA, MatDialogModule, MatDialog } from '@angular/material/dialog';
|
|
32
|
-
import * as i2$
|
|
36
|
+
import * as i2$1 from '@angular/material/tabs';
|
|
33
37
|
import { MatTabsModule } from '@angular/material/tabs';
|
|
34
38
|
|
|
35
39
|
class PraxisCore {
|
|
@@ -594,6 +598,24 @@ function resolveControlTypeAlias(value, fallback = FieldControlType.INPUT) {
|
|
|
594
598
|
return raw;
|
|
595
599
|
}
|
|
596
600
|
|
|
601
|
+
const VALUE_PRESENTATION_TYPES = new Set([
|
|
602
|
+
'string',
|
|
603
|
+
'number',
|
|
604
|
+
'currency',
|
|
605
|
+
'percentage',
|
|
606
|
+
'date',
|
|
607
|
+
'datetime',
|
|
608
|
+
'time',
|
|
609
|
+
'boolean',
|
|
610
|
+
]);
|
|
611
|
+
const VALUE_PRESENTATION_STYLES = new Set([
|
|
612
|
+
'default',
|
|
613
|
+
'short',
|
|
614
|
+
'medium',
|
|
615
|
+
'long',
|
|
616
|
+
'full',
|
|
617
|
+
'compact',
|
|
618
|
+
]);
|
|
597
619
|
/**
|
|
598
620
|
* SchemaNormalizerService
|
|
599
621
|
* -----------------------
|
|
@@ -712,6 +734,41 @@ class SchemaNormalizerService {
|
|
|
712
734
|
}
|
|
713
735
|
return optionSource;
|
|
714
736
|
}
|
|
737
|
+
parseValuePresentation(value) {
|
|
738
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
739
|
+
return undefined;
|
|
740
|
+
}
|
|
741
|
+
const typeToken = String(value.type ?? '').trim();
|
|
742
|
+
if (!typeToken || !VALUE_PRESENTATION_TYPES.has(typeToken)) {
|
|
743
|
+
if (typeToken) {
|
|
744
|
+
console.warn(`[SchemaNormalizer] Ignoring invalid x-ui.valuePresentation.type: ${typeToken}`);
|
|
745
|
+
}
|
|
746
|
+
return undefined;
|
|
747
|
+
}
|
|
748
|
+
const presentation = {
|
|
749
|
+
type: typeToken,
|
|
750
|
+
};
|
|
751
|
+
const styleToken = String(value.style ?? '').trim();
|
|
752
|
+
if (styleToken) {
|
|
753
|
+
if (VALUE_PRESENTATION_STYLES.has(styleToken)) {
|
|
754
|
+
presentation.style = styleToken;
|
|
755
|
+
}
|
|
756
|
+
else {
|
|
757
|
+
console.warn(`[SchemaNormalizer] Ignoring invalid x-ui.valuePresentation.style: ${styleToken}`);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
const formatToken = String(value.format ?? '').trim();
|
|
761
|
+
if (formatToken) {
|
|
762
|
+
presentation.format = formatToken;
|
|
763
|
+
}
|
|
764
|
+
if (value.currency && typeof value.currency === 'object') {
|
|
765
|
+
presentation.currency = { ...value.currency };
|
|
766
|
+
}
|
|
767
|
+
if (value.number && typeof value.number === 'object') {
|
|
768
|
+
presentation.number = { ...value.number };
|
|
769
|
+
}
|
|
770
|
+
return presentation;
|
|
771
|
+
}
|
|
715
772
|
/**
|
|
716
773
|
* Converte string/Function em função real.
|
|
717
774
|
* Atenção: usa `new Function` para avaliar strings – requer backend confiável.
|
|
@@ -955,6 +1012,10 @@ class SchemaNormalizerService {
|
|
|
955
1012
|
field.numericFormat = numericFormat;
|
|
956
1013
|
field.format = numericFormat;
|
|
957
1014
|
}
|
|
1015
|
+
const valuePresentation = this.parseValuePresentation(ui.valuePresentation);
|
|
1016
|
+
if (valuePresentation) {
|
|
1017
|
+
field.valuePresentation = valuePresentation;
|
|
1018
|
+
}
|
|
958
1019
|
if (ui.controlType) {
|
|
959
1020
|
field.controlType = ui.controlType;
|
|
960
1021
|
}
|
|
@@ -1458,6 +1519,8 @@ function resolveDefaultHeaders() {
|
|
|
1458
1519
|
* HTTP-based storage that talks to praxis-config-starter user-config API.
|
|
1459
1520
|
*/
|
|
1460
1521
|
class ApiConfigStorage {
|
|
1522
|
+
static unavailableLoadBaseUrls = new Set();
|
|
1523
|
+
static loadAvailabilityProbes = new Map();
|
|
1461
1524
|
http = inject(HttpClient);
|
|
1462
1525
|
opts = inject(API_CONFIG_STORAGE_OPTIONS, { optional: true });
|
|
1463
1526
|
baseUrl = (this.opts?.baseUrl || '/api/praxis/config/ui').replace(/\/$/, '');
|
|
@@ -1472,13 +1535,86 @@ class ApiConfigStorage {
|
|
|
1472
1535
|
// Simple in-memory cache of etag/payload per key to support 304 reuse
|
|
1473
1536
|
cache = new Map();
|
|
1474
1537
|
constructor() { }
|
|
1538
|
+
shouldLogLoadError(key, err) {
|
|
1539
|
+
if (err?.status === 404)
|
|
1540
|
+
return false;
|
|
1541
|
+
return this.shouldPropagateLoadError(key, err);
|
|
1542
|
+
}
|
|
1543
|
+
shouldLogSaveError(key, err) {
|
|
1544
|
+
if (err?.status === 404)
|
|
1545
|
+
return false;
|
|
1546
|
+
return this.shouldPropagateSaveError(key);
|
|
1547
|
+
}
|
|
1548
|
+
shouldLogClearError(key, err) {
|
|
1549
|
+
if (err?.status === 404)
|
|
1550
|
+
return false;
|
|
1551
|
+
return this.shouldPropagateClearError(key);
|
|
1552
|
+
}
|
|
1475
1553
|
loadConfig(key) {
|
|
1554
|
+
if (ApiConfigStorage.unavailableLoadBaseUrls.has(this.baseUrl)) {
|
|
1555
|
+
return of(null);
|
|
1556
|
+
}
|
|
1557
|
+
const existingProbe = ApiConfigStorage.loadAvailabilityProbes.get(this.baseUrl);
|
|
1558
|
+
if (existingProbe) {
|
|
1559
|
+
return defer(() => from(existingProbe).pipe(switchMap((available) => available ? this.executeLoadConfigRequest(key, false) : of(null))));
|
|
1560
|
+
}
|
|
1561
|
+
return this.executeLoadConfigRequest(key, true);
|
|
1562
|
+
}
|
|
1563
|
+
executeLoadConfigRequest(key, establishAvailability) {
|
|
1476
1564
|
const cached = this.cache.get(key);
|
|
1477
1565
|
const etag = cached?.etag;
|
|
1478
1566
|
const { type, id } = this.resolveKey(key);
|
|
1479
1567
|
const url = `${this.baseUrl}`;
|
|
1480
1568
|
const params = this.buildParams(type, id);
|
|
1481
1569
|
const headers = this.buildHeaders(etag ? { 'If-None-Match': this.formatEtag(etag) } : {});
|
|
1570
|
+
let releaseProbe = null;
|
|
1571
|
+
if (establishAvailability) {
|
|
1572
|
+
let resolveProbe;
|
|
1573
|
+
const probe = new Promise((resolve) => {
|
|
1574
|
+
resolveProbe = resolve;
|
|
1575
|
+
});
|
|
1576
|
+
ApiConfigStorage.loadAvailabilityProbes.set(this.baseUrl, probe);
|
|
1577
|
+
releaseProbe = () => {
|
|
1578
|
+
ApiConfigStorage.loadAvailabilityProbes.delete(this.baseUrl);
|
|
1579
|
+
};
|
|
1580
|
+
const previousRelease = releaseProbe;
|
|
1581
|
+
releaseProbe = () => {
|
|
1582
|
+
resolveProbe(true);
|
|
1583
|
+
previousRelease();
|
|
1584
|
+
};
|
|
1585
|
+
const markUnavailable = () => {
|
|
1586
|
+
ApiConfigStorage.unavailableLoadBaseUrls.add(this.baseUrl);
|
|
1587
|
+
resolveProbe(false);
|
|
1588
|
+
previousRelease();
|
|
1589
|
+
};
|
|
1590
|
+
return this.http
|
|
1591
|
+
.get(url, { observe: 'response', headers, params })
|
|
1592
|
+
.pipe(map((resp) => {
|
|
1593
|
+
const nextEtag = this.stripQuotes(resp.headers.get('ETag'));
|
|
1594
|
+
const body = resp.body;
|
|
1595
|
+
if (nextEtag) {
|
|
1596
|
+
this.cache.set(key, { etag: nextEtag, payload: body?.payload });
|
|
1597
|
+
}
|
|
1598
|
+
releaseProbe?.();
|
|
1599
|
+
return body?.payload ?? null;
|
|
1600
|
+
}), catchError((err) => {
|
|
1601
|
+
if (err.status === 304 && cached?.payload !== undefined) {
|
|
1602
|
+
releaseProbe?.();
|
|
1603
|
+
return of(cached.payload);
|
|
1604
|
+
}
|
|
1605
|
+
if (err.status === 404) {
|
|
1606
|
+
markUnavailable();
|
|
1607
|
+
return of(null);
|
|
1608
|
+
}
|
|
1609
|
+
releaseProbe?.();
|
|
1610
|
+
if (this.shouldLogLoadError(key, err)) {
|
|
1611
|
+
console.warn('[ApiConfigStorage] load error', err);
|
|
1612
|
+
}
|
|
1613
|
+
return this.shouldPropagateLoadError(key, err)
|
|
1614
|
+
? throwError(() => err)
|
|
1615
|
+
: of(null);
|
|
1616
|
+
}));
|
|
1617
|
+
}
|
|
1482
1618
|
return this.http
|
|
1483
1619
|
.get(url, { observe: 'response', headers, params })
|
|
1484
1620
|
.pipe(map((resp) => {
|
|
@@ -1493,9 +1629,13 @@ class ApiConfigStorage {
|
|
|
1493
1629
|
if (err.status === 304 && cached?.payload !== undefined) {
|
|
1494
1630
|
return of(cached.payload);
|
|
1495
1631
|
}
|
|
1496
|
-
if (err.status === 404)
|
|
1632
|
+
if (err.status === 404) {
|
|
1633
|
+
ApiConfigStorage.unavailableLoadBaseUrls.add(this.baseUrl);
|
|
1497
1634
|
return of(null);
|
|
1498
|
-
|
|
1635
|
+
}
|
|
1636
|
+
if (this.shouldLogLoadError(key, err)) {
|
|
1637
|
+
console.warn('[ApiConfigStorage] load error', err);
|
|
1638
|
+
}
|
|
1499
1639
|
return this.shouldPropagateLoadError(key, err)
|
|
1500
1640
|
? throwError(() => err)
|
|
1501
1641
|
: of(null);
|
|
@@ -1513,7 +1653,9 @@ class ApiConfigStorage {
|
|
|
1513
1653
|
const payload = resp.body?.payload ?? config;
|
|
1514
1654
|
this.cache.set(key, { etag: nextEtag, payload });
|
|
1515
1655
|
}), catchError((err) => {
|
|
1516
|
-
|
|
1656
|
+
if (this.shouldLogSaveError(key, err)) {
|
|
1657
|
+
console.warn('[ApiConfigStorage] save error', err);
|
|
1658
|
+
}
|
|
1517
1659
|
return this.shouldPropagateSaveError(key)
|
|
1518
1660
|
? throwError(() => err)
|
|
1519
1661
|
// Soft-fail path: complete without next so runtime can treat as
|
|
@@ -1550,7 +1692,9 @@ class ApiConfigStorage {
|
|
|
1550
1692
|
.pipe(map(() => {
|
|
1551
1693
|
this.cache.delete(key);
|
|
1552
1694
|
}), catchError((err) => {
|
|
1553
|
-
|
|
1695
|
+
if (this.shouldLogClearError(key, err)) {
|
|
1696
|
+
console.warn('[ApiConfigStorage] clear error', err);
|
|
1697
|
+
}
|
|
1554
1698
|
return this.shouldPropagateClearError(key)
|
|
1555
1699
|
? throwError(() => err)
|
|
1556
1700
|
// Soft-fail path: complete without next so runtime can treat as
|
|
@@ -1978,6 +2122,7 @@ class GenericCrudService {
|
|
|
1978
2122
|
emptyEntity: 'A entidade não pode ser nula ou vazia.',
|
|
1979
2123
|
unconfiguredService: 'Serviço não configurado. Chame configure() antes de usar.',
|
|
1980
2124
|
};
|
|
2125
|
+
static unavailableFilteredSchemaUrls = new Set();
|
|
1981
2126
|
baseApiUrl; // Root URL for the API
|
|
1982
2127
|
apiUrl; // Full base path for the configured resource
|
|
1983
2128
|
endpoints = {}; // Stores user-defined custom endpoints
|
|
@@ -2183,6 +2328,10 @@ class GenericCrudService {
|
|
|
2183
2328
|
// Build cache key including the API origin (not the app origin)
|
|
2184
2329
|
const schemaId = buildSchemaId({ path, operation, schemaType, includeInternalSchemas: false, tenant, locale, apiOrigin });
|
|
2185
2330
|
const headersBase = composeHeadersWithVersion(entry);
|
|
2331
|
+
const shouldUseDirectSchemaEndpoint = GenericCrudService.unavailableFilteredSchemaUrls.has(filteredUrl);
|
|
2332
|
+
if (shouldUseDirectSchemaEndpoint) {
|
|
2333
|
+
return this.fetchDirectSchema(url, schemaId, apiOrigin, entry, locale, tenant, options?.httpContext);
|
|
2334
|
+
}
|
|
2186
2335
|
return from(this.ensureSchemaCacheReady()).pipe(concatMap(() => from(this._schemaCache.get(schemaId)).pipe(concatMap((cached) => {
|
|
2187
2336
|
let headers = (headersBase instanceof HttpHeaders ? headersBase : new HttpHeaders(headersBase));
|
|
2188
2337
|
if (cached?.schemaHash) {
|
|
@@ -2279,6 +2428,10 @@ class GenericCrudService {
|
|
|
2279
2428
|
}),
|
|
2280
2429
|
// Angular HttpClient treats 304 as error; also handle status 0 (CORS/network) by reusing cache
|
|
2281
2430
|
catchError((err) => {
|
|
2431
|
+
if (err?.status === 404) {
|
|
2432
|
+
GenericCrudService.unavailableFilteredSchemaUrls.add(filteredUrl);
|
|
2433
|
+
return this.fetchDirectSchema(url, schemaId, apiOrigin, entry, locale, tenant, options?.httpContext);
|
|
2434
|
+
}
|
|
2282
2435
|
if (err?.status === 304 || err?.status === 0) {
|
|
2283
2436
|
return from(this._schemaCache.get(schemaId)).pipe(concatMap((cached) => {
|
|
2284
2437
|
if (cached?.schema) {
|
|
@@ -2335,6 +2488,69 @@ class GenericCrudService {
|
|
|
2335
2488
|
return this.handleError(err);
|
|
2336
2489
|
}))), shareReplay(1));
|
|
2337
2490
|
}
|
|
2491
|
+
fetchDirectSchema(url, schemaId, apiOrigin, entry, locale, tenant, httpContext) {
|
|
2492
|
+
return from(this.ensureSchemaCacheReady()).pipe(concatMap(() => from(this._schemaCache.get(schemaId)).pipe(concatMap((cached) => {
|
|
2493
|
+
const baseHeaders = composeHeadersWithVersion(entry);
|
|
2494
|
+
let headers = (baseHeaders instanceof HttpHeaders ? baseHeaders : new HttpHeaders(baseHeaders));
|
|
2495
|
+
if (cached?.schemaHash) {
|
|
2496
|
+
headers = headers.set('If-None-Match', `"${cached.schemaHash}"`);
|
|
2497
|
+
}
|
|
2498
|
+
if (locale)
|
|
2499
|
+
headers = headers.set('Accept-Language', locale);
|
|
2500
|
+
if (tenant)
|
|
2501
|
+
headers = headers.set('X-Tenant', tenant);
|
|
2502
|
+
return this.http.get(url, {
|
|
2503
|
+
headers,
|
|
2504
|
+
observe: 'response',
|
|
2505
|
+
context: httpContext,
|
|
2506
|
+
}).pipe(concatMap((resp) => {
|
|
2507
|
+
const response = resp instanceof HttpResponse
|
|
2508
|
+
? resp
|
|
2509
|
+
: new HttpResponse({ status: 200, body: resp });
|
|
2510
|
+
const body = response.body;
|
|
2511
|
+
const etag = response.headers.get('ETag') || '';
|
|
2512
|
+
const xHash = response.headers.get('X-Schema-Hash');
|
|
2513
|
+
const schemaHash = (xHash || etag).replace(/^W\//, '').replace(/^"|"$/g, '');
|
|
2514
|
+
const now = new Date().toISOString();
|
|
2515
|
+
const entryToCache = {
|
|
2516
|
+
schema: body,
|
|
2517
|
+
schemaHash,
|
|
2518
|
+
meta: {
|
|
2519
|
+
version: '2.0.0',
|
|
2520
|
+
name: 'Grid/Response Schema',
|
|
2521
|
+
createdAt: now,
|
|
2522
|
+
updatedAt: now,
|
|
2523
|
+
resourcePath: this.resourcePath,
|
|
2524
|
+
schemaId,
|
|
2525
|
+
apiOrigin,
|
|
2526
|
+
},
|
|
2527
|
+
};
|
|
2528
|
+
this._schemaCache.set(schemaId, entryToCache);
|
|
2529
|
+
this._lastSchemaInfo = { schemaId, schemaHash };
|
|
2530
|
+
try {
|
|
2531
|
+
const idField = body?.['x-ui']?.resource?.idField;
|
|
2532
|
+
this._lastResourceMeta = { idField, resourcePath: this.resourcePath };
|
|
2533
|
+
}
|
|
2534
|
+
catch { }
|
|
2535
|
+
return of(this.schemaNormalizer.normalizeSchema(body));
|
|
2536
|
+
}), catchError((err) => {
|
|
2537
|
+
if ((err?.status === 304 || err?.status === 0) && cached?.schema) {
|
|
2538
|
+
try {
|
|
2539
|
+
const idField = cached.schema?.['x-ui']?.resource?.idField;
|
|
2540
|
+
this._lastResourceMeta = {
|
|
2541
|
+
idField: idField || this._lastResourceMeta.idField,
|
|
2542
|
+
resourcePath: this.resourcePath,
|
|
2543
|
+
};
|
|
2544
|
+
}
|
|
2545
|
+
catch { }
|
|
2546
|
+
const cachedHash = cached.schemaHash || '';
|
|
2547
|
+
this._lastSchemaInfo = { schemaId, schemaHash: cachedHash };
|
|
2548
|
+
return of(this.schemaNormalizer.normalizeSchema(cached.schema));
|
|
2549
|
+
}
|
|
2550
|
+
return this.handleError(err);
|
|
2551
|
+
}));
|
|
2552
|
+
}))));
|
|
2553
|
+
}
|
|
2338
2554
|
/** Retorna o campo identificador do recurso (ex.: 'id', 'codigo'), quando derivado do schema. */
|
|
2339
2555
|
getResourceIdField() {
|
|
2340
2556
|
const key = (this._lastResourceMeta?.idField || '').trim();
|
|
@@ -4418,6 +4634,147 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
4418
4634
|
args: [{ providedIn: 'root' }]
|
|
4419
4635
|
}] });
|
|
4420
4636
|
|
|
4637
|
+
class SurfaceBindingRuntimeService {
|
|
4638
|
+
resolveWidget(widget, bindings, actionPayload, actionContext, explicitContext) {
|
|
4639
|
+
const context = this.buildContext(actionPayload, actionContext, explicitContext);
|
|
4640
|
+
let resolvedWidget = this.clone(widget);
|
|
4641
|
+
resolvedWidget = this.resolveTemplate(resolvedWidget, context);
|
|
4642
|
+
for (const binding of bindings || []) {
|
|
4643
|
+
const targetPath = this.normalizeTargetPath(binding?.to);
|
|
4644
|
+
if (!targetPath)
|
|
4645
|
+
continue;
|
|
4646
|
+
const value = this.resolveBindingValue(binding, context);
|
|
4647
|
+
resolvedWidget = this.setValueAtPath(resolvedWidget, targetPath, value);
|
|
4648
|
+
}
|
|
4649
|
+
return resolvedWidget;
|
|
4650
|
+
}
|
|
4651
|
+
extractByPath(obj, path) {
|
|
4652
|
+
if (!path)
|
|
4653
|
+
return obj;
|
|
4654
|
+
return String(path)
|
|
4655
|
+
.split('.')
|
|
4656
|
+
.reduce((acc, key) => acc?.[key], obj);
|
|
4657
|
+
}
|
|
4658
|
+
resolveTemplate(node, context) {
|
|
4659
|
+
if (node == null)
|
|
4660
|
+
return node;
|
|
4661
|
+
if (Array.isArray(node))
|
|
4662
|
+
return node.map((value) => this.resolveTemplate(value, context));
|
|
4663
|
+
if (typeof node === 'object') {
|
|
4664
|
+
const out = {};
|
|
4665
|
+
for (const [key, value] of Object.entries(node)) {
|
|
4666
|
+
out[key] = this.resolveTemplate(value, context);
|
|
4667
|
+
}
|
|
4668
|
+
return out;
|
|
4669
|
+
}
|
|
4670
|
+
if (typeof node === 'string') {
|
|
4671
|
+
const exact = node.match(/^\s*\$\{([^}]+)\}\s*$/);
|
|
4672
|
+
if (exact) {
|
|
4673
|
+
return this.extractByPath(context, exact[1].trim());
|
|
4674
|
+
}
|
|
4675
|
+
return node.replace(/\$\{([^}]+)\}/g, (_match, path) => {
|
|
4676
|
+
const value = this.extractByPath(context, String(path).trim());
|
|
4677
|
+
return value != null ? String(value) : '';
|
|
4678
|
+
});
|
|
4679
|
+
}
|
|
4680
|
+
return node;
|
|
4681
|
+
}
|
|
4682
|
+
setValueAtPath(obj, rawPath, value) {
|
|
4683
|
+
const path = this.tokenizePath(rawPath);
|
|
4684
|
+
if (!path.length)
|
|
4685
|
+
return obj;
|
|
4686
|
+
const clone = Array.isArray(obj) ? obj.slice() : { ...obj };
|
|
4687
|
+
let cursor = clone;
|
|
4688
|
+
for (let i = 0; i < path.length; i++) {
|
|
4689
|
+
const key = path[i];
|
|
4690
|
+
const isLast = i === path.length - 1;
|
|
4691
|
+
if (isLast) {
|
|
4692
|
+
cursor[key] = value;
|
|
4693
|
+
continue;
|
|
4694
|
+
}
|
|
4695
|
+
const next = cursor[key];
|
|
4696
|
+
const nextIsIndex = typeof path[i + 1] === 'number';
|
|
4697
|
+
const created = next != null
|
|
4698
|
+
? (Array.isArray(next) ? next.slice() : { ...next })
|
|
4699
|
+
: (nextIsIndex ? [] : {});
|
|
4700
|
+
cursor[key] = created;
|
|
4701
|
+
cursor = created;
|
|
4702
|
+
}
|
|
4703
|
+
return clone;
|
|
4704
|
+
}
|
|
4705
|
+
buildContext(actionPayload, actionContext, explicitContext) {
|
|
4706
|
+
return {
|
|
4707
|
+
payload: actionContext?.payload,
|
|
4708
|
+
context: explicitContext || {},
|
|
4709
|
+
pageContext: actionContext?.pageContext || undefined,
|
|
4710
|
+
meta: actionContext?.meta || undefined,
|
|
4711
|
+
runtime: actionContext?.runtime || undefined,
|
|
4712
|
+
action: actionPayload,
|
|
4713
|
+
sourceId: actionContext?.sourceId,
|
|
4714
|
+
widgetKey: actionContext?.widgetKey,
|
|
4715
|
+
output: actionContext?.output,
|
|
4716
|
+
};
|
|
4717
|
+
}
|
|
4718
|
+
resolveBindingValue(binding, context) {
|
|
4719
|
+
const mode = binding.mode || (binding.value !== undefined ? 'constant' : 'path');
|
|
4720
|
+
if (mode === 'constant')
|
|
4721
|
+
return this.clone(binding.value);
|
|
4722
|
+
if (mode === 'template') {
|
|
4723
|
+
const templateSource = binding.value !== undefined ? binding.value : binding.from;
|
|
4724
|
+
return this.resolveTemplate(templateSource, context);
|
|
4725
|
+
}
|
|
4726
|
+
return this.extractByPath(context, binding.from);
|
|
4727
|
+
}
|
|
4728
|
+
normalizeTargetPath(rawPath) {
|
|
4729
|
+
const path = String(rawPath || '').trim();
|
|
4730
|
+
if (!path)
|
|
4731
|
+
return '';
|
|
4732
|
+
return path.startsWith('widget.') ? path.slice('widget.'.length) : path;
|
|
4733
|
+
}
|
|
4734
|
+
tokenizePath(path) {
|
|
4735
|
+
const tokens = [];
|
|
4736
|
+
let buffer = '';
|
|
4737
|
+
for (let i = 0; i < path.length; i++) {
|
|
4738
|
+
const char = path[i];
|
|
4739
|
+
if (char === '.') {
|
|
4740
|
+
if (buffer) {
|
|
4741
|
+
tokens.push(buffer);
|
|
4742
|
+
buffer = '';
|
|
4743
|
+
}
|
|
4744
|
+
continue;
|
|
4745
|
+
}
|
|
4746
|
+
if (char === '[') {
|
|
4747
|
+
if (buffer) {
|
|
4748
|
+
tokens.push(buffer);
|
|
4749
|
+
buffer = '';
|
|
4750
|
+
}
|
|
4751
|
+
let num = '';
|
|
4752
|
+
i++;
|
|
4753
|
+
while (i < path.length && path[i] !== ']') {
|
|
4754
|
+
num += path[i];
|
|
4755
|
+
i++;
|
|
4756
|
+
}
|
|
4757
|
+
const index = Number(num);
|
|
4758
|
+
tokens.push(Number.isNaN(index) ? num : index);
|
|
4759
|
+
continue;
|
|
4760
|
+
}
|
|
4761
|
+
buffer += char;
|
|
4762
|
+
}
|
|
4763
|
+
if (buffer)
|
|
4764
|
+
tokens.push(buffer);
|
|
4765
|
+
return tokens;
|
|
4766
|
+
}
|
|
4767
|
+
clone(value) {
|
|
4768
|
+
return value == null ? value : JSON.parse(JSON.stringify(value));
|
|
4769
|
+
}
|
|
4770
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SurfaceBindingRuntimeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
4771
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SurfaceBindingRuntimeService, providedIn: 'root' });
|
|
4772
|
+
}
|
|
4773
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SurfaceBindingRuntimeService, decorators: [{
|
|
4774
|
+
type: Injectable,
|
|
4775
|
+
args: [{ providedIn: 'root' }]
|
|
4776
|
+
}] });
|
|
4777
|
+
|
|
4421
4778
|
const GLOBAL_ACTION_HANDLERS = new InjectionToken('GLOBAL_ACTION_HANDLERS');
|
|
4422
4779
|
const GLOBAL_DIALOG_SERVICE = new InjectionToken('GLOBAL_DIALOG_SERVICE');
|
|
4423
4780
|
const GLOBAL_TOAST_SERVICE = new InjectionToken('GLOBAL_TOAST_SERVICE');
|
|
@@ -4432,6 +4789,8 @@ function provideGlobalActionHandler(entry) {
|
|
|
4432
4789
|
};
|
|
4433
4790
|
}
|
|
4434
4791
|
|
|
4792
|
+
const GLOBAL_SURFACE_SERVICE = new InjectionToken('GLOBAL_SURFACE_SERVICE');
|
|
4793
|
+
|
|
4435
4794
|
class GlobalActionService {
|
|
4436
4795
|
handlers = new Map();
|
|
4437
4796
|
router = (() => { try {
|
|
@@ -4459,10 +4818,12 @@ class GlobalActionService {
|
|
|
4459
4818
|
return null;
|
|
4460
4819
|
} })();
|
|
4461
4820
|
dialog = inject(GLOBAL_DIALOG_SERVICE, { optional: true });
|
|
4821
|
+
surface = inject(GLOBAL_SURFACE_SERVICE, { optional: true });
|
|
4462
4822
|
toast = inject(GLOBAL_TOAST_SERVICE, { optional: true });
|
|
4463
4823
|
analytics = inject(GLOBAL_ANALYTICS_SERVICE, { optional: true });
|
|
4464
4824
|
api = inject(GLOBAL_API_CLIENT, { optional: true });
|
|
4465
4825
|
guardResolver = inject(GLOBAL_ROUTE_GUARD_RESOLVER, { optional: true });
|
|
4826
|
+
surfaceBindingRuntime = inject(SurfaceBindingRuntimeService);
|
|
4466
4827
|
constructor() {
|
|
4467
4828
|
const entries = inject(GLOBAL_ACTION_HANDLERS, { optional: true });
|
|
4468
4829
|
(entries || []).forEach((e) => this.register(e.id, e.handler));
|
|
@@ -4535,6 +4896,17 @@ class GlobalActionService {
|
|
|
4535
4896
|
const data = await this.dialog.open(payload || {});
|
|
4536
4897
|
return { success: true, data };
|
|
4537
4898
|
});
|
|
4899
|
+
this.register('surface.open', async (payload, context) => {
|
|
4900
|
+
if (!this.surface)
|
|
4901
|
+
return { success: false, error: 'Surface service not available' };
|
|
4902
|
+
const surfacePayload = payload;
|
|
4903
|
+
if (!surfacePayload?.widget?.id) {
|
|
4904
|
+
return { success: false, error: 'surface.open requires widget.id' };
|
|
4905
|
+
}
|
|
4906
|
+
const resolvedWidget = this.surfaceBindingRuntime.resolveWidget(surfacePayload.widget, surfacePayload.bindings, surfacePayload, context, surfacePayload.context);
|
|
4907
|
+
const data = await this.surface.open({ ...surfacePayload, widget: resolvedWidget }, context);
|
|
4908
|
+
return { success: true, data };
|
|
4909
|
+
});
|
|
4538
4910
|
this.register('toast.success', async (payload) => {
|
|
4539
4911
|
const message = payload?.message || payload;
|
|
4540
4912
|
if (!message)
|
|
@@ -7868,6 +8240,42 @@ const PRAXIS_GLOBAL_ACTION_CATALOG = [
|
|
|
7868
8240
|
example: { componentId: 'praxis-dynamic-form', inputs: { formId: 'clientes' } },
|
|
7869
8241
|
},
|
|
7870
8242
|
},
|
|
8243
|
+
{
|
|
8244
|
+
id: 'surface.open',
|
|
8245
|
+
label: 'Abrir Surface',
|
|
8246
|
+
icon: 'open_in_new',
|
|
8247
|
+
description: 'Abre modal ou drawer com um widget registrado e bindings dinâmicos.',
|
|
8248
|
+
payloadSchema: {
|
|
8249
|
+
type: 'object',
|
|
8250
|
+
properties: {
|
|
8251
|
+
presentation: { type: 'string', description: 'Tipo de apresentação: modal ou drawer.' },
|
|
8252
|
+
title: { type: 'string', description: 'Título opcional da surface.' },
|
|
8253
|
+
subtitle: { type: 'string', description: 'Subtítulo opcional da surface.' },
|
|
8254
|
+
icon: { type: 'string', description: 'Ícone opcional da surface.' },
|
|
8255
|
+
size: { type: 'object', description: 'Configuração opcional de tamanho da surface.' },
|
|
8256
|
+
widget: { type: 'object', description: 'WidgetDefinition do componente a ser renderizado.' },
|
|
8257
|
+
bindings: { type: 'array', description: 'Bindings declarativos aplicados sobre widget.inputs.*.' },
|
|
8258
|
+
context: { type: 'object', description: 'Contexto explícito adicional exposto ao runtime de bindings.' },
|
|
8259
|
+
},
|
|
8260
|
+
required: ['presentation', 'widget'],
|
|
8261
|
+
example: {
|
|
8262
|
+
presentation: 'drawer',
|
|
8263
|
+
title: 'Detalhes do Funcionário',
|
|
8264
|
+
widget: {
|
|
8265
|
+
id: 'praxis-dynamic-form',
|
|
8266
|
+
bindingOrder: ['resourcePath', 'formId', 'resourceId'],
|
|
8267
|
+
inputs: {
|
|
8268
|
+
resourcePath: 'human-resources/employees',
|
|
8269
|
+
formId: 'employee-detail',
|
|
8270
|
+
mode: 'view',
|
|
8271
|
+
},
|
|
8272
|
+
},
|
|
8273
|
+
bindings: [
|
|
8274
|
+
{ from: 'payload.row.id', to: 'widget.inputs.resourceId' },
|
|
8275
|
+
],
|
|
8276
|
+
},
|
|
8277
|
+
},
|
|
8278
|
+
},
|
|
7871
8279
|
{
|
|
7872
8280
|
id: 'toast.success',
|
|
7873
8281
|
label: 'Toast Sucesso',
|
|
@@ -8007,6 +8415,17 @@ const GLOBAL_ACTION_CATALOG = [
|
|
|
8007
8415
|
example: 'https://docs.exemplo.com',
|
|
8008
8416
|
},
|
|
8009
8417
|
},
|
|
8418
|
+
{
|
|
8419
|
+
id: 'surface.open',
|
|
8420
|
+
label: 'Abrir Surface',
|
|
8421
|
+
description: 'Abre modal ou drawer com um componente registrado e payload dinâmico.',
|
|
8422
|
+
param: {
|
|
8423
|
+
label: 'Payload (JSON)',
|
|
8424
|
+
placeholder: '{"presentation":"drawer","widget":{"id":"praxis-dynamic-form","inputs":{"resourcePath":"employees","formId":"employee-detail"}}}',
|
|
8425
|
+
hint: 'Use o editor especializado para configurar widget, inputs e bindings da surface.',
|
|
8426
|
+
example: '{"presentation":"drawer","widget":{"id":"praxis-dynamic-form","inputs":{"resourcePath":"employees","formId":"employee-detail"}}}',
|
|
8427
|
+
},
|
|
8428
|
+
},
|
|
8010
8429
|
{
|
|
8011
8430
|
id: 'showAlert',
|
|
8012
8431
|
label: 'Alerta simples',
|
|
@@ -8178,6 +8597,110 @@ function findGlobalActionSpec(id) {
|
|
|
8178
8597
|
return GLOBAL_ACTION_CATALOG.find((item) => item.id === id);
|
|
8179
8598
|
}
|
|
8180
8599
|
|
|
8600
|
+
const SURFACE_OPEN_I18N_NAMESPACE = 'surfaceOpen';
|
|
8601
|
+
const SURFACE_OPEN_I18N_CONFIG = {
|
|
8602
|
+
namespaces: {
|
|
8603
|
+
[SURFACE_OPEN_I18N_NAMESPACE]: {
|
|
8604
|
+
'pt-BR': {
|
|
8605
|
+
'editor.presets.title': 'Presets',
|
|
8606
|
+
'editor.presets.help': 'Aplique um preset para começar com inputs mínimos e depois configure bindings conforme a origem da action.',
|
|
8607
|
+
'editor.surface.title': 'Surface',
|
|
8608
|
+
'editor.surface.presentation': 'Apresentação',
|
|
8609
|
+
'editor.surface.presentation.modal': 'Modal',
|
|
8610
|
+
'editor.surface.presentation.drawer': 'Drawer',
|
|
8611
|
+
'editor.surface.titleLabel': 'Título',
|
|
8612
|
+
'editor.surface.subtitleLabel': 'Subtítulo',
|
|
8613
|
+
'editor.surface.iconLabel': 'Ícone',
|
|
8614
|
+
'editor.surface.widthLabel': 'Largura',
|
|
8615
|
+
'editor.surface.heightLabel': 'Altura',
|
|
8616
|
+
'editor.surface.minWidthLabel': 'Largura mínima',
|
|
8617
|
+
'editor.surface.maxWidthLabel': 'Largura máxima',
|
|
8618
|
+
'editor.component.title': 'Componente',
|
|
8619
|
+
'editor.component.select': 'Componente registrado',
|
|
8620
|
+
'editor.component.selectPlaceholder': '-- Selecionar --',
|
|
8621
|
+
'editor.component.bindingOrder': 'bindingOrder (CSV)',
|
|
8622
|
+
'editor.component.bindingOrderPlaceholder': 'resourcePath, formId, resourceId',
|
|
8623
|
+
'editor.inputs.title': 'Inputs',
|
|
8624
|
+
'editor.inputs.empty': 'Selecione um componente registrado para configurar inputs públicos.',
|
|
8625
|
+
'editor.bindings.title': 'Bindings',
|
|
8626
|
+
'editor.bindings.add': 'Binding',
|
|
8627
|
+
'editor.bindings.source': 'Origem',
|
|
8628
|
+
'editor.bindings.target': 'Destino',
|
|
8629
|
+
'editor.bindings.mode': 'Modo',
|
|
8630
|
+
'editor.bindings.constantValue': 'Valor constante',
|
|
8631
|
+
'editor.bindings.remove': 'Remover binding',
|
|
8632
|
+
'editor.bindings.empty': 'Nenhum binding configurado ainda.',
|
|
8633
|
+
'editor.bindings.suggestedSources': 'Origens sugeridas: {{value}}',
|
|
8634
|
+
'editor.bindings.suggestedTargets': 'Destinos sugeridos: {{value}}',
|
|
8635
|
+
'editor.context.title': 'Contexto extra',
|
|
8636
|
+
'editor.context.label': 'context (JSON)',
|
|
8637
|
+
'editor.context.hint': 'Opcional. Mesclado ao contexto da action no runtime.',
|
|
8638
|
+
'editor.validation.invalidJson': 'JSON inválido.',
|
|
8639
|
+
'editor.validation.objectJson': 'Informe um objeto JSON.',
|
|
8640
|
+
'preset.praxis-dynamic-form.label': 'Formulário',
|
|
8641
|
+
'preset.praxis-dynamic-form.description': 'Abre um formulário dinâmico com resourcePath, formId e resourceId.',
|
|
8642
|
+
'preset.praxis-table.label': 'Tabela',
|
|
8643
|
+
'preset.praxis-table.description': 'Abre uma tabela configurável com resourcePath, tableId e queryContext.',
|
|
8644
|
+
'preset.praxis-list.label': 'Lista',
|
|
8645
|
+
'preset.praxis-list.description': 'Abre uma lista com listId e config básicos.',
|
|
8646
|
+
'preset.praxis-crud.label': 'CRUD',
|
|
8647
|
+
'preset.praxis-crud.description': 'Abre a surface de CRUD com resourcePath, formId e bindings configuráveis.',
|
|
8648
|
+
'action.surfaceOpen.label': 'Abrir Surface',
|
|
8649
|
+
'action.surfaceOpen.description': 'Abre modal ou drawer com um componente registrado e payload dinâmico.',
|
|
8650
|
+
'action.surfaceOpen.hint': 'Use o editor especializado para configurar widget, inputs e bindings da surface.',
|
|
8651
|
+
},
|
|
8652
|
+
'en-US': {
|
|
8653
|
+
'editor.presets.title': 'Presets',
|
|
8654
|
+
'editor.presets.help': 'Apply a preset to start with minimal inputs, then configure bindings for the action source.',
|
|
8655
|
+
'editor.surface.title': 'Surface',
|
|
8656
|
+
'editor.surface.presentation': 'Presentation',
|
|
8657
|
+
'editor.surface.presentation.modal': 'Modal',
|
|
8658
|
+
'editor.surface.presentation.drawer': 'Drawer',
|
|
8659
|
+
'editor.surface.titleLabel': 'Title',
|
|
8660
|
+
'editor.surface.subtitleLabel': 'Subtitle',
|
|
8661
|
+
'editor.surface.iconLabel': 'Icon',
|
|
8662
|
+
'editor.surface.widthLabel': 'Width',
|
|
8663
|
+
'editor.surface.heightLabel': 'Height',
|
|
8664
|
+
'editor.surface.minWidthLabel': 'Min width',
|
|
8665
|
+
'editor.surface.maxWidthLabel': 'Max width',
|
|
8666
|
+
'editor.component.title': 'Component',
|
|
8667
|
+
'editor.component.select': 'Registered component',
|
|
8668
|
+
'editor.component.selectPlaceholder': '-- Select --',
|
|
8669
|
+
'editor.component.bindingOrder': 'bindingOrder (CSV)',
|
|
8670
|
+
'editor.component.bindingOrderPlaceholder': 'resourcePath, formId, resourceId',
|
|
8671
|
+
'editor.inputs.title': 'Inputs',
|
|
8672
|
+
'editor.inputs.empty': 'Select a registered component to configure public inputs.',
|
|
8673
|
+
'editor.bindings.title': 'Bindings',
|
|
8674
|
+
'editor.bindings.add': 'Binding',
|
|
8675
|
+
'editor.bindings.source': 'Source',
|
|
8676
|
+
'editor.bindings.target': 'Target',
|
|
8677
|
+
'editor.bindings.mode': 'Mode',
|
|
8678
|
+
'editor.bindings.constantValue': 'Constant value',
|
|
8679
|
+
'editor.bindings.remove': 'Remove binding',
|
|
8680
|
+
'editor.bindings.empty': 'No bindings configured yet.',
|
|
8681
|
+
'editor.bindings.suggestedSources': 'Suggested sources: {{value}}',
|
|
8682
|
+
'editor.bindings.suggestedTargets': 'Suggested targets: {{value}}',
|
|
8683
|
+
'editor.context.title': 'Extra context',
|
|
8684
|
+
'editor.context.label': 'context (JSON)',
|
|
8685
|
+
'editor.context.hint': 'Optional. Merged into the action context at runtime.',
|
|
8686
|
+
'editor.validation.invalidJson': 'Invalid JSON.',
|
|
8687
|
+
'editor.validation.objectJson': 'Provide a JSON object.',
|
|
8688
|
+
'preset.praxis-dynamic-form.label': 'Form',
|
|
8689
|
+
'preset.praxis-dynamic-form.description': 'Opens a dynamic form with resourcePath, formId and resourceId.',
|
|
8690
|
+
'preset.praxis-table.label': 'Table',
|
|
8691
|
+
'preset.praxis-table.description': 'Opens a configurable table with resourcePath, tableId and queryContext.',
|
|
8692
|
+
'preset.praxis-list.label': 'List',
|
|
8693
|
+
'preset.praxis-list.description': 'Opens a list with basic listId and config inputs.',
|
|
8694
|
+
'preset.praxis-crud.label': 'CRUD',
|
|
8695
|
+
'preset.praxis-crud.description': 'Opens the CRUD surface with resourcePath, formId and configurable bindings.',
|
|
8696
|
+
'action.surfaceOpen.label': 'Open Surface',
|
|
8697
|
+
'action.surfaceOpen.description': 'Opens a modal or drawer with a registered component and dynamic payload.',
|
|
8698
|
+
'action.surfaceOpen.hint': 'Use the dedicated editor to configure the surface widget, inputs and bindings.',
|
|
8699
|
+
},
|
|
8700
|
+
},
|
|
8701
|
+
},
|
|
8702
|
+
};
|
|
8703
|
+
|
|
8181
8704
|
const SETTINGS_PANEL_BRIDGE = new InjectionToken('SETTINGS_PANEL_BRIDGE');
|
|
8182
8705
|
// Optional data token for consumers that still use DI-based data passing.
|
|
8183
8706
|
// Prefer using component inputs when opening via SettingsPanelBridge.
|
|
@@ -8390,6 +8913,169 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
8390
8913
|
args: [PRAXIS_I18N_TRANSLATOR]
|
|
8391
8914
|
}] }] });
|
|
8392
8915
|
|
|
8916
|
+
const DEFAULT_LOCALE = 'en-US';
|
|
8917
|
+
const DEFAULT_DATE_TIME = {
|
|
8918
|
+
dateFormat: 'shortDate',
|
|
8919
|
+
timeFormat: 'shortTime',
|
|
8920
|
+
dateTimeFormat: 'short',
|
|
8921
|
+
firstDayOfWeek: 0,
|
|
8922
|
+
relativeTime: false,
|
|
8923
|
+
};
|
|
8924
|
+
const DEFAULT_NUMBER = {
|
|
8925
|
+
decimalSeparator: '.',
|
|
8926
|
+
thousandsSeparator: ',',
|
|
8927
|
+
defaultPrecision: 2,
|
|
8928
|
+
negativeSign: '-',
|
|
8929
|
+
negativeSignPosition: 'before',
|
|
8930
|
+
};
|
|
8931
|
+
const DEFAULT_CURRENCY = {
|
|
8932
|
+
code: 'USD',
|
|
8933
|
+
symbol: '$',
|
|
8934
|
+
position: 'before',
|
|
8935
|
+
spacing: false,
|
|
8936
|
+
precision: 2,
|
|
8937
|
+
};
|
|
8938
|
+
const IMPLICIT_FORMAT_TYPES = new Set([
|
|
8939
|
+
'number',
|
|
8940
|
+
'currency',
|
|
8941
|
+
'percentage',
|
|
8942
|
+
'date',
|
|
8943
|
+
'datetime',
|
|
8944
|
+
'time',
|
|
8945
|
+
]);
|
|
8946
|
+
function resolveValuePresentation(config, context) {
|
|
8947
|
+
const localization = context?.localization ?? null;
|
|
8948
|
+
const locale = resolveValuePresentationLocale(context, localization);
|
|
8949
|
+
const number = resolveNumberLocaleConfig(config, localization);
|
|
8950
|
+
const currency = resolveCurrencyLocaleConfig(config, localization);
|
|
8951
|
+
const dateTime = resolveDateTimeLocaleConfig(localization);
|
|
8952
|
+
return {
|
|
8953
|
+
type: config.type,
|
|
8954
|
+
locale,
|
|
8955
|
+
style: config.style,
|
|
8956
|
+
format: config.format ||
|
|
8957
|
+
resolveDefaultValuePresentationFormat(config.type, config.style, {
|
|
8958
|
+
localization,
|
|
8959
|
+
number,
|
|
8960
|
+
currency,
|
|
8961
|
+
dateTime,
|
|
8962
|
+
}),
|
|
8963
|
+
currency: config.type === 'currency' ? currency : undefined,
|
|
8964
|
+
number: config.type === 'number' || config.type === 'percentage'
|
|
8965
|
+
? number
|
|
8966
|
+
: undefined,
|
|
8967
|
+
dateTime: config.type === 'date' ||
|
|
8968
|
+
config.type === 'datetime' ||
|
|
8969
|
+
config.type === 'time'
|
|
8970
|
+
? dateTime
|
|
8971
|
+
: undefined,
|
|
8972
|
+
};
|
|
8973
|
+
}
|
|
8974
|
+
function resolveValuePresentationLocale(context, localization) {
|
|
8975
|
+
return (context?.valueLocale ||
|
|
8976
|
+
localization?.locale ||
|
|
8977
|
+
context?.surfaceLocale ||
|
|
8978
|
+
context?.appLocale ||
|
|
8979
|
+
DEFAULT_LOCALE);
|
|
8980
|
+
}
|
|
8981
|
+
function supportsImplicitValuePresentation(type) {
|
|
8982
|
+
return !!type && IMPLICIT_FORMAT_TYPES.has(type);
|
|
8983
|
+
}
|
|
8984
|
+
function resolveDefaultValuePresentationFormat(type, style, context) {
|
|
8985
|
+
switch (type) {
|
|
8986
|
+
case 'date':
|
|
8987
|
+
return resolveDateFormat(style, context.dateTime.dateFormat);
|
|
8988
|
+
case 'datetime':
|
|
8989
|
+
return resolveDateTimeFormat(style, context.dateTime.dateTimeFormat);
|
|
8990
|
+
case 'time':
|
|
8991
|
+
return resolveTimeFormat(style, context.dateTime.timeFormat);
|
|
8992
|
+
case 'number':
|
|
8993
|
+
return resolveDigitsFormat(context.number.defaultPrecision);
|
|
8994
|
+
case 'currency':
|
|
8995
|
+
return `${context.currency.code}|symbol|${context.currency.precision}`;
|
|
8996
|
+
case 'percentage':
|
|
8997
|
+
return (context.localization?.formatting?.percentageFormat ||
|
|
8998
|
+
resolveDigitsFormat(context.number.defaultPrecision));
|
|
8999
|
+
default:
|
|
9000
|
+
return undefined;
|
|
9001
|
+
}
|
|
9002
|
+
}
|
|
9003
|
+
function resolveDateTimeLocaleConfig(localization) {
|
|
9004
|
+
return {
|
|
9005
|
+
...DEFAULT_DATE_TIME,
|
|
9006
|
+
...(localization?.dateTime || {}),
|
|
9007
|
+
};
|
|
9008
|
+
}
|
|
9009
|
+
function resolveNumberLocaleConfig(config, localization) {
|
|
9010
|
+
return {
|
|
9011
|
+
...DEFAULT_NUMBER,
|
|
9012
|
+
...(localization?.number || {}),
|
|
9013
|
+
...(config.number || {}),
|
|
9014
|
+
};
|
|
9015
|
+
}
|
|
9016
|
+
function resolveCurrencyLocaleConfig(config, localization) {
|
|
9017
|
+
return {
|
|
9018
|
+
...DEFAULT_CURRENCY,
|
|
9019
|
+
...(localization?.currency || {}),
|
|
9020
|
+
...(config.currency || {}),
|
|
9021
|
+
};
|
|
9022
|
+
}
|
|
9023
|
+
function resolveDateFormat(style, fallback) {
|
|
9024
|
+
switch (style) {
|
|
9025
|
+
case 'short':
|
|
9026
|
+
return 'shortDate';
|
|
9027
|
+
case 'medium':
|
|
9028
|
+
return 'mediumDate';
|
|
9029
|
+
case 'long':
|
|
9030
|
+
return 'longDate';
|
|
9031
|
+
case 'full':
|
|
9032
|
+
return 'fullDate';
|
|
9033
|
+
default:
|
|
9034
|
+
return fallback || DEFAULT_DATE_TIME.dateFormat;
|
|
9035
|
+
}
|
|
9036
|
+
}
|
|
9037
|
+
function resolveDateTimeFormat(style, fallback) {
|
|
9038
|
+
switch (style) {
|
|
9039
|
+
case 'short':
|
|
9040
|
+
return 'short';
|
|
9041
|
+
case 'medium':
|
|
9042
|
+
return 'medium';
|
|
9043
|
+
case 'long':
|
|
9044
|
+
return 'long';
|
|
9045
|
+
case 'full':
|
|
9046
|
+
return 'full';
|
|
9047
|
+
default:
|
|
9048
|
+
return fallback || DEFAULT_DATE_TIME.dateTimeFormat;
|
|
9049
|
+
}
|
|
9050
|
+
}
|
|
9051
|
+
function resolveTimeFormat(style, fallback) {
|
|
9052
|
+
switch (style) {
|
|
9053
|
+
case 'short':
|
|
9054
|
+
return 'shortTime';
|
|
9055
|
+
case 'medium':
|
|
9056
|
+
return 'mediumTime';
|
|
9057
|
+
case 'long':
|
|
9058
|
+
return 'longTime';
|
|
9059
|
+
case 'full':
|
|
9060
|
+
return 'fullTime';
|
|
9061
|
+
default:
|
|
9062
|
+
return fallback || DEFAULT_DATE_TIME.timeFormat;
|
|
9063
|
+
}
|
|
9064
|
+
}
|
|
9065
|
+
function resolveDigitsFormat(defaultPrecision) {
|
|
9066
|
+
const precision = clampPrecision(defaultPrecision);
|
|
9067
|
+
return `1.${precision}-${precision}`;
|
|
9068
|
+
}
|
|
9069
|
+
function clampPrecision(value) {
|
|
9070
|
+
if (typeof value !== 'number' || Number.isNaN(value)) {
|
|
9071
|
+
return DEFAULT_NUMBER.defaultPrecision;
|
|
9072
|
+
}
|
|
9073
|
+
if (value < 0) {
|
|
9074
|
+
return 0;
|
|
9075
|
+
}
|
|
9076
|
+
return Math.floor(value);
|
|
9077
|
+
}
|
|
9078
|
+
|
|
8393
9079
|
/**
|
|
8394
9080
|
* Enum que define os tipos de dados (`TYPE`) disponíveis para configuração dos campos de formulário.
|
|
8395
9081
|
*/
|
|
@@ -9790,6 +10476,7 @@ const RULE_PROPERTY_SCHEMA = {
|
|
|
9790
10476
|
],
|
|
9791
10477
|
},
|
|
9792
10478
|
{ name: 'sectionHeader.initialsMaxLength', type: 'number', label: 'Máximo de iniciais' },
|
|
10479
|
+
{ name: 'headerActions', type: 'object', label: 'Ações do cabeçalho' },
|
|
9793
10480
|
{ name: 'className', type: 'string', label: 'Classe CSS' },
|
|
9794
10481
|
{ name: 'style', type: 'object', label: 'Estilos inline' },
|
|
9795
10482
|
{ name: 'borderColor', type: 'string', label: 'Cor da borda' },
|
|
@@ -10894,6 +11581,66 @@ function createPersistedPage(identity, page, opts) {
|
|
|
10894
11581
|
|
|
10895
11582
|
// Global Dialog domain types for GlobalConfig (kept independent of @praxisui/dialog types)
|
|
10896
11583
|
|
|
11584
|
+
function normalizeRecord(record) {
|
|
11585
|
+
if (!record || typeof record !== 'object')
|
|
11586
|
+
return null;
|
|
11587
|
+
const next = Object.entries(record).reduce((acc, [key, value]) => {
|
|
11588
|
+
if (value === null || value === undefined)
|
|
11589
|
+
return acc;
|
|
11590
|
+
if (Array.isArray(value) && value.length === 0)
|
|
11591
|
+
return acc;
|
|
11592
|
+
if (typeof value === 'string' && value.trim() === '')
|
|
11593
|
+
return acc;
|
|
11594
|
+
acc[key] = value;
|
|
11595
|
+
return acc;
|
|
11596
|
+
}, {});
|
|
11597
|
+
return Object.keys(next).length ? next : null;
|
|
11598
|
+
}
|
|
11599
|
+
function normalizePraxisDataQueryContext(context) {
|
|
11600
|
+
if (!context || typeof context !== 'object')
|
|
11601
|
+
return null;
|
|
11602
|
+
const filters = normalizeRecord(context.filters);
|
|
11603
|
+
const meta = normalizeRecord(context.meta);
|
|
11604
|
+
const sort = Array.isArray(context.sort)
|
|
11605
|
+
? context.sort
|
|
11606
|
+
.map((item) => (typeof item === 'string' ? item.trim() : ''))
|
|
11607
|
+
.filter((item) => item.length > 0)
|
|
11608
|
+
: [];
|
|
11609
|
+
const limit = typeof context.limit === 'number' && Number.isFinite(context.limit)
|
|
11610
|
+
? Math.max(0, Math.trunc(context.limit))
|
|
11611
|
+
: null;
|
|
11612
|
+
const page = context.page && typeof context.page === 'object'
|
|
11613
|
+
? {
|
|
11614
|
+
index: typeof context.page.index === 'number' && Number.isFinite(context.page.index)
|
|
11615
|
+
? Math.max(0, Math.trunc(context.page.index))
|
|
11616
|
+
: null,
|
|
11617
|
+
size: typeof context.page.size === 'number' && Number.isFinite(context.page.size)
|
|
11618
|
+
? Math.max(0, Math.trunc(context.page.size))
|
|
11619
|
+
: null,
|
|
11620
|
+
}
|
|
11621
|
+
: null;
|
|
11622
|
+
const next = {};
|
|
11623
|
+
if (filters)
|
|
11624
|
+
next.filters = filters;
|
|
11625
|
+
if (sort.length)
|
|
11626
|
+
next.sort = sort;
|
|
11627
|
+
if (limit !== null)
|
|
11628
|
+
next.limit = limit;
|
|
11629
|
+
if (page && (page.index !== null || page.size !== null))
|
|
11630
|
+
next.page = page;
|
|
11631
|
+
if (meta)
|
|
11632
|
+
next.meta = meta;
|
|
11633
|
+
return Object.keys(next).length ? next : null;
|
|
11634
|
+
}
|
|
11635
|
+
function resolvePraxisFilterCriteria(filterCriteria, queryContext) {
|
|
11636
|
+
const normalizedFilterCriteria = normalizeRecord(filterCriteria);
|
|
11637
|
+
const normalizedQueryContext = normalizePraxisDataQueryContext(queryContext);
|
|
11638
|
+
return {
|
|
11639
|
+
...(normalizedFilterCriteria || {}),
|
|
11640
|
+
...(normalizedQueryContext?.filters || {}),
|
|
11641
|
+
};
|
|
11642
|
+
}
|
|
11643
|
+
|
|
10897
11644
|
const DEFAULT_FIELD_SELECTOR_CONTROL_TYPE_MAP = {
|
|
10898
11645
|
'pdx-text-input': FieldControlType.INPUT,
|
|
10899
11646
|
'pdx-email-input': FieldControlType.EMAIL_INPUT,
|
|
@@ -11155,6 +11902,18 @@ function mapFieldDefinitionToMetadata(field) {
|
|
|
11155
11902
|
if (field.type) {
|
|
11156
11903
|
metadata.dataType = field.type;
|
|
11157
11904
|
}
|
|
11905
|
+
if (field.valuePresentation) {
|
|
11906
|
+
const valuePresentation = {
|
|
11907
|
+
...field.valuePresentation,
|
|
11908
|
+
};
|
|
11909
|
+
if (field.valuePresentation.currency) {
|
|
11910
|
+
valuePresentation.currency = { ...field.valuePresentation.currency };
|
|
11911
|
+
}
|
|
11912
|
+
if (field.valuePresentation.number) {
|
|
11913
|
+
valuePresentation.number = { ...field.valuePresentation.number };
|
|
11914
|
+
}
|
|
11915
|
+
metadata.valuePresentation = valuePresentation;
|
|
11916
|
+
}
|
|
11158
11917
|
const simpleProps = [
|
|
11159
11918
|
'order',
|
|
11160
11919
|
'group',
|
|
@@ -11454,15 +12213,19 @@ function normalizeTargets(rule) {
|
|
|
11454
12213
|
(Array.isArray(rule.targetFields) && rule.targetFields.length && rule.targetFields) ||
|
|
11455
12214
|
[];
|
|
11456
12215
|
const targetType = rule.targetType ||
|
|
11457
|
-
(rawTargets.some((t) => t
|
|
11458
|
-
: rawTargets.some((t) => t?.startsWith('
|
|
11459
|
-
: rawTargets.some((t) => t?.startsWith('
|
|
11460
|
-
: rawTargets.some((t) => t?.startsWith('
|
|
11461
|
-
: '
|
|
12216
|
+
(rawTargets.some((t) => isScopedSectionHeaderActionTarget(t) || isUnscopedSectionHeaderActionTarget(t)) ? 'action'
|
|
12217
|
+
: rawTargets.some((t) => t?.startsWith('section:')) ? 'section'
|
|
12218
|
+
: rawTargets.some((t) => t?.startsWith('action:')) ? 'action'
|
|
12219
|
+
: rawTargets.some((t) => t?.startsWith('row:')) ? 'row'
|
|
12220
|
+
: rawTargets.some((t) => t?.startsWith('column:')) ? 'column'
|
|
12221
|
+
: 'field');
|
|
11462
12222
|
const targets = rawTargets.map((t) => stripPrefix(t));
|
|
11463
12223
|
return { targetType, targets };
|
|
11464
12224
|
}
|
|
11465
12225
|
function stripPrefix(value) {
|
|
12226
|
+
if (isScopedSectionHeaderActionTarget(value) || isUnscopedSectionHeaderActionTarget(value)) {
|
|
12227
|
+
return value;
|
|
12228
|
+
}
|
|
11466
12229
|
if (value?.startsWith('section:'))
|
|
11467
12230
|
return value.substring('section:'.length);
|
|
11468
12231
|
if (value?.startsWith('action:'))
|
|
@@ -11473,6 +12236,12 @@ function stripPrefix(value) {
|
|
|
11473
12236
|
return value.substring('column:'.length);
|
|
11474
12237
|
return value;
|
|
11475
12238
|
}
|
|
12239
|
+
function isScopedSectionHeaderActionTarget(value) {
|
|
12240
|
+
return !!value && value.startsWith('section:') && value.includes(':header-action:');
|
|
12241
|
+
}
|
|
12242
|
+
function isUnscopedSectionHeaderActionTarget(value) {
|
|
12243
|
+
return !!value && value.startsWith('header-action:');
|
|
12244
|
+
}
|
|
11476
12245
|
function inferPropertiesFromContext(context) {
|
|
11477
12246
|
switch (context) {
|
|
11478
12247
|
case 'visibility':
|
|
@@ -11844,6 +12613,12 @@ const dialogFieldsWithModeDependency = dialogFieldsWithoutMessage.map((field) =>
|
|
|
11844
12613
|
hint: field.hint ?? 'Disponível quando "Usar diálogo" estiver ativo.',
|
|
11845
12614
|
}));
|
|
11846
12615
|
const GLOBAL_ACTION_UI_SCHEMAS = [
|
|
12616
|
+
{
|
|
12617
|
+
id: 'surface.open',
|
|
12618
|
+
label: 'Abrir Surface',
|
|
12619
|
+
fields: [],
|
|
12620
|
+
editorMode: 'surface-open',
|
|
12621
|
+
},
|
|
11847
12622
|
{
|
|
11848
12623
|
id: 'navigate',
|
|
11849
12624
|
label: 'Navegar',
|
|
@@ -12051,41 +12826,1209 @@ function getGlobalActionUiSchema(id) {
|
|
|
12051
12826
|
return GLOBAL_ACTION_UI_SCHEMAS.find((schema) => schema.id === id);
|
|
12052
12827
|
}
|
|
12053
12828
|
|
|
12054
|
-
|
|
12055
|
-
|
|
12056
|
-
|
|
12057
|
-
|
|
12058
|
-
|
|
12059
|
-
|
|
12060
|
-
|
|
12061
|
-
|
|
12062
|
-
|
|
12063
|
-
|
|
12064
|
-
|
|
12065
|
-
|
|
12066
|
-
|
|
12067
|
-
|
|
12068
|
-
|
|
12069
|
-
|
|
12070
|
-
|
|
12071
|
-
|
|
12072
|
-
|
|
12073
|
-
|
|
12074
|
-
|
|
12075
|
-
|
|
12076
|
-
|
|
12077
|
-
|
|
12078
|
-
|
|
12079
|
-
|
|
12080
|
-
|
|
12081
|
-
|
|
12082
|
-
|
|
12083
|
-
|
|
12084
|
-
|
|
12085
|
-
|
|
12086
|
-
|
|
12087
|
-
|
|
12088
|
-
|
|
12829
|
+
const SURFACE_OPEN_PRESETS = [
|
|
12830
|
+
{
|
|
12831
|
+
id: 'praxis-dynamic-form',
|
|
12832
|
+
label: 'Formulário',
|
|
12833
|
+
description: 'Abre um formulário dinâmico com resourcePath, formId e resourceId.',
|
|
12834
|
+
payload: {
|
|
12835
|
+
presentation: 'drawer',
|
|
12836
|
+
widget: {
|
|
12837
|
+
id: 'praxis-dynamic-form',
|
|
12838
|
+
bindingOrder: ['resourcePath', 'formId', 'resourceId'],
|
|
12839
|
+
inputs: {
|
|
12840
|
+
resourcePath: '',
|
|
12841
|
+
formId: '',
|
|
12842
|
+
mode: 'view',
|
|
12843
|
+
},
|
|
12844
|
+
},
|
|
12845
|
+
bindings: [],
|
|
12846
|
+
},
|
|
12847
|
+
},
|
|
12848
|
+
{
|
|
12849
|
+
id: 'praxis-table',
|
|
12850
|
+
label: 'Tabela',
|
|
12851
|
+
description: 'Abre uma tabela filtrável usando inputs declarativos e queryContext.',
|
|
12852
|
+
payload: {
|
|
12853
|
+
presentation: 'drawer',
|
|
12854
|
+
widget: {
|
|
12855
|
+
id: 'praxis-table',
|
|
12856
|
+
bindingOrder: ['resourcePath', 'tableId', 'queryContext'],
|
|
12857
|
+
inputs: {
|
|
12858
|
+
resourcePath: '',
|
|
12859
|
+
tableId: '',
|
|
12860
|
+
queryContext: {
|
|
12861
|
+
filters: {},
|
|
12862
|
+
},
|
|
12863
|
+
},
|
|
12864
|
+
},
|
|
12865
|
+
bindings: [],
|
|
12866
|
+
},
|
|
12867
|
+
},
|
|
12868
|
+
{
|
|
12869
|
+
id: 'praxis-list',
|
|
12870
|
+
label: 'Lista',
|
|
12871
|
+
description: 'Abre uma lista com config/listId e bindings configuráveis.',
|
|
12872
|
+
payload: {
|
|
12873
|
+
presentation: 'drawer',
|
|
12874
|
+
widget: {
|
|
12875
|
+
id: 'praxis-list',
|
|
12876
|
+
bindingOrder: ['listId', 'config'],
|
|
12877
|
+
inputs: {
|
|
12878
|
+
listId: '',
|
|
12879
|
+
config: {},
|
|
12880
|
+
},
|
|
12881
|
+
},
|
|
12882
|
+
bindings: [],
|
|
12883
|
+
},
|
|
12884
|
+
},
|
|
12885
|
+
{
|
|
12886
|
+
id: 'praxis-crud',
|
|
12887
|
+
label: 'CRUD',
|
|
12888
|
+
description: 'Abre a surface de CRUD com inputs mínimos e bindings configuráveis.',
|
|
12889
|
+
payload: {
|
|
12890
|
+
presentation: 'drawer',
|
|
12891
|
+
widget: {
|
|
12892
|
+
id: 'praxis-crud',
|
|
12893
|
+
bindingOrder: ['resourcePath', 'formId', 'resourceId'],
|
|
12894
|
+
inputs: {
|
|
12895
|
+
resourcePath: '',
|
|
12896
|
+
formId: '',
|
|
12897
|
+
},
|
|
12898
|
+
},
|
|
12899
|
+
bindings: [],
|
|
12900
|
+
},
|
|
12901
|
+
},
|
|
12902
|
+
];
|
|
12903
|
+
|
|
12904
|
+
class SurfaceOpenActionEditorComponent {
|
|
12905
|
+
value;
|
|
12906
|
+
hostKind;
|
|
12907
|
+
valueChange = new EventEmitter();
|
|
12908
|
+
draft = this.createDefaultPayload();
|
|
12909
|
+
inputJsonDrafts = {};
|
|
12910
|
+
inputErrors = {};
|
|
12911
|
+
contextDraft = '';
|
|
12912
|
+
contextError = '';
|
|
12913
|
+
registry = inject(ComponentMetadataRegistry);
|
|
12914
|
+
i18n = inject(PraxisI18nService);
|
|
12915
|
+
static nextInstanceId = 0;
|
|
12916
|
+
instanceId = ++SurfaceOpenActionEditorComponent.nextInstanceId;
|
|
12917
|
+
sourceSuggestionsListId = `surface-binding-source-suggestions-${this.instanceId}`;
|
|
12918
|
+
targetSuggestionsListId = `surface-binding-target-suggestions-${this.instanceId}`;
|
|
12919
|
+
get availablePresets() {
|
|
12920
|
+
return SURFACE_OPEN_PRESETS;
|
|
12921
|
+
}
|
|
12922
|
+
get componentOptions() {
|
|
12923
|
+
return this.registry
|
|
12924
|
+
.getAll()
|
|
12925
|
+
.slice()
|
|
12926
|
+
.sort((a, b) => String(a.friendlyName || a.id).localeCompare(String(b.friendlyName || b.id)));
|
|
12927
|
+
}
|
|
12928
|
+
get selectedComponentMeta() {
|
|
12929
|
+
return this.draft.widget?.id ? this.registry.get(this.draft.widget.id) : undefined;
|
|
12930
|
+
}
|
|
12931
|
+
get selectedInputs() {
|
|
12932
|
+
return this.selectedComponentMeta?.inputs || [];
|
|
12933
|
+
}
|
|
12934
|
+
get bindingOrderText() {
|
|
12935
|
+
return (this.draft.widget.bindingOrder || []).join(', ');
|
|
12936
|
+
}
|
|
12937
|
+
get bindingSourceSuggestions() {
|
|
12938
|
+
const generic = [
|
|
12939
|
+
'payload.id',
|
|
12940
|
+
'payload.resourceId',
|
|
12941
|
+
'payload.row.id',
|
|
12942
|
+
'payload.item.id',
|
|
12943
|
+
'payload.formData.id',
|
|
12944
|
+
'context.resourceId',
|
|
12945
|
+
'pageContext.resourceId',
|
|
12946
|
+
];
|
|
12947
|
+
const byHost = {
|
|
12948
|
+
table: ['payload.row.id', 'payload.row.departmentId', 'payload.selection.ids', 'runtime.row.id'],
|
|
12949
|
+
form: ['payload.resourceId', 'payload.formData.customerId', 'runtime.formData.id'],
|
|
12950
|
+
list: ['payload.item.id', 'payload.item.status', 'payload.selection.ids', 'runtime.item.id'],
|
|
12951
|
+
page: ['pageContext.filters.status', 'pageContext.selection.ids', 'context.pageState.activeId'],
|
|
12952
|
+
};
|
|
12953
|
+
return this.uniqueStrings([...(byHost[this.hostKind || ''] || []), ...generic]);
|
|
12954
|
+
}
|
|
12955
|
+
get bindingTargetSuggestions() {
|
|
12956
|
+
const metaTargets = this.selectedInputs.map((input) => `widget.inputs.${input.name}`);
|
|
12957
|
+
const commonTargets = [
|
|
12958
|
+
'widget.inputs.resourcePath',
|
|
12959
|
+
'widget.inputs.formId',
|
|
12960
|
+
'widget.inputs.resourceId',
|
|
12961
|
+
'widget.inputs.tableId',
|
|
12962
|
+
'widget.inputs.listId',
|
|
12963
|
+
'widget.inputs.queryContext',
|
|
12964
|
+
'widget.inputs.queryContext.filters',
|
|
12965
|
+
'widget.inputs.filterCriteria',
|
|
12966
|
+
];
|
|
12967
|
+
return this.uniqueStrings([...metaTargets, ...commonTargets]);
|
|
12968
|
+
}
|
|
12969
|
+
get bindingSourceSuggestionsPreview() {
|
|
12970
|
+
return this.bindingSourceSuggestions.slice(0, 5).join(', ');
|
|
12971
|
+
}
|
|
12972
|
+
get bindingTargetSuggestionsPreview() {
|
|
12973
|
+
return this.bindingTargetSuggestions.slice(0, 5).join(', ');
|
|
12974
|
+
}
|
|
12975
|
+
ngOnChanges(changes) {
|
|
12976
|
+
if (changes['value']) {
|
|
12977
|
+
this.draft = this.normalizePayload(this.value);
|
|
12978
|
+
this.refreshJsonDrafts();
|
|
12979
|
+
}
|
|
12980
|
+
}
|
|
12981
|
+
updatePresentation(value) {
|
|
12982
|
+
this.draft.presentation = value === 'drawer' ? 'drawer' : 'modal';
|
|
12983
|
+
this.emitDraft();
|
|
12984
|
+
}
|
|
12985
|
+
updateTextField(field, value) {
|
|
12986
|
+
this.assignTextField(field, value);
|
|
12987
|
+
this.emitDraft();
|
|
12988
|
+
}
|
|
12989
|
+
updateSizeField(field, value) {
|
|
12990
|
+
const text = String(value || '').trim();
|
|
12991
|
+
if (!text) {
|
|
12992
|
+
if (this.draft.size) {
|
|
12993
|
+
delete this.draft.size[field];
|
|
12994
|
+
if (!Object.keys(this.draft.size).length) {
|
|
12995
|
+
delete this.draft.size;
|
|
12996
|
+
}
|
|
12997
|
+
}
|
|
12998
|
+
}
|
|
12999
|
+
else {
|
|
13000
|
+
this.draft.size = { ...(this.draft.size || {}), [field]: text };
|
|
13001
|
+
}
|
|
13002
|
+
this.emitDraft();
|
|
13003
|
+
}
|
|
13004
|
+
updateWidgetId(componentId) {
|
|
13005
|
+
const nextId = String(componentId || '').trim();
|
|
13006
|
+
const previousInputs = { ...(this.draft.widget.inputs || {}) };
|
|
13007
|
+
this.draft.widget.id = nextId;
|
|
13008
|
+
this.draft.widget.inputs = this.reconcileInputsForComponent(nextId, previousInputs);
|
|
13009
|
+
this.refreshJsonDrafts();
|
|
13010
|
+
this.emitDraft();
|
|
13011
|
+
}
|
|
13012
|
+
updateBindingOrder(value) {
|
|
13013
|
+
const items = String(value || '')
|
|
13014
|
+
.split(',')
|
|
13015
|
+
.map((item) => item.trim())
|
|
13016
|
+
.filter(Boolean);
|
|
13017
|
+
if (items.length) {
|
|
13018
|
+
this.draft.widget.bindingOrder = items;
|
|
13019
|
+
}
|
|
13020
|
+
else {
|
|
13021
|
+
delete this.draft.widget.bindingOrder;
|
|
13022
|
+
}
|
|
13023
|
+
this.emitDraft();
|
|
13024
|
+
}
|
|
13025
|
+
applyPreset(preset) {
|
|
13026
|
+
this.draft = this.normalizePayload(preset.payload);
|
|
13027
|
+
this.refreshJsonDrafts();
|
|
13028
|
+
this.emitDraft();
|
|
13029
|
+
}
|
|
13030
|
+
isBooleanType(type) {
|
|
13031
|
+
return /^(bool|boolean)$/i.test(String(type || ''));
|
|
13032
|
+
}
|
|
13033
|
+
isNumberType(type) {
|
|
13034
|
+
return /^(number|int|float|double)$/i.test(String(type || ''));
|
|
13035
|
+
}
|
|
13036
|
+
isJsonType(type) {
|
|
13037
|
+
return /(json|object|record|map|array|\[\]|criteria|config|input|params)/i.test(String(type || ''));
|
|
13038
|
+
}
|
|
13039
|
+
getBooleanInputValue(name) {
|
|
13040
|
+
return Boolean(this.draft.widget.inputs?.[name]);
|
|
13041
|
+
}
|
|
13042
|
+
getScalarInputValue(name) {
|
|
13043
|
+
return this.draft.widget.inputs?.[name] ?? '';
|
|
13044
|
+
}
|
|
13045
|
+
getJsonInputDraft(name) {
|
|
13046
|
+
if (!(name in this.inputJsonDrafts)) {
|
|
13047
|
+
this.inputJsonDrafts[name] = this.stringifyJson(this.draft.widget.inputs?.[name]);
|
|
13048
|
+
}
|
|
13049
|
+
return this.inputJsonDrafts[name];
|
|
13050
|
+
}
|
|
13051
|
+
scalarPlaceholder(input) {
|
|
13052
|
+
if (input.default !== undefined && input.default !== null && input.default !== '') {
|
|
13053
|
+
return String(input.default);
|
|
13054
|
+
}
|
|
13055
|
+
return '';
|
|
13056
|
+
}
|
|
13057
|
+
jsonPlaceholder(input) {
|
|
13058
|
+
if (input.default !== undefined && input.default !== null && input.default !== '') {
|
|
13059
|
+
return this.stringifyJson(input.default);
|
|
13060
|
+
}
|
|
13061
|
+
return '{ }';
|
|
13062
|
+
}
|
|
13063
|
+
updateBooleanInput(name, value) {
|
|
13064
|
+
this.ensureWidgetInputs();
|
|
13065
|
+
this.draft.widget.inputs[name] = Boolean(value);
|
|
13066
|
+
this.emitDraft();
|
|
13067
|
+
}
|
|
13068
|
+
updateScalarInput(name, type, value) {
|
|
13069
|
+
this.ensureWidgetInputs();
|
|
13070
|
+
const text = String(value ?? '');
|
|
13071
|
+
if (!text.trim()) {
|
|
13072
|
+
delete this.draft.widget.inputs[name];
|
|
13073
|
+
}
|
|
13074
|
+
else if (this.isNumberType(type)) {
|
|
13075
|
+
const parsed = Number(text);
|
|
13076
|
+
this.draft.widget.inputs[name] = Number.isFinite(parsed) ? parsed : text;
|
|
13077
|
+
}
|
|
13078
|
+
else {
|
|
13079
|
+
this.draft.widget.inputs[name] = value;
|
|
13080
|
+
}
|
|
13081
|
+
this.emitDraft();
|
|
13082
|
+
}
|
|
13083
|
+
updateJsonInput(name, value) {
|
|
13084
|
+
const raw = String(value || '');
|
|
13085
|
+
this.inputJsonDrafts[name] = raw;
|
|
13086
|
+
if (!raw.trim()) {
|
|
13087
|
+
delete this.inputErrors[name];
|
|
13088
|
+
if (this.draft.widget.inputs) {
|
|
13089
|
+
delete this.draft.widget.inputs[name];
|
|
13090
|
+
}
|
|
13091
|
+
this.emitDraft();
|
|
13092
|
+
return;
|
|
13093
|
+
}
|
|
13094
|
+
try {
|
|
13095
|
+
const parsed = JSON.parse(raw);
|
|
13096
|
+
delete this.inputErrors[name];
|
|
13097
|
+
this.ensureWidgetInputs();
|
|
13098
|
+
this.draft.widget.inputs[name] = parsed;
|
|
13099
|
+
this.emitDraft();
|
|
13100
|
+
}
|
|
13101
|
+
catch {
|
|
13102
|
+
this.inputErrors[name] = this.t('editor.validation.invalidJson', 'JSON inválido.');
|
|
13103
|
+
}
|
|
13104
|
+
}
|
|
13105
|
+
addBinding() {
|
|
13106
|
+
const bindings = [...(this.draft.bindings || [])];
|
|
13107
|
+
bindings.push({
|
|
13108
|
+
from: '',
|
|
13109
|
+
to: this.selectedInputs[0]
|
|
13110
|
+
? `widget.inputs.${this.selectedInputs[0].name}`
|
|
13111
|
+
: 'widget.inputs.resourceId',
|
|
13112
|
+
mode: 'path',
|
|
13113
|
+
});
|
|
13114
|
+
this.draft.bindings = bindings;
|
|
13115
|
+
this.emitDraft();
|
|
13116
|
+
}
|
|
13117
|
+
updateBinding(index, field, value) {
|
|
13118
|
+
const bindings = [...(this.draft.bindings || [])];
|
|
13119
|
+
const current = { ...(bindings[index] || { to: 'widget.inputs.resourceId', mode: 'path' }) };
|
|
13120
|
+
if (field === 'mode') {
|
|
13121
|
+
current.mode = value || 'path';
|
|
13122
|
+
if (current.mode !== 'constant') {
|
|
13123
|
+
delete current.value;
|
|
13124
|
+
}
|
|
13125
|
+
else if (current.value === undefined) {
|
|
13126
|
+
current.value = '';
|
|
13127
|
+
}
|
|
13128
|
+
}
|
|
13129
|
+
else if (field === 'value') {
|
|
13130
|
+
current.value = value;
|
|
13131
|
+
}
|
|
13132
|
+
else if (field === 'from') {
|
|
13133
|
+
current.from = String(value || '').trim();
|
|
13134
|
+
}
|
|
13135
|
+
else if (field === 'to') {
|
|
13136
|
+
current.to = String(value || '').trim();
|
|
13137
|
+
}
|
|
13138
|
+
bindings[index] = current;
|
|
13139
|
+
this.draft.bindings = bindings;
|
|
13140
|
+
this.emitDraft();
|
|
13141
|
+
}
|
|
13142
|
+
removeBinding(index) {
|
|
13143
|
+
const bindings = [...(this.draft.bindings || [])];
|
|
13144
|
+
bindings.splice(index, 1);
|
|
13145
|
+
this.draft.bindings = bindings.length ? bindings : undefined;
|
|
13146
|
+
this.emitDraft();
|
|
13147
|
+
}
|
|
13148
|
+
updateContext(value) {
|
|
13149
|
+
const raw = String(value || '');
|
|
13150
|
+
this.contextDraft = raw;
|
|
13151
|
+
if (!raw.trim()) {
|
|
13152
|
+
this.contextError = '';
|
|
13153
|
+
delete this.draft.context;
|
|
13154
|
+
this.emitDraft();
|
|
13155
|
+
return;
|
|
13156
|
+
}
|
|
13157
|
+
try {
|
|
13158
|
+
const parsed = JSON.parse(raw);
|
|
13159
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
13160
|
+
this.contextError = this.t('editor.validation.objectJson', 'Informe um objeto JSON.');
|
|
13161
|
+
return;
|
|
13162
|
+
}
|
|
13163
|
+
this.contextError = '';
|
|
13164
|
+
this.draft.context = parsed;
|
|
13165
|
+
this.emitDraft();
|
|
13166
|
+
}
|
|
13167
|
+
catch {
|
|
13168
|
+
this.contextError = this.t('editor.validation.invalidJson', 'JSON inválido.');
|
|
13169
|
+
}
|
|
13170
|
+
}
|
|
13171
|
+
presetLabel(preset) {
|
|
13172
|
+
return this.t(`preset.${preset.id}.label`, preset.label);
|
|
13173
|
+
}
|
|
13174
|
+
presetDescription(preset) {
|
|
13175
|
+
return this.t(`preset.${preset.id}.description`, preset.description);
|
|
13176
|
+
}
|
|
13177
|
+
t(key, fallback, params) {
|
|
13178
|
+
return this.i18n.t(key, params, fallback, SURFACE_OPEN_I18N_NAMESPACE);
|
|
13179
|
+
}
|
|
13180
|
+
refreshJsonDrafts() {
|
|
13181
|
+
this.inputJsonDrafts = {};
|
|
13182
|
+
this.inputErrors = {};
|
|
13183
|
+
for (const input of this.selectedInputs) {
|
|
13184
|
+
if (this.isJsonType(input.type)) {
|
|
13185
|
+
this.inputJsonDrafts[input.name] = this.stringifyJson(this.draft.widget.inputs?.[input.name]);
|
|
13186
|
+
}
|
|
13187
|
+
}
|
|
13188
|
+
this.contextDraft = this.stringifyJson(this.draft.context);
|
|
13189
|
+
this.contextError = '';
|
|
13190
|
+
}
|
|
13191
|
+
emitDraft() {
|
|
13192
|
+
const normalized = this.normalizePayload(this.draft);
|
|
13193
|
+
this.draft = normalized;
|
|
13194
|
+
this.valueChange.emit(this.clone(normalized));
|
|
13195
|
+
}
|
|
13196
|
+
ensureWidgetInputs() {
|
|
13197
|
+
this.draft.widget.inputs = { ...(this.draft.widget.inputs || {}) };
|
|
13198
|
+
}
|
|
13199
|
+
reconcileInputsForComponent(componentId, previousInputs) {
|
|
13200
|
+
const meta = componentId ? this.registry.get(componentId) : undefined;
|
|
13201
|
+
if (!meta?.inputs?.length) {
|
|
13202
|
+
return {};
|
|
13203
|
+
}
|
|
13204
|
+
const nextInputs = {};
|
|
13205
|
+
for (const input of meta.inputs) {
|
|
13206
|
+
if (Object.prototype.hasOwnProperty.call(previousInputs, input.name)) {
|
|
13207
|
+
nextInputs[input.name] = previousInputs[input.name];
|
|
13208
|
+
continue;
|
|
13209
|
+
}
|
|
13210
|
+
if (input.default !== undefined) {
|
|
13211
|
+
nextInputs[input.name] = this.clone(input.default);
|
|
13212
|
+
}
|
|
13213
|
+
}
|
|
13214
|
+
return nextInputs;
|
|
13215
|
+
}
|
|
13216
|
+
assignTextField(field, value) {
|
|
13217
|
+
const text = String(value || '').trim();
|
|
13218
|
+
if (text) {
|
|
13219
|
+
this.draft[field] = text;
|
|
13220
|
+
}
|
|
13221
|
+
else {
|
|
13222
|
+
delete this.draft[field];
|
|
13223
|
+
}
|
|
13224
|
+
}
|
|
13225
|
+
normalizePayload(value) {
|
|
13226
|
+
const clone = this.clone(value || this.createDefaultPayload());
|
|
13227
|
+
const normalized = {
|
|
13228
|
+
presentation: clone.presentation === 'drawer' ? 'drawer' : 'modal',
|
|
13229
|
+
widget: {
|
|
13230
|
+
id: String(clone.widget?.id || '').trim(),
|
|
13231
|
+
inputs: { ...(clone.widget?.inputs || {}) },
|
|
13232
|
+
},
|
|
13233
|
+
};
|
|
13234
|
+
if (clone.title)
|
|
13235
|
+
normalized.title = clone.title;
|
|
13236
|
+
if (clone.subtitle)
|
|
13237
|
+
normalized.subtitle = clone.subtitle;
|
|
13238
|
+
if (clone.icon)
|
|
13239
|
+
normalized.icon = clone.icon;
|
|
13240
|
+
if (clone.size && Object.keys(clone.size).length) {
|
|
13241
|
+
normalized.size = { ...clone.size };
|
|
13242
|
+
}
|
|
13243
|
+
if (clone.widget?.bindingOrder?.length) {
|
|
13244
|
+
normalized.widget.bindingOrder = clone.widget.bindingOrder
|
|
13245
|
+
.map((item) => String(item || '').trim())
|
|
13246
|
+
.filter(Boolean);
|
|
13247
|
+
}
|
|
13248
|
+
if (clone.bindings?.length) {
|
|
13249
|
+
normalized.bindings = clone.bindings
|
|
13250
|
+
.map((binding) => ({
|
|
13251
|
+
from: binding.from ? String(binding.from).trim() : undefined,
|
|
13252
|
+
to: String(binding.to || '').trim(),
|
|
13253
|
+
mode: binding.mode || 'path',
|
|
13254
|
+
value: binding.value,
|
|
13255
|
+
}))
|
|
13256
|
+
.filter((binding) => !!binding.to);
|
|
13257
|
+
}
|
|
13258
|
+
if (clone.context && typeof clone.context === 'object' && !Array.isArray(clone.context)) {
|
|
13259
|
+
normalized.context = { ...clone.context };
|
|
13260
|
+
}
|
|
13261
|
+
return normalized;
|
|
13262
|
+
}
|
|
13263
|
+
createDefaultPayload() {
|
|
13264
|
+
return {
|
|
13265
|
+
presentation: 'modal',
|
|
13266
|
+
widget: {
|
|
13267
|
+
id: '',
|
|
13268
|
+
inputs: {},
|
|
13269
|
+
},
|
|
13270
|
+
bindings: [],
|
|
13271
|
+
};
|
|
13272
|
+
}
|
|
13273
|
+
stringifyJson(value) {
|
|
13274
|
+
if (value === undefined || value === null || value === '')
|
|
13275
|
+
return '';
|
|
13276
|
+
if (typeof value === 'string')
|
|
13277
|
+
return value;
|
|
13278
|
+
try {
|
|
13279
|
+
return JSON.stringify(value, null, 2);
|
|
13280
|
+
}
|
|
13281
|
+
catch {
|
|
13282
|
+
return '';
|
|
13283
|
+
}
|
|
13284
|
+
}
|
|
13285
|
+
clone(value) {
|
|
13286
|
+
return value == null ? value : JSON.parse(JSON.stringify(value));
|
|
13287
|
+
}
|
|
13288
|
+
uniqueStrings(values) {
|
|
13289
|
+
return Array.from(new Set(values
|
|
13290
|
+
.map((value) => String(value || '').trim())
|
|
13291
|
+
.filter(Boolean)));
|
|
13292
|
+
}
|
|
13293
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SurfaceOpenActionEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
13294
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: SurfaceOpenActionEditorComponent, isStandalone: true, selector: "praxis-surface-open-action-editor", inputs: { value: "value", hostKind: "hostKind" }, outputs: { valueChange: "valueChange" }, providers: [providePraxisI18nConfig(SURFACE_OPEN_I18N_CONFIG)], usesOnChanges: true, ngImport: i0, template: `
|
|
13295
|
+
<div class="surface-editor">
|
|
13296
|
+
<div class="surface-section">
|
|
13297
|
+
<div class="surface-section-title">{{ t('editor.presets.title', 'Presets') }}</div>
|
|
13298
|
+
<div class="surface-preset-row">
|
|
13299
|
+
@for (preset of availablePresets; track preset.id) {
|
|
13300
|
+
<button
|
|
13301
|
+
mat-stroked-button
|
|
13302
|
+
type="button"
|
|
13303
|
+
(click)="applyPreset(preset)"
|
|
13304
|
+
[matTooltip]="presetDescription(preset)"
|
|
13305
|
+
>
|
|
13306
|
+
{{ presetLabel(preset) }}
|
|
13307
|
+
</button>
|
|
13308
|
+
}
|
|
13309
|
+
</div>
|
|
13310
|
+
<div class="surface-empty">
|
|
13311
|
+
{{
|
|
13312
|
+
t(
|
|
13313
|
+
'editor.presets.help',
|
|
13314
|
+
'Aplique um preset para começar com inputs mínimos e depois configure bindings conforme a origem da action.'
|
|
13315
|
+
)
|
|
13316
|
+
}}
|
|
13317
|
+
</div>
|
|
13318
|
+
</div>
|
|
13319
|
+
|
|
13320
|
+
<div class="surface-section">
|
|
13321
|
+
<div class="surface-section-title">{{ t('editor.surface.title', 'Surface') }}</div>
|
|
13322
|
+
<div class="surface-grid">
|
|
13323
|
+
<mat-form-field appearance="outline">
|
|
13324
|
+
<mat-label>{{ t('editor.surface.presentation', 'Apresentação') }}</mat-label>
|
|
13325
|
+
<mat-select
|
|
13326
|
+
[ngModel]="draft.presentation"
|
|
13327
|
+
(ngModelChange)="updatePresentation($event)"
|
|
13328
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13329
|
+
>
|
|
13330
|
+
<mat-option value="modal">{{ t('editor.surface.presentation.modal', 'Modal') }}</mat-option>
|
|
13331
|
+
<mat-option value="drawer">{{ t('editor.surface.presentation.drawer', 'Drawer') }}</mat-option>
|
|
13332
|
+
</mat-select>
|
|
13333
|
+
</mat-form-field>
|
|
13334
|
+
|
|
13335
|
+
<mat-form-field appearance="outline">
|
|
13336
|
+
<mat-label>{{ t('editor.surface.titleLabel', 'Título') }}</mat-label>
|
|
13337
|
+
<input
|
|
13338
|
+
matInput
|
|
13339
|
+
[ngModel]="draft.title || ''"
|
|
13340
|
+
(ngModelChange)="updateTextField('title', $event)"
|
|
13341
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13342
|
+
/>
|
|
13343
|
+
</mat-form-field>
|
|
13344
|
+
|
|
13345
|
+
<mat-form-field appearance="outline">
|
|
13346
|
+
<mat-label>{{ t('editor.surface.subtitleLabel', 'Subtítulo') }}</mat-label>
|
|
13347
|
+
<input
|
|
13348
|
+
matInput
|
|
13349
|
+
[ngModel]="draft.subtitle || ''"
|
|
13350
|
+
(ngModelChange)="updateTextField('subtitle', $event)"
|
|
13351
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13352
|
+
/>
|
|
13353
|
+
</mat-form-field>
|
|
13354
|
+
|
|
13355
|
+
<mat-form-field appearance="outline">
|
|
13356
|
+
<mat-label>{{ t('editor.surface.iconLabel', 'Ícone') }}</mat-label>
|
|
13357
|
+
<input
|
|
13358
|
+
matInput
|
|
13359
|
+
[ngModel]="draft.icon || ''"
|
|
13360
|
+
(ngModelChange)="updateTextField('icon', $event)"
|
|
13361
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13362
|
+
placeholder="open_in_new"
|
|
13363
|
+
/>
|
|
13364
|
+
</mat-form-field>
|
|
13365
|
+
|
|
13366
|
+
<mat-form-field appearance="outline">
|
|
13367
|
+
<mat-label>{{ t('editor.surface.widthLabel', 'Largura') }}</mat-label>
|
|
13368
|
+
<input
|
|
13369
|
+
matInput
|
|
13370
|
+
[ngModel]="draft.size?.width || ''"
|
|
13371
|
+
(ngModelChange)="updateSizeField('width', $event)"
|
|
13372
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13373
|
+
placeholder="720px"
|
|
13374
|
+
/>
|
|
13375
|
+
</mat-form-field>
|
|
13376
|
+
|
|
13377
|
+
<mat-form-field appearance="outline">
|
|
13378
|
+
<mat-label>{{ t('editor.surface.heightLabel', 'Altura') }}</mat-label>
|
|
13379
|
+
<input
|
|
13380
|
+
matInput
|
|
13381
|
+
[ngModel]="draft.size?.height || ''"
|
|
13382
|
+
(ngModelChange)="updateSizeField('height', $event)"
|
|
13383
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13384
|
+
placeholder="80vh"
|
|
13385
|
+
/>
|
|
13386
|
+
</mat-form-field>
|
|
13387
|
+
|
|
13388
|
+
<mat-form-field appearance="outline">
|
|
13389
|
+
<mat-label>{{ t('editor.surface.minWidthLabel', 'Largura mínima') }}</mat-label>
|
|
13390
|
+
<input
|
|
13391
|
+
matInput
|
|
13392
|
+
[ngModel]="draft.size?.minWidth || ''"
|
|
13393
|
+
(ngModelChange)="updateSizeField('minWidth', $event)"
|
|
13394
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13395
|
+
placeholder="360px"
|
|
13396
|
+
/>
|
|
13397
|
+
</mat-form-field>
|
|
13398
|
+
|
|
13399
|
+
<mat-form-field appearance="outline">
|
|
13400
|
+
<mat-label>{{ t('editor.surface.maxWidthLabel', 'Largura máxima') }}</mat-label>
|
|
13401
|
+
<input
|
|
13402
|
+
matInput
|
|
13403
|
+
[ngModel]="draft.size?.maxWidth || ''"
|
|
13404
|
+
(ngModelChange)="updateSizeField('maxWidth', $event)"
|
|
13405
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13406
|
+
placeholder="90vw"
|
|
13407
|
+
/>
|
|
13408
|
+
</mat-form-field>
|
|
13409
|
+
</div>
|
|
13410
|
+
</div>
|
|
13411
|
+
|
|
13412
|
+
<div class="surface-section">
|
|
13413
|
+
<div class="surface-section-title">{{ t('editor.component.title', 'Componente') }}</div>
|
|
13414
|
+
<div class="surface-grid">
|
|
13415
|
+
<mat-form-field appearance="outline" class="surface-span-2">
|
|
13416
|
+
<mat-label>{{ t('editor.component.select', 'Componente registrado') }}</mat-label>
|
|
13417
|
+
<mat-select
|
|
13418
|
+
[ngModel]="draft.widget.id"
|
|
13419
|
+
(ngModelChange)="updateWidgetId($event)"
|
|
13420
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13421
|
+
>
|
|
13422
|
+
<mat-option value="">{{ t('editor.component.selectPlaceholder', '-- Selecionar --') }}</mat-option>
|
|
13423
|
+
@for (option of componentOptions; track option.id) {
|
|
13424
|
+
<mat-option [value]="option.id">
|
|
13425
|
+
{{ option.friendlyName || option.id }}
|
|
13426
|
+
</mat-option>
|
|
13427
|
+
}
|
|
13428
|
+
</mat-select>
|
|
13429
|
+
</mat-form-field>
|
|
13430
|
+
|
|
13431
|
+
@if (selectedComponentMeta) {
|
|
13432
|
+
<div class="surface-component-meta surface-span-2">
|
|
13433
|
+
<div class="surface-component-title">
|
|
13434
|
+
{{ selectedComponentMeta.friendlyName || selectedComponentMeta.id }}
|
|
13435
|
+
</div>
|
|
13436
|
+
@if (selectedComponentMeta.description) {
|
|
13437
|
+
<div class="surface-component-description">
|
|
13438
|
+
{{ selectedComponentMeta.description }}
|
|
13439
|
+
</div>
|
|
13440
|
+
}
|
|
13441
|
+
</div>
|
|
13442
|
+
}
|
|
13443
|
+
|
|
13444
|
+
<mat-form-field appearance="outline" class="surface-span-2">
|
|
13445
|
+
<mat-label>{{ t('editor.component.bindingOrder', 'bindingOrder (CSV)') }}</mat-label>
|
|
13446
|
+
<input
|
|
13447
|
+
matInput
|
|
13448
|
+
[ngModel]="bindingOrderText"
|
|
13449
|
+
(ngModelChange)="updateBindingOrder($event)"
|
|
13450
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13451
|
+
[placeholder]="t('editor.component.bindingOrderPlaceholder', 'resourcePath, formId, resourceId')"
|
|
13452
|
+
/>
|
|
13453
|
+
</mat-form-field>
|
|
13454
|
+
</div>
|
|
13455
|
+
</div>
|
|
13456
|
+
|
|
13457
|
+
<div class="surface-section">
|
|
13458
|
+
<div class="surface-section-title">{{ t('editor.inputs.title', 'Inputs') }}</div>
|
|
13459
|
+
@if (selectedInputs.length) {
|
|
13460
|
+
<div class="surface-grid">
|
|
13461
|
+
@for (input of selectedInputs; track input.name) {
|
|
13462
|
+
@if (isBooleanType(input.type)) {
|
|
13463
|
+
<mat-slide-toggle
|
|
13464
|
+
[ngModel]="getBooleanInputValue(input.name)"
|
|
13465
|
+
(ngModelChange)="updateBooleanInput(input.name, $event)"
|
|
13466
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13467
|
+
>
|
|
13468
|
+
{{ input.label || input.name }}
|
|
13469
|
+
</mat-slide-toggle>
|
|
13470
|
+
} @else if (isJsonType(input.type)) {
|
|
13471
|
+
<mat-form-field appearance="outline" class="surface-span-2">
|
|
13472
|
+
<mat-label>{{ input.label || input.name }}</mat-label>
|
|
13473
|
+
<textarea
|
|
13474
|
+
matInput
|
|
13475
|
+
rows="4"
|
|
13476
|
+
[ngModel]="getJsonInputDraft(input.name)"
|
|
13477
|
+
(ngModelChange)="updateJsonInput(input.name, $event)"
|
|
13478
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13479
|
+
[placeholder]="jsonPlaceholder(input)"
|
|
13480
|
+
></textarea>
|
|
13481
|
+
@if (input.description) {
|
|
13482
|
+
<mat-hint>{{ input.description }}</mat-hint>
|
|
13483
|
+
}
|
|
13484
|
+
@if (inputErrors[input.name]) {
|
|
13485
|
+
<mat-error>{{ inputErrors[input.name] }}</mat-error>
|
|
13486
|
+
}
|
|
13487
|
+
</mat-form-field>
|
|
13488
|
+
} @else {
|
|
13489
|
+
<mat-form-field appearance="outline">
|
|
13490
|
+
<mat-label>{{ input.label || input.name }}</mat-label>
|
|
13491
|
+
<input
|
|
13492
|
+
matInput
|
|
13493
|
+
[type]="isNumberType(input.type) ? 'number' : 'text'"
|
|
13494
|
+
[ngModel]="getScalarInputValue(input.name)"
|
|
13495
|
+
(ngModelChange)="updateScalarInput(input.name, input.type, $event)"
|
|
13496
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13497
|
+
[placeholder]="scalarPlaceholder(input)"
|
|
13498
|
+
/>
|
|
13499
|
+
@if (input.description) {
|
|
13500
|
+
<mat-hint>{{ input.description }}</mat-hint>
|
|
13501
|
+
}
|
|
13502
|
+
</mat-form-field>
|
|
13503
|
+
}
|
|
13504
|
+
}
|
|
13505
|
+
</div>
|
|
13506
|
+
} @else {
|
|
13507
|
+
<div class="surface-empty">
|
|
13508
|
+
{{ t('editor.inputs.empty', 'Selecione um componente registrado para configurar inputs públicos.') }}
|
|
13509
|
+
</div>
|
|
13510
|
+
}
|
|
13511
|
+
</div>
|
|
13512
|
+
|
|
13513
|
+
<div class="surface-section">
|
|
13514
|
+
<div class="surface-section-header">
|
|
13515
|
+
<div class="surface-section-title">{{ t('editor.bindings.title', 'Bindings') }}</div>
|
|
13516
|
+
<button mat-stroked-button type="button" (click)="addBinding()">
|
|
13517
|
+
<mat-icon>add</mat-icon>
|
|
13518
|
+
{{ t('editor.bindings.add', 'Binding') }}
|
|
13519
|
+
</button>
|
|
13520
|
+
</div>
|
|
13521
|
+
@if (draft.bindings?.length) {
|
|
13522
|
+
<div class="surface-bindings">
|
|
13523
|
+
@for (binding of draft.bindings || []; track $index) {
|
|
13524
|
+
<div class="surface-binding-row">
|
|
13525
|
+
<mat-form-field appearance="outline">
|
|
13526
|
+
<mat-label>{{ t('editor.bindings.source', 'Origem') }}</mat-label>
|
|
13527
|
+
<input
|
|
13528
|
+
matInput
|
|
13529
|
+
[ngModel]="binding.from || ''"
|
|
13530
|
+
(ngModelChange)="updateBinding($index, 'from', $event)"
|
|
13531
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13532
|
+
[attr.list]="sourceSuggestionsListId"
|
|
13533
|
+
placeholder="payload.row.id"
|
|
13534
|
+
/>
|
|
13535
|
+
</mat-form-field>
|
|
13536
|
+
|
|
13537
|
+
<mat-form-field appearance="outline">
|
|
13538
|
+
<mat-label>{{ t('editor.bindings.target', 'Destino') }}</mat-label>
|
|
13539
|
+
<input
|
|
13540
|
+
matInput
|
|
13541
|
+
[ngModel]="binding.to"
|
|
13542
|
+
(ngModelChange)="updateBinding($index, 'to', $event)"
|
|
13543
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13544
|
+
[attr.list]="targetSuggestionsListId"
|
|
13545
|
+
placeholder="widget.inputs.resourceId"
|
|
13546
|
+
/>
|
|
13547
|
+
</mat-form-field>
|
|
13548
|
+
|
|
13549
|
+
<mat-form-field appearance="outline">
|
|
13550
|
+
<mat-label>{{ t('editor.bindings.mode', 'Modo') }}</mat-label>
|
|
13551
|
+
<mat-select
|
|
13552
|
+
[ngModel]="binding.mode || 'path'"
|
|
13553
|
+
(ngModelChange)="updateBinding($index, 'mode', $event)"
|
|
13554
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13555
|
+
>
|
|
13556
|
+
<mat-option value="path">path</mat-option>
|
|
13557
|
+
<mat-option value="template">template</mat-option>
|
|
13558
|
+
<mat-option value="constant">constant</mat-option>
|
|
13559
|
+
</mat-select>
|
|
13560
|
+
</mat-form-field>
|
|
13561
|
+
|
|
13562
|
+
@if ((binding.mode || 'path') === 'constant') {
|
|
13563
|
+
<mat-form-field appearance="outline">
|
|
13564
|
+
<mat-label>{{ t('editor.bindings.constantValue', 'Valor constante') }}</mat-label>
|
|
13565
|
+
<input
|
|
13566
|
+
matInput
|
|
13567
|
+
[ngModel]="binding.value ?? ''"
|
|
13568
|
+
(ngModelChange)="updateBinding($index, 'value', $event)"
|
|
13569
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13570
|
+
/>
|
|
13571
|
+
</mat-form-field>
|
|
13572
|
+
}
|
|
13573
|
+
|
|
13574
|
+
<button
|
|
13575
|
+
mat-icon-button
|
|
13576
|
+
color="warn"
|
|
13577
|
+
type="button"
|
|
13578
|
+
(click)="removeBinding($index)"
|
|
13579
|
+
[attr.aria-label]="t('editor.bindings.remove', 'Remover binding')"
|
|
13580
|
+
>
|
|
13581
|
+
<mat-icon>delete</mat-icon>
|
|
13582
|
+
</button>
|
|
13583
|
+
</div>
|
|
13584
|
+
}
|
|
13585
|
+
</div>
|
|
13586
|
+
} @else {
|
|
13587
|
+
<div class="surface-empty">
|
|
13588
|
+
{{ t('editor.bindings.empty', 'Nenhum binding configurado ainda.') }}
|
|
13589
|
+
</div>
|
|
13590
|
+
}
|
|
13591
|
+
<div class="surface-empty">
|
|
13592
|
+
@if (bindingSourceSuggestionsPreview) {
|
|
13593
|
+
<div>
|
|
13594
|
+
{{ t('editor.bindings.suggestedSources', 'Origens sugeridas: {{value}}', { value: bindingSourceSuggestionsPreview }) }}
|
|
13595
|
+
</div>
|
|
13596
|
+
}
|
|
13597
|
+
@if (bindingTargetSuggestionsPreview) {
|
|
13598
|
+
<div>
|
|
13599
|
+
{{ t('editor.bindings.suggestedTargets', 'Destinos sugeridos: {{value}}', { value: bindingTargetSuggestionsPreview }) }}
|
|
13600
|
+
</div>
|
|
13601
|
+
}
|
|
13602
|
+
</div>
|
|
13603
|
+
<datalist [id]="sourceSuggestionsListId">
|
|
13604
|
+
@for (suggestion of bindingSourceSuggestions; track suggestion) {
|
|
13605
|
+
<option [value]="suggestion"></option>
|
|
13606
|
+
}
|
|
13607
|
+
</datalist>
|
|
13608
|
+
<datalist [id]="targetSuggestionsListId">
|
|
13609
|
+
@for (suggestion of bindingTargetSuggestions; track suggestion) {
|
|
13610
|
+
<option [value]="suggestion"></option>
|
|
13611
|
+
}
|
|
13612
|
+
</datalist>
|
|
13613
|
+
</div>
|
|
13614
|
+
|
|
13615
|
+
<div class="surface-section">
|
|
13616
|
+
<div class="surface-section-title">{{ t('editor.context.title', 'Contexto extra') }}</div>
|
|
13617
|
+
<mat-form-field appearance="outline" class="surface-span-all">
|
|
13618
|
+
<mat-label>{{ t('editor.context.label', 'context (JSON)') }}</mat-label>
|
|
13619
|
+
<textarea
|
|
13620
|
+
matInput
|
|
13621
|
+
rows="4"
|
|
13622
|
+
[ngModel]="contextDraft"
|
|
13623
|
+
(ngModelChange)="updateContext($event)"
|
|
13624
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13625
|
+
placeholder="{ }"
|
|
13626
|
+
></textarea>
|
|
13627
|
+
<mat-hint>{{ t('editor.context.hint', 'Opcional. Mesclado ao contexto da action no runtime.') }}</mat-hint>
|
|
13628
|
+
@if (contextError) {
|
|
13629
|
+
<mat-error>{{ contextError }}</mat-error>
|
|
13630
|
+
}
|
|
13631
|
+
</mat-form-field>
|
|
13632
|
+
</div>
|
|
13633
|
+
</div>
|
|
13634
|
+
`, isInline: true, styles: [".surface-editor{display:grid;gap:16px}.surface-section{padding:12px 14px;border:1px dashed var(--md-sys-color-outline-variant, rgba(0, 0, 0, .18));border-radius:10px;background:var(--md-sys-color-surface-container-lowest, #fff)}.surface-section-header{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px}.surface-section-title{font-size:12px;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant, #5f6368);margin-bottom:10px}.surface-section-header .surface-section-title{margin-bottom:0}.surface-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px 16px}.surface-preset-row{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}.surface-span-2{grid-column:span 2}.surface-span-all{width:100%}.surface-component-meta{display:grid;gap:4px}.surface-component-title{font-weight:600}.surface-component-description,.surface-empty{color:var(--md-sys-color-on-surface-variant, #5f6368);font-size:12px}.surface-bindings{display:grid;gap:12px}.surface-binding-row{display:grid;grid-template-columns:minmax(200px,1.2fr) minmax(220px,1.4fr) minmax(140px,.8fr) minmax(180px,1fr) auto;gap:12px;align-items:start}mat-form-field{width:100%}@media(max-width:960px){.surface-binding-row{grid-template-columns:minmax(0,1fr)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { 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: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.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: "component", type: i6.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: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i7.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
13635
|
+
}
|
|
13636
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SurfaceOpenActionEditorComponent, decorators: [{
|
|
13637
|
+
type: Component,
|
|
13638
|
+
args: [{ selector: 'praxis-surface-open-action-editor', standalone: true, providers: [providePraxisI18nConfig(SURFACE_OPEN_I18N_CONFIG)], imports: [
|
|
13639
|
+
CommonModule,
|
|
13640
|
+
FormsModule,
|
|
13641
|
+
MatButtonModule,
|
|
13642
|
+
MatFormFieldModule,
|
|
13643
|
+
MatIconModule,
|
|
13644
|
+
MatInputModule,
|
|
13645
|
+
MatSelectModule,
|
|
13646
|
+
MatSlideToggleModule,
|
|
13647
|
+
MatTooltipModule,
|
|
13648
|
+
], template: `
|
|
13649
|
+
<div class="surface-editor">
|
|
13650
|
+
<div class="surface-section">
|
|
13651
|
+
<div class="surface-section-title">{{ t('editor.presets.title', 'Presets') }}</div>
|
|
13652
|
+
<div class="surface-preset-row">
|
|
13653
|
+
@for (preset of availablePresets; track preset.id) {
|
|
13654
|
+
<button
|
|
13655
|
+
mat-stroked-button
|
|
13656
|
+
type="button"
|
|
13657
|
+
(click)="applyPreset(preset)"
|
|
13658
|
+
[matTooltip]="presetDescription(preset)"
|
|
13659
|
+
>
|
|
13660
|
+
{{ presetLabel(preset) }}
|
|
13661
|
+
</button>
|
|
13662
|
+
}
|
|
13663
|
+
</div>
|
|
13664
|
+
<div class="surface-empty">
|
|
13665
|
+
{{
|
|
13666
|
+
t(
|
|
13667
|
+
'editor.presets.help',
|
|
13668
|
+
'Aplique um preset para começar com inputs mínimos e depois configure bindings conforme a origem da action.'
|
|
13669
|
+
)
|
|
13670
|
+
}}
|
|
13671
|
+
</div>
|
|
13672
|
+
</div>
|
|
13673
|
+
|
|
13674
|
+
<div class="surface-section">
|
|
13675
|
+
<div class="surface-section-title">{{ t('editor.surface.title', 'Surface') }}</div>
|
|
13676
|
+
<div class="surface-grid">
|
|
13677
|
+
<mat-form-field appearance="outline">
|
|
13678
|
+
<mat-label>{{ t('editor.surface.presentation', 'Apresentação') }}</mat-label>
|
|
13679
|
+
<mat-select
|
|
13680
|
+
[ngModel]="draft.presentation"
|
|
13681
|
+
(ngModelChange)="updatePresentation($event)"
|
|
13682
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13683
|
+
>
|
|
13684
|
+
<mat-option value="modal">{{ t('editor.surface.presentation.modal', 'Modal') }}</mat-option>
|
|
13685
|
+
<mat-option value="drawer">{{ t('editor.surface.presentation.drawer', 'Drawer') }}</mat-option>
|
|
13686
|
+
</mat-select>
|
|
13687
|
+
</mat-form-field>
|
|
13688
|
+
|
|
13689
|
+
<mat-form-field appearance="outline">
|
|
13690
|
+
<mat-label>{{ t('editor.surface.titleLabel', 'Título') }}</mat-label>
|
|
13691
|
+
<input
|
|
13692
|
+
matInput
|
|
13693
|
+
[ngModel]="draft.title || ''"
|
|
13694
|
+
(ngModelChange)="updateTextField('title', $event)"
|
|
13695
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13696
|
+
/>
|
|
13697
|
+
</mat-form-field>
|
|
13698
|
+
|
|
13699
|
+
<mat-form-field appearance="outline">
|
|
13700
|
+
<mat-label>{{ t('editor.surface.subtitleLabel', 'Subtítulo') }}</mat-label>
|
|
13701
|
+
<input
|
|
13702
|
+
matInput
|
|
13703
|
+
[ngModel]="draft.subtitle || ''"
|
|
13704
|
+
(ngModelChange)="updateTextField('subtitle', $event)"
|
|
13705
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13706
|
+
/>
|
|
13707
|
+
</mat-form-field>
|
|
13708
|
+
|
|
13709
|
+
<mat-form-field appearance="outline">
|
|
13710
|
+
<mat-label>{{ t('editor.surface.iconLabel', 'Ícone') }}</mat-label>
|
|
13711
|
+
<input
|
|
13712
|
+
matInput
|
|
13713
|
+
[ngModel]="draft.icon || ''"
|
|
13714
|
+
(ngModelChange)="updateTextField('icon', $event)"
|
|
13715
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13716
|
+
placeholder="open_in_new"
|
|
13717
|
+
/>
|
|
13718
|
+
</mat-form-field>
|
|
13719
|
+
|
|
13720
|
+
<mat-form-field appearance="outline">
|
|
13721
|
+
<mat-label>{{ t('editor.surface.widthLabel', 'Largura') }}</mat-label>
|
|
13722
|
+
<input
|
|
13723
|
+
matInput
|
|
13724
|
+
[ngModel]="draft.size?.width || ''"
|
|
13725
|
+
(ngModelChange)="updateSizeField('width', $event)"
|
|
13726
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13727
|
+
placeholder="720px"
|
|
13728
|
+
/>
|
|
13729
|
+
</mat-form-field>
|
|
13730
|
+
|
|
13731
|
+
<mat-form-field appearance="outline">
|
|
13732
|
+
<mat-label>{{ t('editor.surface.heightLabel', 'Altura') }}</mat-label>
|
|
13733
|
+
<input
|
|
13734
|
+
matInput
|
|
13735
|
+
[ngModel]="draft.size?.height || ''"
|
|
13736
|
+
(ngModelChange)="updateSizeField('height', $event)"
|
|
13737
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13738
|
+
placeholder="80vh"
|
|
13739
|
+
/>
|
|
13740
|
+
</mat-form-field>
|
|
13741
|
+
|
|
13742
|
+
<mat-form-field appearance="outline">
|
|
13743
|
+
<mat-label>{{ t('editor.surface.minWidthLabel', 'Largura mínima') }}</mat-label>
|
|
13744
|
+
<input
|
|
13745
|
+
matInput
|
|
13746
|
+
[ngModel]="draft.size?.minWidth || ''"
|
|
13747
|
+
(ngModelChange)="updateSizeField('minWidth', $event)"
|
|
13748
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13749
|
+
placeholder="360px"
|
|
13750
|
+
/>
|
|
13751
|
+
</mat-form-field>
|
|
13752
|
+
|
|
13753
|
+
<mat-form-field appearance="outline">
|
|
13754
|
+
<mat-label>{{ t('editor.surface.maxWidthLabel', 'Largura máxima') }}</mat-label>
|
|
13755
|
+
<input
|
|
13756
|
+
matInput
|
|
13757
|
+
[ngModel]="draft.size?.maxWidth || ''"
|
|
13758
|
+
(ngModelChange)="updateSizeField('maxWidth', $event)"
|
|
13759
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13760
|
+
placeholder="90vw"
|
|
13761
|
+
/>
|
|
13762
|
+
</mat-form-field>
|
|
13763
|
+
</div>
|
|
13764
|
+
</div>
|
|
13765
|
+
|
|
13766
|
+
<div class="surface-section">
|
|
13767
|
+
<div class="surface-section-title">{{ t('editor.component.title', 'Componente') }}</div>
|
|
13768
|
+
<div class="surface-grid">
|
|
13769
|
+
<mat-form-field appearance="outline" class="surface-span-2">
|
|
13770
|
+
<mat-label>{{ t('editor.component.select', 'Componente registrado') }}</mat-label>
|
|
13771
|
+
<mat-select
|
|
13772
|
+
[ngModel]="draft.widget.id"
|
|
13773
|
+
(ngModelChange)="updateWidgetId($event)"
|
|
13774
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13775
|
+
>
|
|
13776
|
+
<mat-option value="">{{ t('editor.component.selectPlaceholder', '-- Selecionar --') }}</mat-option>
|
|
13777
|
+
@for (option of componentOptions; track option.id) {
|
|
13778
|
+
<mat-option [value]="option.id">
|
|
13779
|
+
{{ option.friendlyName || option.id }}
|
|
13780
|
+
</mat-option>
|
|
13781
|
+
}
|
|
13782
|
+
</mat-select>
|
|
13783
|
+
</mat-form-field>
|
|
13784
|
+
|
|
13785
|
+
@if (selectedComponentMeta) {
|
|
13786
|
+
<div class="surface-component-meta surface-span-2">
|
|
13787
|
+
<div class="surface-component-title">
|
|
13788
|
+
{{ selectedComponentMeta.friendlyName || selectedComponentMeta.id }}
|
|
13789
|
+
</div>
|
|
13790
|
+
@if (selectedComponentMeta.description) {
|
|
13791
|
+
<div class="surface-component-description">
|
|
13792
|
+
{{ selectedComponentMeta.description }}
|
|
13793
|
+
</div>
|
|
13794
|
+
}
|
|
13795
|
+
</div>
|
|
13796
|
+
}
|
|
13797
|
+
|
|
13798
|
+
<mat-form-field appearance="outline" class="surface-span-2">
|
|
13799
|
+
<mat-label>{{ t('editor.component.bindingOrder', 'bindingOrder (CSV)') }}</mat-label>
|
|
13800
|
+
<input
|
|
13801
|
+
matInput
|
|
13802
|
+
[ngModel]="bindingOrderText"
|
|
13803
|
+
(ngModelChange)="updateBindingOrder($event)"
|
|
13804
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13805
|
+
[placeholder]="t('editor.component.bindingOrderPlaceholder', 'resourcePath, formId, resourceId')"
|
|
13806
|
+
/>
|
|
13807
|
+
</mat-form-field>
|
|
13808
|
+
</div>
|
|
13809
|
+
</div>
|
|
13810
|
+
|
|
13811
|
+
<div class="surface-section">
|
|
13812
|
+
<div class="surface-section-title">{{ t('editor.inputs.title', 'Inputs') }}</div>
|
|
13813
|
+
@if (selectedInputs.length) {
|
|
13814
|
+
<div class="surface-grid">
|
|
13815
|
+
@for (input of selectedInputs; track input.name) {
|
|
13816
|
+
@if (isBooleanType(input.type)) {
|
|
13817
|
+
<mat-slide-toggle
|
|
13818
|
+
[ngModel]="getBooleanInputValue(input.name)"
|
|
13819
|
+
(ngModelChange)="updateBooleanInput(input.name, $event)"
|
|
13820
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13821
|
+
>
|
|
13822
|
+
{{ input.label || input.name }}
|
|
13823
|
+
</mat-slide-toggle>
|
|
13824
|
+
} @else if (isJsonType(input.type)) {
|
|
13825
|
+
<mat-form-field appearance="outline" class="surface-span-2">
|
|
13826
|
+
<mat-label>{{ input.label || input.name }}</mat-label>
|
|
13827
|
+
<textarea
|
|
13828
|
+
matInput
|
|
13829
|
+
rows="4"
|
|
13830
|
+
[ngModel]="getJsonInputDraft(input.name)"
|
|
13831
|
+
(ngModelChange)="updateJsonInput(input.name, $event)"
|
|
13832
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13833
|
+
[placeholder]="jsonPlaceholder(input)"
|
|
13834
|
+
></textarea>
|
|
13835
|
+
@if (input.description) {
|
|
13836
|
+
<mat-hint>{{ input.description }}</mat-hint>
|
|
13837
|
+
}
|
|
13838
|
+
@if (inputErrors[input.name]) {
|
|
13839
|
+
<mat-error>{{ inputErrors[input.name] }}</mat-error>
|
|
13840
|
+
}
|
|
13841
|
+
</mat-form-field>
|
|
13842
|
+
} @else {
|
|
13843
|
+
<mat-form-field appearance="outline">
|
|
13844
|
+
<mat-label>{{ input.label || input.name }}</mat-label>
|
|
13845
|
+
<input
|
|
13846
|
+
matInput
|
|
13847
|
+
[type]="isNumberType(input.type) ? 'number' : 'text'"
|
|
13848
|
+
[ngModel]="getScalarInputValue(input.name)"
|
|
13849
|
+
(ngModelChange)="updateScalarInput(input.name, input.type, $event)"
|
|
13850
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13851
|
+
[placeholder]="scalarPlaceholder(input)"
|
|
13852
|
+
/>
|
|
13853
|
+
@if (input.description) {
|
|
13854
|
+
<mat-hint>{{ input.description }}</mat-hint>
|
|
13855
|
+
}
|
|
13856
|
+
</mat-form-field>
|
|
13857
|
+
}
|
|
13858
|
+
}
|
|
13859
|
+
</div>
|
|
13860
|
+
} @else {
|
|
13861
|
+
<div class="surface-empty">
|
|
13862
|
+
{{ t('editor.inputs.empty', 'Selecione um componente registrado para configurar inputs públicos.') }}
|
|
13863
|
+
</div>
|
|
13864
|
+
}
|
|
13865
|
+
</div>
|
|
13866
|
+
|
|
13867
|
+
<div class="surface-section">
|
|
13868
|
+
<div class="surface-section-header">
|
|
13869
|
+
<div class="surface-section-title">{{ t('editor.bindings.title', 'Bindings') }}</div>
|
|
13870
|
+
<button mat-stroked-button type="button" (click)="addBinding()">
|
|
13871
|
+
<mat-icon>add</mat-icon>
|
|
13872
|
+
{{ t('editor.bindings.add', 'Binding') }}
|
|
13873
|
+
</button>
|
|
13874
|
+
</div>
|
|
13875
|
+
@if (draft.bindings?.length) {
|
|
13876
|
+
<div class="surface-bindings">
|
|
13877
|
+
@for (binding of draft.bindings || []; track $index) {
|
|
13878
|
+
<div class="surface-binding-row">
|
|
13879
|
+
<mat-form-field appearance="outline">
|
|
13880
|
+
<mat-label>{{ t('editor.bindings.source', 'Origem') }}</mat-label>
|
|
13881
|
+
<input
|
|
13882
|
+
matInput
|
|
13883
|
+
[ngModel]="binding.from || ''"
|
|
13884
|
+
(ngModelChange)="updateBinding($index, 'from', $event)"
|
|
13885
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13886
|
+
[attr.list]="sourceSuggestionsListId"
|
|
13887
|
+
placeholder="payload.row.id"
|
|
13888
|
+
/>
|
|
13889
|
+
</mat-form-field>
|
|
13890
|
+
|
|
13891
|
+
<mat-form-field appearance="outline">
|
|
13892
|
+
<mat-label>{{ t('editor.bindings.target', 'Destino') }}</mat-label>
|
|
13893
|
+
<input
|
|
13894
|
+
matInput
|
|
13895
|
+
[ngModel]="binding.to"
|
|
13896
|
+
(ngModelChange)="updateBinding($index, 'to', $event)"
|
|
13897
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13898
|
+
[attr.list]="targetSuggestionsListId"
|
|
13899
|
+
placeholder="widget.inputs.resourceId"
|
|
13900
|
+
/>
|
|
13901
|
+
</mat-form-field>
|
|
13902
|
+
|
|
13903
|
+
<mat-form-field appearance="outline">
|
|
13904
|
+
<mat-label>{{ t('editor.bindings.mode', 'Modo') }}</mat-label>
|
|
13905
|
+
<mat-select
|
|
13906
|
+
[ngModel]="binding.mode || 'path'"
|
|
13907
|
+
(ngModelChange)="updateBinding($index, 'mode', $event)"
|
|
13908
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13909
|
+
>
|
|
13910
|
+
<mat-option value="path">path</mat-option>
|
|
13911
|
+
<mat-option value="template">template</mat-option>
|
|
13912
|
+
<mat-option value="constant">constant</mat-option>
|
|
13913
|
+
</mat-select>
|
|
13914
|
+
</mat-form-field>
|
|
13915
|
+
|
|
13916
|
+
@if ((binding.mode || 'path') === 'constant') {
|
|
13917
|
+
<mat-form-field appearance="outline">
|
|
13918
|
+
<mat-label>{{ t('editor.bindings.constantValue', 'Valor constante') }}</mat-label>
|
|
13919
|
+
<input
|
|
13920
|
+
matInput
|
|
13921
|
+
[ngModel]="binding.value ?? ''"
|
|
13922
|
+
(ngModelChange)="updateBinding($index, 'value', $event)"
|
|
13923
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13924
|
+
/>
|
|
13925
|
+
</mat-form-field>
|
|
13926
|
+
}
|
|
13927
|
+
|
|
13928
|
+
<button
|
|
13929
|
+
mat-icon-button
|
|
13930
|
+
color="warn"
|
|
13931
|
+
type="button"
|
|
13932
|
+
(click)="removeBinding($index)"
|
|
13933
|
+
[attr.aria-label]="t('editor.bindings.remove', 'Remover binding')"
|
|
13934
|
+
>
|
|
13935
|
+
<mat-icon>delete</mat-icon>
|
|
13936
|
+
</button>
|
|
13937
|
+
</div>
|
|
13938
|
+
}
|
|
13939
|
+
</div>
|
|
13940
|
+
} @else {
|
|
13941
|
+
<div class="surface-empty">
|
|
13942
|
+
{{ t('editor.bindings.empty', 'Nenhum binding configurado ainda.') }}
|
|
13943
|
+
</div>
|
|
13944
|
+
}
|
|
13945
|
+
<div class="surface-empty">
|
|
13946
|
+
@if (bindingSourceSuggestionsPreview) {
|
|
13947
|
+
<div>
|
|
13948
|
+
{{ t('editor.bindings.suggestedSources', 'Origens sugeridas: {{value}}', { value: bindingSourceSuggestionsPreview }) }}
|
|
13949
|
+
</div>
|
|
13950
|
+
}
|
|
13951
|
+
@if (bindingTargetSuggestionsPreview) {
|
|
13952
|
+
<div>
|
|
13953
|
+
{{ t('editor.bindings.suggestedTargets', 'Destinos sugeridos: {{value}}', { value: bindingTargetSuggestionsPreview }) }}
|
|
13954
|
+
</div>
|
|
13955
|
+
}
|
|
13956
|
+
</div>
|
|
13957
|
+
<datalist [id]="sourceSuggestionsListId">
|
|
13958
|
+
@for (suggestion of bindingSourceSuggestions; track suggestion) {
|
|
13959
|
+
<option [value]="suggestion"></option>
|
|
13960
|
+
}
|
|
13961
|
+
</datalist>
|
|
13962
|
+
<datalist [id]="targetSuggestionsListId">
|
|
13963
|
+
@for (suggestion of bindingTargetSuggestions; track suggestion) {
|
|
13964
|
+
<option [value]="suggestion"></option>
|
|
13965
|
+
}
|
|
13966
|
+
</datalist>
|
|
13967
|
+
</div>
|
|
13968
|
+
|
|
13969
|
+
<div class="surface-section">
|
|
13970
|
+
<div class="surface-section-title">{{ t('editor.context.title', 'Contexto extra') }}</div>
|
|
13971
|
+
<mat-form-field appearance="outline" class="surface-span-all">
|
|
13972
|
+
<mat-label>{{ t('editor.context.label', 'context (JSON)') }}</mat-label>
|
|
13973
|
+
<textarea
|
|
13974
|
+
matInput
|
|
13975
|
+
rows="4"
|
|
13976
|
+
[ngModel]="contextDraft"
|
|
13977
|
+
(ngModelChange)="updateContext($event)"
|
|
13978
|
+
[ngModelOptions]="{ standalone: true }"
|
|
13979
|
+
placeholder="{ }"
|
|
13980
|
+
></textarea>
|
|
13981
|
+
<mat-hint>{{ t('editor.context.hint', 'Opcional. Mesclado ao contexto da action no runtime.') }}</mat-hint>
|
|
13982
|
+
@if (contextError) {
|
|
13983
|
+
<mat-error>{{ contextError }}</mat-error>
|
|
13984
|
+
}
|
|
13985
|
+
</mat-form-field>
|
|
13986
|
+
</div>
|
|
13987
|
+
</div>
|
|
13988
|
+
`, styles: [".surface-editor{display:grid;gap:16px}.surface-section{padding:12px 14px;border:1px dashed var(--md-sys-color-outline-variant, rgba(0, 0, 0, .18));border-radius:10px;background:var(--md-sys-color-surface-container-lowest, #fff)}.surface-section-header{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px}.surface-section-title{font-size:12px;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--md-sys-color-on-surface-variant, #5f6368);margin-bottom:10px}.surface-section-header .surface-section-title{margin-bottom:0}.surface-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px 16px}.surface-preset-row{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}.surface-span-2{grid-column:span 2}.surface-span-all{width:100%}.surface-component-meta{display:grid;gap:4px}.surface-component-title{font-weight:600}.surface-component-description,.surface-empty{color:var(--md-sys-color-on-surface-variant, #5f6368);font-size:12px}.surface-bindings{display:grid;gap:12px}.surface-binding-row{display:grid;grid-template-columns:minmax(200px,1.2fr) minmax(220px,1.4fr) minmax(140px,.8fr) minmax(180px,1fr) auto;gap:12px;align-items:start}mat-form-field{width:100%}@media(max-width:960px){.surface-binding-row{grid-template-columns:minmax(0,1fr)}}\n"] }]
|
|
13989
|
+
}], propDecorators: { value: [{
|
|
13990
|
+
type: Input
|
|
13991
|
+
}], hostKind: [{
|
|
13992
|
+
type: Input
|
|
13993
|
+
}], valueChange: [{
|
|
13994
|
+
type: Output
|
|
13995
|
+
}] } });
|
|
13996
|
+
|
|
13997
|
+
/**
|
|
13998
|
+
* Catálogo de capacidades genéricas de FieldMetadata para uso da IA.
|
|
13999
|
+
* Baseado em projects/praxis-core/src/lib/models/component-metadata.interface.ts
|
|
14000
|
+
*/
|
|
14001
|
+
const ENUMS$1 = {
|
|
14002
|
+
fieldControlType: Object.values(FieldControlType),
|
|
14003
|
+
fieldDataType: Object.values(FieldDataType),
|
|
14004
|
+
componentContext: ['form', 'filter', 'table', 'dialog', 'standalone'],
|
|
14005
|
+
iconPosition: ['start', 'end'],
|
|
14006
|
+
iconSize: ['small', 'medium', 'large'],
|
|
14007
|
+
validationMode: ['immediate', 'blur', 'submit'],
|
|
14008
|
+
validatorTrigger: ['change', 'blur', 'submit', 'immediate'],
|
|
14009
|
+
validatorErrorPosition: ['bottom', 'top', 'tooltip'],
|
|
14010
|
+
dependencyMergeStrategy: ['replace', 'merge'],
|
|
14011
|
+
dependencyLoadOnChange: ['respectLoadOn', 'immediate', 'manual'],
|
|
14012
|
+
textTransformApply: ['displayOnly', 'saveOnly', 'both'],
|
|
14013
|
+
visibleIn: ['form', 'filter', 'table', 'dialog'],
|
|
14014
|
+
appearance: ['fill', 'outline'],
|
|
14015
|
+
color: ['primary', 'accent', 'warn'],
|
|
14016
|
+
floatLabel: ['auto', 'always', 'never'],
|
|
14017
|
+
hintPosition: ['start', 'end'],
|
|
14018
|
+
align: ['start', 'center', 'end', 'stretch'],
|
|
14019
|
+
sectionTitleStyle: ['titleLarge', 'titleMedium', 'titleSmall', 'headlineSmall'],
|
|
14020
|
+
sectionDescriptionStyle: ['bodyLarge', 'bodyMedium', 'bodySmall'],
|
|
14021
|
+
};
|
|
14022
|
+
const FIELD_METADATA_CAPABILITIES = {
|
|
14023
|
+
version: 'v1.3',
|
|
14024
|
+
enums: ENUMS$1,
|
|
14025
|
+
notes: [
|
|
14026
|
+
'Este catálogo define as capacidades genéricas de FieldMetadata.',
|
|
14027
|
+
'O host típico para estes metadados é FormConfig (via fieldMetadata[]) ou FormLayout.',
|
|
14028
|
+
'Detalhes específicos de cada controle (ex: opções de datepicker, máscaras específicas) devem ser consultados nos catálogos de microcomponentes.',
|
|
14029
|
+
'POLICY: Arrays e objetos (ex: options, validators) devem sofrer merge/append, nunca substituição completa sem confirmação.',
|
|
14030
|
+
'Funções (conditionalRequired, transforms) não são serializáveis. O LLM não deve gerar código de função, apenas expressões string se suportado pelo interpretador, ou solicitar configuração manual.',
|
|
14031
|
+
],
|
|
12089
14032
|
capabilities: [
|
|
12090
14033
|
// =============================================================================
|
|
12091
14034
|
// COMPONENT METADATA (BASE)
|
|
@@ -13547,7 +15490,7 @@ class PraxisFooterLinksComponent {
|
|
|
13547
15490
|
</a>
|
|
13548
15491
|
</nav>
|
|
13549
15492
|
</footer>
|
|
13550
|
-
`, isInline: true, styles: [":host{display:block;--pfl-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 78%, transparent);--pfl-brand-color: var(--md-sys-color-on-surface);--pfl-secondary-color: var(--md-sys-color-on-surface-variant);--pfl-link-color: var(--md-sys-color-primary);--pfl-surface-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, transparent)}:host-context(.mdc-theme-dark),:host-context(.theme-dark){--pfl-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 90%, transparent);--pfl-link-color: color-mix(in srgb, var(--md-sys-color-primary) 86%, white);--pfl-surface-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 96%, transparent)}.pfl-shell{display:flex;align-items:center;justify-content:space-between;gap:16px 24px;padding:16px 4px 4px;border-top:1px solid var(--pfl-border)}.pfl-stacked{flex-direction:column;align-items:flex-start}.pfl-plain{padding-top:6px;border-top:0}.pfl-surface{padding:16px 18px;border-top:0;border-radius:18px;background:var(--pfl-surface-bg)}.pfl-brand{display:grid;gap:4px}.pfl-brand-text{color:var(--pfl-brand-color);font-size:.92rem;font-weight:700}.pfl-secondary-text{color:var(--pfl-secondary-color);font-size:.8rem;line-height:1.5}.pfl-nav{display:flex;flex-wrap:wrap;gap:10px 16px}.pfl-link{color:var(--pfl-link-color);font-size:.84rem;line-height:1.5;text-decoration:underline;text-underline-offset:2px}@media(max-width:720px){.pfl-shell{flex-direction:column;align-items:flex-start}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$
|
|
15493
|
+
`, isInline: true, styles: [":host{display:block;--pfl-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 78%, transparent);--pfl-brand-color: var(--md-sys-color-on-surface);--pfl-secondary-color: var(--md-sys-color-on-surface-variant);--pfl-link-color: var(--md-sys-color-primary);--pfl-surface-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, transparent)}:host-context(.mdc-theme-dark),:host-context(.theme-dark){--pfl-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 90%, transparent);--pfl-link-color: color-mix(in srgb, var(--md-sys-color-primary) 86%, white);--pfl-surface-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 96%, transparent)}.pfl-shell{display:flex;align-items:center;justify-content:space-between;gap:16px 24px;padding:16px 4px 4px;border-top:1px solid var(--pfl-border)}.pfl-stacked{flex-direction:column;align-items:flex-start}.pfl-plain{padding-top:6px;border-top:0}.pfl-surface{padding:16px 18px;border-top:0;border-radius:18px;background:var(--pfl-surface-bg)}.pfl-brand{display:grid;gap:4px}.pfl-brand-text{color:var(--pfl-brand-color);font-size:.92rem;font-weight:700}.pfl-secondary-text{color:var(--pfl-secondary-color);font-size:.8rem;line-height:1.5}.pfl-nav{display:flex;flex-wrap:wrap;gap:10px 16px}.pfl-link{color:var(--pfl-link-color);font-size:.84rem;line-height:1.5;text-decoration:underline;text-underline-offset:2px}@media(max-width:720px){.pfl-shell{flex-direction:column;align-items:flex-start}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
13551
15494
|
}
|
|
13552
15495
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisFooterLinksComponent, decorators: [{
|
|
13553
15496
|
type: Component,
|
|
@@ -13699,7 +15642,7 @@ class PraxisHeroBannerComponent {
|
|
|
13699
15642
|
</div>
|
|
13700
15643
|
</ng-template>
|
|
13701
15644
|
</section>
|
|
13702
|
-
`, isInline: true, styles: [":host{display:block;--phb-shell-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 60%, transparent);--phb-shell-shadow: 0 24px 60px color-mix(in srgb, var(--md-sys-color-shadow, #000) 10%, transparent);--phb-shell-bg: radial-gradient(circle at top right, color-mix(in srgb, var(--md-sys-color-primary) 14%, transparent), transparent 38%), linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-surface-container-lowest) 92%, var(--md-sys-color-primary-container) 8%) 0%, color-mix(in srgb, var(--md-sys-color-surface-container-low) 88%, var(--md-sys-color-primary-container) 12%) 54%, color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-surface-container) 4%) 100% );--phb-event-bg: radial-gradient(circle at top right, rgba(255, 184, 77, .24), transparent 34%), linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-primary-container) 16%, var(--md-sys-color-surface-container-lowest) 84%) 0%, color-mix(in srgb, var(--md-sys-color-primary-container) 24%, var(--md-sys-color-surface-container-low) 76%) 45%, color-mix(in srgb, var(--md-sys-color-surface) 92%, var(--md-sys-color-primary-container) 8%) 100% );--phb-institutional-bg: radial-gradient(circle at top right, rgba(17, 94, 89, .2), transparent 34%), linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-secondary-container) 18%, var(--md-sys-color-surface-container-lowest) 82%) 0%, color-mix(in srgb, var(--md-sys-color-secondary-container) 24%, var(--md-sys-color-surface-container-low) 76%) 48%, color-mix(in srgb, var(--md-sys-color-surface) 94%, var(--md-sys-color-secondary-container) 6%) 100% );--phb-brand-color: color-mix(in srgb, var(--md-sys-color-primary) 68%, var(--md-sys-color-on-surface) 32%);--phb-subtitle-color: color-mix(in srgb, var(--md-sys-color-primary) 52%, var(--md-sys-color-on-surface) 48%);--phb-title-color: var(--md-sys-color-on-surface);--phb-description-color: var(--md-sys-color-on-surface-variant);--phb-badge-bg: color-mix(in srgb, var(--md-sys-color-surface-container-high) 78%, transparent);--phb-badge-color: var(--md-sys-color-on-surface);--phb-badge-highlight-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 78%, transparent);--phb-badge-highlight-color: var(--md-sys-color-on-primary-container);--phb-badge-muted-bg: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 82%, transparent);--phb-badge-muted-color: var(--md-sys-color-on-surface-variant);--phb-badge-warning-bg: color-mix(in srgb, var(--md-sys-color-error-container) 74%, transparent);--phb-badge-warning-color: var(--md-sys-color-on-error-container);--phb-meta-bg: color-mix(in srgb, var(--md-sys-color-surface-container-lowest) 72%, transparent);--phb-meta-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 48%, transparent);--phb-meta-label-color: var(--md-sys-color-on-surface-variant);--phb-meta-value-color: var(--md-sys-color-on-surface);--phb-visual-bg: linear-gradient( 160deg, color-mix(in srgb, var(--md-sys-color-surface-container-high) 90%, var(--md-sys-color-primary) 10%), color-mix(in srgb, var(--md-sys-color-surface-container-low) 88%, var(--md-sys-color-primary-container) 12%) );--phb-visual-fallback: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface-bright, var(--md-sys-color-surface-container-high)) 24%, transparent), color-mix(in srgb, var(--md-sys-color-surface-container-lowest) 8%, transparent) ), linear-gradient( 145deg, color-mix(in srgb, var(--md-sys-color-primary) 18%, var(--md-sys-color-surface-container-high) 82%), color-mix(in srgb, var(--md-sys-color-primary-container) 18%, var(--md-sys-color-surface-container-low) 82%) );--phb-orb-a-bg: color-mix(in srgb, var(--md-sys-color-surface-bright, var(--md-sys-color-surface-container-high)) 68%, transparent);--phb-orb-b-bg: color-mix(in srgb, var(--md-sys-color-primary) 22%, transparent);--phb-grid-line: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent)}:host-context(.mdc-theme-dark),:host-context(.theme-dark){--phb-shell-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 84%, transparent);--phb-shell-shadow: 0 22px 54px rgba(0, 0, 0, .28);--phb-shell-bg: radial-gradient(circle at top right, color-mix(in srgb, var(--md-sys-color-primary) 16%, transparent), transparent 40%), linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-surface-container-lowest) 90%, var(--md-sys-color-primary-container) 10%) 0%, color-mix(in srgb, var(--md-sys-color-surface-container-low) 84%, var(--md-sys-color-primary-container) 16%) 54%, color-mix(in srgb, var(--md-sys-color-surface) 92%, var(--md-sys-color-primary-container) 8%) 100% );--phb-event-bg: radial-gradient(circle at top right, rgba(255, 184, 77, .18), transparent 36%), linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-primary-container) 16%, var(--md-sys-color-surface-container-lowest) 84%) 0%, color-mix(in srgb, var(--md-sys-color-primary-container) 22%, var(--md-sys-color-surface-container-low) 78%) 45%, color-mix(in srgb, var(--md-sys-color-surface-container) 90%, var(--md-sys-color-primary-container) 10%) 100% );--phb-institutional-bg: radial-gradient(circle at top right, rgba(17, 94, 89, .16), transparent 36%), linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-secondary-container) 16%, var(--md-sys-color-surface-container-lowest) 84%) 0%, color-mix(in srgb, var(--md-sys-color-secondary-container) 20%, var(--md-sys-color-surface-container-low) 80%) 48%, color-mix(in srgb, var(--md-sys-color-surface-container) 92%, var(--md-sys-color-secondary-container) 8%) 100% );--phb-meta-bg: color-mix(in srgb, var(--md-sys-color-surface-container-lowest) 70%, transparent);--phb-meta-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 60%, transparent);--phb-visual-bg: linear-gradient( 160deg, color-mix(in srgb, var(--md-sys-color-surface-container-high) 88%, var(--md-sys-color-primary) 12%), color-mix(in srgb, var(--md-sys-color-surface-container) 82%, var(--md-sys-color-primary-container) 18%) );--phb-visual-fallback: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface-container-high) 22%, transparent), color-mix(in srgb, var(--md-sys-color-surface-container-lowest) 8%, transparent) ), linear-gradient( 145deg, color-mix(in srgb, var(--md-sys-color-primary) 22%, var(--md-sys-color-surface-container-high) 78%), color-mix(in srgb, var(--md-sys-color-primary-container) 24%, var(--md-sys-color-surface-container-low) 76%) );--phb-orb-a-bg: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 34%, transparent);--phb-orb-b-bg: color-mix(in srgb, var(--md-sys-color-primary) 26%, transparent);--phb-grid-line: color-mix(in srgb, var(--md-sys-color-on-surface) 10%, transparent)}.phb-shell{display:grid;grid-template-columns:minmax(0,1.45fr) minmax(240px,.95fr);gap:22px;align-items:stretch;padding:22px;border-radius:28px;overflow:hidden;background:var(--phb-shell-bg);border:1px solid var(--phb-shell-border);box-shadow:var(--phb-shell-shadow)}.phb-event{background:var(--phb-event-bg)}.phb-institutional{background:var(--phb-institutional-bg)}.phb-copy{display:grid;gap:18px;min-width:0}.phb-brand{margin:0;color:var(--phb-brand-color);font-size:.88rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase}.phb-badges{display:flex;flex-wrap:wrap;gap:8px}.phb-badge{display:inline-flex;align-items:center;min-height:28px;padding:0 12px;border-radius:999px;background:var(--phb-badge-bg);color:var(--phb-badge-color);font-size:.76rem;font-weight:700;letter-spacing:.02em}.phb-badge-highlight{background:var(--phb-badge-highlight-bg);color:var(--phb-badge-highlight-color)}.phb-badge-muted{background:var(--phb-badge-muted-bg);color:var(--phb-badge-muted-color)}.phb-badge-warning{background:var(--phb-badge-warning-bg);color:var(--phb-badge-warning-color)}.phb-text{display:grid;gap:8px}.phb-subtitle{margin:0;color:var(--phb-subtitle-color);font-size:.9rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em}.phb-title{margin:0;color:var(--phb-title-color);font-size:clamp(1.6rem,2.2vw,2.5rem);line-height:1.08;letter-spacing:-.03em}.phb-title-accent{display:inline;margin-left:.18em;background:linear-gradient(90deg,#4285f4,#6ea8ff 28%,#a142f4 62%,#ea4335);-webkit-background-clip:text;background-clip:text;color:transparent}.phb-description{margin:0;max-width:56ch;color:var(--phb-description-color);font-size:.98rem;line-height:1.65}.phb-meta{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin:0}.phb-meta-item{display:grid;gap:4px;padding:12px 14px;border-radius:16px;background:var(--phb-meta-bg);border:1px solid var(--phb-meta-border);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}.phb-meta-item dt{margin:0;color:var(--phb-meta-label-color);font-size:.73rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em}.phb-meta-item dd{margin:0;color:var(--phb-meta-value-color);font-size:.92rem;line-height:1.45}.phb-visual{position:relative;min-height:220px;border-radius:22px;overflow:hidden;background:var(--phb-visual-bg)}.phb-image{display:block;width:100%;height:100%;object-fit:cover}.phb-visual-fallback{background:var(--phb-visual-fallback)}.phb-flat{padding:0 0 18px;border:0;border-radius:0;box-shadow:none;background:transparent;grid-template-columns:minmax(0,1.15fr) minmax(220px,.85fr);gap:18px}.phb-flat .phb-brand{color:var(--md-sys-color-primary)}.phb-flat .phb-badges{order:3}.phb-flat .phb-meta{grid-template-columns:1fr;gap:6px}.phb-flat .phb-meta-item{padding:0;border:0;border-radius:0;background:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}.phb-flat .phb-meta-item dt,.phb-flat .phb-meta-item dd{display:inline}.phb-flat .phb-meta-item dt{margin-right:6px}.phb-flat .phb-visual{min-height:190px;border-radius:26px}.phb-orb{position:absolute;border-radius:999px;filter:blur(2px)}.phb-orb-a{inset:24px auto auto 20px;width:86px;height:86px;background:var(--phb-orb-a-bg)}.phb-orb-b{inset:auto 16px 18px auto;width:132px;height:132px;background:var(--phb-orb-b-bg)}.phb-grid{position:absolute;inset:0;background-image:linear-gradient(var(--phb-grid-line) 1px,transparent 1px),linear-gradient(90deg,var(--phb-grid-line) 1px,transparent 1px);background-size:24px 24px;opacity:.5}@media(max-width:900px){.phb-shell{grid-template-columns:1fr;padding:18px}.phb-visual{order:-1;min-height:180px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
15645
|
+
`, isInline: true, styles: [":host{display:block;--phb-shell-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 60%, transparent);--phb-shell-shadow: 0 24px 60px color-mix(in srgb, var(--md-sys-color-shadow, #000) 10%, transparent);--phb-shell-bg: radial-gradient(circle at top right, color-mix(in srgb, var(--md-sys-color-primary) 14%, transparent), transparent 38%), linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-surface-container-lowest) 92%, var(--md-sys-color-primary-container) 8%) 0%, color-mix(in srgb, var(--md-sys-color-surface-container-low) 88%, var(--md-sys-color-primary-container) 12%) 54%, color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-surface-container) 4%) 100% );--phb-event-bg: radial-gradient(circle at top right, rgba(255, 184, 77, .24), transparent 34%), linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-primary-container) 16%, var(--md-sys-color-surface-container-lowest) 84%) 0%, color-mix(in srgb, var(--md-sys-color-primary-container) 24%, var(--md-sys-color-surface-container-low) 76%) 45%, color-mix(in srgb, var(--md-sys-color-surface) 92%, var(--md-sys-color-primary-container) 8%) 100% );--phb-institutional-bg: radial-gradient(circle at top right, rgba(17, 94, 89, .2), transparent 34%), linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-secondary-container) 18%, var(--md-sys-color-surface-container-lowest) 82%) 0%, color-mix(in srgb, var(--md-sys-color-secondary-container) 24%, var(--md-sys-color-surface-container-low) 76%) 48%, color-mix(in srgb, var(--md-sys-color-surface) 94%, var(--md-sys-color-secondary-container) 6%) 100% );--phb-brand-color: color-mix(in srgb, var(--md-sys-color-primary) 68%, var(--md-sys-color-on-surface) 32%);--phb-subtitle-color: color-mix(in srgb, var(--md-sys-color-primary) 52%, var(--md-sys-color-on-surface) 48%);--phb-title-color: var(--md-sys-color-on-surface);--phb-description-color: var(--md-sys-color-on-surface-variant);--phb-badge-bg: color-mix(in srgb, var(--md-sys-color-surface-container-high) 78%, transparent);--phb-badge-color: var(--md-sys-color-on-surface);--phb-badge-highlight-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 78%, transparent);--phb-badge-highlight-color: var(--md-sys-color-on-primary-container);--phb-badge-muted-bg: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 82%, transparent);--phb-badge-muted-color: var(--md-sys-color-on-surface-variant);--phb-badge-warning-bg: color-mix(in srgb, var(--md-sys-color-error-container) 74%, transparent);--phb-badge-warning-color: var(--md-sys-color-on-error-container);--phb-meta-bg: color-mix(in srgb, var(--md-sys-color-surface-container-lowest) 72%, transparent);--phb-meta-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 48%, transparent);--phb-meta-label-color: var(--md-sys-color-on-surface-variant);--phb-meta-value-color: var(--md-sys-color-on-surface);--phb-visual-bg: linear-gradient( 160deg, color-mix(in srgb, var(--md-sys-color-surface-container-high) 90%, var(--md-sys-color-primary) 10%), color-mix(in srgb, var(--md-sys-color-surface-container-low) 88%, var(--md-sys-color-primary-container) 12%) );--phb-visual-fallback: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface-bright, var(--md-sys-color-surface-container-high)) 24%, transparent), color-mix(in srgb, var(--md-sys-color-surface-container-lowest) 8%, transparent) ), linear-gradient( 145deg, color-mix(in srgb, var(--md-sys-color-primary) 18%, var(--md-sys-color-surface-container-high) 82%), color-mix(in srgb, var(--md-sys-color-primary-container) 18%, var(--md-sys-color-surface-container-low) 82%) );--phb-orb-a-bg: color-mix(in srgb, var(--md-sys-color-surface-bright, var(--md-sys-color-surface-container-high)) 68%, transparent);--phb-orb-b-bg: color-mix(in srgb, var(--md-sys-color-primary) 22%, transparent);--phb-grid-line: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent)}:host-context(.mdc-theme-dark),:host-context(.theme-dark){--phb-shell-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 84%, transparent);--phb-shell-shadow: 0 22px 54px rgba(0, 0, 0, .28);--phb-shell-bg: radial-gradient(circle at top right, color-mix(in srgb, var(--md-sys-color-primary) 16%, transparent), transparent 40%), linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-surface-container-lowest) 90%, var(--md-sys-color-primary-container) 10%) 0%, color-mix(in srgb, var(--md-sys-color-surface-container-low) 84%, var(--md-sys-color-primary-container) 16%) 54%, color-mix(in srgb, var(--md-sys-color-surface) 92%, var(--md-sys-color-primary-container) 8%) 100% );--phb-event-bg: radial-gradient(circle at top right, rgba(255, 184, 77, .18), transparent 36%), linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-primary-container) 16%, var(--md-sys-color-surface-container-lowest) 84%) 0%, color-mix(in srgb, var(--md-sys-color-primary-container) 22%, var(--md-sys-color-surface-container-low) 78%) 45%, color-mix(in srgb, var(--md-sys-color-surface-container) 90%, var(--md-sys-color-primary-container) 10%) 100% );--phb-institutional-bg: radial-gradient(circle at top right, rgba(17, 94, 89, .16), transparent 36%), linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-secondary-container) 16%, var(--md-sys-color-surface-container-lowest) 84%) 0%, color-mix(in srgb, var(--md-sys-color-secondary-container) 20%, var(--md-sys-color-surface-container-low) 80%) 48%, color-mix(in srgb, var(--md-sys-color-surface-container) 92%, var(--md-sys-color-secondary-container) 8%) 100% );--phb-meta-bg: color-mix(in srgb, var(--md-sys-color-surface-container-lowest) 70%, transparent);--phb-meta-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 60%, transparent);--phb-visual-bg: linear-gradient( 160deg, color-mix(in srgb, var(--md-sys-color-surface-container-high) 88%, var(--md-sys-color-primary) 12%), color-mix(in srgb, var(--md-sys-color-surface-container) 82%, var(--md-sys-color-primary-container) 18%) );--phb-visual-fallback: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface-container-high) 22%, transparent), color-mix(in srgb, var(--md-sys-color-surface-container-lowest) 8%, transparent) ), linear-gradient( 145deg, color-mix(in srgb, var(--md-sys-color-primary) 22%, var(--md-sys-color-surface-container-high) 78%), color-mix(in srgb, var(--md-sys-color-primary-container) 24%, var(--md-sys-color-surface-container-low) 76%) );--phb-orb-a-bg: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 34%, transparent);--phb-orb-b-bg: color-mix(in srgb, var(--md-sys-color-primary) 26%, transparent);--phb-grid-line: color-mix(in srgb, var(--md-sys-color-on-surface) 10%, transparent)}.phb-shell{display:grid;grid-template-columns:minmax(0,1.45fr) minmax(240px,.95fr);gap:22px;align-items:stretch;padding:22px;border-radius:28px;overflow:hidden;background:var(--phb-shell-bg);border:1px solid var(--phb-shell-border);box-shadow:var(--phb-shell-shadow)}.phb-event{background:var(--phb-event-bg)}.phb-institutional{background:var(--phb-institutional-bg)}.phb-copy{display:grid;gap:18px;min-width:0}.phb-brand{margin:0;color:var(--phb-brand-color);font-size:.88rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase}.phb-badges{display:flex;flex-wrap:wrap;gap:8px}.phb-badge{display:inline-flex;align-items:center;min-height:28px;padding:0 12px;border-radius:999px;background:var(--phb-badge-bg);color:var(--phb-badge-color);font-size:.76rem;font-weight:700;letter-spacing:.02em}.phb-badge-highlight{background:var(--phb-badge-highlight-bg);color:var(--phb-badge-highlight-color)}.phb-badge-muted{background:var(--phb-badge-muted-bg);color:var(--phb-badge-muted-color)}.phb-badge-warning{background:var(--phb-badge-warning-bg);color:var(--phb-badge-warning-color)}.phb-text{display:grid;gap:8px}.phb-subtitle{margin:0;color:var(--phb-subtitle-color);font-size:.9rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em}.phb-title{margin:0;color:var(--phb-title-color);font-size:clamp(1.6rem,2.2vw,2.5rem);line-height:1.08;letter-spacing:-.03em}.phb-title-accent{display:inline;margin-left:.18em;background:linear-gradient(90deg,#4285f4,#6ea8ff 28%,#a142f4 62%,#ea4335);-webkit-background-clip:text;background-clip:text;color:transparent}.phb-description{margin:0;max-width:56ch;color:var(--phb-description-color);font-size:.98rem;line-height:1.65}.phb-meta{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin:0}.phb-meta-item{display:grid;gap:4px;padding:12px 14px;border-radius:16px;background:var(--phb-meta-bg);border:1px solid var(--phb-meta-border);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}.phb-meta-item dt{margin:0;color:var(--phb-meta-label-color);font-size:.73rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em}.phb-meta-item dd{margin:0;color:var(--phb-meta-value-color);font-size:.92rem;line-height:1.45}.phb-visual{position:relative;min-height:220px;border-radius:22px;overflow:hidden;background:var(--phb-visual-bg)}.phb-image{display:block;width:100%;height:100%;object-fit:cover}.phb-visual-fallback{background:var(--phb-visual-fallback)}.phb-flat{padding:0 0 18px;border:0;border-radius:0;box-shadow:none;background:transparent;grid-template-columns:minmax(0,1.15fr) minmax(220px,.85fr);gap:18px}.phb-flat .phb-brand{color:var(--md-sys-color-primary)}.phb-flat .phb-badges{order:3}.phb-flat .phb-meta{grid-template-columns:1fr;gap:6px}.phb-flat .phb-meta-item{padding:0;border:0;border-radius:0;background:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}.phb-flat .phb-meta-item dt,.phb-flat .phb-meta-item dd{display:inline}.phb-flat .phb-meta-item dt{margin-right:6px}.phb-flat .phb-visual{min-height:190px;border-radius:26px}.phb-orb{position:absolute;border-radius:999px;filter:blur(2px)}.phb-orb-a{inset:24px auto auto 20px;width:86px;height:86px;background:var(--phb-orb-a-bg)}.phb-orb-b{inset:auto 16px 18px auto;width:132px;height:132px;background:var(--phb-orb-b-bg)}.phb-grid{position:absolute;inset:0;background-image:linear-gradient(var(--phb-grid-line) 1px,transparent 1px),linear-gradient(90deg,var(--phb-grid-line) 1px,transparent 1px);background-size:24px 24px;opacity:.5}@media(max-width:900px){.phb-shell{grid-template-columns:1fr;padding:18px}.phb-visual{order:-1;min-height:180px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
13703
15646
|
}
|
|
13704
15647
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisHeroBannerComponent, decorators: [{
|
|
13705
15648
|
type: Component,
|
|
@@ -13954,7 +15897,7 @@ class PraxisRichTextBlockComponent {
|
|
|
13954
15897
|
|
|
13955
15898
|
<div class="prt-content" [innerHTML]="renderedContent"></div>
|
|
13956
15899
|
</section>
|
|
13957
|
-
`, isInline: true, styles: [":host{display:block;--prt-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 72%, transparent);--prt-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-surface-container-lowest) 4%), color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8%) );--prt-emphasis-border: color-mix(in srgb, var(--md-sys-color-primary) 32%, var(--md-sys-color-outline-variant));--prt-emphasis-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary-container) 36%, var(--md-sys-color-surface) 64%), color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-primary-container) 4%) );--prt-subtle-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 82%, transparent);--prt-icon-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 64%, transparent);--prt-code-bg: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 82%, transparent)}:host-context(.mdc-theme-dark),:host-context(.theme-dark){--prt-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 84%, transparent);--prt-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8%), color-mix(in srgb, var(--md-sys-color-surface-container) 90%, var(--md-sys-color-surface-container-high) 10%) );--prt-emphasis-border: color-mix(in srgb, var(--md-sys-color-primary) 42%, var(--md-sys-color-outline-variant));--prt-emphasis-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary-container) 28%, var(--md-sys-color-surface-container-low) 72%), color-mix(in srgb, var(--md-sys-color-surface-container) 92%, var(--md-sys-color-primary-container) 8%) );--prt-subtle-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 88%, transparent);--prt-icon-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 42%, transparent);--prt-code-bg: color-mix(in srgb, var(--md-sys-color-surface-container-high) 88%, transparent)}.prt-block{display:grid;gap:12px;padding:16px 18px;border-radius:16px;border:1px solid var(--prt-border);background:var(--prt-bg);color:var(--md-sys-color-on-surface)}.prt-block-emphasis{border-color:var(--prt-emphasis-border);background:var(--prt-emphasis-bg)}.prt-block-subtle{background:var(--prt-subtle-bg);border-style:dashed}.prt-block-plain{padding:0;border:0;border-radius:0;background:transparent}.prt-head{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:start}.prt-icon{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:12px;background:var(--prt-icon-bg);color:var(--md-sys-color-primary);font-size:20px;line-height:1}.prt-title-wrap{display:grid;gap:4px}.prt-title{margin:0;font-size:1rem;font-weight:700;line-height:1.3}.prt-subtitle{margin:0;color:var(--md-sys-color-on-surface-variant);font-size:.86rem;line-height:1.4}.prt-content{color:var(--md-sys-color-on-surface);font-size:.94rem;line-height:1.6}.prt-content :where(p,ul){margin:0}.prt-content :where(p+p,p+ul,ul+p,ul+ul){margin-top:10px}.prt-content ul{padding-left:18px}.prt-content a{color:var(--md-sys-color-primary);text-decoration:underline;text-underline-offset:2px}.prt-content strong{font-weight:700}.prt-content em{font-style:italic}.prt-content code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.88em;padding:.1em .35em;border-radius:6px;background:var(--prt-code-bg)}.prt-block-plain .prt-icon{width:32px;height:32px;border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 80%,transparent)}.prt-block-plain .prt-content{font-size:.92rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$
|
|
15900
|
+
`, isInline: true, styles: [":host{display:block;--prt-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 72%, transparent);--prt-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-surface-container-lowest) 4%), color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8%) );--prt-emphasis-border: color-mix(in srgb, var(--md-sys-color-primary) 32%, var(--md-sys-color-outline-variant));--prt-emphasis-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary-container) 36%, var(--md-sys-color-surface) 64%), color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-primary-container) 4%) );--prt-subtle-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 82%, transparent);--prt-icon-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 64%, transparent);--prt-code-bg: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 82%, transparent)}:host-context(.mdc-theme-dark),:host-context(.theme-dark){--prt-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 84%, transparent);--prt-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8%), color-mix(in srgb, var(--md-sys-color-surface-container) 90%, var(--md-sys-color-surface-container-high) 10%) );--prt-emphasis-border: color-mix(in srgb, var(--md-sys-color-primary) 42%, var(--md-sys-color-outline-variant));--prt-emphasis-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary-container) 28%, var(--md-sys-color-surface-container-low) 72%), color-mix(in srgb, var(--md-sys-color-surface-container) 92%, var(--md-sys-color-primary-container) 8%) );--prt-subtle-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 88%, transparent);--prt-icon-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 42%, transparent);--prt-code-bg: color-mix(in srgb, var(--md-sys-color-surface-container-high) 88%, transparent)}.prt-block{display:grid;gap:12px;padding:16px 18px;border-radius:16px;border:1px solid var(--prt-border);background:var(--prt-bg);color:var(--md-sys-color-on-surface)}.prt-block-emphasis{border-color:var(--prt-emphasis-border);background:var(--prt-emphasis-bg)}.prt-block-subtle{background:var(--prt-subtle-bg);border-style:dashed}.prt-block-plain{padding:0;border:0;border-radius:0;background:transparent}.prt-head{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:start}.prt-icon{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:12px;background:var(--prt-icon-bg);color:var(--md-sys-color-primary);font-size:20px;line-height:1}.prt-title-wrap{display:grid;gap:4px}.prt-title{margin:0;font-size:1rem;font-weight:700;line-height:1.3}.prt-subtitle{margin:0;color:var(--md-sys-color-on-surface-variant);font-size:.86rem;line-height:1.4}.prt-content{color:var(--md-sys-color-on-surface);font-size:.94rem;line-height:1.6}.prt-content :where(p,ul){margin:0}.prt-content :where(p+p,p+ul,ul+p,ul+ul){margin-top:10px}.prt-content ul{padding-left:18px}.prt-content a{color:var(--md-sys-color-primary);text-decoration:underline;text-underline-offset:2px}.prt-content strong{font-weight:700}.prt-content em{font-style:italic}.prt-content code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.88em;padding:.1em .35em;border-radius:6px;background:var(--prt-code-bg)}.prt-block-plain .prt-icon{width:32px;height:32px;border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 80%,transparent)}.prt-block-plain .prt-content{font-size:.92rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.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 });
|
|
13958
15901
|
}
|
|
13959
15902
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisRichTextBlockComponent, decorators: [{
|
|
13960
15903
|
type: Component,
|
|
@@ -14160,7 +16103,7 @@ class PraxisLegalNoticeComponent {
|
|
|
14160
16103
|
</a>
|
|
14161
16104
|
</nav>
|
|
14162
16105
|
</section>
|
|
14163
|
-
`, isInline: true, styles: [":host{display:block}.pln-shell{display:grid;gap:10px}.pln-shell .praxis-rich-text-block .prt-block,.pln-shell .prt-block{border-left:4px solid color-mix(in srgb,var(--md-sys-color-primary) 56%,transparent)}.pln-warning .praxis-rich-text-block .prt-block,.pln-warning .prt-block{border-left-color:var(--md-sys-color-error)}.pln-muted .praxis-rich-text-block .prt-block,.pln-muted .prt-block{border-left-color:color-mix(in srgb,var(--md-sys-color-outline) 58%,transparent)}.pln-plain .praxis-rich-text-block .prt-block,.pln-plain .prt-block{border-left:0}.pln-links{display:flex;flex-wrap:wrap;gap:8px 12px;padding-left:18px}.pln-plain .pln-links{padding-left:0;padding-top:2px}.pln-link{color:var(--md-sys-color-primary);font-size:.84rem;line-height:1.4;text-decoration:underline;text-underline-offset:2px}:host-context(.mdc-theme-dark) .pln-link,:host-context(.theme-dark) .pln-link{color:color-mix(in srgb,var(--md-sys-color-primary) 86%,white)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$
|
|
16106
|
+
`, isInline: true, styles: [":host{display:block}.pln-shell{display:grid;gap:10px}.pln-shell .praxis-rich-text-block .prt-block,.pln-shell .prt-block{border-left:4px solid color-mix(in srgb,var(--md-sys-color-primary) 56%,transparent)}.pln-warning .praxis-rich-text-block .prt-block,.pln-warning .prt-block{border-left-color:var(--md-sys-color-error)}.pln-muted .praxis-rich-text-block .prt-block,.pln-muted .prt-block{border-left-color:color-mix(in srgb,var(--md-sys-color-outline) 58%,transparent)}.pln-plain .praxis-rich-text-block .prt-block,.pln-plain .prt-block{border-left:0}.pln-links{display:flex;flex-wrap:wrap;gap:8px 12px;padding-left:18px}.pln-plain .pln-links{padding-left:0;padding-top:2px}.pln-link{color:var(--md-sys-color-primary);font-size:.84rem;line-height:1.4;text-decoration:underline;text-underline-offset:2px}:host-context(.mdc-theme-dark) .pln-link,:host-context(.theme-dark) .pln-link{color:color-mix(in srgb,var(--md-sys-color-primary) 86%,white)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PraxisRichTextBlockComponent, selector: "praxis-rich-text-block", inputs: ["instanceId", "analyticsId", "ariaLabel", "title", "subtitle", "icon", "variant", "appearance", "contentFormat", "content"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
14164
16107
|
}
|
|
14165
16108
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisLegalNoticeComponent, decorators: [{
|
|
14166
16109
|
type: Component,
|
|
@@ -14350,7 +16293,7 @@ class PraxisUserContextSummaryComponent {
|
|
|
14350
16293
|
<button type="button" class="pux-action" (click)="emitAction()">{{ actionLabel }}</button>
|
|
14351
16294
|
</div>
|
|
14352
16295
|
</section>
|
|
14353
|
-
`, isInline: true, styles: [":host{display:block}.pux-card{display:grid;gap:14px;padding:16px 18px;border-radius:18px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 78%,transparent);background:linear-gradient(180deg,#fffffffa,#f4f8fcfa)}.pux-head{display:grid;gap:4px}.pux-title{margin:0;color:var(--md-sys-color-on-surface);font-size:.98rem;font-weight:700}.pux-subtitle{margin:0;color:var(--md-sys-color-on-surface-variant);font-size:.84rem;line-height:1.5}.pux-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px;margin:0}.pux-item{display:grid;gap:4px;padding:12px 14px;border-radius:14px;background:#ffffffb8;border:1px solid rgba(66,93,135,.1)}.pux-item dt{margin:0;color:#5d7186;font-size:.73rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em}.pux-item dd{margin:0;color:#17314f;font-size:.92rem;line-height:1.45}.pux-actions{display:flex;justify-content:flex-start}.pux-action{min-height:36px;padding:0 14px;border:1px solid rgba(33,88,201,.18);border-radius:999px;background:#2060d214;color:#1e55b8;font:inherit;font-size:.84rem;font-weight:700;cursor:pointer}.pux-empty{margin:0;color:var(--md-sys-color-on-surface-variant);font-size:.84rem}.pux-plain{gap:10px;padding:8px 0 4px;border:0;border-radius:0;background:transparent}.pux-plain .pux-grid{grid-template-columns:1fr;gap:6px}.pux-plain .pux-item{padding:12px 14px;border-radius:14px;background:#ffffff8f;border:1px solid rgba(66,93,135,.08)}.pux-plain .pux-actions{margin-top:2px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$
|
|
16296
|
+
`, isInline: true, styles: [":host{display:block}.pux-card{display:grid;gap:14px;padding:16px 18px;border-radius:18px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 78%,transparent);background:linear-gradient(180deg,#fffffffa,#f4f8fcfa)}.pux-head{display:grid;gap:4px}.pux-title{margin:0;color:var(--md-sys-color-on-surface);font-size:.98rem;font-weight:700}.pux-subtitle{margin:0;color:var(--md-sys-color-on-surface-variant);font-size:.84rem;line-height:1.5}.pux-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px;margin:0}.pux-item{display:grid;gap:4px;padding:12px 14px;border-radius:14px;background:#ffffffb8;border:1px solid rgba(66,93,135,.1)}.pux-item dt{margin:0;color:#5d7186;font-size:.73rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em}.pux-item dd{margin:0;color:#17314f;font-size:.92rem;line-height:1.45}.pux-actions{display:flex;justify-content:flex-start}.pux-action{min-height:36px;padding:0 14px;border:1px solid rgba(33,88,201,.18);border-radius:999px;background:#2060d214;color:#1e55b8;font:inherit;font-size:.84rem;font-weight:700;cursor:pointer}.pux-empty{margin:0;color:var(--md-sys-color-on-surface-variant);font-size:.84rem}.pux-plain{gap:10px;padding:8px 0 4px;border:0;border-radius:0;background:transparent}.pux-plain .pux-grid{grid-template-columns:1fr;gap:6px}.pux-plain .pux-item{padding:12px 14px;border-radius:14px;background:#ffffff8f;border:1px solid rgba(66,93,135,.08)}.pux-plain .pux-actions{margin-top:2px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
14354
16297
|
}
|
|
14355
16298
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisUserContextSummaryComponent, decorators: [{
|
|
14356
16299
|
type: Component,
|
|
@@ -15102,7 +17045,7 @@ class WidgetShellComponent {
|
|
|
15102
17045
|
@if (expanded || fullscreen) {
|
|
15103
17046
|
<div class="pdx-shell-backdrop" (click)="closeOverlay()"></div>
|
|
15104
17047
|
}
|
|
15105
|
-
`, isInline: true, styles: [":host{display:block;height:100%}.pdx-shell{position:relative;height:100%;display:flex;flex-direction:column}.pdx-shell.no-shell{background:transparent;border:none;border-radius:0;box-shadow:none}.pdx-shell.dashboard{background:var(--pdx-shell-card-bg, var(--pdx-dashboard-card-bg, var(--md-sys-color-surface-container-low)));border:1px solid var(--pdx-shell-card-border, var(--pdx-dashboard-card-border, var(--md-sys-color-outline-variant)));border-radius:var(--pdx-shell-card-radius, 14px);box-shadow:var(--pdx-shell-card-shadow, var(--mat-elevation-level2));overflow:hidden}.pdx-shell-header{display:flex;align-items:center;gap:12px;padding:10px 12px 8px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.pdx-shell-title{display:flex;align-items:center;gap:10px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.pdx-shell-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.pdx-shell-text{min-width:0}.pdx-shell-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 14px);line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-subtitle{font-size:var(--pdx-shell-subtitle-size, 12px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-actions,.pdx-shell-window-actions{display:flex;align-items:center;gap:6px}.pdx-shell-window-actions{margin-left:auto}.pdx-action-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-action-text{padding:0 8px}.pdx-action-label{font-size:12px;font-weight:500}.pdx-shell-body{flex:1;min-height:0;padding:var(--pdx-shell-body-padding, 10px 12px 12px 12px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit)}.pdx-shell.no-shell .pdx-shell-body{padding:0}.pdx-shell-body.hidden{display:none}.pdx-shell.collapsed .pdx-shell-header{border-bottom-color:transparent}.pdx-shell.expanded .pdx-shell-body,.pdx-shell.fullscreen .pdx-shell-body{overflow:auto;display:flex;flex-direction:column;min-height:0}.pdx-shell.expanded .pdx-shell-body>*,.pdx-shell.fullscreen .pdx-shell-body>*{flex:1 1 auto;min-height:0;width:100%}.pdx-shell.expanded{position:fixed;top:10vh;left:50%;width:min(920px,92vw);height:min(640px,82vh);transform:translate(-50%);z-index:1200;box-shadow:var(--mat-elevation-level8)}.pdx-shell.fullscreen{position:fixed;top:50%;left:50%;width:95vw;height:95vh;transform:translate(-50%,-50%);z-index:1201;box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:1199;background:#0000008c;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$
|
|
17048
|
+
`, isInline: true, styles: [":host{display:block;height:100%}.pdx-shell{position:relative;height:100%;display:flex;flex-direction:column}.pdx-shell.no-shell{background:transparent;border:none;border-radius:0;box-shadow:none}.pdx-shell.dashboard{background:var(--pdx-shell-card-bg, var(--pdx-dashboard-card-bg, var(--md-sys-color-surface-container-low)));border:1px solid var(--pdx-shell-card-border, var(--pdx-dashboard-card-border, var(--md-sys-color-outline-variant)));border-radius:var(--pdx-shell-card-radius, 14px);box-shadow:var(--pdx-shell-card-shadow, var(--mat-elevation-level2));overflow:hidden}.pdx-shell-header{display:flex;align-items:center;gap:12px;padding:10px 12px 8px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.pdx-shell-title{display:flex;align-items:center;gap:10px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.pdx-shell-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.pdx-shell-text{min-width:0}.pdx-shell-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 14px);line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-subtitle{font-size:var(--pdx-shell-subtitle-size, 12px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-actions,.pdx-shell-window-actions{display:flex;align-items:center;gap:6px}.pdx-shell-window-actions{margin-left:auto}.pdx-action-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-action-text{padding:0 8px}.pdx-action-label{font-size:12px;font-weight:500}.pdx-shell-body{flex:1;min-height:0;padding:var(--pdx-shell-body-padding, 10px 12px 12px 12px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit)}.pdx-shell.no-shell .pdx-shell-body{padding:0}.pdx-shell-body.hidden{display:none}.pdx-shell.collapsed .pdx-shell-header{border-bottom-color:transparent}.pdx-shell.expanded .pdx-shell-body,.pdx-shell.fullscreen .pdx-shell-body{overflow:auto;display:flex;flex-direction:column;min-height:0}.pdx-shell.expanded .pdx-shell-body>*,.pdx-shell.fullscreen .pdx-shell-body>*{flex:1 1 auto;min-height:0;width:100%}.pdx-shell.expanded{position:fixed;top:10vh;left:50%;width:min(920px,92vw);height:min(640px,82vh);transform:translate(-50%);z-index:1200;box-shadow:var(--mat-elevation-level8)}.pdx-shell.fullscreen{position:fixed;top:50%;left:50%;width:95vw;height:95vh;transform:translate(-50%,-50%);z-index:1201;box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:1199;background:#0000008c;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$1.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: i4$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$1.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: MatTooltipModule }, { kind: "directive", type: i5$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 });
|
|
15106
17049
|
}
|
|
15107
17050
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: WidgetShellComponent, decorators: [{
|
|
15108
17051
|
type: Component,
|
|
@@ -15243,6 +17186,180 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
15243
17186
|
args: [DynamicWidgetLoaderDirective]
|
|
15244
17187
|
}] } });
|
|
15245
17188
|
|
|
17189
|
+
const BUILTIN_PAGE_LAYOUT_PRESETS = {
|
|
17190
|
+
'analytics-overview': {
|
|
17191
|
+
id: 'analytics-overview',
|
|
17192
|
+
label: 'Analytics Overview',
|
|
17193
|
+
description: 'Hero, KPIs, charts principais e tabela detalhada em uma página analítica ampla.',
|
|
17194
|
+
category: 'analytics',
|
|
17195
|
+
defaultLayout: {
|
|
17196
|
+
orientation: 'columns',
|
|
17197
|
+
columns: 2,
|
|
17198
|
+
gap: '20px',
|
|
17199
|
+
breakpoints: { sm: 1, md: 2, lg: 2, xl: 2 },
|
|
17200
|
+
},
|
|
17201
|
+
defaultGrouping: [
|
|
17202
|
+
{ kind: 'hero', id: 'hero', widgetKeys: ['hero'], emphasis: 'high' },
|
|
17203
|
+
{ kind: 'section', id: 'kpis', label: 'KPIs', widgetKeys: ['kpis'], layout: 'row' },
|
|
17204
|
+
{ kind: 'section', id: 'charts', label: 'Charts', widgetKeys: ['primary-chart', 'secondary-chart-a', 'secondary-chart-b'], layout: 'grid' },
|
|
17205
|
+
{ kind: 'section', id: 'detail-table', label: 'Detail Table', widgetKeys: ['detail-table'], layout: 'stack' },
|
|
17206
|
+
],
|
|
17207
|
+
defaultThemePreset: 'analytics-calm',
|
|
17208
|
+
slotModel: [
|
|
17209
|
+
{ id: 'hero', label: 'Hero', required: false, maxItems: 1 },
|
|
17210
|
+
{ id: 'kpis', label: 'KPIs', required: true, minItems: 1 },
|
|
17211
|
+
{ id: 'primary-chart', label: 'Primary Chart', required: true, minItems: 1, maxItems: 1 },
|
|
17212
|
+
{ id: 'secondary-chart-a', label: 'Secondary Chart A', required: false, maxItems: 1 },
|
|
17213
|
+
{ id: 'secondary-chart-b', label: 'Secondary Chart B', required: false, maxItems: 1 },
|
|
17214
|
+
{ id: 'detail-table', label: 'Detail Table', required: true, minItems: 1, maxItems: 1 },
|
|
17215
|
+
],
|
|
17216
|
+
widgetSuggestions: [
|
|
17217
|
+
{ slot: 'kpis', widgetType: 'form:user-context-summary', priority: 'primary' },
|
|
17218
|
+
{ slot: 'primary-chart', widgetType: 'praxis-chart', priority: 'primary' },
|
|
17219
|
+
{ slot: 'detail-table', widgetType: 'praxis-table', priority: 'primary' },
|
|
17220
|
+
],
|
|
17221
|
+
devicePolicy: {
|
|
17222
|
+
stacking: 'compress',
|
|
17223
|
+
preferTabsOnMobile: false,
|
|
17224
|
+
},
|
|
17225
|
+
},
|
|
17226
|
+
'kpi-plus-table': {
|
|
17227
|
+
id: 'kpi-plus-table',
|
|
17228
|
+
label: 'KPI Plus Table',
|
|
17229
|
+
description: 'Faixa superior de métricas com uma tabela dominante e visuais auxiliares.',
|
|
17230
|
+
category: 'analytics',
|
|
17231
|
+
defaultLayout: {
|
|
17232
|
+
orientation: 'columns',
|
|
17233
|
+
columns: 2,
|
|
17234
|
+
gap: '18px',
|
|
17235
|
+
breakpoints: { sm: 1, md: 1, lg: 2, xl: 2 },
|
|
17236
|
+
},
|
|
17237
|
+
defaultGrouping: [
|
|
17238
|
+
{ kind: 'section', id: 'filters', label: 'Filters', widgetKeys: ['filters'], layout: 'stack' },
|
|
17239
|
+
{ kind: 'section', id: 'kpis', label: 'KPIs', widgetKeys: ['kpis'], layout: 'row' },
|
|
17240
|
+
{ kind: 'section', id: 'table', label: 'Table', widgetKeys: ['detail-table'], layout: 'stack' },
|
|
17241
|
+
{ kind: 'section', id: 'aux', label: 'Auxiliary Charts', widgetKeys: ['aux-chart-a', 'aux-chart-b'], layout: 'grid' },
|
|
17242
|
+
],
|
|
17243
|
+
defaultThemePreset: 'analytics-calm',
|
|
17244
|
+
slotModel: [
|
|
17245
|
+
{ id: 'filters', label: 'Filters', required: false, maxItems: 1 },
|
|
17246
|
+
{ id: 'kpis', label: 'KPIs', required: true, minItems: 1 },
|
|
17247
|
+
{ id: 'detail-table', label: 'Detail Table', required: true, minItems: 1, maxItems: 1 },
|
|
17248
|
+
{ id: 'aux-chart-a', label: 'Auxiliary Chart A', required: false, maxItems: 1 },
|
|
17249
|
+
{ id: 'aux-chart-b', label: 'Auxiliary Chart B', required: false, maxItems: 1 },
|
|
17250
|
+
],
|
|
17251
|
+
widgetSuggestions: [
|
|
17252
|
+
{ slot: 'filters', widgetType: 'praxis-filter', priority: 'primary' },
|
|
17253
|
+
{ slot: 'detail-table', widgetType: 'praxis-table', priority: 'primary' },
|
|
17254
|
+
],
|
|
17255
|
+
devicePolicy: {
|
|
17256
|
+
stacking: 'linearize',
|
|
17257
|
+
hideSecondaryContentOnMobile: true,
|
|
17258
|
+
},
|
|
17259
|
+
},
|
|
17260
|
+
'master-detail-dashboard': {
|
|
17261
|
+
id: 'master-detail-dashboard',
|
|
17262
|
+
label: 'Master Detail Dashboard',
|
|
17263
|
+
description: 'Master dominante com áreas de detalhe, KPIs e tabs sincronizadas.',
|
|
17264
|
+
category: 'master-detail',
|
|
17265
|
+
defaultLayout: {
|
|
17266
|
+
orientation: 'columns',
|
|
17267
|
+
columns: 3,
|
|
17268
|
+
gap: '18px',
|
|
17269
|
+
breakpoints: { sm: 1, md: 1, lg: 2, xl: 3 },
|
|
17270
|
+
},
|
|
17271
|
+
defaultGrouping: [
|
|
17272
|
+
{ kind: 'section', id: 'master', label: 'Master', widgetKeys: ['master'], layout: 'stack' },
|
|
17273
|
+
{ kind: 'section', id: 'detail-kpis', label: 'Detail KPIs', widgetKeys: ['detail-kpis'], layout: 'row' },
|
|
17274
|
+
{
|
|
17275
|
+
kind: 'tabs',
|
|
17276
|
+
id: 'detail-tabs',
|
|
17277
|
+
label: 'Detail Tabs',
|
|
17278
|
+
tabs: [
|
|
17279
|
+
{ id: 'detail-insights', label: 'Insights', widgetKeys: ['detail-chart-a', 'detail-chart-b'] },
|
|
17280
|
+
{ id: 'detail-table', label: 'Details', widgetKeys: ['detail-table'] },
|
|
17281
|
+
],
|
|
17282
|
+
},
|
|
17283
|
+
],
|
|
17284
|
+
defaultThemePreset: 'workspace-balanced',
|
|
17285
|
+
slotModel: [
|
|
17286
|
+
{ id: 'master', label: 'Master', required: true, minItems: 1, maxItems: 1 },
|
|
17287
|
+
{ id: 'detail-kpis', label: 'Detail KPIs', required: false, minItems: 1 },
|
|
17288
|
+
{ id: 'detail-chart-a', label: 'Detail Chart A', required: false, maxItems: 1 },
|
|
17289
|
+
{ id: 'detail-chart-b', label: 'Detail Chart B', required: false, maxItems: 1 },
|
|
17290
|
+
{ id: 'detail-table', label: 'Detail Table', required: true, minItems: 1, maxItems: 1 },
|
|
17291
|
+
],
|
|
17292
|
+
widgetSuggestions: [
|
|
17293
|
+
{ slot: 'master', widgetType: 'praxis-table', priority: 'primary' },
|
|
17294
|
+
{ slot: 'detail-table', widgetType: 'praxis-table', priority: 'primary' },
|
|
17295
|
+
{ slot: 'detail-chart-a', widgetType: 'praxis-chart', priority: 'secondary' },
|
|
17296
|
+
],
|
|
17297
|
+
devicePolicy: {
|
|
17298
|
+
stacking: 'compress',
|
|
17299
|
+
preferTabsOnMobile: true,
|
|
17300
|
+
},
|
|
17301
|
+
},
|
|
17302
|
+
'ops-monitoring': {
|
|
17303
|
+
id: 'ops-monitoring',
|
|
17304
|
+
label: 'Ops Monitoring',
|
|
17305
|
+
description: 'Cards de status, séries temporais, fila operacional e área de alertas.',
|
|
17306
|
+
category: 'operations',
|
|
17307
|
+
defaultLayout: {
|
|
17308
|
+
orientation: 'columns',
|
|
17309
|
+
columns: 3,
|
|
17310
|
+
gap: '18px',
|
|
17311
|
+
breakpoints: { sm: 1, md: 2, lg: 3, xl: 3 },
|
|
17312
|
+
},
|
|
17313
|
+
defaultGrouping: [
|
|
17314
|
+
{ kind: 'hero', id: 'status-cards', widgetKeys: ['status-cards'], emphasis: 'medium' },
|
|
17315
|
+
{ kind: 'section', id: 'timelines', label: 'Timelines', widgetKeys: ['timeline-a', 'timeline-b'], layout: 'grid' },
|
|
17316
|
+
{ kind: 'section', id: 'queue', label: 'Operational Queue', widgetKeys: ['queue'], layout: 'stack' },
|
|
17317
|
+
{ kind: 'rail', id: 'alerts', side: 'right', widgetKeys: ['alerts'] },
|
|
17318
|
+
],
|
|
17319
|
+
defaultThemePreset: 'ops-monitoring',
|
|
17320
|
+
slotModel: [
|
|
17321
|
+
{ id: 'status-cards', label: 'Status Cards', required: true, minItems: 1 },
|
|
17322
|
+
{ id: 'timeline-a', label: 'Timeline A', required: true, minItems: 1, maxItems: 1 },
|
|
17323
|
+
{ id: 'timeline-b', label: 'Timeline B', required: false, maxItems: 1 },
|
|
17324
|
+
{ id: 'queue', label: 'Operational Queue', required: true, minItems: 1, maxItems: 1 },
|
|
17325
|
+
{ id: 'alerts', label: 'Alerts Rail', required: false, maxItems: 1 },
|
|
17326
|
+
],
|
|
17327
|
+
widgetSuggestions: [
|
|
17328
|
+
{ slot: 'status-cards', widgetType: 'form:user-context-summary', priority: 'primary' },
|
|
17329
|
+
{ slot: 'timeline-a', widgetType: 'praxis-chart', priority: 'primary' },
|
|
17330
|
+
{ slot: 'queue', widgetType: 'praxis-table', priority: 'primary' },
|
|
17331
|
+
],
|
|
17332
|
+
devicePolicy: {
|
|
17333
|
+
stacking: 'compress',
|
|
17334
|
+
hideSecondaryContentOnMobile: true,
|
|
17335
|
+
preferTabsOnMobile: true,
|
|
17336
|
+
},
|
|
17337
|
+
},
|
|
17338
|
+
};
|
|
17339
|
+
const BUILTIN_PAGE_THEME_PRESETS = {
|
|
17340
|
+
'analytics-calm': {
|
|
17341
|
+
id: 'analytics-calm',
|
|
17342
|
+
label: 'Analytics Calm',
|
|
17343
|
+
description: 'Superfícies leves, ênfase clara em dados e motion sutil.',
|
|
17344
|
+
density: 'comfortable',
|
|
17345
|
+
motion: 'subtle',
|
|
17346
|
+
},
|
|
17347
|
+
'workspace-balanced': {
|
|
17348
|
+
id: 'workspace-balanced',
|
|
17349
|
+
label: 'Workspace Balanced',
|
|
17350
|
+
description: 'Equilíbrio entre densidade operacional e clareza visual.',
|
|
17351
|
+
density: 'comfortable',
|
|
17352
|
+
motion: 'subtle',
|
|
17353
|
+
},
|
|
17354
|
+
'ops-monitoring': {
|
|
17355
|
+
id: 'ops-monitoring',
|
|
17356
|
+
label: 'Ops Monitoring',
|
|
17357
|
+
description: 'Contraste um pouco maior para leitura rápida de status, filas e alertas.',
|
|
17358
|
+
density: 'compact',
|
|
17359
|
+
motion: 'subtle',
|
|
17360
|
+
},
|
|
17361
|
+
};
|
|
17362
|
+
|
|
15246
17363
|
class ConnectionManagerService {
|
|
15247
17364
|
/** Extract value from an object using dot-path (e.g., 'payload.row.id'). */
|
|
15248
17365
|
extractByPath(obj, path) {
|
|
@@ -15577,6 +17694,69 @@ class WidgetPageStateRuntimeService {
|
|
|
15577
17694
|
}
|
|
15578
17695
|
return omitted;
|
|
15579
17696
|
}
|
|
17697
|
+
case 'aggregate-array': {
|
|
17698
|
+
const source = this.resolveNamedSource(options['source'], sources, env.state);
|
|
17699
|
+
const metrics = Array.isArray(options['metrics']) ? options['metrics'] : [];
|
|
17700
|
+
if (!Array.isArray(source))
|
|
17701
|
+
return {};
|
|
17702
|
+
return this.aggregateArray(source, metrics);
|
|
17703
|
+
}
|
|
17704
|
+
case 'build-field-list': {
|
|
17705
|
+
const source = this.resolveNamedSource(options['source'], sources, env.state);
|
|
17706
|
+
const items = Array.isArray(options['items']) ? options['items'] : [];
|
|
17707
|
+
return this.buildFieldList(source, items, env);
|
|
17708
|
+
}
|
|
17709
|
+
case 'group-top': {
|
|
17710
|
+
const source = this.resolveNamedSource(options['source'], sources, env.state);
|
|
17711
|
+
if (!Array.isArray(source))
|
|
17712
|
+
return [];
|
|
17713
|
+
return this.groupTop(source, options);
|
|
17714
|
+
}
|
|
17715
|
+
case 'when-present': {
|
|
17716
|
+
const source = this.resolveNamedSource(options['source'], sources, env.state);
|
|
17717
|
+
if (source == null)
|
|
17718
|
+
return options['fallback'];
|
|
17719
|
+
const text = String(source).trim();
|
|
17720
|
+
if (!text)
|
|
17721
|
+
return options['fallback'];
|
|
17722
|
+
return `${String(options['prefix'] || '')}${text}${String(options['suffix'] || '')}`;
|
|
17723
|
+
}
|
|
17724
|
+
case 'join-nonempty': {
|
|
17725
|
+
const values = Array.isArray(options['paths'])
|
|
17726
|
+
? options['paths'].map((path) => this.readPath(env.state, String(path)))
|
|
17727
|
+
: sources;
|
|
17728
|
+
const parts = values
|
|
17729
|
+
.map((value) => value == null ? '' : String(value).trim())
|
|
17730
|
+
.filter((value) => value.length > 0);
|
|
17731
|
+
if (!parts.length)
|
|
17732
|
+
return options['fallback'];
|
|
17733
|
+
return parts.join(typeof options['delimiter'] === 'string' ? options['delimiter'] : ', ');
|
|
17734
|
+
}
|
|
17735
|
+
case 'format-value': {
|
|
17736
|
+
const source = this.resolveNamedSource(options['source'], sources, env.state);
|
|
17737
|
+
return this.formatFieldValue(source, options['format']);
|
|
17738
|
+
}
|
|
17739
|
+
case 'coalesce': {
|
|
17740
|
+
const values = Array.isArray(options['paths'])
|
|
17741
|
+
? options['paths'].map((path) => this.readPath(env.state, String(path)))
|
|
17742
|
+
: sources;
|
|
17743
|
+
for (const value of values) {
|
|
17744
|
+
if (value == null)
|
|
17745
|
+
continue;
|
|
17746
|
+
if (typeof value === 'string' && !value.trim())
|
|
17747
|
+
continue;
|
|
17748
|
+
return value;
|
|
17749
|
+
}
|
|
17750
|
+
return options['fallback'];
|
|
17751
|
+
}
|
|
17752
|
+
case 'count-nonempty-entries': {
|
|
17753
|
+
const source = this.resolveNamedSource(options['source'], sources, env.state);
|
|
17754
|
+
if (!this.isPlainObject(source))
|
|
17755
|
+
return 0;
|
|
17756
|
+
return Object.values(source).filter((value) => !this.isEmptyValue(value)).length;
|
|
17757
|
+
}
|
|
17758
|
+
case 'select-case':
|
|
17759
|
+
return this.selectCase(options, env);
|
|
15580
17760
|
case 'template':
|
|
15581
17761
|
return this.resolveTemplate(options['value'], env);
|
|
15582
17762
|
default:
|
|
@@ -15593,6 +17773,145 @@ class WidgetPageStateRuntimeService {
|
|
|
15593
17773
|
resolveSourceValues(paths, state) {
|
|
15594
17774
|
return (paths || []).map((path) => this.readPath(state, path));
|
|
15595
17775
|
}
|
|
17776
|
+
aggregateArray(rows, metrics) {
|
|
17777
|
+
const output = {};
|
|
17778
|
+
for (const metric of metrics) {
|
|
17779
|
+
const key = typeof metric?.['key'] === 'string' ? metric['key'].trim() : '';
|
|
17780
|
+
const op = typeof metric?.['op'] === 'string' ? metric['op'].trim() : '';
|
|
17781
|
+
if (!key || !op)
|
|
17782
|
+
continue;
|
|
17783
|
+
switch (op) {
|
|
17784
|
+
case 'count':
|
|
17785
|
+
output[key] = rows.length;
|
|
17786
|
+
break;
|
|
17787
|
+
case 'sum':
|
|
17788
|
+
output[key] = rows.reduce((sum, row) => sum + this.toNumber(this.readMetricValue(row, metric['field'])), 0);
|
|
17789
|
+
break;
|
|
17790
|
+
case 'avg':
|
|
17791
|
+
output[key] = rows.length
|
|
17792
|
+
? rows.reduce((sum, row) => sum + this.toNumber(this.readMetricValue(row, metric['field'])), 0) / rows.length
|
|
17793
|
+
: 0;
|
|
17794
|
+
break;
|
|
17795
|
+
case 'distinct-count': {
|
|
17796
|
+
const values = rows
|
|
17797
|
+
.map((row) => this.readMetricValue(row, metric['field']))
|
|
17798
|
+
.filter((value) => value !== null && value !== undefined && String(value).trim() !== '');
|
|
17799
|
+
output[key] = new Set(values.map((value) => String(value))).size;
|
|
17800
|
+
break;
|
|
17801
|
+
}
|
|
17802
|
+
}
|
|
17803
|
+
}
|
|
17804
|
+
return output;
|
|
17805
|
+
}
|
|
17806
|
+
buildFieldList(source, items, env) {
|
|
17807
|
+
const templateEnv = {
|
|
17808
|
+
...env,
|
|
17809
|
+
source: this.clone(source),
|
|
17810
|
+
};
|
|
17811
|
+
return items.reduce((acc, item) => {
|
|
17812
|
+
if (!item || typeof item !== 'object')
|
|
17813
|
+
return acc;
|
|
17814
|
+
const label = typeof item['labelTemplate'] === 'string'
|
|
17815
|
+
? this.resolveTemplate(item['labelTemplate'], templateEnv)
|
|
17816
|
+
: this.resolveTemplate(item['label'] ?? '', templateEnv);
|
|
17817
|
+
const rawValue = typeof item['valueTemplate'] === 'string'
|
|
17818
|
+
? this.resolveTemplate(item['valueTemplate'], templateEnv)
|
|
17819
|
+
: this.readPath(source || {}, String(item['valuePath'] || '').trim());
|
|
17820
|
+
const formattedValue = this.formatFieldValue(rawValue, item['format']);
|
|
17821
|
+
acc.push({
|
|
17822
|
+
label: typeof label === 'string' ? label : String(label ?? ''),
|
|
17823
|
+
value: formattedValue,
|
|
17824
|
+
});
|
|
17825
|
+
return acc;
|
|
17826
|
+
}, []);
|
|
17827
|
+
}
|
|
17828
|
+
groupTop(rows, options) {
|
|
17829
|
+
const groupBy = typeof options['groupBy'] === 'string' ? options['groupBy'].trim() : '';
|
|
17830
|
+
if (!groupBy)
|
|
17831
|
+
return [];
|
|
17832
|
+
const aggregate = typeof options['aggregate'] === 'string' ? options['aggregate'].trim() : 'count';
|
|
17833
|
+
const field = typeof options['field'] === 'string' ? options['field'].trim() : '';
|
|
17834
|
+
const limit = typeof options['limit'] === 'number' && options['limit'] > 0 ? Math.floor(options['limit']) : 5;
|
|
17835
|
+
const totals = new Map();
|
|
17836
|
+
for (const row of rows) {
|
|
17837
|
+
const groupValue = this.readMetricValue(row, groupBy);
|
|
17838
|
+
const key = String(groupValue ?? '').trim();
|
|
17839
|
+
if (!key)
|
|
17840
|
+
continue;
|
|
17841
|
+
const amount = aggregate === 'sum'
|
|
17842
|
+
? this.toNumber(this.readMetricValue(row, field))
|
|
17843
|
+
: 1;
|
|
17844
|
+
totals.set(key, (totals.get(key) || 0) + amount);
|
|
17845
|
+
}
|
|
17846
|
+
return Array.from(totals.entries())
|
|
17847
|
+
.sort((left, right) => right[1] - left[1])
|
|
17848
|
+
.slice(0, limit)
|
|
17849
|
+
.map(([value, total]) => ({
|
|
17850
|
+
label: value,
|
|
17851
|
+
value,
|
|
17852
|
+
metric: this.formatFieldValue(total, options['metricFormat'] || 'integer'),
|
|
17853
|
+
}));
|
|
17854
|
+
}
|
|
17855
|
+
selectCase(options, env) {
|
|
17856
|
+
const cases = Array.isArray(options['cases']) ? options['cases'] : [];
|
|
17857
|
+
for (const item of cases) {
|
|
17858
|
+
if (!item || typeof item !== 'object')
|
|
17859
|
+
continue;
|
|
17860
|
+
if (!this.matchesCase(item['when'], env.state))
|
|
17861
|
+
continue;
|
|
17862
|
+
return this.resolveCaseValue(item, env);
|
|
17863
|
+
}
|
|
17864
|
+
return this.resolveCaseValue({
|
|
17865
|
+
value: options['defaultValue'],
|
|
17866
|
+
template: options['defaultTemplate'],
|
|
17867
|
+
path: options['defaultPath'],
|
|
17868
|
+
}, env);
|
|
17869
|
+
}
|
|
17870
|
+
matchesCase(condition, state) {
|
|
17871
|
+
if (!condition || typeof condition !== 'object')
|
|
17872
|
+
return false;
|
|
17873
|
+
const path = typeof condition['path'] === 'string' ? condition['path'].trim() : '';
|
|
17874
|
+
const value = path ? this.readPath(state, path) : undefined;
|
|
17875
|
+
const compareValue = condition['comparePath']
|
|
17876
|
+
? this.readPath(state, String(condition['comparePath']).trim())
|
|
17877
|
+
: condition['value'];
|
|
17878
|
+
if ('equals' in condition)
|
|
17879
|
+
return value === condition['equals'];
|
|
17880
|
+
if ('notEquals' in condition)
|
|
17881
|
+
return value !== condition['notEquals'];
|
|
17882
|
+
if (condition['truthy'] === true)
|
|
17883
|
+
return Boolean(value);
|
|
17884
|
+
if (condition['falsy'] === true)
|
|
17885
|
+
return !value;
|
|
17886
|
+
if (condition['notEmpty'] === true)
|
|
17887
|
+
return value != null && String(value).trim().length > 0;
|
|
17888
|
+
if ('lt' in condition)
|
|
17889
|
+
return this.toNumber(value) < this.toNumber(condition['lt']);
|
|
17890
|
+
if ('lte' in condition)
|
|
17891
|
+
return this.toNumber(value) <= this.toNumber(condition['lte']);
|
|
17892
|
+
if ('gt' in condition)
|
|
17893
|
+
return this.toNumber(value) > this.toNumber(condition['gt']);
|
|
17894
|
+
if ('gte' in condition)
|
|
17895
|
+
return this.toNumber(value) >= this.toNumber(condition['gte']);
|
|
17896
|
+
if ('comparePath' in condition && 'op' in condition) {
|
|
17897
|
+
switch (String(condition['op']).trim()) {
|
|
17898
|
+
case 'lt': return this.toNumber(value) < this.toNumber(compareValue);
|
|
17899
|
+
case 'lte': return this.toNumber(value) <= this.toNumber(compareValue);
|
|
17900
|
+
case 'gt': return this.toNumber(value) > this.toNumber(compareValue);
|
|
17901
|
+
case 'gte': return this.toNumber(value) >= this.toNumber(compareValue);
|
|
17902
|
+
case 'equals': return value === compareValue;
|
|
17903
|
+
}
|
|
17904
|
+
}
|
|
17905
|
+
return false;
|
|
17906
|
+
}
|
|
17907
|
+
resolveCaseValue(item, env) {
|
|
17908
|
+
if ('path' in item && typeof item['path'] === 'string' && item['path'].trim()) {
|
|
17909
|
+
return this.readPath(env.state, item['path'].trim());
|
|
17910
|
+
}
|
|
17911
|
+
if ('template' in item)
|
|
17912
|
+
return this.resolveTemplate(item['template'], env);
|
|
17913
|
+
return item['value'];
|
|
17914
|
+
}
|
|
15596
17915
|
resolveTemplate(node, env) {
|
|
15597
17916
|
if (node == null)
|
|
15598
17917
|
return node;
|
|
@@ -15626,6 +17945,65 @@ class WidgetPageStateRuntimeService {
|
|
|
15626
17945
|
isEqual(left, right) {
|
|
15627
17946
|
return JSON.stringify(left) === JSON.stringify(right);
|
|
15628
17947
|
}
|
|
17948
|
+
isEmptyValue(value) {
|
|
17949
|
+
if (value == null)
|
|
17950
|
+
return true;
|
|
17951
|
+
if (typeof value === 'string')
|
|
17952
|
+
return value.trim().length === 0;
|
|
17953
|
+
if (Array.isArray(value))
|
|
17954
|
+
return value.length === 0 || value.every((item) => this.isEmptyValue(item));
|
|
17955
|
+
if (this.isPlainObject(value))
|
|
17956
|
+
return Object.values(value).every((item) => this.isEmptyValue(item));
|
|
17957
|
+
return false;
|
|
17958
|
+
}
|
|
17959
|
+
readMetricValue(row, field) {
|
|
17960
|
+
if (typeof field !== 'string' || !field.trim())
|
|
17961
|
+
return row;
|
|
17962
|
+
return this.readPath(row || {}, field.trim());
|
|
17963
|
+
}
|
|
17964
|
+
toNumber(value) {
|
|
17965
|
+
if (typeof value === 'number')
|
|
17966
|
+
return Number.isFinite(value) ? value : 0;
|
|
17967
|
+
if (typeof value === 'string' && value.trim()) {
|
|
17968
|
+
const parsed = Number(value);
|
|
17969
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
17970
|
+
}
|
|
17971
|
+
return 0;
|
|
17972
|
+
}
|
|
17973
|
+
formatFieldValue(value, format) {
|
|
17974
|
+
if (format == null)
|
|
17975
|
+
return value == null ? '' : String(value);
|
|
17976
|
+
const normalized = typeof format === 'string' ? { kind: format } : format;
|
|
17977
|
+
const kind = typeof normalized?.kind === 'string' ? normalized.kind.trim() : '';
|
|
17978
|
+
const locale = typeof normalized?.locale === 'string' && normalized.locale.trim() ? normalized.locale.trim() : 'pt-BR';
|
|
17979
|
+
switch (kind) {
|
|
17980
|
+
case 'integer':
|
|
17981
|
+
return new Intl.NumberFormat(locale, {
|
|
17982
|
+
maximumFractionDigits: 0,
|
|
17983
|
+
minimumFractionDigits: 0,
|
|
17984
|
+
}).format(this.toNumber(value));
|
|
17985
|
+
case 'number':
|
|
17986
|
+
return new Intl.NumberFormat(locale, {
|
|
17987
|
+
maximumFractionDigits: this.toNumber(normalized?.maximumFractionDigits),
|
|
17988
|
+
minimumFractionDigits: this.toNumber(normalized?.minimumFractionDigits),
|
|
17989
|
+
}).format(this.toNumber(value));
|
|
17990
|
+
case 'currency':
|
|
17991
|
+
return new Intl.NumberFormat(locale, {
|
|
17992
|
+
style: 'currency',
|
|
17993
|
+
currency: typeof normalized?.currency === 'string' && normalized.currency.trim() ? normalized.currency.trim() : 'BRL',
|
|
17994
|
+
maximumFractionDigits: normalized?.maximumFractionDigits ?? 2,
|
|
17995
|
+
minimumFractionDigits: normalized?.minimumFractionDigits ?? 2,
|
|
17996
|
+
}).format(this.toNumber(value));
|
|
17997
|
+
case 'percent':
|
|
17998
|
+
return new Intl.NumberFormat(locale, {
|
|
17999
|
+
style: 'percent',
|
|
18000
|
+
maximumFractionDigits: normalized?.maximumFractionDigits ?? 1,
|
|
18001
|
+
minimumFractionDigits: normalized?.minimumFractionDigits ?? 0,
|
|
18002
|
+
}).format(this.toNumber(value));
|
|
18003
|
+
default:
|
|
18004
|
+
return value == null ? '' : String(value);
|
|
18005
|
+
}
|
|
18006
|
+
}
|
|
15629
18007
|
clone(value) {
|
|
15630
18008
|
if (value == null || typeof value !== 'object')
|
|
15631
18009
|
return value;
|
|
@@ -15664,6 +18042,7 @@ class DynamicWidgetPageComponent {
|
|
|
15664
18042
|
componentInstanceId;
|
|
15665
18043
|
pageChange = new EventEmitter();
|
|
15666
18044
|
widgets = signal([], ...(ngDevMode ? [{ debugName: "widgets" }] : []));
|
|
18045
|
+
renderedGroups = signal([], ...(ngDevMode ? [{ debugName: "renderedGroups" }] : []));
|
|
15667
18046
|
mergedContext = {};
|
|
15668
18047
|
pageGap = '16px';
|
|
15669
18048
|
gridTemplateColumns = 'minmax(0, 1fr)';
|
|
@@ -15677,6 +18056,9 @@ class DynamicWidgetPageComponent {
|
|
|
15677
18056
|
diagnostics: [],
|
|
15678
18057
|
};
|
|
15679
18058
|
layout;
|
|
18059
|
+
grouping = [];
|
|
18060
|
+
pageColumnCount = 1;
|
|
18061
|
+
activeTabs = {};
|
|
15680
18062
|
appliedPersisted = false;
|
|
15681
18063
|
isHydrating = false;
|
|
15682
18064
|
persistenceReady = false;
|
|
@@ -15700,17 +18082,16 @@ class DynamicWidgetPageComponent {
|
|
|
15700
18082
|
ngOnChanges(changes) {
|
|
15701
18083
|
if (changes['page'] || changes['context'] || changes['enableCustomization']) {
|
|
15702
18084
|
const parsed = this.parsePage(this.page);
|
|
15703
|
-
|
|
18085
|
+
const resolvedPage = parsed ? this.resolvePagePresets(parsed) : parsed;
|
|
18086
|
+
this.pageDefinition = resolvedPage ? { ...resolvedPage, state: this.stateRuntime.normalizeState(resolvedPage.state) } : resolvedPage;
|
|
15704
18087
|
this.pageRuntime = this.buildStateRuntime(this.pageDefinition?.state, this.pageDefinition?.context);
|
|
15705
18088
|
this.pageState = this.pageRuntime.state;
|
|
15706
|
-
const rawWidgets =
|
|
18089
|
+
const rawWidgets = this.pageDefinition?.widgets || [];
|
|
15707
18090
|
let widgets = this.applyEditShellActions(rawWidgets);
|
|
15708
|
-
widgets = this.applyStateConnections(
|
|
18091
|
+
widgets = this.applyStateConnections(this.pageDefinition?.connections, this.pageRuntime.effectiveValues, this.collectConnectedStatePaths(this.pageDefinition?.connections), widgets);
|
|
15709
18092
|
this.pageDefinition = this.pageDefinition ? { ...this.pageDefinition, widgets } : this.pageDefinition;
|
|
15710
18093
|
this.page = this.pageDefinition;
|
|
15711
|
-
this.widgets.
|
|
15712
|
-
this.mergedContext = this.mergeContext(parsed?.context, this.context, this.pageRuntime);
|
|
15713
|
-
this.applyLayout(parsed?.layout);
|
|
18094
|
+
this.applyResponsivePresentation(this.pageDefinition, widgets, this.pageRuntime);
|
|
15714
18095
|
this.reportStateDiagnostics(this.pageRuntime.diagnostics);
|
|
15715
18096
|
}
|
|
15716
18097
|
if (this.autoPersist && (changes['pageIdentity'] || changes['componentInstanceId'])) {
|
|
@@ -15962,42 +18343,49 @@ class DynamicWidgetPageComponent {
|
|
|
15962
18343
|
applyPageUpdate(next, persist = true, runtime = this.buildStateRuntime(next.state, next.context)) {
|
|
15963
18344
|
const normalized = { ...next, state: runtime.state };
|
|
15964
18345
|
const stateBoundWidgets = this.applyStateConnections(normalized.connections, runtime.effectiveValues, this.collectConnectedStatePaths(normalized.connections), normalized.widgets || []);
|
|
15965
|
-
const hydrated = { ...normalized, widgets: stateBoundWidgets };
|
|
18346
|
+
const hydrated = this.resolvePagePresets({ ...normalized, widgets: stateBoundWidgets });
|
|
15966
18347
|
this.pageDefinition = hydrated;
|
|
15967
18348
|
this.page = hydrated;
|
|
15968
18349
|
this.pageState = runtime.state;
|
|
15969
18350
|
this.pageRuntime = runtime;
|
|
15970
|
-
this.
|
|
15971
|
-
this.mergedContext = this.mergeContext(hydrated.context, this.context, runtime);
|
|
15972
|
-
this.applyLayout(hydrated.layout);
|
|
18351
|
+
this.applyResponsivePresentation(hydrated, stateBoundWidgets, runtime);
|
|
15973
18352
|
this.pageChange.emit(hydrated);
|
|
15974
18353
|
this.reportStateDiagnostics(runtime.diagnostics);
|
|
15975
18354
|
if (persist && this.autoPersist && !this.isHydrating) {
|
|
15976
18355
|
this.savePage(hydrated);
|
|
15977
18356
|
}
|
|
15978
18357
|
}
|
|
15979
|
-
applyLayout(layout) {
|
|
18358
|
+
applyLayout(layout, grouping) {
|
|
15980
18359
|
this.layout = layout;
|
|
18360
|
+
this.grouping = grouping || [];
|
|
15981
18361
|
const orientation = layout?.orientation || 'vertical';
|
|
15982
18362
|
const columns = orientation === 'columns' ? this.resolveColumns(layout) : 1;
|
|
18363
|
+
this.pageColumnCount = columns;
|
|
15983
18364
|
this.gridTemplateColumns = `repeat(${columns}, minmax(0, 1fr))`;
|
|
15984
18365
|
this.pageGap = layout?.gap || '16px';
|
|
15985
18366
|
}
|
|
15986
|
-
mergeContext(pageContext, inputContext, runtime) {
|
|
18367
|
+
mergeContext(pageContext, inputContext, runtime, pageDefinition) {
|
|
15987
18368
|
const baseContext = this.buildStateContext(pageContext);
|
|
18369
|
+
const themePresetId = pageDefinition?.themePreset || '';
|
|
18370
|
+
const themePreset = themePresetId ? BUILTIN_PAGE_THEME_PRESETS[themePresetId] : undefined;
|
|
18371
|
+
const layoutPresetId = pageDefinition?.layoutPreset || '';
|
|
18372
|
+
const layoutPreset = layoutPresetId ? BUILTIN_PAGE_LAYOUT_PRESETS[layoutPresetId] : undefined;
|
|
15988
18373
|
return {
|
|
15989
18374
|
...baseContext,
|
|
15990
18375
|
...(inputContext || {}),
|
|
18376
|
+
pageDeviceKind: this.resolveDeviceKind(),
|
|
18377
|
+
pageLayoutPreset: layoutPreset || null,
|
|
18378
|
+
pageThemePreset: themePreset || null,
|
|
18379
|
+
pageGrouping: this.cloneGrouping(pageDefinition?.grouping),
|
|
15991
18380
|
pageState: this.cloneStateValues(runtime.primaryValues),
|
|
15992
18381
|
pageStateDerived: this.cloneStateValues(runtime.derivedValues),
|
|
15993
18382
|
pageStateEffective: this.cloneStateValues(runtime.effectiveValues),
|
|
15994
18383
|
};
|
|
15995
18384
|
}
|
|
15996
18385
|
onWindowResize() {
|
|
15997
|
-
if (!this.
|
|
18386
|
+
if (!this.pageDefinition)
|
|
15998
18387
|
return;
|
|
15999
|
-
|
|
16000
|
-
this.gridTemplateColumns = `repeat(${columns}, minmax(0, 1fr))`;
|
|
18388
|
+
this.applyResponsivePresentation(this.pageDefinition, this.pageDefinition.widgets || [], this.pageRuntime);
|
|
16001
18389
|
}
|
|
16002
18390
|
resolveColumns(layout) {
|
|
16003
18391
|
const base = Math.max(1, Number(layout?.columns) || 2);
|
|
@@ -16030,7 +18418,7 @@ class DynamicWidgetPageComponent {
|
|
|
16030
18418
|
return this.pageDefinition;
|
|
16031
18419
|
const parsed = this.parsePage(this.page);
|
|
16032
18420
|
if (parsed)
|
|
16033
|
-
return parsed;
|
|
18421
|
+
return this.resolvePagePresets(parsed);
|
|
16034
18422
|
return { widgets: this.widgets(), state: this.stateRuntime.normalizeState(this.pageState) };
|
|
16035
18423
|
}
|
|
16036
18424
|
parsePage(input) {
|
|
@@ -16046,6 +18434,217 @@ class DynamicWidgetPageComponent {
|
|
|
16046
18434
|
}
|
|
16047
18435
|
return input;
|
|
16048
18436
|
}
|
|
18437
|
+
resolvePagePresets(page) {
|
|
18438
|
+
const preset = page.layoutPreset ? BUILTIN_PAGE_LAYOUT_PRESETS[page.layoutPreset] : undefined;
|
|
18439
|
+
const themePresetId = page.themePreset || preset?.defaultThemePreset;
|
|
18440
|
+
const mergedLayout = this.mergeLayout(preset?.defaultLayout, page.layout);
|
|
18441
|
+
const grouping = (page.grouping && page.grouping.length ? page.grouping : preset?.defaultGrouping) || undefined;
|
|
18442
|
+
return {
|
|
18443
|
+
...page,
|
|
18444
|
+
layout: mergedLayout,
|
|
18445
|
+
grouping,
|
|
18446
|
+
themePreset: themePresetId,
|
|
18447
|
+
};
|
|
18448
|
+
}
|
|
18449
|
+
mergeLayout(presetLayout, pageLayout) {
|
|
18450
|
+
if (!presetLayout && !pageLayout)
|
|
18451
|
+
return undefined;
|
|
18452
|
+
return {
|
|
18453
|
+
...(presetLayout || {}),
|
|
18454
|
+
...(pageLayout || {}),
|
|
18455
|
+
breakpoints: {
|
|
18456
|
+
...(presetLayout?.breakpoints || {}),
|
|
18457
|
+
...(pageLayout?.breakpoints || {}),
|
|
18458
|
+
},
|
|
18459
|
+
};
|
|
18460
|
+
}
|
|
18461
|
+
applyResponsivePresentation(pageDefinition, widgets, runtime) {
|
|
18462
|
+
const effective = this.resolveEffectivePresentation(pageDefinition, widgets);
|
|
18463
|
+
this.applyLayout(effective.layout, effective.grouping);
|
|
18464
|
+
this.syncActiveTabs(effective.groups);
|
|
18465
|
+
this.mergedContext = this.mergeContext(pageDefinition?.context, this.context, runtime, {
|
|
18466
|
+
...(pageDefinition || { widgets: [] }),
|
|
18467
|
+
layout: effective.layout,
|
|
18468
|
+
grouping: effective.grouping,
|
|
18469
|
+
});
|
|
18470
|
+
this.renderedGroups.set(effective.groups);
|
|
18471
|
+
this.widgets.set(this.resolveShellTemplates(effective.widgets, runtime));
|
|
18472
|
+
}
|
|
18473
|
+
resolveEffectivePresentation(pageDefinition, widgets) {
|
|
18474
|
+
const variant = this.resolveDeviceVariant(pageDefinition?.deviceLayouts);
|
|
18475
|
+
const layout = this.mergeLayout(pageDefinition?.layout, variant?.layout);
|
|
18476
|
+
const grouping = this.applyGroupingOverrides(pageDefinition?.grouping, variant?.groupingOverrides);
|
|
18477
|
+
const widgetsWithOverrides = this.applyWidgetLayoutOverrides(this.applyEditShellActions(widgets), variant?.widgetOverrides);
|
|
18478
|
+
const groups = this.buildRenderedGroups(grouping, widgetsWithOverrides);
|
|
18479
|
+
return {
|
|
18480
|
+
layout,
|
|
18481
|
+
grouping,
|
|
18482
|
+
widgets: widgetsWithOverrides,
|
|
18483
|
+
groups,
|
|
18484
|
+
};
|
|
18485
|
+
}
|
|
18486
|
+
resolveDeviceVariant(deviceLayouts) {
|
|
18487
|
+
const kind = this.resolveDeviceKind();
|
|
18488
|
+
if (kind === 'mobile')
|
|
18489
|
+
return deviceLayouts?.mobile;
|
|
18490
|
+
if (kind === 'tablet')
|
|
18491
|
+
return deviceLayouts?.tablet;
|
|
18492
|
+
return deviceLayouts?.desktop;
|
|
18493
|
+
}
|
|
18494
|
+
resolveDeviceKind() {
|
|
18495
|
+
const width = typeof window !== 'undefined' ? window.innerWidth : 1440;
|
|
18496
|
+
if (width < 768)
|
|
18497
|
+
return 'mobile';
|
|
18498
|
+
if (width < 1280)
|
|
18499
|
+
return 'tablet';
|
|
18500
|
+
return 'desktop';
|
|
18501
|
+
}
|
|
18502
|
+
applyWidgetLayoutOverrides(widgets, overrides) {
|
|
18503
|
+
const rendered = widgets
|
|
18504
|
+
.map((widget) => {
|
|
18505
|
+
const override = overrides?.[widget.key];
|
|
18506
|
+
if (override?.hidden)
|
|
18507
|
+
return null;
|
|
18508
|
+
const renderClassName = this.mergeClassNames(widget.className, override?.className);
|
|
18509
|
+
return {
|
|
18510
|
+
...widget,
|
|
18511
|
+
renderClassName,
|
|
18512
|
+
renderSpan: override?.span,
|
|
18513
|
+
__order: typeof override?.order === 'number' ? override.order : Number.MAX_SAFE_INTEGER,
|
|
18514
|
+
};
|
|
18515
|
+
})
|
|
18516
|
+
.filter((widget) => !!widget)
|
|
18517
|
+
.sort((left, right) => left.__order - right.__order);
|
|
18518
|
+
return rendered.map(({ __order, ...widget }) => widget);
|
|
18519
|
+
}
|
|
18520
|
+
applyGroupingOverrides(grouping, overrides) {
|
|
18521
|
+
if (!grouping?.length)
|
|
18522
|
+
return grouping;
|
|
18523
|
+
if (!overrides?.length)
|
|
18524
|
+
return this.cloneGrouping(grouping);
|
|
18525
|
+
const overridesById = new Map(overrides.map((item) => [item.id, item]));
|
|
18526
|
+
return this.cloneGrouping(grouping)
|
|
18527
|
+
.map((group) => {
|
|
18528
|
+
const override = overridesById.get(group.id);
|
|
18529
|
+
if (!override || override.hidden)
|
|
18530
|
+
return override?.hidden ? null : group;
|
|
18531
|
+
if (group.kind === 'tabs') {
|
|
18532
|
+
return {
|
|
18533
|
+
...group,
|
|
18534
|
+
tabs: override.tabs?.length ? override.tabs : group.tabs,
|
|
18535
|
+
};
|
|
18536
|
+
}
|
|
18537
|
+
return {
|
|
18538
|
+
...group,
|
|
18539
|
+
widgetKeys: override.widgetKeys?.length ? override.widgetKeys : group.widgetKeys,
|
|
18540
|
+
};
|
|
18541
|
+
})
|
|
18542
|
+
.filter((group) => !!group);
|
|
18543
|
+
}
|
|
18544
|
+
buildRenderedGroups(grouping, widgets) {
|
|
18545
|
+
if (!grouping?.length)
|
|
18546
|
+
return [];
|
|
18547
|
+
const widgetMap = new Map(widgets.map((widget) => [widget.key, widget]));
|
|
18548
|
+
const usedKeys = new Set();
|
|
18549
|
+
const groups = [];
|
|
18550
|
+
for (const group of grouping) {
|
|
18551
|
+
if (group.kind === 'tabs') {
|
|
18552
|
+
const tabs = group.tabs
|
|
18553
|
+
.map((tab) => {
|
|
18554
|
+
const tabWidgets = tab.widgetKeys
|
|
18555
|
+
.map((key) => widgetMap.get(key))
|
|
18556
|
+
.filter((widget) => !!widget);
|
|
18557
|
+
for (const widget of tabWidgets)
|
|
18558
|
+
usedKeys.add(widget.key);
|
|
18559
|
+
return { id: tab.id, label: tab.label, widgets: tabWidgets };
|
|
18560
|
+
})
|
|
18561
|
+
.filter((tab) => tab.widgets.length);
|
|
18562
|
+
if (tabs.length) {
|
|
18563
|
+
groups.push({
|
|
18564
|
+
id: group.id,
|
|
18565
|
+
kind: 'tabs',
|
|
18566
|
+
label: group.label,
|
|
18567
|
+
widgets: [],
|
|
18568
|
+
tabs,
|
|
18569
|
+
});
|
|
18570
|
+
}
|
|
18571
|
+
continue;
|
|
18572
|
+
}
|
|
18573
|
+
const groupWidgets = group.widgetKeys
|
|
18574
|
+
.map((key) => widgetMap.get(key))
|
|
18575
|
+
.filter((widget) => !!widget);
|
|
18576
|
+
for (const widget of groupWidgets)
|
|
18577
|
+
usedKeys.add(widget.key);
|
|
18578
|
+
if (!groupWidgets.length)
|
|
18579
|
+
continue;
|
|
18580
|
+
groups.push({
|
|
18581
|
+
id: group.id,
|
|
18582
|
+
kind: group.kind,
|
|
18583
|
+
label: 'label' in group ? group.label : undefined,
|
|
18584
|
+
layout: 'layout' in group ? group.layout : undefined,
|
|
18585
|
+
emphasis: 'emphasis' in group ? group.emphasis : undefined,
|
|
18586
|
+
side: 'side' in group ? group.side : undefined,
|
|
18587
|
+
widgets: groupWidgets,
|
|
18588
|
+
});
|
|
18589
|
+
}
|
|
18590
|
+
const ungrouped = widgets.filter((widget) => !usedKeys.has(widget.key));
|
|
18591
|
+
if (ungrouped.length) {
|
|
18592
|
+
groups.push({
|
|
18593
|
+
id: 'ungrouped',
|
|
18594
|
+
kind: 'ungrouped',
|
|
18595
|
+
label: undefined,
|
|
18596
|
+
layout: this.pageColumnCount > 1 ? 'grid' : 'stack',
|
|
18597
|
+
widgets: ungrouped,
|
|
18598
|
+
});
|
|
18599
|
+
}
|
|
18600
|
+
return groups;
|
|
18601
|
+
}
|
|
18602
|
+
syncActiveTabs(groups) {
|
|
18603
|
+
const next = { ...this.activeTabs };
|
|
18604
|
+
for (const group of groups) {
|
|
18605
|
+
if (group.kind !== 'tabs' || !group.tabs?.length)
|
|
18606
|
+
continue;
|
|
18607
|
+
const current = next[group.id];
|
|
18608
|
+
if (!current || !group.tabs.some((tab) => tab.id === current)) {
|
|
18609
|
+
next[group.id] = group.tabs[0].id;
|
|
18610
|
+
}
|
|
18611
|
+
}
|
|
18612
|
+
this.activeTabs = next;
|
|
18613
|
+
}
|
|
18614
|
+
activeTabId(groupId) {
|
|
18615
|
+
return this.activeTabs[groupId] || '';
|
|
18616
|
+
}
|
|
18617
|
+
selectGroupTab(groupId, tabId) {
|
|
18618
|
+
this.activeTabs = { ...this.activeTabs, [groupId]: tabId };
|
|
18619
|
+
}
|
|
18620
|
+
resolveGroupContentLayout(group) {
|
|
18621
|
+
if (group.kind === 'hero')
|
|
18622
|
+
return 'row';
|
|
18623
|
+
if (group.kind === 'rail')
|
|
18624
|
+
return 'stack';
|
|
18625
|
+
return group.layout || (this.pageColumnCount > 1 ? 'grid' : 'stack');
|
|
18626
|
+
}
|
|
18627
|
+
groupGridColumn(group) {
|
|
18628
|
+
if (group.kind === 'rail' && this.pageColumnCount > 1) {
|
|
18629
|
+
return `${this.pageColumnCount} / span 1`;
|
|
18630
|
+
}
|
|
18631
|
+
return '1 / -1';
|
|
18632
|
+
}
|
|
18633
|
+
widgetGridColumn(widget) {
|
|
18634
|
+
if (!widget.renderSpan || widget.renderSpan <= 1)
|
|
18635
|
+
return null;
|
|
18636
|
+
return `span ${widget.renderSpan}`;
|
|
18637
|
+
}
|
|
18638
|
+
widgetClassName(widget) {
|
|
18639
|
+
return widget.renderClassName || widget.className || '';
|
|
18640
|
+
}
|
|
18641
|
+
mergeClassNames(...classNames) {
|
|
18642
|
+
const merged = classNames
|
|
18643
|
+
.flatMap((value) => (value || '').split(/\s+/))
|
|
18644
|
+
.map((value) => value.trim())
|
|
18645
|
+
.filter(Boolean);
|
|
18646
|
+
return merged.length ? Array.from(new Set(merged)).join(' ') : undefined;
|
|
18647
|
+
}
|
|
16049
18648
|
applyEditShellActions(widgets) {
|
|
16050
18649
|
if (!this.enableCustomization)
|
|
16051
18650
|
return widgets;
|
|
@@ -16173,6 +18772,9 @@ class DynamicWidgetPageComponent {
|
|
|
16173
18772
|
cloneStateValues(state) {
|
|
16174
18773
|
return state ? JSON.parse(JSON.stringify(state)) : {};
|
|
16175
18774
|
}
|
|
18775
|
+
cloneGrouping(grouping) {
|
|
18776
|
+
return grouping ? JSON.parse(JSON.stringify(grouping)) : [];
|
|
18777
|
+
}
|
|
16176
18778
|
collectConnectedStatePaths(connections) {
|
|
16177
18779
|
return Array.from(new Set((connections || [])
|
|
16178
18780
|
.filter((connection) => 'state' in connection.from)
|
|
@@ -16187,6 +18789,18 @@ class DynamicWidgetPageComponent {
|
|
|
16187
18789
|
...(this.context || {}),
|
|
16188
18790
|
};
|
|
16189
18791
|
}
|
|
18792
|
+
resolveShellTemplates(widgets, runtime) {
|
|
18793
|
+
const context = {
|
|
18794
|
+
...(this.mergedContext || {}),
|
|
18795
|
+
state: this.cloneStateValues(runtime.effectiveValues),
|
|
18796
|
+
pageState: this.cloneStateValues(runtime.primaryValues),
|
|
18797
|
+
pageStateDerived: this.cloneStateValues(runtime.derivedValues),
|
|
18798
|
+
pageStateEffective: this.cloneStateValues(runtime.effectiveValues),
|
|
18799
|
+
};
|
|
18800
|
+
return widgets.map((widget) => (widget.shell
|
|
18801
|
+
? { ...widget, shell: this.resolveTemplate(widget.shell, context) }
|
|
18802
|
+
: widget));
|
|
18803
|
+
}
|
|
16190
18804
|
reportStateDiagnostics(diagnostics) {
|
|
16191
18805
|
for (const diagnostic of diagnostics || []) {
|
|
16192
18806
|
console.warn(`[DynamicWidgetPage] ${diagnostic}`);
|
|
@@ -16213,25 +18827,100 @@ class DynamicWidgetPageComponent {
|
|
|
16213
18827
|
[style.gap]="pageGap"
|
|
16214
18828
|
[style.gridTemplateColumns]="gridTemplateColumns"
|
|
16215
18829
|
>
|
|
16216
|
-
@
|
|
16217
|
-
|
|
16218
|
-
<
|
|
16219
|
-
|
|
16220
|
-
[
|
|
16221
|
-
|
|
18830
|
+
@if (renderedGroups().length) {
|
|
18831
|
+
@for (group of renderedGroups(); track group.id) {
|
|
18832
|
+
<section
|
|
18833
|
+
class="pdx-group"
|
|
18834
|
+
[class]="'pdx-group--' + group.kind + (group.layout ? ' pdx-group--layout-' + group.layout : '') + (group.emphasis ? ' pdx-group--emphasis-' + group.emphasis : '') + (group.side ? ' pdx-group--side-' + group.side : '')"
|
|
18835
|
+
[style.gridColumn]="groupGridColumn(group)"
|
|
18836
|
+
[attr.data-group-id]="group.id"
|
|
18837
|
+
[attr.data-group-kind]="group.kind"
|
|
16222
18838
|
>
|
|
16223
|
-
|
|
16224
|
-
|
|
18839
|
+
@if (group.label) {
|
|
18840
|
+
<header class="pdx-group-header">
|
|
18841
|
+
<div class="pdx-group-title">{{ group.label }}</div>
|
|
18842
|
+
</header>
|
|
18843
|
+
}
|
|
18844
|
+
@if (group.kind === 'tabs') {
|
|
18845
|
+
<div class="pdx-group-tabs">
|
|
18846
|
+
<div class="pdx-tabs-header">
|
|
18847
|
+
@for (tab of group.tabs || []; track tab.id) {
|
|
18848
|
+
<button
|
|
18849
|
+
class="pdx-tab-chip"
|
|
18850
|
+
type="button"
|
|
18851
|
+
[class.active]="activeTabId(group.id) === tab.id"
|
|
18852
|
+
(click)="selectGroupTab(group.id, tab.id)"
|
|
18853
|
+
>
|
|
18854
|
+
{{ tab.label || tab.id }}
|
|
18855
|
+
</button>
|
|
18856
|
+
}
|
|
18857
|
+
</div>
|
|
18858
|
+
@for (tab of group.tabs || []; track tab.id) {
|
|
18859
|
+
@if (activeTabId(group.id) === tab.id) {
|
|
18860
|
+
<div class="pdx-group-content" [class]="'pdx-group-content--' + resolveGroupContentLayout(group)">
|
|
18861
|
+
@for (w of tab.widgets; track w.key) {
|
|
18862
|
+
<div class="pdx-widget" [class]="w.renderClassName || w.className || ''" [style.gridColumn]="widgetGridColumn(w)">
|
|
18863
|
+
<praxis-widget-shell
|
|
18864
|
+
[shell]="w.shell"
|
|
18865
|
+
[context]="mergedContext"
|
|
18866
|
+
(action)="onShellAction(w.key, $event)"
|
|
18867
|
+
>
|
|
18868
|
+
<ng-container
|
|
18869
|
+
[dynamicWidgetLoader]="w.definition"
|
|
18870
|
+
[context]="mergedContext"
|
|
18871
|
+
[strictValidation]="strictValidation"
|
|
18872
|
+
(widgetEvent)="onWidgetEvent(w.key, $event)"
|
|
18873
|
+
></ng-container>
|
|
18874
|
+
</praxis-widget-shell>
|
|
18875
|
+
</div>
|
|
18876
|
+
}
|
|
18877
|
+
</div>
|
|
18878
|
+
}
|
|
18879
|
+
}
|
|
18880
|
+
</div>
|
|
18881
|
+
} @else {
|
|
18882
|
+
<div class="pdx-group-content" [class]="'pdx-group-content--' + resolveGroupContentLayout(group)">
|
|
18883
|
+
@for (w of group.widgets; track w.key) {
|
|
18884
|
+
<div class="pdx-widget" [class]="widgetClassName(w)" [style.gridColumn]="widgetGridColumn(w)">
|
|
18885
|
+
<praxis-widget-shell
|
|
18886
|
+
[shell]="w.shell"
|
|
18887
|
+
[context]="mergedContext"
|
|
18888
|
+
(action)="onShellAction(w.key, $event)"
|
|
18889
|
+
>
|
|
18890
|
+
<ng-container
|
|
18891
|
+
[dynamicWidgetLoader]="w.definition"
|
|
18892
|
+
[context]="mergedContext"
|
|
18893
|
+
[strictValidation]="strictValidation"
|
|
18894
|
+
(widgetEvent)="onWidgetEvent(w.key, $event)"
|
|
18895
|
+
></ng-container>
|
|
18896
|
+
</praxis-widget-shell>
|
|
18897
|
+
</div>
|
|
18898
|
+
}
|
|
18899
|
+
</div>
|
|
18900
|
+
}
|
|
18901
|
+
</section>
|
|
18902
|
+
}
|
|
18903
|
+
} @else {
|
|
18904
|
+
@for (w of widgets(); track w.key) {
|
|
18905
|
+
<div class="pdx-widget" [class]="widgetClassName(w)" [style.gridColumn]="widgetGridColumn(w)">
|
|
18906
|
+
<praxis-widget-shell
|
|
18907
|
+
[shell]="w.shell"
|
|
16225
18908
|
[context]="mergedContext"
|
|
16226
|
-
|
|
16227
|
-
|
|
16228
|
-
|
|
16229
|
-
|
|
16230
|
-
|
|
18909
|
+
(action)="onShellAction(w.key, $event)"
|
|
18910
|
+
>
|
|
18911
|
+
<ng-container
|
|
18912
|
+
[dynamicWidgetLoader]="w.definition"
|
|
18913
|
+
[context]="mergedContext"
|
|
18914
|
+
[strictValidation]="strictValidation"
|
|
18915
|
+
(widgetEvent)="onWidgetEvent(w.key, $event)"
|
|
18916
|
+
></ng-container>
|
|
18917
|
+
</praxis-widget-shell>
|
|
18918
|
+
</div>
|
|
18919
|
+
}
|
|
16231
18920
|
}
|
|
16232
18921
|
</div>
|
|
16233
18922
|
</div>
|
|
16234
|
-
`, isInline: true, styles: [".pdx-page-wrapper{position:relative;display:block}.pdx-page{display:grid;gap:16px;grid-template-columns:minmax(0,1fr)}.pdx-page-settings{position:sticky;top:8px;z-index:2;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);color:inherit;border-radius:999px;margin-bottom:8px}.pdx-widget{position:relative;background:var(--pfx-surface, transparent);border-radius:8px}.pdx-page-wrapper.editing .pdx-widget-settings{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatButtonModule }, { 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: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: DynamicWidgetLoaderDirective, selector: "[dynamicWidgetLoader]", inputs: ["dynamicWidgetLoader", "context", "strictValidation", "autoWireOutputs"], outputs: ["widgetEvent"], exportAs: ["dynamicWidgetLoader"] }, { kind: "component", type: WidgetShellComponent, selector: "praxis-widget-shell", inputs: ["shell", "context"], outputs: ["action"] }] });
|
|
18923
|
+
`, isInline: true, styles: [".pdx-page-wrapper{position:relative;display:block}.pdx-page{display:grid;gap:16px;grid-template-columns:minmax(0,1fr)}.pdx-page-settings{position:sticky;top:8px;z-index:2;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);color:inherit;border-radius:999px;margin-bottom:8px}.pdx-widget{position:relative;background:var(--pfx-surface, transparent);border-radius:8px}.pdx-group{display:grid;gap:12px;grid-column:1 / -1;padding:12px;border-radius:16px;background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 76%,transparent);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 72%,transparent)}.pdx-group--hero{padding:16px;background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-primary-container) 42%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-low) 86%,transparent))}.pdx-group--rail{align-self:start}.pdx-group-header{display:flex;align-items:center;justify-content:space-between;gap:12px}.pdx-group-title{font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface)}.pdx-group-content{display:grid;gap:12px}.pdx-group-content--stack{grid-template-columns:minmax(0,1fr)}.pdx-group-content--row{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.pdx-group-content--grid{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.pdx-group-tabs{display:grid;gap:12px}.pdx-tabs-header{display:flex;flex-wrap:wrap;gap:8px}.pdx-tab-chip{appearance:none;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-lowest);color:var(--md-sys-color-on-surface);border-radius:999px;padding:8px 12px;font:inherit;cursor:pointer}.pdx-tab-chip.active{border-color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 78%,transparent);color:var(--md-sys-color-on-primary-container)}.pdx-page-wrapper.editing .pdx-widget-settings{opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatButtonModule }, { 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: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: DynamicWidgetLoaderDirective, selector: "[dynamicWidgetLoader]", inputs: ["dynamicWidgetLoader", "context", "strictValidation", "autoWireOutputs"], outputs: ["widgetEvent"], exportAs: ["dynamicWidgetLoader"] }, { kind: "component", type: WidgetShellComponent, selector: "praxis-widget-shell", inputs: ["shell", "context"], outputs: ["action"] }] });
|
|
16235
18924
|
}
|
|
16236
18925
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DynamicWidgetPageComponent, decorators: [{
|
|
16237
18926
|
type: Component,
|
|
@@ -16255,25 +18944,100 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
16255
18944
|
[style.gap]="pageGap"
|
|
16256
18945
|
[style.gridTemplateColumns]="gridTemplateColumns"
|
|
16257
18946
|
>
|
|
16258
|
-
@
|
|
16259
|
-
|
|
16260
|
-
<
|
|
16261
|
-
|
|
16262
|
-
[
|
|
16263
|
-
|
|
18947
|
+
@if (renderedGroups().length) {
|
|
18948
|
+
@for (group of renderedGroups(); track group.id) {
|
|
18949
|
+
<section
|
|
18950
|
+
class="pdx-group"
|
|
18951
|
+
[class]="'pdx-group--' + group.kind + (group.layout ? ' pdx-group--layout-' + group.layout : '') + (group.emphasis ? ' pdx-group--emphasis-' + group.emphasis : '') + (group.side ? ' pdx-group--side-' + group.side : '')"
|
|
18952
|
+
[style.gridColumn]="groupGridColumn(group)"
|
|
18953
|
+
[attr.data-group-id]="group.id"
|
|
18954
|
+
[attr.data-group-kind]="group.kind"
|
|
16264
18955
|
>
|
|
16265
|
-
|
|
16266
|
-
|
|
18956
|
+
@if (group.label) {
|
|
18957
|
+
<header class="pdx-group-header">
|
|
18958
|
+
<div class="pdx-group-title">{{ group.label }}</div>
|
|
18959
|
+
</header>
|
|
18960
|
+
}
|
|
18961
|
+
@if (group.kind === 'tabs') {
|
|
18962
|
+
<div class="pdx-group-tabs">
|
|
18963
|
+
<div class="pdx-tabs-header">
|
|
18964
|
+
@for (tab of group.tabs || []; track tab.id) {
|
|
18965
|
+
<button
|
|
18966
|
+
class="pdx-tab-chip"
|
|
18967
|
+
type="button"
|
|
18968
|
+
[class.active]="activeTabId(group.id) === tab.id"
|
|
18969
|
+
(click)="selectGroupTab(group.id, tab.id)"
|
|
18970
|
+
>
|
|
18971
|
+
{{ tab.label || tab.id }}
|
|
18972
|
+
</button>
|
|
18973
|
+
}
|
|
18974
|
+
</div>
|
|
18975
|
+
@for (tab of group.tabs || []; track tab.id) {
|
|
18976
|
+
@if (activeTabId(group.id) === tab.id) {
|
|
18977
|
+
<div class="pdx-group-content" [class]="'pdx-group-content--' + resolveGroupContentLayout(group)">
|
|
18978
|
+
@for (w of tab.widgets; track w.key) {
|
|
18979
|
+
<div class="pdx-widget" [class]="w.renderClassName || w.className || ''" [style.gridColumn]="widgetGridColumn(w)">
|
|
18980
|
+
<praxis-widget-shell
|
|
18981
|
+
[shell]="w.shell"
|
|
18982
|
+
[context]="mergedContext"
|
|
18983
|
+
(action)="onShellAction(w.key, $event)"
|
|
18984
|
+
>
|
|
18985
|
+
<ng-container
|
|
18986
|
+
[dynamicWidgetLoader]="w.definition"
|
|
18987
|
+
[context]="mergedContext"
|
|
18988
|
+
[strictValidation]="strictValidation"
|
|
18989
|
+
(widgetEvent)="onWidgetEvent(w.key, $event)"
|
|
18990
|
+
></ng-container>
|
|
18991
|
+
</praxis-widget-shell>
|
|
18992
|
+
</div>
|
|
18993
|
+
}
|
|
18994
|
+
</div>
|
|
18995
|
+
}
|
|
18996
|
+
}
|
|
18997
|
+
</div>
|
|
18998
|
+
} @else {
|
|
18999
|
+
<div class="pdx-group-content" [class]="'pdx-group-content--' + resolveGroupContentLayout(group)">
|
|
19000
|
+
@for (w of group.widgets; track w.key) {
|
|
19001
|
+
<div class="pdx-widget" [class]="widgetClassName(w)" [style.gridColumn]="widgetGridColumn(w)">
|
|
19002
|
+
<praxis-widget-shell
|
|
19003
|
+
[shell]="w.shell"
|
|
19004
|
+
[context]="mergedContext"
|
|
19005
|
+
(action)="onShellAction(w.key, $event)"
|
|
19006
|
+
>
|
|
19007
|
+
<ng-container
|
|
19008
|
+
[dynamicWidgetLoader]="w.definition"
|
|
19009
|
+
[context]="mergedContext"
|
|
19010
|
+
[strictValidation]="strictValidation"
|
|
19011
|
+
(widgetEvent)="onWidgetEvent(w.key, $event)"
|
|
19012
|
+
></ng-container>
|
|
19013
|
+
</praxis-widget-shell>
|
|
19014
|
+
</div>
|
|
19015
|
+
}
|
|
19016
|
+
</div>
|
|
19017
|
+
}
|
|
19018
|
+
</section>
|
|
19019
|
+
}
|
|
19020
|
+
} @else {
|
|
19021
|
+
@for (w of widgets(); track w.key) {
|
|
19022
|
+
<div class="pdx-widget" [class]="widgetClassName(w)" [style.gridColumn]="widgetGridColumn(w)">
|
|
19023
|
+
<praxis-widget-shell
|
|
19024
|
+
[shell]="w.shell"
|
|
16267
19025
|
[context]="mergedContext"
|
|
16268
|
-
|
|
16269
|
-
|
|
16270
|
-
|
|
16271
|
-
|
|
16272
|
-
|
|
19026
|
+
(action)="onShellAction(w.key, $event)"
|
|
19027
|
+
>
|
|
19028
|
+
<ng-container
|
|
19029
|
+
[dynamicWidgetLoader]="w.definition"
|
|
19030
|
+
[context]="mergedContext"
|
|
19031
|
+
[strictValidation]="strictValidation"
|
|
19032
|
+
(widgetEvent)="onWidgetEvent(w.key, $event)"
|
|
19033
|
+
></ng-container>
|
|
19034
|
+
</praxis-widget-shell>
|
|
19035
|
+
</div>
|
|
19036
|
+
}
|
|
16273
19037
|
}
|
|
16274
19038
|
</div>
|
|
16275
19039
|
</div>
|
|
16276
|
-
`, styles: [".pdx-page-wrapper{position:relative;display:block}.pdx-page{display:grid;gap:16px;grid-template-columns:minmax(0,1fr)}.pdx-page-settings{position:sticky;top:8px;z-index:2;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);color:inherit;border-radius:999px;margin-bottom:8px}.pdx-widget{position:relative;background:var(--pfx-surface, transparent);border-radius:8px}.pdx-page-wrapper.editing .pdx-widget-settings{opacity:1}\n"] }]
|
|
19040
|
+
`, styles: [".pdx-page-wrapper{position:relative;display:block}.pdx-page{display:grid;gap:16px;grid-template-columns:minmax(0,1fr)}.pdx-page-settings{position:sticky;top:8px;z-index:2;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);color:inherit;border-radius:999px;margin-bottom:8px}.pdx-widget{position:relative;background:var(--pfx-surface, transparent);border-radius:8px}.pdx-group{display:grid;gap:12px;grid-column:1 / -1;padding:12px;border-radius:16px;background:color-mix(in srgb,var(--md-sys-color-surface-container-low) 76%,transparent);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant) 72%,transparent)}.pdx-group--hero{padding:16px;background:linear-gradient(180deg,color-mix(in srgb,var(--md-sys-color-primary-container) 42%,transparent),color-mix(in srgb,var(--md-sys-color-surface-container-low) 86%,transparent))}.pdx-group--rail{align-self:start}.pdx-group-header{display:flex;align-items:center;justify-content:space-between;gap:12px}.pdx-group-title{font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface)}.pdx-group-content{display:grid;gap:12px}.pdx-group-content--stack{grid-template-columns:minmax(0,1fr)}.pdx-group-content--row{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.pdx-group-content--grid{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.pdx-group-tabs{display:grid;gap:12px}.pdx-tabs-header{display:flex;flex-wrap:wrap;gap:8px}.pdx-tab-chip{appearance:none;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-lowest);color:var(--md-sys-color-on-surface);border-radius:999px;padding:8px 12px;font:inherit;cursor:pointer}.pdx-tab-chip.active{border-color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary-container) 78%,transparent);color:var(--md-sys-color-on-primary-container)}.pdx-page-wrapper.editing .pdx-widget-settings{opacity:1}\n"] }]
|
|
16277
19041
|
}], ctorParameters: () => [{ type: ConnectionManagerService }, { type: WidgetPageStateRuntimeService }, { type: undefined, decorators: [{
|
|
16278
19042
|
type: Optional
|
|
16279
19043
|
}, {
|
|
@@ -16649,6 +19413,92 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
16649
19413
|
type: Input
|
|
16650
19414
|
}] } });
|
|
16651
19415
|
|
|
19416
|
+
class PraxisSurfaceHostComponent {
|
|
19417
|
+
title;
|
|
19418
|
+
subtitle;
|
|
19419
|
+
icon;
|
|
19420
|
+
widget;
|
|
19421
|
+
context = null;
|
|
19422
|
+
strictValidation = true;
|
|
19423
|
+
/**
|
|
19424
|
+
* Keep disabled by default to avoid duplicating the title already shown by
|
|
19425
|
+
* modal/drawer hosts. Inline consumers may opt into rendering it again.
|
|
19426
|
+
*/
|
|
19427
|
+
renderTitleInsideBody = false;
|
|
19428
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisSurfaceHostComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
19429
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: PraxisSurfaceHostComponent, isStandalone: true, selector: "praxis-surface-host", inputs: { title: "title", subtitle: "subtitle", icon: "icon", widget: "widget", context: "context", strictValidation: "strictValidation", renderTitleInsideBody: "renderTitleInsideBody" }, ngImport: i0, template: `
|
|
19430
|
+
<div class="pdx-surface-host">
|
|
19431
|
+
@if (subtitle || (title && renderTitleInsideBody)) {
|
|
19432
|
+
<header class="pdx-surface-host__header">
|
|
19433
|
+
@if (icon) {
|
|
19434
|
+
<span class="material-icons pdx-surface-host__icon" aria-hidden="true">{{ icon }}</span>
|
|
19435
|
+
}
|
|
19436
|
+
<div class="pdx-surface-host__copy">
|
|
19437
|
+
@if (title && renderTitleInsideBody) {
|
|
19438
|
+
<h2 class="pdx-surface-host__title">{{ title }}</h2>
|
|
19439
|
+
}
|
|
19440
|
+
@if (subtitle) {
|
|
19441
|
+
<p class="pdx-surface-host__subtitle">{{ subtitle }}</p>
|
|
19442
|
+
}
|
|
19443
|
+
</div>
|
|
19444
|
+
</header>
|
|
19445
|
+
}
|
|
19446
|
+
|
|
19447
|
+
<section class="pdx-surface-host__body">
|
|
19448
|
+
<ng-container
|
|
19449
|
+
[dynamicWidgetLoader]="widget"
|
|
19450
|
+
[context]="context"
|
|
19451
|
+
[strictValidation]="strictValidation"
|
|
19452
|
+
></ng-container>
|
|
19453
|
+
</section>
|
|
19454
|
+
</div>
|
|
19455
|
+
`, isInline: true, styles: [":host{display:block;min-width:0}.pdx-surface-host{display:grid;gap:16px;min-width:0}.pdx-surface-host__header{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:start}.pdx-surface-host__icon{font-size:20px;line-height:20px;color:var(--md-sys-color-primary, currentColor)}.pdx-surface-host__copy{display:grid;gap:4px;min-width:0}.pdx-surface-host__title,.pdx-surface-host__subtitle{margin:0}.pdx-surface-host__title{font-size:1rem;font-weight:600}.pdx-surface-host__subtitle{color:var(--md-sys-color-on-surface-variant, rgba(0, 0, 0, .64));font-size:.9375rem}.pdx-surface-host__body{min-width:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: DynamicWidgetLoaderDirective, selector: "[dynamicWidgetLoader]", inputs: ["dynamicWidgetLoader", "context", "strictValidation", "autoWireOutputs"], outputs: ["widgetEvent"], exportAs: ["dynamicWidgetLoader"] }] });
|
|
19456
|
+
}
|
|
19457
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisSurfaceHostComponent, decorators: [{
|
|
19458
|
+
type: Component,
|
|
19459
|
+
args: [{ selector: 'praxis-surface-host', standalone: true, imports: [CommonModule, DynamicWidgetLoaderDirective], template: `
|
|
19460
|
+
<div class="pdx-surface-host">
|
|
19461
|
+
@if (subtitle || (title && renderTitleInsideBody)) {
|
|
19462
|
+
<header class="pdx-surface-host__header">
|
|
19463
|
+
@if (icon) {
|
|
19464
|
+
<span class="material-icons pdx-surface-host__icon" aria-hidden="true">{{ icon }}</span>
|
|
19465
|
+
}
|
|
19466
|
+
<div class="pdx-surface-host__copy">
|
|
19467
|
+
@if (title && renderTitleInsideBody) {
|
|
19468
|
+
<h2 class="pdx-surface-host__title">{{ title }}</h2>
|
|
19469
|
+
}
|
|
19470
|
+
@if (subtitle) {
|
|
19471
|
+
<p class="pdx-surface-host__subtitle">{{ subtitle }}</p>
|
|
19472
|
+
}
|
|
19473
|
+
</div>
|
|
19474
|
+
</header>
|
|
19475
|
+
}
|
|
19476
|
+
|
|
19477
|
+
<section class="pdx-surface-host__body">
|
|
19478
|
+
<ng-container
|
|
19479
|
+
[dynamicWidgetLoader]="widget"
|
|
19480
|
+
[context]="context"
|
|
19481
|
+
[strictValidation]="strictValidation"
|
|
19482
|
+
></ng-container>
|
|
19483
|
+
</section>
|
|
19484
|
+
</div>
|
|
19485
|
+
`, styles: [":host{display:block;min-width:0}.pdx-surface-host{display:grid;gap:16px;min-width:0}.pdx-surface-host__header{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:start}.pdx-surface-host__icon{font-size:20px;line-height:20px;color:var(--md-sys-color-primary, currentColor)}.pdx-surface-host__copy{display:grid;gap:4px;min-width:0}.pdx-surface-host__title,.pdx-surface-host__subtitle{margin:0}.pdx-surface-host__title{font-size:1rem;font-weight:600}.pdx-surface-host__subtitle{color:var(--md-sys-color-on-surface-variant, rgba(0, 0, 0, .64));font-size:.9375rem}.pdx-surface-host__body{min-width:0}\n"] }]
|
|
19486
|
+
}], propDecorators: { title: [{
|
|
19487
|
+
type: Input
|
|
19488
|
+
}], subtitle: [{
|
|
19489
|
+
type: Input
|
|
19490
|
+
}], icon: [{
|
|
19491
|
+
type: Input
|
|
19492
|
+
}], widget: [{
|
|
19493
|
+
type: Input
|
|
19494
|
+
}], context: [{
|
|
19495
|
+
type: Input
|
|
19496
|
+
}], strictValidation: [{
|
|
19497
|
+
type: Input
|
|
19498
|
+
}], renderTitleInsideBody: [{
|
|
19499
|
+
type: Input
|
|
19500
|
+
}] } });
|
|
19501
|
+
|
|
16652
19502
|
class EmptyStateCardComponent {
|
|
16653
19503
|
icon = 'tab';
|
|
16654
19504
|
title = 'Sem configuração disponível';
|
|
@@ -16686,7 +19536,7 @@ class EmptyStateCardComponent {
|
|
|
16686
19536
|
</div>
|
|
16687
19537
|
</mat-card-content>
|
|
16688
19538
|
</mat-card>
|
|
16689
|
-
`, isInline: true, styles: [".empty-card{display:block;margin:12px;border-color:var(--md-sys-color-outline-variant);--empty-icon-color: var(--md-sys-color-on-surface-variant)}.empty-card.empty-inline{margin:8px 0}.content{display:flex;align-items:center;gap:12px}.icon{font-size:32px;width:32px;height:32px;color:var(--empty-icon-color)}.texts{display:grid;gap:4px}.title{margin:0;font-size:16px;font-weight:600;color:var(--md-sys-color-on-surface)}.desc{margin:0;color:var(--md-sys-color-on-surface-variant)}.actions{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap}.empty-card.tone-primary{--empty-icon-color: var(--md-sys-color-primary)}.empty-card.tone-secondary{--empty-icon-color: var(--md-sys-color-secondary)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$
|
|
19539
|
+
`, isInline: true, styles: [".empty-card{display:block;margin:12px;border-color:var(--md-sys-color-outline-variant);--empty-icon-color: var(--md-sys-color-on-surface-variant)}.empty-card.empty-inline{margin:8px 0}.content{display:flex;align-items:center;gap:12px}.icon{font-size:32px;width:32px;height:32px;color:var(--empty-icon-color)}.texts{display:grid;gap:4px}.title{margin:0;font-size:16px;font-weight:600;color:var(--md-sys-color-on-surface)}.desc{margin:0;color:var(--md-sys-color-on-surface-variant)}.actions{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap}.empty-card.tone-primary{--empty-icon-color: var(--md-sys-color-primary)}.empty-card.tone-secondary{--empty-icon-color: var(--md-sys-color-secondary)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i3$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3$1.MatCardContent, selector: "mat-card-content" }, { 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: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
|
|
16690
19540
|
}
|
|
16691
19541
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: EmptyStateCardComponent, decorators: [{
|
|
16692
19542
|
type: Component,
|
|
@@ -16791,7 +19641,7 @@ class ResourceQuickConnectComponent {
|
|
|
16791
19641
|
Rota normalizada: {{ normalizedPath() }}
|
|
16792
19642
|
</small>
|
|
16793
19643
|
</div>
|
|
16794
|
-
`, isInline: true, styles: [".pdx-quick-connect{display:grid;gap:12px;padding:12px;border-radius:12px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface);color:var(--md-sys-color-on-surface)}.pdx-quick-connect__hint{color:var(--md-sys-color-on-surface-variant);font-size:.9rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$
|
|
19644
|
+
`, isInline: true, styles: [".pdx-quick-connect{display:grid;gap:12px;padding:12px;border-radius:12px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface);color:var(--md-sys-color-on-surface)}.pdx-quick-connect__hint{color:var(--md-sys-color-on-surface-variant);font-size:.9rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.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: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }] });
|
|
16795
19645
|
}
|
|
16796
19646
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ResourceQuickConnectComponent, decorators: [{
|
|
16797
19647
|
type: Component,
|
|
@@ -16961,7 +19811,7 @@ class PraxisIconPickerComponent {
|
|
|
16961
19811
|
return { family: 'mss', name };
|
|
16962
19812
|
return { family: 'mi', name };
|
|
16963
19813
|
}
|
|
16964
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisIconPickerComponent, deps: [{ token: MAT_DIALOG_DATA, optional: true }, { token: i1$
|
|
19814
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisIconPickerComponent, deps: [{ token: MAT_DIALOG_DATA, optional: true }, { token: i1$3.MatDialogRef, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
16965
19815
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: PraxisIconPickerComponent, isStandalone: true, selector: "praxis-icon-picker", inputs: { value: "value", icons: "icons" }, outputs: { selected: "selected", cancel: "cancel" }, host: { listeners: { "document:keydown.escape": "onEsc($event)", "document:keydown": "onGlobalKey($event)" } }, viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true }], ngImport: i0, template: `
|
|
16966
19816
|
<div class="pip-root">
|
|
16967
19817
|
<div class="pip-head">
|
|
@@ -17019,7 +19869,7 @@ class PraxisIconPickerComponent {
|
|
|
17019
19869
|
<span class="pip-typed" *ngIf="query.trim()">{{ previewValue() }}</span>
|
|
17020
19870
|
</div>
|
|
17021
19871
|
</div>
|
|
17022
|
-
`, isInline: true, styles: [".pip-root{display:flex;flex-direction:column;min-width:340px;max-width:760px;max-height:80vh;overflow:hidden;padding:16px;color:var(--md-sys-color-on-surface)}.pip-head{display:flex;gap:12px;align-items:center;margin-bottom:12px;flex-wrap:wrap}.pip-search{flex:1;min-width:180px}.pip-spacer{flex:1}.pip-body{flex:1;overflow:auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:10px;padding:4px}.pip-item{display:flex;gap:10px;align-items:center;justify-content:flex-start;padding:10px;border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;background:var(--md-sys-color-surface);color:inherit;cursor:pointer;transition:background-color .18s ease,border-color .18s ease,box-shadow .18s ease}.pip-item:hover{background:var(--md-sys-color-surface-container)}.pip-item:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pip-item.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.pip-name{font-size:12px;color:var(--md-sys-color-on-surface-variant);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.pip-hint{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin:-6px 0 8px}.pip-stats{display:flex;justify-content:space-between;gap:8px;font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-bottom:8px}.pip-shortcut{opacity:.9}.pip-empty{padding:12px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:10px;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container);margin-top:8px}.pip-footer{display:flex;gap:12px;align-items:center;margin-top:10px}.pip-typed{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:12px;color:var(--md-sys-color-on-surface)}.pip-family{display:flex;align-items:center}.pip-family .mat-mdc-chip-listbox{min-width:260px}.pip-root .mat-icon{font-family:Material Icons,Material Symbols Outlined,Material Symbols Rounded,Material Symbols Sharp!important;font-variation-settings:\"FILL\" 0,\"wght\" 400,\"GRAD\" 0,\"opsz\" 24;color:currentColor}.material-symbols-outlined{font-family:Material Symbols Outlined;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:\"liga\";-webkit-font-smoothing:antialiased;font-variation-settings:\"FILL\" 0,\"wght\" 400,\"GRAD\" 0,\"opsz\" 24}.material-symbols-rounded{font-family:Material Symbols Rounded;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:\"liga\";-webkit-font-smoothing:antialiased;font-variation-settings:\"FILL\" 0,\"wght\" 400,\"GRAD\" 0,\"opsz\" 24}.material-symbols-sharp{font-family:Material Symbols Sharp;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:\"liga\";-webkit-font-smoothing:antialiased;font-variation-settings:\"FILL\" 0,\"wght\" 400,\"GRAD\" 0,\"opsz\" 24}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$
|
|
19872
|
+
`, isInline: true, styles: [".pip-root{display:flex;flex-direction:column;min-width:340px;max-width:760px;max-height:80vh;overflow:hidden;padding:16px;color:var(--md-sys-color-on-surface)}.pip-head{display:flex;gap:12px;align-items:center;margin-bottom:12px;flex-wrap:wrap}.pip-search{flex:1;min-width:180px}.pip-spacer{flex:1}.pip-body{flex:1;overflow:auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:10px;padding:4px}.pip-item{display:flex;gap:10px;align-items:center;justify-content:flex-start;padding:10px;border:1px solid var(--md-sys-color-outline-variant);border-radius:10px;background:var(--md-sys-color-surface);color:inherit;cursor:pointer;transition:background-color .18s ease,border-color .18s ease,box-shadow .18s ease}.pip-item:hover{background:var(--md-sys-color-surface-container)}.pip-item:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pip-item.selected{border-color:var(--md-sys-color-primary);box-shadow:0 0 0 2px var(--md-sys-color-primary)}.pip-name{font-size:12px;color:var(--md-sys-color-on-surface-variant);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.pip-hint{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin:-6px 0 8px}.pip-stats{display:flex;justify-content:space-between;gap:8px;font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-bottom:8px}.pip-shortcut{opacity:.9}.pip-empty{padding:12px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:10px;color:var(--md-sys-color-on-surface-variant);background:var(--md-sys-color-surface-container);margin-top:8px}.pip-footer{display:flex;gap:12px;align-items:center;margin-top:10px}.pip-typed{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:12px;color:var(--md-sys-color-on-surface)}.pip-family{display:flex;align-items:center}.pip-family .mat-mdc-chip-listbox{min-width:260px}.pip-root .mat-icon{font-family:Material Icons,Material Symbols Outlined,Material Symbols Rounded,Material Symbols Sharp!important;font-variation-settings:\"FILL\" 0,\"wght\" 400,\"GRAD\" 0,\"opsz\" 24;color:currentColor}.material-symbols-outlined{font-family:Material Symbols Outlined;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:\"liga\";-webkit-font-smoothing:antialiased;font-variation-settings:\"FILL\" 0,\"wght\" 400,\"GRAD\" 0,\"opsz\" 24}.material-symbols-rounded{font-family:Material Symbols Rounded;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:\"liga\";-webkit-font-smoothing:antialiased;font-variation-settings:\"FILL\" 0,\"wght\" 400,\"GRAD\" 0,\"opsz\" 24}.material-symbols-sharp{font-family:Material Symbols Sharp;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-feature-settings:\"liga\";-webkit-font-smoothing:antialiased;font-variation-settings:\"FILL\" 0,\"wght\" 400,\"GRAD\" 0,\"opsz\" 24}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.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: MatIconModule }, { kind: "component", type: i4.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: "ngmodule", type: MatChipsModule }, { kind: "component", type: i8.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "component", type: i8.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
17023
19873
|
}
|
|
17024
19874
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisIconPickerComponent, decorators: [{
|
|
17025
19875
|
type: Component,
|
|
@@ -17086,7 +19936,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
17086
19936
|
}, {
|
|
17087
19937
|
type: Inject,
|
|
17088
19938
|
args: [MAT_DIALOG_DATA]
|
|
17089
|
-
}] }, { type: i1$
|
|
19939
|
+
}] }, { type: i1$3.MatDialogRef, decorators: [{
|
|
17090
19940
|
type: Optional
|
|
17091
19941
|
}] }], propDecorators: { value: [{
|
|
17092
19942
|
type: Input
|
|
@@ -17363,7 +20213,7 @@ class SchemaViewerComponent {
|
|
|
17363
20213
|
</mat-tab-group>
|
|
17364
20214
|
</mat-card-content>
|
|
17365
20215
|
</mat-card>
|
|
17366
|
-
`, isInline: true, styles: [".schema-viewer{display:block;border-color:var(--md-sys-color-outline-variant)}.header{display:flex;align-items:center;justify-content:space-between;gap:8px}.title{display:flex;align-items:center;gap:8px}.title h3{margin:0;font-weight:600;color:var(--md-sys-color-on-surface)}.notes{margin-top:6px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.copy-status{margin-top:6px;font-size:12px;color:var(--md-sys-color-primary)}.section{padding:12px}.section-actions{display:flex;justify-content:flex-end;margin-bottom:8px}.sub{font-weight:600;margin:12px 0 4px;color:var(--md-sys-color-on-surface)}.pretty{background:var(--md-sys-color-surface-container);padding:10px;border-radius:8px;overflow:auto;border:1px solid var(--md-sys-color-outline-variant)}.kv{display:grid;grid-template-columns:140px 1fr;align-items:baseline;gap:8px;margin:2px 0}.kv>span{color:var(--md-sys-color-on-surface-variant)}.kv>code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.muted{color:var(--md-sys-color-on-surface-variant)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$
|
|
20216
|
+
`, isInline: true, styles: [".schema-viewer{display:block;border-color:var(--md-sys-color-outline-variant)}.header{display:flex;align-items:center;justify-content:space-between;gap:8px}.title{display:flex;align-items:center;gap:8px}.title h3{margin:0;font-weight:600;color:var(--md-sys-color-on-surface)}.notes{margin-top:6px;color:var(--md-sys-color-on-surface-variant);font-size:12px}.copy-status{margin-top:6px;font-size:12px;color:var(--md-sys-color-primary)}.section{padding:12px}.section-actions{display:flex;justify-content:flex-end;margin-bottom:8px}.sub{font-weight:600;margin:12px 0 4px;color:var(--md-sys-color-on-surface)}.pretty{background:var(--md-sys-color-surface-container);padding:10px;border-radius:8px;overflow:auto;border:1px solid var(--md-sys-color-outline-variant)}.kv{display:grid;grid-template-columns:140px 1fr;align-items:baseline;gap:8px;margin:2px 0}.kv>span{color:var(--md-sys-color-on-surface-variant)}.kv>code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.muted{color:var(--md-sys-color-on-surface-variant)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i2$1.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2$1.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i3$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3$1.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i3$1.MatCardHeader, selector: "mat-card-header" }, { 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: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: i1$2.JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
17367
20217
|
}
|
|
17368
20218
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SchemaViewerComponent, decorators: [{
|
|
17369
20219
|
type: Component,
|
|
@@ -18129,5 +20979,5 @@ function provideHookWhitelist(allowed) {
|
|
|
18129
20979
|
* Generated bundle index. Do not edit.
|
|
18130
20980
|
*/
|
|
18131
20981
|
|
|
18132
|
-
export { API_CONFIG_STORAGE_OPTIONS, API_URL, ASYNC_CONFIG_STORAGE, AllowedFileTypes, ApiConfigStorage, ApiEndpoint, BUILTIN_SHELL_PRESETS, CONFIG_STORAGE, CONNECTION_STORAGE, ComponentKeyService, ComponentMetadataRegistry, ConnectionManagerService, ConsoleLoggerSink, DEFAULT_FIELD_SELECTOR_CONTROL_TYPE_MAP, DEFAULT_TABLE_CONFIG, DYNAMIC_PAGE_AI_CAPABILITIES, DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK, DYNAMIC_PAGE_CONFIG_EDITOR, DYNAMIC_PAGE_SHELL_EDITOR, DefaultLoadingRenderer, DeferredAsyncConfigStorage, DynamicFormService, DynamicGridPageComponent, DynamicWidgetLoaderDirective, DynamicWidgetPageComponent, EDITORIAL_ALLOWED_CONTENT_FORMATS, EDITORIAL_COMPLIANCE_PRESETS, EDITORIAL_EXTERNAL_LINK_REL, EDITORIAL_FORM_TEMPLATE_CATALOG, EDITORIAL_HTML_ENABLED, EDITORIAL_MARKDOWN_IMAGES_ENABLED, EDITORIAL_SOLUTION_CATALOG, EDITORIAL_SOLUTION_PRESETS, EDITORIAL_THEME_PRESETS, EDITORIAL_WIDGET_CONVENTION_INPUTS, EDITORIAL_WIDGET_TAG, EMPLOYEE_ONBOARDING_EDITORIAL_SOLUTION, EMPLOYEE_ONBOARDING_EDITORIAL_TEMPLATE, EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_SOLUTION, EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_TEMPLATE, EVENT_REGISTRATION_EDITORIAL_SOLUTION, EVENT_REGISTRATION_EDITORIAL_TEMPLATE, EmptyStateCardComponent, ErrorMessageService, FIELD_METADATA_CAPABILITIES, FIELD_SELECTOR_REGISTRY_BASE, FIELD_SELECTOR_REGISTRY_DISABLE_DEFAULTS, FIELD_SELECTOR_REGISTRY_OVERRIDES, FORM_HOOKS, FORM_HOOKS_PRESETS, FORM_HOOKS_WHITELIST, FORM_HOOK_RESOLVERS, FieldControlType, FieldDataType, FieldSelectorRegistry, FormHooksRegistry, GLOBAL_ACTION_CATALOG$1 as GLOBAL_ACTION_CATALOG, GLOBAL_ACTION_HANDLERS, GLOBAL_ACTION_CATALOG as GLOBAL_ACTION_SPEC_CATALOG, GLOBAL_ACTION_UI_SCHEMAS, GLOBAL_ANALYTICS_SERVICE, GLOBAL_API_CLIENT, GLOBAL_CONFIG, GLOBAL_DIALOG_SERVICE, GLOBAL_ROUTE_GUARD_RESOLVER, GLOBAL_TOAST_SERVICE, GenericCrudService, GlobalActionService, GlobalConfigService, INLINE_FILTER_ALIAS_TOKENS, INLINE_FILTER_CONTROL_TYPES, INLINE_FILTER_CONTROL_TYPE_SET, INLINE_FILTER_CONTROL_TYPE_VALUES, INLINE_FILTER_TOKEN_TO_BASE_CONTROL_TYPE, INLINE_FILTER_TOKEN_TO_CONTROL_TYPE, IconPickerService, IconPosition, IconSize, LOGGER_LEVEL_BY_ENV, LOGGER_LEVEL_PRIORITY, LoadingOrchestrator, LocalConnectionStorage, LocalStorageAsyncAdapter, LocalStorageCacheAdapter, LocalStorageConfigService, LoggerService, LoggerThrottleTracker, LoggerWarnOnceTracker, MemoryCacheAdapter, NumericFormat, OVERLAY_DECIDER_DEBUG, OVERLAY_DECISION_MATRIX, ObservabilityDashboardService, OverlayDeciderService, PRAXIS_CORPORATE_SENSITIVE_KEYS, PRAXIS_DEFAULT_OBSERVABILITY_ALERT_RULES, PRAXIS_DYNAMIC_PAGE_COMPONENT_METADATA, PRAXIS_FOOTER_LINKS_METADATA, PRAXIS_GLOBAL_ACTION_CATALOG, PRAXIS_GLOBAL_CONFIG_BOOTSTRAP_OPTIONS, PRAXIS_GLOBAL_CONFIG_BOOTSTRAP_READY, PRAXIS_GLOBAL_CONFIG_TENANT_RESOLVER, PRAXIS_HERO_BANNER_METADATA, PRAXIS_I18N_CONFIG, PRAXIS_I18N_TRANSLATOR, PRAXIS_LEGAL_NOTICE_METADATA, PRAXIS_LOADING_CTX, PRAXIS_LOADING_RENDERER, PRAXIS_LOGGER_CONFIG, PRAXIS_LOGGER_SINKS, PRAXIS_OBSERVABILITY_DASHBOARD_OPTIONS, PRAXIS_RICH_TEXT_BLOCK_METADATA, PRAXIS_TELEMETRY_TRANSPORT, PRAXIS_USER_CONTEXT_SUMMARY_METADATA, PRIVACY_CONSENT_EDITORIAL_SOLUTION, PRIVACY_CONSENT_EDITORIAL_TEMPLATE, PraxisCore, PraxisFooterLinksComponent, PraxisGlobalErrorHandler, PraxisHeroBannerComponent, PraxisI18nService, PraxisIconDirective, PraxisIconPickerComponent, PraxisLegalNoticeComponent, PraxisLoadingInterceptor, PraxisRichTextBlockComponent, PraxisUserContextSummaryComponent, RULE_PROPERTY_SCHEMA, RemoteConfigStorage, ResourceQuickConnectComponent, SCHEMA_VIEWER_CONTEXT, SETTINGS_PANEL_BRIDGE, SETTINGS_PANEL_DATA, STEPPER_CONFIG_EDITOR, SchemaMetadataClient, SchemaNormalizerService, SchemaViewerComponent, TABLE_CONFIG_EDITOR, TableConfigService, TelemetryLoggerSink, TelemetryService, ValidationPattern, WidgetPageStateRuntimeService, WidgetShellComponent, applyLocalCustomizations$2 as applyLocalCustomizations, applyLocalCustomizations$1 as applyLocalFormCustomizations, buildAngularValidators, buildApiUrl, buildBaseColumnFromDef, buildBaseFormField, buildFormConfigFromEditorialTemplate, buildHeaders, buildPageKey, buildSchemaId, buildValidatorsFromValidatorOptions, cancelIfCpfInvalidHook, clampRange, cloneTableConfig, cnpjAlphaValidator, collapseWhitespace, composeHeadersWithVersion, conditionalAsyncValidator, convertFormLayoutToConfig, createCorporateLoggerConfig, createCorporateObservabilityOptions, createCpfCnpjValidator, createDefaultFormConfig, createDefaultTableConfig, createEmptyFormConfig, createPersistedPage, customAsyncValidatorFn, customValidatorFn, debounceAsyncValidator, deepMerge, ensureIds, ensureNoConflictsHookFactory, ensurePageIds, extractNormalizedError, fetchWithETag, fileTypeValidator, fillUndefined, generateId, getDefaultFormHints, getEditorialCompliancePresetById, getEditorialFormTemplateById, getEditorialFormTemplateCatalog, getEditorialSolutionById, getEditorialSolutionCatalog, getEditorialSolutionPresetById, getEditorialThemePresetById, getEssentialConfig, getFieldMetadataCapabilities, getGlobalActionCatalog, getGlobalActionUiSchema, getReferencedFieldMetadata, getTextTransformer, interpolatePraxisTranslation, isAllowedEditorialContentFormat, isAllowedEditorialHref, isCssTextTransform, isEditorialComponentMeta, isInlineFilterControlType, isRangeValidForFilter, isTableConfigV2, isValidFormConfig, isValidTableConfig, legacyCnpjValidator, legacyCpfValidator, logOnErrorHook, mapFieldDefinitionToMetadata, mapFieldDefinitionsToMetadata, matchFieldValidator, maxFileSizeValidator, mergeFieldMetadata, mergePraxisI18nConfigs, mergeTableConfigs, migrateFormLayoutRule, minWordsValidator, normalizeControlTypeKey, normalizeControlTypeToken, normalizeEditorialLink, normalizeEnd, normalizeFieldConstraints, normalizeFormConfig, normalizeFormMetadata, normalizePath, normalizeStart, normalizeUnknownError, notifySuccessHook, parseJsonResponseOrEmpty, praxisLoadingInterceptorFn, prefillFromContextHook, provideDefaultFormHooks, provideFieldSelectorRegistryBase, provideFieldSelectorRegistryOverride, provideFieldSelectorRegistryRuntime, provideFormHookPresets, provideFormHooks, provideGlobalActionCatalog, provideGlobalActionHandler, provideGlobalConfig, provideGlobalConfigReady, provideGlobalConfigSeed, provideGlobalConfigTenant, provideHookResolvers, provideHookWhitelist, provideOverlayDecisionMatrix, providePraxisAnalyticsGlobalActions, providePraxisDynamicPageMetadata, providePraxisFooterLinksMetadata, providePraxisGlobalActionCatalog, providePraxisGlobalActions, providePraxisGlobalConfigBootstrap, providePraxisHeroBannerMetadata, providePraxisHttpLoading, providePraxisI18n, providePraxisI18nConfig, providePraxisI18nTranslator, providePraxisLegalNoticeMetadata, providePraxisLoadingDefaults, providePraxisLogging, providePraxisRichTextBlockMetadata, providePraxisToastGlobalActions, providePraxisUserContextSummaryMetadata, provideRemoteGlobalConfig, reconcileFilterConfig, reconcileFormConfig, reconcileTableConfig, removeDiacritics, reportTelemetryHookFactory, requiredCheckedValidator, resolveBuiltinPresets, resolveControlTypeAlias, resolveHidden, resolveInlineFilterControlType, resolveInlineFilterControlTypeToBaseControlType, resolveLoggerConfig, resolveObservabilityOptions, resolveOffset, resolveOrder, resolveSpan, slugify, stripMasksHook, syncWithServerMetadata, toCamel, toCapitalize, toKebab, toPascal, toSentenceCase, toSnake, toTitleCase, trim, uniqueAsyncValidator, urlValidator, withMessage, withPraxisHttpLoading };
|
|
20982
|
+
export { API_CONFIG_STORAGE_OPTIONS, API_URL, ASYNC_CONFIG_STORAGE, AllowedFileTypes, ApiConfigStorage, ApiEndpoint, BUILTIN_PAGE_LAYOUT_PRESETS, BUILTIN_PAGE_THEME_PRESETS, BUILTIN_SHELL_PRESETS, CONFIG_STORAGE, CONNECTION_STORAGE, ComponentKeyService, ComponentMetadataRegistry, ConnectionManagerService, ConsoleLoggerSink, DEFAULT_FIELD_SELECTOR_CONTROL_TYPE_MAP, DEFAULT_TABLE_CONFIG, DYNAMIC_PAGE_AI_CAPABILITIES, DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK, DYNAMIC_PAGE_CONFIG_EDITOR, DYNAMIC_PAGE_SHELL_EDITOR, DefaultLoadingRenderer, DeferredAsyncConfigStorage, DynamicFormService, DynamicGridPageComponent, DynamicWidgetLoaderDirective, DynamicWidgetPageComponent, EDITORIAL_ALLOWED_CONTENT_FORMATS, EDITORIAL_COMPLIANCE_PRESETS, EDITORIAL_EXTERNAL_LINK_REL, EDITORIAL_FORM_TEMPLATE_CATALOG, EDITORIAL_HTML_ENABLED, EDITORIAL_MARKDOWN_IMAGES_ENABLED, EDITORIAL_SOLUTION_CATALOG, EDITORIAL_SOLUTION_PRESETS, EDITORIAL_THEME_PRESETS, EDITORIAL_WIDGET_CONVENTION_INPUTS, EDITORIAL_WIDGET_TAG, EMPLOYEE_ONBOARDING_EDITORIAL_SOLUTION, EMPLOYEE_ONBOARDING_EDITORIAL_TEMPLATE, EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_SOLUTION, EMPLOYEE_ONBOARDING_GUIDED_EDITORIAL_TEMPLATE, EVENT_REGISTRATION_EDITORIAL_SOLUTION, EVENT_REGISTRATION_EDITORIAL_TEMPLATE, EmptyStateCardComponent, ErrorMessageService, FIELD_METADATA_CAPABILITIES, FIELD_SELECTOR_REGISTRY_BASE, FIELD_SELECTOR_REGISTRY_DISABLE_DEFAULTS, FIELD_SELECTOR_REGISTRY_OVERRIDES, FORM_HOOKS, FORM_HOOKS_PRESETS, FORM_HOOKS_WHITELIST, FORM_HOOK_RESOLVERS, FieldControlType, FieldDataType, FieldSelectorRegistry, FormHooksRegistry, GLOBAL_ACTION_CATALOG$1 as GLOBAL_ACTION_CATALOG, GLOBAL_ACTION_HANDLERS, GLOBAL_ACTION_CATALOG as GLOBAL_ACTION_SPEC_CATALOG, GLOBAL_ACTION_UI_SCHEMAS, GLOBAL_ANALYTICS_SERVICE, GLOBAL_API_CLIENT, GLOBAL_CONFIG, GLOBAL_DIALOG_SERVICE, GLOBAL_ROUTE_GUARD_RESOLVER, GLOBAL_SURFACE_SERVICE, GLOBAL_TOAST_SERVICE, GenericCrudService, GlobalActionService, GlobalConfigService, INLINE_FILTER_ALIAS_TOKENS, INLINE_FILTER_CONTROL_TYPES, INLINE_FILTER_CONTROL_TYPE_SET, INLINE_FILTER_CONTROL_TYPE_VALUES, INLINE_FILTER_TOKEN_TO_BASE_CONTROL_TYPE, INLINE_FILTER_TOKEN_TO_CONTROL_TYPE, IconPickerService, IconPosition, IconSize, LOGGER_LEVEL_BY_ENV, LOGGER_LEVEL_PRIORITY, LoadingOrchestrator, LocalConnectionStorage, LocalStorageAsyncAdapter, LocalStorageCacheAdapter, LocalStorageConfigService, LoggerService, LoggerThrottleTracker, LoggerWarnOnceTracker, MemoryCacheAdapter, NumericFormat, OVERLAY_DECIDER_DEBUG, OVERLAY_DECISION_MATRIX, ObservabilityDashboardService, OverlayDeciderService, PRAXIS_CORPORATE_SENSITIVE_KEYS, PRAXIS_DEFAULT_OBSERVABILITY_ALERT_RULES, PRAXIS_DYNAMIC_PAGE_COMPONENT_METADATA, PRAXIS_FOOTER_LINKS_METADATA, PRAXIS_GLOBAL_ACTION_CATALOG, PRAXIS_GLOBAL_CONFIG_BOOTSTRAP_OPTIONS, PRAXIS_GLOBAL_CONFIG_BOOTSTRAP_READY, PRAXIS_GLOBAL_CONFIG_TENANT_RESOLVER, PRAXIS_HERO_BANNER_METADATA, PRAXIS_I18N_CONFIG, PRAXIS_I18N_TRANSLATOR, PRAXIS_LEGAL_NOTICE_METADATA, PRAXIS_LOADING_CTX, PRAXIS_LOADING_RENDERER, PRAXIS_LOGGER_CONFIG, PRAXIS_LOGGER_SINKS, PRAXIS_OBSERVABILITY_DASHBOARD_OPTIONS, PRAXIS_RICH_TEXT_BLOCK_METADATA, PRAXIS_TELEMETRY_TRANSPORT, PRAXIS_USER_CONTEXT_SUMMARY_METADATA, PRIVACY_CONSENT_EDITORIAL_SOLUTION, PRIVACY_CONSENT_EDITORIAL_TEMPLATE, PraxisCore, PraxisFooterLinksComponent, PraxisGlobalErrorHandler, PraxisHeroBannerComponent, PraxisI18nService, PraxisIconDirective, PraxisIconPickerComponent, PraxisLegalNoticeComponent, PraxisLoadingInterceptor, PraxisRichTextBlockComponent, PraxisSurfaceHostComponent, PraxisUserContextSummaryComponent, RULE_PROPERTY_SCHEMA, RemoteConfigStorage, ResourceQuickConnectComponent, SCHEMA_VIEWER_CONTEXT, SETTINGS_PANEL_BRIDGE, SETTINGS_PANEL_DATA, STEPPER_CONFIG_EDITOR, SURFACE_OPEN_I18N_CONFIG, SURFACE_OPEN_I18N_NAMESPACE, SURFACE_OPEN_PRESETS, SchemaMetadataClient, SchemaNormalizerService, SchemaViewerComponent, SurfaceBindingRuntimeService, SurfaceOpenActionEditorComponent, TABLE_CONFIG_EDITOR, TableConfigService, TelemetryLoggerSink, TelemetryService, ValidationPattern, WidgetPageStateRuntimeService, WidgetShellComponent, applyLocalCustomizations$2 as applyLocalCustomizations, applyLocalCustomizations$1 as applyLocalFormCustomizations, buildAngularValidators, buildApiUrl, buildBaseColumnFromDef, buildBaseFormField, buildFormConfigFromEditorialTemplate, buildHeaders, buildPageKey, buildSchemaId, buildValidatorsFromValidatorOptions, cancelIfCpfInvalidHook, clampRange, cloneTableConfig, cnpjAlphaValidator, collapseWhitespace, composeHeadersWithVersion, conditionalAsyncValidator, convertFormLayoutToConfig, createCorporateLoggerConfig, createCorporateObservabilityOptions, createCpfCnpjValidator, createDefaultFormConfig, createDefaultTableConfig, createEmptyFormConfig, createPersistedPage, customAsyncValidatorFn, customValidatorFn, debounceAsyncValidator, deepMerge, ensureIds, ensureNoConflictsHookFactory, ensurePageIds, extractNormalizedError, fetchWithETag, fileTypeValidator, fillUndefined, generateId, getDefaultFormHints, getEditorialCompliancePresetById, getEditorialFormTemplateById, getEditorialFormTemplateCatalog, getEditorialSolutionById, getEditorialSolutionCatalog, getEditorialSolutionPresetById, getEditorialThemePresetById, getEssentialConfig, getFieldMetadataCapabilities, getGlobalActionCatalog, getGlobalActionUiSchema, getReferencedFieldMetadata, getTextTransformer, interpolatePraxisTranslation, isAllowedEditorialContentFormat, isAllowedEditorialHref, isCssTextTransform, isEditorialComponentMeta, isInlineFilterControlType, isRangeValidForFilter, isTableConfigV2, isValidFormConfig, isValidTableConfig, legacyCnpjValidator, legacyCpfValidator, logOnErrorHook, mapFieldDefinitionToMetadata, mapFieldDefinitionsToMetadata, matchFieldValidator, maxFileSizeValidator, mergeFieldMetadata, mergePraxisI18nConfigs, mergeTableConfigs, migrateFormLayoutRule, minWordsValidator, normalizeControlTypeKey, normalizeControlTypeToken, normalizeEditorialLink, normalizeEnd, normalizeFieldConstraints, normalizeFormConfig, normalizeFormMetadata, normalizePath, normalizePraxisDataQueryContext, normalizeStart, normalizeUnknownError, notifySuccessHook, parseJsonResponseOrEmpty, praxisLoadingInterceptorFn, prefillFromContextHook, provideDefaultFormHooks, provideFieldSelectorRegistryBase, provideFieldSelectorRegistryOverride, provideFieldSelectorRegistryRuntime, provideFormHookPresets, provideFormHooks, provideGlobalActionCatalog, provideGlobalActionHandler, provideGlobalConfig, provideGlobalConfigReady, provideGlobalConfigSeed, provideGlobalConfigTenant, provideHookResolvers, provideHookWhitelist, provideOverlayDecisionMatrix, providePraxisAnalyticsGlobalActions, providePraxisDynamicPageMetadata, providePraxisFooterLinksMetadata, providePraxisGlobalActionCatalog, providePraxisGlobalActions, providePraxisGlobalConfigBootstrap, providePraxisHeroBannerMetadata, providePraxisHttpLoading, providePraxisI18n, providePraxisI18nConfig, providePraxisI18nTranslator, providePraxisLegalNoticeMetadata, providePraxisLoadingDefaults, providePraxisLogging, providePraxisRichTextBlockMetadata, providePraxisToastGlobalActions, providePraxisUserContextSummaryMetadata, provideRemoteGlobalConfig, reconcileFilterConfig, reconcileFormConfig, reconcileTableConfig, removeDiacritics, reportTelemetryHookFactory, requiredCheckedValidator, resolveBuiltinPresets, resolveControlTypeAlias, resolveDefaultValuePresentationFormat, resolveHidden, resolveInlineFilterControlType, resolveInlineFilterControlTypeToBaseControlType, resolveLoggerConfig, resolveObservabilityOptions, resolveOffset, resolveOrder, resolvePraxisFilterCriteria, resolveSpan, resolveValuePresentation, resolveValuePresentationLocale, slugify, stripMasksHook, supportsImplicitValuePresentation, syncWithServerMetadata, toCamel, toCapitalize, toKebab, toPascal, toSentenceCase, toSnake, toTitleCase, trim, uniqueAsyncValidator, urlValidator, withMessage, withPraxisHttpLoading };
|
|
18133
20983
|
//# sourceMappingURL=praxisui-core.mjs.map
|