@praxisui/core 3.0.0-beta.9 → 4.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -1
- package/fesm2022/praxisui-core.mjs +2586 -1175
- package/index.d.ts +511 -99
- package/package.json +1 -1
|
@@ -5,7 +5,7 @@ import { HttpHeaders, HttpClient, HttpParams, HttpResponse, HttpContextToken, HT
|
|
|
5
5
|
import { of, defer, throwError, from, EMPTY, BehaviorSubject, firstValueFrom, Subject, map as map$1 } from 'rxjs';
|
|
6
6
|
import { switchMap, take, map, catchError, concatMap, tap, shareReplay, takeUntil, toArray, finalize } from 'rxjs/operators';
|
|
7
7
|
import * as i1$2 from '@angular/common';
|
|
8
|
-
import { Location, CommonModule } from '@angular/common';
|
|
8
|
+
import { Location, DOCUMENT, CommonModule } from '@angular/common';
|
|
9
9
|
import { Router, ActivatedRoute } from '@angular/router';
|
|
10
10
|
import * as i1$1 from '@angular/forms';
|
|
11
11
|
import { Validators, FormGroup, FormControl, FormsModule } from '@angular/forms';
|
|
@@ -14,9 +14,9 @@ import * as i2 from '@angular/material/button';
|
|
|
14
14
|
import { MatButtonModule } from '@angular/material/button';
|
|
15
15
|
import * as i3 from '@angular/material/form-field';
|
|
16
16
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
17
|
-
import * as
|
|
17
|
+
import * as i3$1 from '@angular/material/icon';
|
|
18
18
|
import { MatIconModule } from '@angular/material/icon';
|
|
19
|
-
import * as i5
|
|
19
|
+
import * as i5 from '@angular/material/input';
|
|
20
20
|
import { MatInputModule } from '@angular/material/input';
|
|
21
21
|
import * as i6 from '@angular/material/select';
|
|
22
22
|
import { MatSelectModule } from '@angular/material/select';
|
|
@@ -27,7 +27,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
|
|
|
27
27
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
28
28
|
import * as i4 from '@angular/material/menu';
|
|
29
29
|
import { MatMenuModule } from '@angular/material/menu';
|
|
30
|
-
import * as i3$
|
|
30
|
+
import * as i3$2 from '@angular/material/card';
|
|
31
31
|
import { MatCardModule } from '@angular/material/card';
|
|
32
32
|
import * as i8$1 from '@angular/material/chips';
|
|
33
33
|
import { MatChipsModule } from '@angular/material/chips';
|
|
@@ -1822,9 +1822,9 @@ function isObject(value) {
|
|
|
1822
1822
|
*/
|
|
1823
1823
|
function deepMerge(left, right) {
|
|
1824
1824
|
if (right === undefined || right === null)
|
|
1825
|
-
return clone(left);
|
|
1825
|
+
return clone$1(left);
|
|
1826
1826
|
if (Array.isArray(left)) {
|
|
1827
|
-
return (Array.isArray(right) ? right : clone(left));
|
|
1827
|
+
return (Array.isArray(right) ? right : clone$1(left));
|
|
1828
1828
|
}
|
|
1829
1829
|
if (!isObject(left) || !isObject(right)) {
|
|
1830
1830
|
// Right wins when defined, else left
|
|
@@ -1837,13 +1837,13 @@ function deepMerge(left, right) {
|
|
|
1837
1837
|
if (r === undefined)
|
|
1838
1838
|
continue; // keep left as-is
|
|
1839
1839
|
if (Array.isArray(r)) {
|
|
1840
|
-
out[key] = r.map((v) => clone(v));
|
|
1840
|
+
out[key] = r.map((v) => clone$1(v));
|
|
1841
1841
|
}
|
|
1842
1842
|
else if (isObject(r) && isObject(l)) {
|
|
1843
1843
|
out[key] = deepMerge(l, r);
|
|
1844
1844
|
}
|
|
1845
1845
|
else {
|
|
1846
|
-
out[key] = clone(r);
|
|
1846
|
+
out[key] = clone$1(r);
|
|
1847
1847
|
}
|
|
1848
1848
|
}
|
|
1849
1849
|
return out;
|
|
@@ -1855,7 +1855,7 @@ function deepMerge(left, right) {
|
|
|
1855
1855
|
*/
|
|
1856
1856
|
function fillUndefined(target, defaults) {
|
|
1857
1857
|
if (defaults === undefined || defaults === null)
|
|
1858
|
-
return clone(target);
|
|
1858
|
+
return clone$1(target);
|
|
1859
1859
|
if (!isObject(target) || !isObject(defaults)) {
|
|
1860
1860
|
return (target === undefined || target === null ? defaults : target);
|
|
1861
1861
|
}
|
|
@@ -1864,7 +1864,7 @@ function fillUndefined(target, defaults) {
|
|
|
1864
1864
|
const d = defaults[key];
|
|
1865
1865
|
const t = target[key];
|
|
1866
1866
|
if (t === undefined || t === null) {
|
|
1867
|
-
out[key] = clone(d);
|
|
1867
|
+
out[key] = clone$1(d);
|
|
1868
1868
|
}
|
|
1869
1869
|
else if (isObject(t) && isObject(d)) {
|
|
1870
1870
|
out[key] = fillUndefined(t, d);
|
|
@@ -1875,7 +1875,7 @@ function fillUndefined(target, defaults) {
|
|
|
1875
1875
|
}
|
|
1876
1876
|
return out;
|
|
1877
1877
|
}
|
|
1878
|
-
function clone(v) {
|
|
1878
|
+
function clone$1(v) {
|
|
1879
1879
|
if (v == null || typeof v !== 'object')
|
|
1880
1880
|
return v;
|
|
1881
1881
|
try {
|
|
@@ -2183,12 +2183,15 @@ class GenericCrudService {
|
|
|
2183
2183
|
get errorMessages() {
|
|
2184
2184
|
return GenericCrudService.ERROR_MESSAGES;
|
|
2185
2185
|
}
|
|
2186
|
-
configure(resourcePath,
|
|
2186
|
+
configure(resourcePath, endpointKeyOrOptions) {
|
|
2187
2187
|
if (!resourcePath || !resourcePath.trim()) {
|
|
2188
2188
|
throw new Error(this.errorMessages.emptyResourcePath);
|
|
2189
2189
|
}
|
|
2190
|
-
const
|
|
2191
|
-
|
|
2190
|
+
const configureOptions = typeof endpointKeyOrOptions === 'object' && endpointKeyOrOptions !== null
|
|
2191
|
+
? endpointKeyOrOptions
|
|
2192
|
+
: { endpointKey: endpointKeyOrOptions };
|
|
2193
|
+
const nextEndpointKey = configureOptions.endpointKey ?? this.currentEndpointKey;
|
|
2194
|
+
const entry = configureOptions.apiUrlEntry ?? this.resolveEndpointEntry(nextEndpointKey);
|
|
2192
2195
|
const nextBaseApiUrl = buildApiUrl(entry);
|
|
2193
2196
|
const base = nextBaseApiUrl.replace(/\/+$/, '');
|
|
2194
2197
|
let resource = resourcePath.trim();
|
|
@@ -2963,6 +2966,16 @@ class GenericCrudService {
|
|
|
2963
2966
|
})));
|
|
2964
2967
|
}
|
|
2965
2968
|
filter(filterCriteria, pageable, opts) {
|
|
2969
|
+
const response$ = opts
|
|
2970
|
+
? this.filterResponse(filterCriteria, pageable, opts)
|
|
2971
|
+
: this.filterResponse(filterCriteria, pageable);
|
|
2972
|
+
return response$.pipe(map((resp) => {
|
|
2973
|
+
const body = this.unwrapPageResponse(resp?.data);
|
|
2974
|
+
const version = resp?.dataVersion;
|
|
2975
|
+
return version ? { ...body, dataVersion: version } : body;
|
|
2976
|
+
}));
|
|
2977
|
+
}
|
|
2978
|
+
filterResponse(filterCriteria, pageable, opts) {
|
|
2966
2979
|
let params = new HttpParams()
|
|
2967
2980
|
.set('page', pageable.pageNumber)
|
|
2968
2981
|
.set('size', pageable.pageSize);
|
|
@@ -2987,12 +3000,13 @@ class GenericCrudService {
|
|
|
2987
3000
|
headers: composeHeadersWithVersion(entry),
|
|
2988
3001
|
context: opts?.httpContext,
|
|
2989
3002
|
});
|
|
2990
|
-
return observeVersion
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
3003
|
+
return observeVersion
|
|
3004
|
+
? req$.pipe(map((resp) => {
|
|
3005
|
+
const body = this.normalizeRestApiResponse(resp.body);
|
|
3006
|
+
const version = resp.headers.get('X-Data-Version') || undefined;
|
|
3007
|
+
return version ? { ...body, dataVersion: version } : body;
|
|
3008
|
+
}), catchError(this.handleError))
|
|
3009
|
+
: req$.pipe(map((raw) => this.normalizeRestApiResponse(raw)), catchError(this.handleError));
|
|
2996
3010
|
}
|
|
2997
3011
|
/** GET /by-ids */
|
|
2998
3012
|
getByIds(ids, options) {
|
|
@@ -3693,6 +3707,12 @@ class GenericCrudService {
|
|
|
3693
3707
|
}
|
|
3694
3708
|
return raw;
|
|
3695
3709
|
}
|
|
3710
|
+
normalizeRestApiResponse(raw) {
|
|
3711
|
+
if (raw && typeof raw === 'object' && 'data' in raw) {
|
|
3712
|
+
return raw;
|
|
3713
|
+
}
|
|
3714
|
+
return { data: raw };
|
|
3715
|
+
}
|
|
3696
3716
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: GenericCrudService, deps: [{ token: i1.HttpClient }, { token: SchemaNormalizerService }, { token: GlobalConfigService }, { token: API_URL }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3697
3717
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: GenericCrudService, providedIn: null });
|
|
3698
3718
|
}
|
|
@@ -7012,7 +7032,7 @@ class DefaultLoadingRenderer {
|
|
|
7012
7032
|
.pfx-loading-root {
|
|
7013
7033
|
position: fixed;
|
|
7014
7034
|
inset: 0;
|
|
7015
|
-
z-index:
|
|
7035
|
+
z-index: var(--praxis-layer-loading-blocking, 2000);
|
|
7016
7036
|
pointer-events: none;
|
|
7017
7037
|
}
|
|
7018
7038
|
.pfx-loading-entry {
|
|
@@ -7090,260 +7110,1293 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
7090
7110
|
type: Injectable
|
|
7091
7111
|
}] });
|
|
7092
7112
|
|
|
7093
|
-
|
|
7094
|
-
|
|
7095
|
-
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
|
|
7102
|
-
|
|
7103
|
-
|
|
7104
|
-
|
|
7105
|
-
|
|
7106
|
-
|
|
7107
|
-
|
|
7108
|
-
|
|
7109
|
-
|
|
7110
|
-
|
|
7111
|
-
|
|
7112
|
-
|
|
7113
|
-
|
|
7114
|
-
|
|
7115
|
-
|
|
7116
|
-
|
|
7117
|
-
|
|
7118
|
-
|
|
7119
|
-
|
|
7120
|
-
|
|
7121
|
-
|
|
7122
|
-
|
|
7123
|
-
|
|
7124
|
-
|
|
7125
|
-
|
|
7126
|
-
|
|
7127
|
-
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
|
|
7131
|
-
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
|
|
7135
|
-
|
|
7136
|
-
|
|
7137
|
-
|
|
7113
|
+
const PRAXIS_LAYER_SCALE_DEFAULTS = {
|
|
7114
|
+
stickyLocal: 100,
|
|
7115
|
+
floatingLocal: 200,
|
|
7116
|
+
authoringInsert: 280,
|
|
7117
|
+
authoringHover: 300,
|
|
7118
|
+
authoringSelected: 320,
|
|
7119
|
+
authoringToolbar: 340,
|
|
7120
|
+
cdkOverlayContainer: 1200,
|
|
7121
|
+
cdkOverlayBackdrop: 1200,
|
|
7122
|
+
cdkOverlayWrapper: 1210,
|
|
7123
|
+
settingsPanel: 1220,
|
|
7124
|
+
widgetShellBackdrop: 1280,
|
|
7125
|
+
widgetShellExpanded: 1290,
|
|
7126
|
+
widgetShellFullscreen: 1291,
|
|
7127
|
+
dialog: 1300,
|
|
7128
|
+
popup: 1400,
|
|
7129
|
+
loadingBlocking: 2000,
|
|
7130
|
+
};
|
|
7131
|
+
const PRAXIS_LAYER_SCALE_VARS = {
|
|
7132
|
+
stickyLocal: '--praxis-layer-sticky-local',
|
|
7133
|
+
floatingLocal: '--praxis-layer-floating-local',
|
|
7134
|
+
authoringInsert: '--praxis-layer-authoring-insert',
|
|
7135
|
+
authoringHover: '--praxis-layer-authoring-hover',
|
|
7136
|
+
authoringSelected: '--praxis-layer-authoring-selected',
|
|
7137
|
+
authoringToolbar: '--praxis-layer-authoring-toolbar',
|
|
7138
|
+
cdkOverlayContainer: '--praxis-layer-cdk-overlay-container',
|
|
7139
|
+
cdkOverlayBackdrop: '--praxis-layer-cdk-overlay-backdrop',
|
|
7140
|
+
cdkOverlayWrapper: '--praxis-layer-cdk-overlay-wrapper',
|
|
7141
|
+
settingsPanel: '--praxis-layer-settings-panel',
|
|
7142
|
+
widgetShellBackdrop: '--praxis-layer-widget-shell-backdrop',
|
|
7143
|
+
widgetShellExpanded: '--praxis-layer-widget-shell-expanded',
|
|
7144
|
+
widgetShellFullscreen: '--praxis-layer-widget-shell-fullscreen',
|
|
7145
|
+
dialog: '--praxis-layer-dialog',
|
|
7146
|
+
popup: '--praxis-layer-popup',
|
|
7147
|
+
loadingBlocking: '--praxis-layer-loading-blocking',
|
|
7148
|
+
};
|
|
7149
|
+
function buildPraxisLayerScaleCss(scale = PRAXIS_LAYER_SCALE_DEFAULTS) {
|
|
7150
|
+
return `
|
|
7151
|
+
:root {
|
|
7152
|
+
${PRAXIS_LAYER_SCALE_VARS.stickyLocal}: ${scale.stickyLocal};
|
|
7153
|
+
${PRAXIS_LAYER_SCALE_VARS.floatingLocal}: ${scale.floatingLocal};
|
|
7154
|
+
${PRAXIS_LAYER_SCALE_VARS.authoringInsert}: ${scale.authoringInsert};
|
|
7155
|
+
${PRAXIS_LAYER_SCALE_VARS.authoringHover}: ${scale.authoringHover};
|
|
7156
|
+
${PRAXIS_LAYER_SCALE_VARS.authoringSelected}: ${scale.authoringSelected};
|
|
7157
|
+
${PRAXIS_LAYER_SCALE_VARS.authoringToolbar}: ${scale.authoringToolbar};
|
|
7158
|
+
${PRAXIS_LAYER_SCALE_VARS.cdkOverlayContainer}: ${scale.cdkOverlayContainer};
|
|
7159
|
+
${PRAXIS_LAYER_SCALE_VARS.cdkOverlayBackdrop}: ${scale.cdkOverlayBackdrop};
|
|
7160
|
+
${PRAXIS_LAYER_SCALE_VARS.cdkOverlayWrapper}: ${scale.cdkOverlayWrapper};
|
|
7161
|
+
${PRAXIS_LAYER_SCALE_VARS.settingsPanel}: ${scale.settingsPanel};
|
|
7162
|
+
${PRAXIS_LAYER_SCALE_VARS.widgetShellBackdrop}: ${scale.widgetShellBackdrop};
|
|
7163
|
+
${PRAXIS_LAYER_SCALE_VARS.widgetShellExpanded}: ${scale.widgetShellExpanded};
|
|
7164
|
+
${PRAXIS_LAYER_SCALE_VARS.widgetShellFullscreen}: ${scale.widgetShellFullscreen};
|
|
7165
|
+
${PRAXIS_LAYER_SCALE_VARS.dialog}: ${scale.dialog};
|
|
7166
|
+
${PRAXIS_LAYER_SCALE_VARS.popup}: ${scale.popup};
|
|
7167
|
+
${PRAXIS_LAYER_SCALE_VARS.loadingBlocking}: ${scale.loadingBlocking};
|
|
7138
7168
|
}
|
|
7139
7169
|
|
|
7140
|
-
|
|
7141
|
-
|
|
7142
|
-
provide: GLOBAL_ANALYTICS_SERVICE,
|
|
7143
|
-
useFactory: () => {
|
|
7144
|
-
const telemetry = (() => { try {
|
|
7145
|
-
return inject(TelemetryService);
|
|
7146
|
-
}
|
|
7147
|
-
catch {
|
|
7148
|
-
return null;
|
|
7149
|
-
} })();
|
|
7150
|
-
const prefix = opts.prefix ? `${opts.prefix}.` : '';
|
|
7151
|
-
return {
|
|
7152
|
-
track: (eventName, payload) => {
|
|
7153
|
-
if (telemetry) {
|
|
7154
|
-
telemetry.record(`${prefix}${eventName}`, payload);
|
|
7155
|
-
}
|
|
7156
|
-
else {
|
|
7157
|
-
console.log('[Analytics]', `${prefix}${eventName}`, payload ?? null);
|
|
7158
|
-
}
|
|
7159
|
-
},
|
|
7160
|
-
};
|
|
7161
|
-
},
|
|
7162
|
-
};
|
|
7170
|
+
.cdk-overlay-container {
|
|
7171
|
+
z-index: var(${PRAXIS_LAYER_SCALE_VARS.cdkOverlayContainer}, ${scale.cdkOverlayContainer}) !important;
|
|
7163
7172
|
}
|
|
7164
7173
|
|
|
7165
|
-
|
|
7166
|
-
|
|
7167
|
-
*
|
|
7168
|
-
* This does not wire any HTTP interceptor by itself. Use this when the host
|
|
7169
|
-
* wants a custom HTTP integration path but still wants the stock Praxis UI.
|
|
7170
|
-
*/
|
|
7171
|
-
function providePraxisLoadingDefaults() {
|
|
7172
|
-
return [
|
|
7173
|
-
{
|
|
7174
|
-
provide: PRAXIS_LOADING_RENDERER,
|
|
7175
|
-
useClass: DefaultLoadingRenderer,
|
|
7176
|
-
},
|
|
7177
|
-
];
|
|
7178
|
-
}
|
|
7179
|
-
/**
|
|
7180
|
-
* Official DI-based entrypoint to enable Praxis HTTP loading.
|
|
7181
|
-
*
|
|
7182
|
-
* Recommended when the host already uses DI interceptors, e.g.:
|
|
7183
|
-
*
|
|
7184
|
-
* ```ts
|
|
7185
|
-
* providers: [
|
|
7186
|
-
* provideHttpClient(withInterceptorsFromDi()),
|
|
7187
|
-
* ...providePraxisHttpLoading(),
|
|
7188
|
-
* ]
|
|
7189
|
-
* ```
|
|
7190
|
-
*
|
|
7191
|
-
* By default this provider does not register any renderer implementation.
|
|
7192
|
-
* Add `...providePraxisLoadingDefaults()` or a custom `PRAXIS_LOADING_RENDERER`
|
|
7193
|
-
* explicitly so hosts keep full control over visual composition.
|
|
7194
|
-
*
|
|
7195
|
-
* Requests remain opt-in and only show loading when they carry
|
|
7196
|
-
* `PRAXIS_LOADING_CTX` in the `HttpContext`.
|
|
7197
|
-
*/
|
|
7198
|
-
function providePraxisHttpLoading(opts = {}) {
|
|
7199
|
-
const providers = [
|
|
7200
|
-
{
|
|
7201
|
-
provide: HTTP_INTERCEPTORS,
|
|
7202
|
-
useClass: PraxisLoadingInterceptor,
|
|
7203
|
-
multi: true,
|
|
7204
|
-
},
|
|
7205
|
-
];
|
|
7206
|
-
if (opts.includeDefaultRenderer === true) {
|
|
7207
|
-
providers.unshift(...providePraxisLoadingDefaults());
|
|
7208
|
-
}
|
|
7209
|
-
return providers;
|
|
7210
|
-
}
|
|
7211
|
-
/**
|
|
7212
|
-
* Angular modern helper for `provideHttpClient(...)`.
|
|
7213
|
-
*
|
|
7214
|
-
* Usage:
|
|
7215
|
-
*
|
|
7216
|
-
* ```ts
|
|
7217
|
-
* providers: [
|
|
7218
|
-
* provideHttpClient(
|
|
7219
|
-
* withInterceptors([authInterceptor]),
|
|
7220
|
-
* withPraxisHttpLoading(),
|
|
7221
|
-
* ),
|
|
7222
|
-
* ...providePraxisLoadingDefaults(),
|
|
7223
|
-
* ]
|
|
7224
|
-
* ```
|
|
7225
|
-
*
|
|
7226
|
-
* Use this helper or `providePraxisHttpLoading()`, never both in the same host.
|
|
7227
|
-
*/
|
|
7228
|
-
function withPraxisHttpLoading() {
|
|
7229
|
-
return withInterceptors([praxisLoadingInterceptorFn]);
|
|
7174
|
+
.cdk-overlay-backdrop {
|
|
7175
|
+
z-index: var(${PRAXIS_LAYER_SCALE_VARS.cdkOverlayBackdrop}, ${scale.cdkOverlayBackdrop}) !important;
|
|
7230
7176
|
}
|
|
7231
7177
|
|
|
7232
|
-
|
|
7233
|
-
|
|
7234
|
-
warn: 1,
|
|
7235
|
-
info: 2,
|
|
7236
|
-
debug: 3,
|
|
7237
|
-
trace: 4,
|
|
7238
|
-
};
|
|
7239
|
-
const LOGGER_LEVEL_BY_ENV = {
|
|
7240
|
-
prod: 'warn',
|
|
7241
|
-
qa: 'warn',
|
|
7242
|
-
hml: 'info',
|
|
7243
|
-
dev: 'debug',
|
|
7244
|
-
};
|
|
7245
|
-
const PRAXIS_CORPORATE_SENSITIVE_KEYS = [
|
|
7246
|
-
'password',
|
|
7247
|
-
'pass',
|
|
7248
|
-
'token',
|
|
7249
|
-
'accessToken',
|
|
7250
|
-
'refreshToken',
|
|
7251
|
-
'authorization',
|
|
7252
|
-
'secret',
|
|
7253
|
-
'apiKey',
|
|
7254
|
-
'cpf',
|
|
7255
|
-
'cnpj',
|
|
7256
|
-
'document',
|
|
7257
|
-
'ssn',
|
|
7258
|
-
'email',
|
|
7259
|
-
'phone',
|
|
7260
|
-
];
|
|
7261
|
-
const PRAXIS_CORPORATE_THROTTLE = {
|
|
7262
|
-
enabled: true,
|
|
7263
|
-
windowMs: 5000,
|
|
7264
|
-
maxOccurrences: 3,
|
|
7265
|
-
};
|
|
7266
|
-
function createCorporateLoggerConfig(environment = 'prod') {
|
|
7267
|
-
return {
|
|
7268
|
-
environment,
|
|
7269
|
-
minLevel: LOGGER_LEVEL_BY_ENV[environment],
|
|
7270
|
-
warnOnceEnabled: true,
|
|
7271
|
-
throttle: { ...PRAXIS_CORPORATE_THROTTLE },
|
|
7272
|
-
pii: {
|
|
7273
|
-
enabled: true,
|
|
7274
|
-
redactionText: '[REDACTED]',
|
|
7275
|
-
sensitiveKeys: [...PRAXIS_CORPORATE_SENSITIVE_KEYS],
|
|
7276
|
-
},
|
|
7277
|
-
};
|
|
7178
|
+
.cdk-global-overlay-wrapper {
|
|
7179
|
+
z-index: var(${PRAXIS_LAYER_SCALE_VARS.cdkOverlayWrapper}, ${scale.cdkOverlayWrapper}) !important;
|
|
7278
7180
|
}
|
|
7279
|
-
|
|
7280
|
-
const environment = options.environment ?? 'prod';
|
|
7281
|
-
const corporate = createCorporateLoggerConfig(environment);
|
|
7282
|
-
const overridePII = options.pii ?? {};
|
|
7283
|
-
return {
|
|
7284
|
-
...corporate,
|
|
7285
|
-
minLevel: options.minLevel ?? corporate.minLevel,
|
|
7286
|
-
warnOnceEnabled: options.warnOnceEnabled ?? corporate.warnOnceEnabled,
|
|
7287
|
-
throttle: {
|
|
7288
|
-
...corporate.throttle,
|
|
7289
|
-
...(options.throttle ?? {}),
|
|
7290
|
-
},
|
|
7291
|
-
pii: {
|
|
7292
|
-
...corporate.pii,
|
|
7293
|
-
...overridePII,
|
|
7294
|
-
sensitiveKeys: overridePII.sensitiveKeys
|
|
7295
|
-
? [...overridePII.sensitiveKeys]
|
|
7296
|
-
: [...corporate.pii.sensitiveKeys],
|
|
7297
|
-
},
|
|
7298
|
-
defaultContext: options.defaultContext
|
|
7299
|
-
? { ...options.defaultContext }
|
|
7300
|
-
: corporate.defaultContext,
|
|
7301
|
-
environment,
|
|
7302
|
-
};
|
|
7181
|
+
`;
|
|
7303
7182
|
}
|
|
7304
7183
|
|
|
7305
|
-
class
|
|
7306
|
-
|
|
7307
|
-
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
environment: event.environment,
|
|
7311
|
-
timestamp: event.timestamp,
|
|
7312
|
-
context: event.context ?? null,
|
|
7313
|
-
data: event.data ?? null,
|
|
7314
|
-
};
|
|
7315
|
-
if (event.context || event.data !== undefined) {
|
|
7316
|
-
print(`${prefix} ${event.message}`, envelope);
|
|
7317
|
-
return;
|
|
7318
|
-
}
|
|
7319
|
-
print(`${prefix} ${event.message}`);
|
|
7184
|
+
class PraxisLayerScaleStyleService {
|
|
7185
|
+
doc = inject(DOCUMENT);
|
|
7186
|
+
styleId = 'praxis-layer-scale';
|
|
7187
|
+
constructor() {
|
|
7188
|
+
this.ensureInstalled();
|
|
7320
7189
|
}
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
if (level === 'warn' && typeof console.warn === 'function') {
|
|
7326
|
-
return console.warn.bind(console);
|
|
7327
|
-
}
|
|
7328
|
-
if (level === 'info' && typeof console.info === 'function') {
|
|
7329
|
-
return console.info.bind(console);
|
|
7330
|
-
}
|
|
7331
|
-
if (level === 'debug' && typeof console.debug === 'function') {
|
|
7332
|
-
return console.debug.bind(console);
|
|
7190
|
+
ensureInstalled() {
|
|
7191
|
+
const doc = this.doc;
|
|
7192
|
+
if (!doc?.head) {
|
|
7193
|
+
return;
|
|
7333
7194
|
}
|
|
7334
|
-
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
|
|
7338
|
-
|
|
7339
|
-
return console.debug.bind(console);
|
|
7195
|
+
const css = buildPraxisLayerScaleCss();
|
|
7196
|
+
const existing = doc.getElementById(this.styleId);
|
|
7197
|
+
if (existing) {
|
|
7198
|
+
if (existing.textContent !== css) {
|
|
7199
|
+
existing.textContent = css;
|
|
7340
7200
|
}
|
|
7201
|
+
return;
|
|
7341
7202
|
}
|
|
7342
|
-
|
|
7203
|
+
const style = doc.createElement('style');
|
|
7204
|
+
style.id = this.styleId;
|
|
7205
|
+
style.textContent = css;
|
|
7206
|
+
doc.head.appendChild(style);
|
|
7343
7207
|
}
|
|
7208
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisLayerScaleStyleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
7209
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisLayerScaleStyleService, providedIn: 'root' });
|
|
7344
7210
|
}
|
|
7211
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisLayerScaleStyleService, decorators: [{
|
|
7212
|
+
type: Injectable,
|
|
7213
|
+
args: [{ providedIn: 'root' }]
|
|
7214
|
+
}], ctorParameters: () => [] });
|
|
7345
7215
|
|
|
7346
|
-
|
|
7216
|
+
class ResourceDiscoveryService {
|
|
7217
|
+
http = inject(HttpClient);
|
|
7218
|
+
schemaNormalizer = inject(SchemaNormalizerService);
|
|
7219
|
+
apiUrlConfig = inject(API_URL);
|
|
7220
|
+
getLinks(source, rel) {
|
|
7221
|
+
const candidate = this.extractLinks(source)?.[rel];
|
|
7222
|
+
if (!candidate) {
|
|
7223
|
+
return [];
|
|
7224
|
+
}
|
|
7225
|
+
return Array.isArray(candidate) ? candidate.filter(Boolean) : [candidate];
|
|
7226
|
+
}
|
|
7227
|
+
getLink(source, rel) {
|
|
7228
|
+
return this.getLinks(source, rel)[0] ?? null;
|
|
7229
|
+
}
|
|
7230
|
+
hasLink(source, rel) {
|
|
7231
|
+
return this.getLinks(source, rel).length > 0;
|
|
7232
|
+
}
|
|
7233
|
+
resolveLinkHref(source, rel, options) {
|
|
7234
|
+
const link = this.getLink(source, rel);
|
|
7235
|
+
return link?.href ? this.resolveHref(link.href, options) : null;
|
|
7236
|
+
}
|
|
7237
|
+
followLink(source, rel, options) {
|
|
7238
|
+
return this.fetchJson(this.requireLinkHref(source, rel, options), options);
|
|
7239
|
+
}
|
|
7240
|
+
getSurfaces(source, options) {
|
|
7241
|
+
return this.followLink(source, 'surfaces', options);
|
|
7242
|
+
}
|
|
7243
|
+
getActions(source, options) {
|
|
7244
|
+
return this.followLink(source, 'actions', options);
|
|
7245
|
+
}
|
|
7246
|
+
getCapabilities(source, options) {
|
|
7247
|
+
return this.followLink(source, 'capabilities', options);
|
|
7248
|
+
}
|
|
7249
|
+
fetchJson(href, options) {
|
|
7250
|
+
return this.http.get(this.resolveHref(href, options));
|
|
7251
|
+
}
|
|
7252
|
+
getSchemaByUrl(schemaUrl, options) {
|
|
7253
|
+
return this.fetchJson(schemaUrl, options);
|
|
7254
|
+
}
|
|
7255
|
+
getSchemaFieldsByUrl(schemaUrl, options) {
|
|
7256
|
+
return this.getSchemaByUrl(schemaUrl, options).pipe(map$1((schema) => this.schemaNormalizer.normalizeSchema(schema)));
|
|
7257
|
+
}
|
|
7258
|
+
resolveHref(href, options) {
|
|
7259
|
+
const normalizedHref = String(href || '').trim();
|
|
7260
|
+
if (!normalizedHref) {
|
|
7261
|
+
throw new Error('ResourceDiscoveryService cannot resolve an empty href.');
|
|
7262
|
+
}
|
|
7263
|
+
if (/^https?:\/\//i.test(normalizedHref)) {
|
|
7264
|
+
return normalizedHref;
|
|
7265
|
+
}
|
|
7266
|
+
const apiBaseUrl = this.resolveApiBaseHref(options);
|
|
7267
|
+
if (!apiBaseUrl) {
|
|
7268
|
+
return normalizedHref;
|
|
7269
|
+
}
|
|
7270
|
+
if (normalizedHref.startsWith('/')) {
|
|
7271
|
+
const apiOrigin = this.resolveApiOrigin(options);
|
|
7272
|
+
return apiOrigin
|
|
7273
|
+
? new URL(normalizedHref, `${apiOrigin}/`).toString()
|
|
7274
|
+
: normalizedHref;
|
|
7275
|
+
}
|
|
7276
|
+
return new URL(normalizedHref, this.ensureTrailingSlash(apiBaseUrl)).toString();
|
|
7277
|
+
}
|
|
7278
|
+
requireLinkHref(source, rel, options) {
|
|
7279
|
+
const href = this.resolveLinkHref(source, rel, options);
|
|
7280
|
+
if (!href) {
|
|
7281
|
+
throw new Error(`ResourceDiscoveryService could not resolve rel "${rel}".`);
|
|
7282
|
+
}
|
|
7283
|
+
return href;
|
|
7284
|
+
}
|
|
7285
|
+
extractLinks(source) {
|
|
7286
|
+
if (!source) {
|
|
7287
|
+
return undefined;
|
|
7288
|
+
}
|
|
7289
|
+
if (this.isRestApiResponse(source)) {
|
|
7290
|
+
return source._links;
|
|
7291
|
+
}
|
|
7292
|
+
return source;
|
|
7293
|
+
}
|
|
7294
|
+
resolveApiEntry(options) {
|
|
7295
|
+
if (options?.apiUrlEntry) {
|
|
7296
|
+
return options.apiUrlEntry;
|
|
7297
|
+
}
|
|
7298
|
+
return this.resolveEndpointEntry(options?.endpointKey);
|
|
7299
|
+
}
|
|
7300
|
+
resolveApiOrigin(options) {
|
|
7301
|
+
const baseUrl = this.resolveApiBaseUrl(options);
|
|
7302
|
+
if (!baseUrl) {
|
|
7303
|
+
return '';
|
|
7304
|
+
}
|
|
7305
|
+
try {
|
|
7306
|
+
return new URL(baseUrl).origin.replace(/\/+$/, '');
|
|
7307
|
+
}
|
|
7308
|
+
catch {
|
|
7309
|
+
const runtimeOrigin = this.getRuntimeOrigin();
|
|
7310
|
+
return runtimeOrigin ? runtimeOrigin.replace(/\/+$/, '') : '';
|
|
7311
|
+
}
|
|
7312
|
+
}
|
|
7313
|
+
resolveApiBaseUrl(options) {
|
|
7314
|
+
const entry = this.resolveApiEntry(options);
|
|
7315
|
+
return String(buildApiUrl(entry) || '').trim();
|
|
7316
|
+
}
|
|
7317
|
+
resolveApiBaseHref(options) {
|
|
7318
|
+
const baseUrl = this.resolveApiBaseUrl(options);
|
|
7319
|
+
if (!baseUrl) {
|
|
7320
|
+
return '';
|
|
7321
|
+
}
|
|
7322
|
+
try {
|
|
7323
|
+
return new URL(baseUrl).toString();
|
|
7324
|
+
}
|
|
7325
|
+
catch {
|
|
7326
|
+
const runtimeOrigin = this.getRuntimeOrigin();
|
|
7327
|
+
return runtimeOrigin
|
|
7328
|
+
? new URL(baseUrl.replace(/^\/+/, ''), this.ensureTrailingSlash(runtimeOrigin)).toString()
|
|
7329
|
+
: '';
|
|
7330
|
+
}
|
|
7331
|
+
}
|
|
7332
|
+
resolveEndpointEntry(endpointKey) {
|
|
7333
|
+
const key = endpointKey ?? ApiEndpoint.Default;
|
|
7334
|
+
return this.apiUrlConfig[key] || this.apiUrlConfig.default || {};
|
|
7335
|
+
}
|
|
7336
|
+
getRuntimeOrigin() {
|
|
7337
|
+
try {
|
|
7338
|
+
const origin = globalThis?.location?.origin;
|
|
7339
|
+
return typeof origin === 'string' && origin.startsWith('http') ? origin : undefined;
|
|
7340
|
+
}
|
|
7341
|
+
catch {
|
|
7342
|
+
return undefined;
|
|
7343
|
+
}
|
|
7344
|
+
}
|
|
7345
|
+
ensureTrailingSlash(value) {
|
|
7346
|
+
return /\/$/.test(value) ? value : `${value}/`;
|
|
7347
|
+
}
|
|
7348
|
+
isRestApiResponse(source) {
|
|
7349
|
+
return 'data' in source;
|
|
7350
|
+
}
|
|
7351
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ResourceDiscoveryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
7352
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ResourceDiscoveryService, providedIn: 'any' });
|
|
7353
|
+
}
|
|
7354
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ResourceDiscoveryService, decorators: [{
|
|
7355
|
+
type: Injectable,
|
|
7356
|
+
args: [{ providedIn: 'any' }]
|
|
7357
|
+
}] });
|
|
7358
|
+
|
|
7359
|
+
const SURFACE_OPEN_PRESETS = [
|
|
7360
|
+
{
|
|
7361
|
+
id: 'praxis-dynamic-form',
|
|
7362
|
+
label: 'Formulário',
|
|
7363
|
+
description: 'Abre um formulário dinâmico com resourcePath, formId e resourceId.',
|
|
7364
|
+
payload: {
|
|
7365
|
+
presentation: 'drawer',
|
|
7366
|
+
widget: {
|
|
7367
|
+
id: 'praxis-dynamic-form',
|
|
7368
|
+
bindingOrder: ['resourcePath', 'formId', 'resourceId'],
|
|
7369
|
+
inputs: {
|
|
7370
|
+
resourcePath: '',
|
|
7371
|
+
formId: '',
|
|
7372
|
+
mode: 'view',
|
|
7373
|
+
},
|
|
7374
|
+
},
|
|
7375
|
+
bindings: [],
|
|
7376
|
+
},
|
|
7377
|
+
},
|
|
7378
|
+
{
|
|
7379
|
+
id: 'praxis-table',
|
|
7380
|
+
label: 'Tabela',
|
|
7381
|
+
description: 'Abre uma tabela filtrável usando inputs declarativos e queryContext.',
|
|
7382
|
+
payload: {
|
|
7383
|
+
presentation: 'drawer',
|
|
7384
|
+
widget: {
|
|
7385
|
+
id: 'praxis-table',
|
|
7386
|
+
bindingOrder: ['resourcePath', 'tableId', 'queryContext'],
|
|
7387
|
+
inputs: {
|
|
7388
|
+
resourcePath: '',
|
|
7389
|
+
tableId: '',
|
|
7390
|
+
queryContext: {
|
|
7391
|
+
filters: {},
|
|
7392
|
+
},
|
|
7393
|
+
},
|
|
7394
|
+
},
|
|
7395
|
+
bindings: [],
|
|
7396
|
+
},
|
|
7397
|
+
},
|
|
7398
|
+
{
|
|
7399
|
+
id: 'praxis-list',
|
|
7400
|
+
label: 'Lista',
|
|
7401
|
+
description: 'Abre uma lista com config/listId e bindings configuráveis.',
|
|
7402
|
+
payload: {
|
|
7403
|
+
presentation: 'drawer',
|
|
7404
|
+
widget: {
|
|
7405
|
+
id: 'praxis-list',
|
|
7406
|
+
bindingOrder: ['listId', 'config'],
|
|
7407
|
+
inputs: {
|
|
7408
|
+
listId: '',
|
|
7409
|
+
config: {},
|
|
7410
|
+
},
|
|
7411
|
+
},
|
|
7412
|
+
bindings: [],
|
|
7413
|
+
},
|
|
7414
|
+
},
|
|
7415
|
+
{
|
|
7416
|
+
id: 'praxis-crud',
|
|
7417
|
+
label: 'CRUD',
|
|
7418
|
+
description: 'Abre a surface de CRUD com inputs mínimos e bindings configuráveis.',
|
|
7419
|
+
payload: {
|
|
7420
|
+
presentation: 'drawer',
|
|
7421
|
+
widget: {
|
|
7422
|
+
id: 'praxis-crud',
|
|
7423
|
+
bindingOrder: ['resourcePath', 'formId', 'resourceId'],
|
|
7424
|
+
inputs: {
|
|
7425
|
+
resourcePath: '',
|
|
7426
|
+
formId: '',
|
|
7427
|
+
},
|
|
7428
|
+
},
|
|
7429
|
+
bindings: [],
|
|
7430
|
+
},
|
|
7431
|
+
},
|
|
7432
|
+
];
|
|
7433
|
+
|
|
7434
|
+
class ResourceActionOpenAdapterService {
|
|
7435
|
+
discovery = inject(ResourceDiscoveryService);
|
|
7436
|
+
toPayload(action, options) {
|
|
7437
|
+
const resourcePath = this.normalizeResourcePath(options.resourcePath);
|
|
7438
|
+
if (!resourcePath) {
|
|
7439
|
+
throw new Error('ResourceActionOpenAdapterService requires resourcePath.');
|
|
7440
|
+
}
|
|
7441
|
+
if (!action.requestSchemaUrl) {
|
|
7442
|
+
throw new Error(`ResourceActionOpenAdapterService requires requestSchemaUrl for action "${action.id}".`);
|
|
7443
|
+
}
|
|
7444
|
+
const discoveryOptions = options.endpointKey || options.apiUrlEntry
|
|
7445
|
+
? {
|
|
7446
|
+
...(options.endpointKey ? { endpointKey: options.endpointKey } : {}),
|
|
7447
|
+
...(options.apiUrlEntry ? { apiUrlEntry: options.apiUrlEntry } : {}),
|
|
7448
|
+
}
|
|
7449
|
+
: undefined;
|
|
7450
|
+
const resolvedRequestSchemaUrl = this.discovery.resolveHref(action.requestSchemaUrl, discoveryOptions);
|
|
7451
|
+
const resolvedResponseSchemaUrl = action.responseSchemaUrl
|
|
7452
|
+
? this.discovery.resolveHref(action.responseSchemaUrl, discoveryOptions)
|
|
7453
|
+
: null;
|
|
7454
|
+
const resolvedSubmitUrl = this.discovery.resolveHref(action.path, discoveryOptions);
|
|
7455
|
+
const payload = this.clone(this.resolveDynamicFormPreset());
|
|
7456
|
+
payload.presentation = options.presentation ?? payload.presentation;
|
|
7457
|
+
payload.title = options.title ?? action.title ?? payload.title;
|
|
7458
|
+
payload.subtitle = options.subtitle ?? action.description ?? payload.subtitle;
|
|
7459
|
+
payload.icon = options.icon ?? payload.icon;
|
|
7460
|
+
payload.context = {
|
|
7461
|
+
resource: {
|
|
7462
|
+
resourceKey: action.resourceKey,
|
|
7463
|
+
resourcePath,
|
|
7464
|
+
resourceId: options.resourceId ?? null,
|
|
7465
|
+
group: options.group ?? null,
|
|
7466
|
+
},
|
|
7467
|
+
action: {
|
|
7468
|
+
id: action.id,
|
|
7469
|
+
scope: action.scope,
|
|
7470
|
+
operationId: action.operationId,
|
|
7471
|
+
path: action.path,
|
|
7472
|
+
method: action.method,
|
|
7473
|
+
requestSchemaId: action.requestSchemaId ?? null,
|
|
7474
|
+
requestSchemaUrl: action.requestSchemaUrl,
|
|
7475
|
+
responseSchemaId: action.responseSchemaId ?? null,
|
|
7476
|
+
responseSchemaUrl: action.responseSchemaUrl ?? null,
|
|
7477
|
+
availability: action.availability,
|
|
7478
|
+
successMessage: action.successMessage ?? null,
|
|
7479
|
+
tags: action.tags,
|
|
7480
|
+
},
|
|
7481
|
+
};
|
|
7482
|
+
payload.widget.inputs = {
|
|
7483
|
+
...(payload.widget.inputs || {}),
|
|
7484
|
+
resourcePath,
|
|
7485
|
+
formId: this.buildStableInstanceId(action),
|
|
7486
|
+
mode: 'create',
|
|
7487
|
+
schemaUrl: resolvedRequestSchemaUrl,
|
|
7488
|
+
apiEndpointKey: options.endpointKey ?? null,
|
|
7489
|
+
apiUrlEntry: options.apiUrlEntry ?? (discoveryOptions ? this.discovery.resolveApiEntry(discoveryOptions) : null),
|
|
7490
|
+
submitMethod: String(action.method || '').trim().toLowerCase(),
|
|
7491
|
+
submitUrl: resolvedSubmitUrl,
|
|
7492
|
+
responseSchemaUrl: resolvedResponseSchemaUrl,
|
|
7493
|
+
};
|
|
7494
|
+
if (action.scope === 'ITEM') {
|
|
7495
|
+
if (options.resourceId != null) {
|
|
7496
|
+
payload.widget.inputs['resourceId'] = options.resourceId;
|
|
7497
|
+
}
|
|
7498
|
+
else if (options.idBindingPath) {
|
|
7499
|
+
payload.bindings = [
|
|
7500
|
+
...(payload.bindings || []),
|
|
7501
|
+
this.buildIdBinding(options.idBindingPath),
|
|
7502
|
+
];
|
|
7503
|
+
}
|
|
7504
|
+
else {
|
|
7505
|
+
throw new Error(`ResourceActionOpenAdapterService requires resourceId or idBindingPath for item action "${action.id}".`);
|
|
7506
|
+
}
|
|
7507
|
+
}
|
|
7508
|
+
return payload;
|
|
7509
|
+
}
|
|
7510
|
+
resolveDynamicFormPreset() {
|
|
7511
|
+
const preset = SURFACE_OPEN_PRESETS.find((candidate) => candidate.id === 'praxis-dynamic-form');
|
|
7512
|
+
if (!preset) {
|
|
7513
|
+
throw new Error('Missing canonical surface preset "praxis-dynamic-form".');
|
|
7514
|
+
}
|
|
7515
|
+
return preset.payload;
|
|
7516
|
+
}
|
|
7517
|
+
buildStableInstanceId(action) {
|
|
7518
|
+
return `${action.resourceKey}.action.${action.id}`.replace(/[^a-zA-Z0-9._-]+/g, '-');
|
|
7519
|
+
}
|
|
7520
|
+
normalizeResourcePath(resourcePath) {
|
|
7521
|
+
return String(resourcePath || '').trim().replace(/^\/+/, '').replace(/\/+$/, '');
|
|
7522
|
+
}
|
|
7523
|
+
buildIdBinding(idBindingPath) {
|
|
7524
|
+
return {
|
|
7525
|
+
from: idBindingPath,
|
|
7526
|
+
to: 'widget.inputs.resourceId',
|
|
7527
|
+
mode: 'path',
|
|
7528
|
+
};
|
|
7529
|
+
}
|
|
7530
|
+
clone(value) {
|
|
7531
|
+
return value == null ? value : JSON.parse(JSON.stringify(value));
|
|
7532
|
+
}
|
|
7533
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ResourceActionOpenAdapterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
7534
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ResourceActionOpenAdapterService, providedIn: 'any' });
|
|
7535
|
+
}
|
|
7536
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ResourceActionOpenAdapterService, decorators: [{
|
|
7537
|
+
type: Injectable,
|
|
7538
|
+
args: [{ providedIn: 'any' }]
|
|
7539
|
+
}] });
|
|
7540
|
+
|
|
7541
|
+
class ResourceSurfaceOpenAdapterService {
|
|
7542
|
+
discovery = inject(ResourceDiscoveryService);
|
|
7543
|
+
toPayload(surface, options) {
|
|
7544
|
+
const resourcePath = this.normalizeResourcePath(options.resourcePath);
|
|
7545
|
+
if (!resourcePath) {
|
|
7546
|
+
throw new Error('ResourceSurfaceOpenAdapterService requires resourcePath.');
|
|
7547
|
+
}
|
|
7548
|
+
const discoveryOptions = options.endpointKey || options.apiUrlEntry
|
|
7549
|
+
? {
|
|
7550
|
+
...(options.endpointKey ? { endpointKey: options.endpointKey } : {}),
|
|
7551
|
+
...(options.apiUrlEntry ? { apiUrlEntry: options.apiUrlEntry } : {}),
|
|
7552
|
+
}
|
|
7553
|
+
: undefined;
|
|
7554
|
+
const resolvedSchemaUrl = this.discovery.resolveHref(surface.schemaUrl, discoveryOptions);
|
|
7555
|
+
const resolvedSubmitUrl = this.isWritableFormSurface(surface.kind)
|
|
7556
|
+
? this.discovery.resolveHref(surface.path, discoveryOptions)
|
|
7557
|
+
: null;
|
|
7558
|
+
const basePayload = this.buildBasePayload(surface);
|
|
7559
|
+
const payload = {
|
|
7560
|
+
...basePayload,
|
|
7561
|
+
presentation: options.presentation ?? basePayload.presentation,
|
|
7562
|
+
title: options.title ?? surface.title ?? basePayload.title,
|
|
7563
|
+
subtitle: options.subtitle ?? surface.description ?? basePayload.subtitle,
|
|
7564
|
+
icon: options.icon ?? basePayload.icon,
|
|
7565
|
+
context: {
|
|
7566
|
+
resource: {
|
|
7567
|
+
resourceKey: surface.resourceKey,
|
|
7568
|
+
resourcePath,
|
|
7569
|
+
resourceId: options.resourceId ?? null,
|
|
7570
|
+
group: options.group ?? null,
|
|
7571
|
+
},
|
|
7572
|
+
surface: {
|
|
7573
|
+
id: surface.id,
|
|
7574
|
+
kind: surface.kind,
|
|
7575
|
+
scope: surface.scope,
|
|
7576
|
+
intent: surface.intent ?? null,
|
|
7577
|
+
operationId: surface.operationId,
|
|
7578
|
+
path: surface.path,
|
|
7579
|
+
method: surface.method,
|
|
7580
|
+
schemaId: surface.schemaId,
|
|
7581
|
+
schemaUrl: surface.schemaUrl,
|
|
7582
|
+
availability: surface.availability,
|
|
7583
|
+
tags: surface.tags,
|
|
7584
|
+
},
|
|
7585
|
+
},
|
|
7586
|
+
};
|
|
7587
|
+
if (basePayload.widget.id === 'praxis-table') {
|
|
7588
|
+
payload.widget.inputs = {
|
|
7589
|
+
...(payload.widget.inputs || {}),
|
|
7590
|
+
resourcePath,
|
|
7591
|
+
tableId: this.buildStableInstanceId(surface),
|
|
7592
|
+
queryContext: options.queryContext ?? payload.widget.inputs?.['queryContext'] ?? { filters: {} },
|
|
7593
|
+
};
|
|
7594
|
+
return payload;
|
|
7595
|
+
}
|
|
7596
|
+
const mode = this.resolveFormMode(surface.kind, surface.scope);
|
|
7597
|
+
payload.widget.inputs = {
|
|
7598
|
+
...(payload.widget.inputs || {}),
|
|
7599
|
+
resourcePath,
|
|
7600
|
+
formId: this.buildStableInstanceId(surface),
|
|
7601
|
+
mode,
|
|
7602
|
+
schemaUrl: resolvedSchemaUrl,
|
|
7603
|
+
apiEndpointKey: options.endpointKey ?? null,
|
|
7604
|
+
apiUrlEntry: options.apiUrlEntry ?? (discoveryOptions ? this.discovery.resolveApiEntry(discoveryOptions) : null),
|
|
7605
|
+
};
|
|
7606
|
+
if (this.isWritableFormSurface(surface.kind)) {
|
|
7607
|
+
payload.widget.inputs['submitMethod'] = surface.method.toLowerCase();
|
|
7608
|
+
payload.widget.inputs['submitUrl'] = resolvedSubmitUrl;
|
|
7609
|
+
}
|
|
7610
|
+
if (surface.scope === 'ITEM') {
|
|
7611
|
+
if (options.resourceId != null) {
|
|
7612
|
+
payload.widget.inputs['resourceId'] = options.resourceId;
|
|
7613
|
+
}
|
|
7614
|
+
else if (options.idBindingPath) {
|
|
7615
|
+
payload.bindings = [
|
|
7616
|
+
...(payload.bindings || []),
|
|
7617
|
+
this.buildIdBinding(options.idBindingPath),
|
|
7618
|
+
];
|
|
7619
|
+
}
|
|
7620
|
+
else {
|
|
7621
|
+
throw new Error(`ResourceSurfaceOpenAdapterService requires resourceId or idBindingPath for item surface "${surface.id}".`);
|
|
7622
|
+
}
|
|
7623
|
+
}
|
|
7624
|
+
return payload;
|
|
7625
|
+
}
|
|
7626
|
+
buildBasePayload(surface) {
|
|
7627
|
+
const presetId = surface.scope === 'COLLECTION' && this.isCollectionView(surface.kind)
|
|
7628
|
+
? 'praxis-table'
|
|
7629
|
+
: 'praxis-dynamic-form';
|
|
7630
|
+
const preset = SURFACE_OPEN_PRESETS.find((candidate) => candidate.id === presetId);
|
|
7631
|
+
if (!preset) {
|
|
7632
|
+
throw new Error(`Missing canonical surface preset "${presetId}".`);
|
|
7633
|
+
}
|
|
7634
|
+
return this.clone(preset.payload);
|
|
7635
|
+
}
|
|
7636
|
+
buildStableInstanceId(surface) {
|
|
7637
|
+
return `${surface.resourceKey}.${surface.id}`.replace(/[^a-zA-Z0-9._-]+/g, '-');
|
|
7638
|
+
}
|
|
7639
|
+
normalizeResourcePath(resourcePath) {
|
|
7640
|
+
return String(resourcePath || '').trim().replace(/^\/+/, '').replace(/\/+$/, '');
|
|
7641
|
+
}
|
|
7642
|
+
resolveFormMode(kind, scope) {
|
|
7643
|
+
if (kind === 'VIEW' || kind === 'READ_PROJECTION') {
|
|
7644
|
+
return 'view';
|
|
7645
|
+
}
|
|
7646
|
+
if (scope === 'ITEM') {
|
|
7647
|
+
return 'edit';
|
|
7648
|
+
}
|
|
7649
|
+
return 'create';
|
|
7650
|
+
}
|
|
7651
|
+
isCollectionView(kind) {
|
|
7652
|
+
return kind === 'VIEW' || kind === 'READ_PROJECTION';
|
|
7653
|
+
}
|
|
7654
|
+
isWritableFormSurface(kind) {
|
|
7655
|
+
return kind === 'FORM' || kind === 'PARTIAL_FORM';
|
|
7656
|
+
}
|
|
7657
|
+
buildIdBinding(idBindingPath) {
|
|
7658
|
+
return {
|
|
7659
|
+
from: idBindingPath,
|
|
7660
|
+
to: 'widget.inputs.resourceId',
|
|
7661
|
+
mode: 'path',
|
|
7662
|
+
};
|
|
7663
|
+
}
|
|
7664
|
+
clone(value) {
|
|
7665
|
+
return value == null ? value : JSON.parse(JSON.stringify(value));
|
|
7666
|
+
}
|
|
7667
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ResourceSurfaceOpenAdapterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
7668
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ResourceSurfaceOpenAdapterService, providedIn: 'any' });
|
|
7669
|
+
}
|
|
7670
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ResourceSurfaceOpenAdapterService, decorators: [{
|
|
7671
|
+
type: Injectable,
|
|
7672
|
+
args: [{ providedIn: 'any' }]
|
|
7673
|
+
}] });
|
|
7674
|
+
|
|
7675
|
+
const DEFAULT_FAMILIES = [
|
|
7676
|
+
'chart',
|
|
7677
|
+
'analytic-table',
|
|
7678
|
+
'kpi',
|
|
7679
|
+
'summary-list',
|
|
7680
|
+
];
|
|
7681
|
+
const ANALYTIC_TABLE_OPERATIONS = new Set(['group-by', 'timeseries', 'distribution']);
|
|
7682
|
+
class AnalyticsPresentationResolver {
|
|
7683
|
+
resolve(analytics, options) {
|
|
7684
|
+
const projections = analytics?.projections?.filter(Boolean) ?? [];
|
|
7685
|
+
if (!projections.length) {
|
|
7686
|
+
throw new Error('AnalyticsPresentationResolver requires at least one analytics projection.');
|
|
7687
|
+
}
|
|
7688
|
+
const availableFamilies = this.normalizeFamilies(options?.availableFamilies);
|
|
7689
|
+
const preferredDecision = this.tryResolvePreferredProjection(projections, availableFamilies, options?.preferFamily ?? null);
|
|
7690
|
+
if (preferredDecision) {
|
|
7691
|
+
return preferredDecision;
|
|
7692
|
+
}
|
|
7693
|
+
for (const projection of projections) {
|
|
7694
|
+
const inferredDecision = this.inferDecision(projection, availableFamilies);
|
|
7695
|
+
if (inferredDecision) {
|
|
7696
|
+
return inferredDecision;
|
|
7697
|
+
}
|
|
7698
|
+
}
|
|
7699
|
+
throw new Error('AnalyticsPresentationResolver could not resolve a semantic presentation family. Expose analytic-table or publish stronger semantic hints.');
|
|
7700
|
+
}
|
|
7701
|
+
tryResolvePreferredProjection(projections, availableFamilies, preferredFamily) {
|
|
7702
|
+
if (preferredFamily) {
|
|
7703
|
+
for (const projection of projections) {
|
|
7704
|
+
if (this.supportsFamily(projection, preferredFamily, availableFamilies)) {
|
|
7705
|
+
return {
|
|
7706
|
+
projectionId: projection.id,
|
|
7707
|
+
family: preferredFamily,
|
|
7708
|
+
reason: `Preferencia explicita do host pelo renderer "${preferredFamily}".`,
|
|
7709
|
+
};
|
|
7710
|
+
}
|
|
7711
|
+
}
|
|
7712
|
+
}
|
|
7713
|
+
for (const projection of projections) {
|
|
7714
|
+
const compatibleFamilies = this.getCompatiblePreferredFamilies(projection, availableFamilies);
|
|
7715
|
+
if (!compatibleFamilies.length) {
|
|
7716
|
+
continue;
|
|
7717
|
+
}
|
|
7718
|
+
return {
|
|
7719
|
+
projectionId: projection.id,
|
|
7720
|
+
family: compatibleFamilies[0],
|
|
7721
|
+
reason: `Projection "${projection.id}" publicou a familia preferencial "${compatibleFamilies[0]}".`,
|
|
7722
|
+
};
|
|
7723
|
+
}
|
|
7724
|
+
return null;
|
|
7725
|
+
}
|
|
7726
|
+
inferDecision(projection, availableFamilies) {
|
|
7727
|
+
if (this.supportsFamily(projection, 'chart', availableFamilies)) {
|
|
7728
|
+
return {
|
|
7729
|
+
projectionId: projection.id,
|
|
7730
|
+
family: 'chart',
|
|
7731
|
+
reason: this.buildInferenceReason(projection, 'chart'),
|
|
7732
|
+
};
|
|
7733
|
+
}
|
|
7734
|
+
if (this.supportsFamily(projection, 'analytic-table', availableFamilies)) {
|
|
7735
|
+
return {
|
|
7736
|
+
projectionId: projection.id,
|
|
7737
|
+
family: 'analytic-table',
|
|
7738
|
+
reason: this.buildInferenceReason(projection, 'analytic-table'),
|
|
7739
|
+
};
|
|
7740
|
+
}
|
|
7741
|
+
return null;
|
|
7742
|
+
}
|
|
7743
|
+
buildInferenceReason(projection, family) {
|
|
7744
|
+
if (family === 'chart') {
|
|
7745
|
+
return `Projection "${projection.id}" foi inferida como chart por combinar trend + timeseries + eixo temporal.`;
|
|
7746
|
+
}
|
|
7747
|
+
return `Projection "${projection.id}" foi resolvida como analytic-table por preservar a leitura semantica declarada sem forcar um chart ambiguo.`;
|
|
7748
|
+
}
|
|
7749
|
+
getCompatiblePreferredFamilies(projection, availableFamilies) {
|
|
7750
|
+
const preferredFamilies = projection.presentationHints?.preferredFamilies ?? [];
|
|
7751
|
+
return preferredFamilies.filter((family) => this.supportsFamily(projection, family, availableFamilies));
|
|
7752
|
+
}
|
|
7753
|
+
supportsFamily(projection, family, availableFamilies) {
|
|
7754
|
+
if (!availableFamilies.includes(family)) {
|
|
7755
|
+
return false;
|
|
7756
|
+
}
|
|
7757
|
+
if (family === 'chart') {
|
|
7758
|
+
return this.isChartInequivocal(projection) || this.hasExplicitPreferredFamily(projection, 'chart');
|
|
7759
|
+
}
|
|
7760
|
+
if (family === 'analytic-table') {
|
|
7761
|
+
return this.isAnalyticTableEligible(projection) || this.hasExplicitPreferredFamily(projection, 'analytic-table');
|
|
7762
|
+
}
|
|
7763
|
+
return this.hasExplicitPreferredFamily(projection, family);
|
|
7764
|
+
}
|
|
7765
|
+
isChartInequivocal(projection) {
|
|
7766
|
+
return (projection.intent === 'trend' &&
|
|
7767
|
+
projection.source.operation === 'timeseries' &&
|
|
7768
|
+
projection.bindings.primaryDimension?.role === 'time');
|
|
7769
|
+
}
|
|
7770
|
+
isAnalyticTableEligible(projection) {
|
|
7771
|
+
return (projection.bindings.primaryMetrics.length > 0 &&
|
|
7772
|
+
ANALYTIC_TABLE_OPERATIONS.has(projection.source.operation) &&
|
|
7773
|
+
(!!projection.bindings.primaryDimension || projection.bindings.primaryMetrics.length > 0));
|
|
7774
|
+
}
|
|
7775
|
+
hasExplicitPreferredFamily(projection, family) {
|
|
7776
|
+
return (projection.presentationHints?.preferredFamilies ?? []).includes(family);
|
|
7777
|
+
}
|
|
7778
|
+
normalizeFamilies(families) {
|
|
7779
|
+
const normalized = (families ?? DEFAULT_FAMILIES).filter(Boolean);
|
|
7780
|
+
return normalized.length ? normalized : [...DEFAULT_FAMILIES];
|
|
7781
|
+
}
|
|
7782
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: AnalyticsPresentationResolver, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
7783
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: AnalyticsPresentationResolver, providedIn: 'root' });
|
|
7784
|
+
}
|
|
7785
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: AnalyticsPresentationResolver, decorators: [{
|
|
7786
|
+
type: Injectable,
|
|
7787
|
+
args: [{ providedIn: 'root' }]
|
|
7788
|
+
}] });
|
|
7789
|
+
|
|
7790
|
+
async function parseJsonResponseOrEmpty(res, context = 'response') {
|
|
7791
|
+
const raw = await res.text();
|
|
7792
|
+
if (!raw || !raw.trim()) {
|
|
7793
|
+
return {};
|
|
7794
|
+
}
|
|
7795
|
+
try {
|
|
7796
|
+
return JSON.parse(raw);
|
|
7797
|
+
}
|
|
7798
|
+
catch (error) {
|
|
7799
|
+
const e = new Error(`${context}: invalid JSON payload`);
|
|
7800
|
+
e.cause = error;
|
|
7801
|
+
throw e;
|
|
7802
|
+
}
|
|
7803
|
+
}
|
|
7804
|
+
async function fetchWithETag(params) {
|
|
7805
|
+
const headers = { Accept: 'application/json' };
|
|
7806
|
+
if (params.schemaHash)
|
|
7807
|
+
headers['If-None-Match'] = `"${params.schemaHash}"`;
|
|
7808
|
+
if (params.tenant)
|
|
7809
|
+
headers['X-Tenant'] = params.tenant;
|
|
7810
|
+
if (params.locale)
|
|
7811
|
+
headers['Accept-Language'] = params.locale;
|
|
7812
|
+
// Allow host apps to provide additional headers (e.g., Authorization) without coupling
|
|
7813
|
+
try {
|
|
7814
|
+
const extra = globalThis?.PAX_FETCH_HEADERS?.();
|
|
7815
|
+
if (extra && typeof extra === 'object') {
|
|
7816
|
+
for (const [k, v] of Object.entries(extra)) {
|
|
7817
|
+
const key = String(k);
|
|
7818
|
+
const val = Array.isArray(v) ? String(v[0]) : String(v);
|
|
7819
|
+
if (val && !headers[key])
|
|
7820
|
+
headers[key] = val;
|
|
7821
|
+
}
|
|
7822
|
+
}
|
|
7823
|
+
}
|
|
7824
|
+
catch {
|
|
7825
|
+
// ignore header hook errors
|
|
7826
|
+
}
|
|
7827
|
+
const res = await fetch(params.url, {
|
|
7828
|
+
headers,
|
|
7829
|
+
cache: 'no-cache',
|
|
7830
|
+
credentials: params.credentials ?? 'include',
|
|
7831
|
+
signal: params.signal,
|
|
7832
|
+
});
|
|
7833
|
+
if (res.status === 304)
|
|
7834
|
+
return { status: 304 };
|
|
7835
|
+
if (!res.ok) {
|
|
7836
|
+
const raw = await res.text().catch(() => '');
|
|
7837
|
+
const bodyHint = raw?.trim() ? `: ${raw.trim().slice(0, 240)}` : '';
|
|
7838
|
+
throw new Error(`fetchWithETag failed (${res.status} ${res.statusText || 'HTTP error'})${bodyHint}`);
|
|
7839
|
+
}
|
|
7840
|
+
const etag = res.headers.get('ETag') || '';
|
|
7841
|
+
const newHash = etag.replace(/^W\//, '').replace(/^\"|\"$/g, '');
|
|
7842
|
+
const xSchemaHash = res.headers.get('X-Schema-Hash');
|
|
7843
|
+
const schemaHash = xSchemaHash || newHash; // prefer explicit header when available
|
|
7844
|
+
const schema = await parseJsonResponseOrEmpty(res, 'fetchWithETag');
|
|
7845
|
+
return { status: 200, schema, schemaHash };
|
|
7846
|
+
}
|
|
7847
|
+
|
|
7848
|
+
class SchemaMetadataClient {
|
|
7849
|
+
cache;
|
|
7850
|
+
inFlight = new Map();
|
|
7851
|
+
constructor(cache) {
|
|
7852
|
+
this.cache = cache;
|
|
7853
|
+
}
|
|
7854
|
+
async getSchema(params) {
|
|
7855
|
+
// Bind identity to API origin to avoid cross-origin collisions
|
|
7856
|
+
let apiOrigin = '';
|
|
7857
|
+
try {
|
|
7858
|
+
apiOrigin = new URL(params.baseUrl).origin;
|
|
7859
|
+
}
|
|
7860
|
+
catch {
|
|
7861
|
+
try {
|
|
7862
|
+
apiOrigin = globalThis?.location?.origin || '';
|
|
7863
|
+
}
|
|
7864
|
+
catch { }
|
|
7865
|
+
}
|
|
7866
|
+
const schemaId = buildSchemaId({ ...params, apiOrigin });
|
|
7867
|
+
const cached = await this.cache.get(schemaId);
|
|
7868
|
+
// Build URL with query params
|
|
7869
|
+
let u;
|
|
7870
|
+
try {
|
|
7871
|
+
u = new URL(params.baseUrl);
|
|
7872
|
+
}
|
|
7873
|
+
catch (err) {
|
|
7874
|
+
// Accept relative baseUrl by resolving against the app origin when available
|
|
7875
|
+
const origin = (() => {
|
|
7876
|
+
try {
|
|
7877
|
+
return globalThis?.location?.origin;
|
|
7878
|
+
}
|
|
7879
|
+
catch {
|
|
7880
|
+
return undefined;
|
|
7881
|
+
}
|
|
7882
|
+
})();
|
|
7883
|
+
if (origin && origin.startsWith('http')) {
|
|
7884
|
+
u = new URL(params.baseUrl, origin);
|
|
7885
|
+
}
|
|
7886
|
+
else {
|
|
7887
|
+
// Friendly error for hosts: instruct to set absolute baseUrl or provide runtime origin
|
|
7888
|
+
const e = new Error(`Failed to construct schema URL. API_URL.baseUrl appears relative and no runtime origin is available. ` +
|
|
7889
|
+
`Set API_URL.baseUrl to an absolute URL (e.g., http://localhost:4200/api) or run in a browser context. ` +
|
|
7890
|
+
`Received baseUrl="${params.baseUrl}".`);
|
|
7891
|
+
e.cause = err;
|
|
7892
|
+
throw e;
|
|
7893
|
+
}
|
|
7894
|
+
}
|
|
7895
|
+
u.searchParams.set('path', params.path);
|
|
7896
|
+
u.searchParams.set('operation', (params.operation || 'get').toLowerCase());
|
|
7897
|
+
u.searchParams.set('schemaType', (params.schemaType || 'response').toLowerCase());
|
|
7898
|
+
u.searchParams.set('includeInternalSchemas', String(!!params.includeInternalSchemas));
|
|
7899
|
+
const key = schemaId;
|
|
7900
|
+
if (this.inFlight.has(key))
|
|
7901
|
+
return this.inFlight.get(key);
|
|
7902
|
+
const p = (async () => {
|
|
7903
|
+
const res = await fetchWithETag({
|
|
7904
|
+
url: u.toString(),
|
|
7905
|
+
schemaHash: cached?.schemaHash,
|
|
7906
|
+
tenant: params.tenant,
|
|
7907
|
+
locale: params.locale,
|
|
7908
|
+
});
|
|
7909
|
+
if (res.status === 304) {
|
|
7910
|
+
if (cached)
|
|
7911
|
+
return cached;
|
|
7912
|
+
// No cache: refetch without If-None-Match
|
|
7913
|
+
const refetch = await fetch(u.toString(), { cache: 'no-cache', credentials: 'include' });
|
|
7914
|
+
if (!refetch.ok) {
|
|
7915
|
+
const raw = await refetch.text().catch(() => '');
|
|
7916
|
+
const bodyHint = raw?.trim() ? `: ${raw.trim().slice(0, 240)}` : '';
|
|
7917
|
+
throw new Error(`SchemaMetadataClient refetch failed (${refetch.status} ${refetch.statusText || 'HTTP error'})${bodyHint}`);
|
|
7918
|
+
}
|
|
7919
|
+
const etag = refetch.headers.get('ETag') || '';
|
|
7920
|
+
const xHash = refetch.headers.get('X-Schema-Hash') || '';
|
|
7921
|
+
const schemaHash = (xHash || etag).replace(/^W\//, '').replace(/^\"|\"$/g, '');
|
|
7922
|
+
const schema = await parseJsonResponseOrEmpty(refetch, 'SchemaMetadataClient refetch');
|
|
7923
|
+
const fallback = { schema, schemaHash };
|
|
7924
|
+
await this.cache.set(schemaId, fallback);
|
|
7925
|
+
return fallback;
|
|
7926
|
+
}
|
|
7927
|
+
// res.status === 200
|
|
7928
|
+
const entry = {
|
|
7929
|
+
schema: res.schema,
|
|
7930
|
+
schemaHash: res.schemaHash,
|
|
7931
|
+
};
|
|
7932
|
+
await this.cache.set(schemaId, entry);
|
|
7933
|
+
return entry;
|
|
7934
|
+
})();
|
|
7935
|
+
this.inFlight.set(key, p);
|
|
7936
|
+
try {
|
|
7937
|
+
const result = await p;
|
|
7938
|
+
return result;
|
|
7939
|
+
}
|
|
7940
|
+
finally {
|
|
7941
|
+
this.inFlight.delete(key);
|
|
7942
|
+
}
|
|
7943
|
+
}
|
|
7944
|
+
}
|
|
7945
|
+
|
|
7946
|
+
const DEFAULT_CACHE_NAMESPACE = 'praxis.analytics.contract';
|
|
7947
|
+
const DEFAULT_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
7948
|
+
class AnalyticsSchemaContractService {
|
|
7949
|
+
apiUrl;
|
|
7950
|
+
constructor(apiUrl) {
|
|
7951
|
+
this.apiUrl = apiUrl;
|
|
7952
|
+
}
|
|
7953
|
+
async getAnalytics(request) {
|
|
7954
|
+
const client = new SchemaMetadataClient(new LocalStorageCacheAdapter({
|
|
7955
|
+
namespace: request.cacheNamespace || DEFAULT_CACHE_NAMESPACE,
|
|
7956
|
+
ttlMs: request.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS,
|
|
7957
|
+
}));
|
|
7958
|
+
const entry = await client.getSchema({
|
|
7959
|
+
baseUrl: this.buildSchemasBaseUrl(),
|
|
7960
|
+
path: request.path,
|
|
7961
|
+
operation: request.operation ?? 'post',
|
|
7962
|
+
schemaType: request.schemaType ?? 'response',
|
|
7963
|
+
includeInternalSchemas: request.includeInternalSchemas ?? false,
|
|
7964
|
+
tenant: request.tenant,
|
|
7965
|
+
locale: request.locale,
|
|
7966
|
+
});
|
|
7967
|
+
const schema = this.asRecord(entry.schema);
|
|
7968
|
+
if (!schema) {
|
|
7969
|
+
throw new Error(`Schema payload for ${request.path} is not a JSON object.`);
|
|
7970
|
+
}
|
|
7971
|
+
const xUi = this.asRecord(schema?.['x-ui']);
|
|
7972
|
+
const analytics = this.asRecord(xUi?.['analytics']);
|
|
7973
|
+
const projections = Array.isArray(analytics?.['projections'])
|
|
7974
|
+
? analytics['projections']
|
|
7975
|
+
: [];
|
|
7976
|
+
if (!analytics || !projections.length) {
|
|
7977
|
+
throw new Error(`x-ui.analytics.projections[] was not published for ${request.path}.`);
|
|
7978
|
+
}
|
|
7979
|
+
return {
|
|
7980
|
+
...analytics,
|
|
7981
|
+
projections: projections,
|
|
7982
|
+
};
|
|
7983
|
+
}
|
|
7984
|
+
buildSchemasBaseUrl() {
|
|
7985
|
+
const baseUrl = String(this.apiUrl?.default?.baseUrl || '').replace(/\/+$/, '');
|
|
7986
|
+
if (!baseUrl) {
|
|
7987
|
+
throw new Error('AnalyticsSchemaContractService requires API_URL.default.baseUrl to resolve /schemas/filtered.');
|
|
7988
|
+
}
|
|
7989
|
+
return `${baseUrl}/schemas/filtered`;
|
|
7990
|
+
}
|
|
7991
|
+
asRecord(value) {
|
|
7992
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
7993
|
+
? value
|
|
7994
|
+
: null;
|
|
7995
|
+
}
|
|
7996
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: AnalyticsSchemaContractService, deps: [{ token: API_URL }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
7997
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: AnalyticsSchemaContractService, providedIn: 'root' });
|
|
7998
|
+
}
|
|
7999
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: AnalyticsSchemaContractService, decorators: [{
|
|
8000
|
+
type: Injectable,
|
|
8001
|
+
args: [{ providedIn: 'root' }]
|
|
8002
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
8003
|
+
type: Inject,
|
|
8004
|
+
args: [API_URL]
|
|
8005
|
+
}] }] });
|
|
8006
|
+
|
|
8007
|
+
class AnalyticsStatsRequestBuilderService {
|
|
8008
|
+
buildExecutionPlan(projection) {
|
|
8009
|
+
const dimension = projection.bindings.primaryDimension;
|
|
8010
|
+
const metrics = this.getExecutionMetrics(projection);
|
|
8011
|
+
if (!dimension?.field) {
|
|
8012
|
+
throw new Error(`AnalyticsStatsRequestBuilderService requires primaryDimension for projection "${projection.id}".`);
|
|
8013
|
+
}
|
|
8014
|
+
if (!metrics.length) {
|
|
8015
|
+
throw new Error(`AnalyticsStatsRequestBuilderService requires at least one metric for projection "${projection.id}".`);
|
|
8016
|
+
}
|
|
8017
|
+
return {
|
|
8018
|
+
resourcePath: projection.source.resource,
|
|
8019
|
+
statsPath: `${projection.source.resource.replace(/\/+$/, '')}/stats/${projection.source.operation}`,
|
|
8020
|
+
operation: projection.source.operation,
|
|
8021
|
+
statsRequest: this.buildStatsRequest(projection),
|
|
8022
|
+
dimensions: [dimension.field],
|
|
8023
|
+
metrics: metrics.map((metric) => ({
|
|
8024
|
+
field: metric.field,
|
|
8025
|
+
aggregation: metric.aggregation ?? undefined,
|
|
8026
|
+
alias: metric.field,
|
|
8027
|
+
})),
|
|
8028
|
+
sort: projection.defaults?.sort?.map((item) => `${item.field}:${item.direction}`) ?? undefined,
|
|
8029
|
+
limit: projection.defaults?.limit ?? undefined,
|
|
8030
|
+
};
|
|
8031
|
+
}
|
|
8032
|
+
buildStatsRequest(projection) {
|
|
8033
|
+
const field = projection.bindings.primaryDimension.field;
|
|
8034
|
+
const metrics = this.getExecutionMetrics(projection).map((metric) => this.buildStatsMetric(metric.field, metric.aggregation));
|
|
8035
|
+
const metric = metrics[0];
|
|
8036
|
+
const requestMetrics = metrics.length > 1 ? metrics : undefined;
|
|
8037
|
+
const limit = projection.defaults?.limit ?? undefined;
|
|
8038
|
+
const orderBy = this.mapOrderBy(projection.defaults?.sort?.[0]?.field, projection.defaults?.sort?.[0]?.direction, projection);
|
|
8039
|
+
switch (projection.source.operation) {
|
|
8040
|
+
case 'group-by':
|
|
8041
|
+
return {
|
|
8042
|
+
filter: {},
|
|
8043
|
+
field,
|
|
8044
|
+
metric,
|
|
8045
|
+
metrics: requestMetrics,
|
|
8046
|
+
limit,
|
|
8047
|
+
orderBy,
|
|
8048
|
+
};
|
|
8049
|
+
case 'timeseries':
|
|
8050
|
+
if (!projection.defaults?.granularity) {
|
|
8051
|
+
throw new Error(`AnalyticsStatsRequestBuilderService requires defaults.granularity for timeseries projection "${projection.id}".`);
|
|
8052
|
+
}
|
|
8053
|
+
return {
|
|
8054
|
+
filter: {},
|
|
8055
|
+
field,
|
|
8056
|
+
granularity: this.mapGranularityToBackend(projection.defaults.granularity),
|
|
8057
|
+
metric,
|
|
8058
|
+
metrics: requestMetrics,
|
|
8059
|
+
};
|
|
8060
|
+
case 'distribution':
|
|
8061
|
+
return {
|
|
8062
|
+
filter: {},
|
|
8063
|
+
field,
|
|
8064
|
+
mode: 'TERMS',
|
|
8065
|
+
metric,
|
|
8066
|
+
bucketCount: limit,
|
|
8067
|
+
limit,
|
|
8068
|
+
orderBy,
|
|
8069
|
+
};
|
|
8070
|
+
default:
|
|
8071
|
+
throw new Error(`Unsupported analytics stats operation "${projection.source.operation}".`);
|
|
8072
|
+
}
|
|
8073
|
+
}
|
|
8074
|
+
buildStatsMetric(field, aggregation) {
|
|
8075
|
+
const operation = this.mapAggregationToBackend(aggregation);
|
|
8076
|
+
return {
|
|
8077
|
+
operation,
|
|
8078
|
+
field: operation === 'COUNT' ? undefined : field,
|
|
8079
|
+
alias: field,
|
|
8080
|
+
};
|
|
8081
|
+
}
|
|
8082
|
+
mapAggregationToBackend(aggregation) {
|
|
8083
|
+
switch ((aggregation ?? '').toLowerCase()) {
|
|
8084
|
+
case 'avg':
|
|
8085
|
+
return 'AVG';
|
|
8086
|
+
case 'min':
|
|
8087
|
+
return 'MIN';
|
|
8088
|
+
case 'max':
|
|
8089
|
+
return 'MAX';
|
|
8090
|
+
case 'count':
|
|
8091
|
+
case '':
|
|
8092
|
+
return 'COUNT';
|
|
8093
|
+
case 'sum':
|
|
8094
|
+
return 'SUM';
|
|
8095
|
+
default:
|
|
8096
|
+
throw new Error(`Analytics aggregation "${aggregation}" is not supported in praxis.stats execution.`);
|
|
8097
|
+
}
|
|
8098
|
+
}
|
|
8099
|
+
mapOrderBy(field, direction, projection) {
|
|
8100
|
+
if (!field || !direction) {
|
|
8101
|
+
return undefined;
|
|
8102
|
+
}
|
|
8103
|
+
const dimensionField = projection.bindings.primaryDimension?.field;
|
|
8104
|
+
if (field === dimensionField) {
|
|
8105
|
+
return direction === 'asc' ? 'KEY_ASC' : 'KEY_DESC';
|
|
8106
|
+
}
|
|
8107
|
+
const metricFields = [
|
|
8108
|
+
...(projection.bindings.primaryMetrics ?? []),
|
|
8109
|
+
...(projection.bindings.secondaryMetrics ?? []),
|
|
8110
|
+
].map((metric) => metric.field);
|
|
8111
|
+
if (metricFields.includes(field)) {
|
|
8112
|
+
return direction === 'asc' ? 'VALUE_ASC' : 'VALUE_DESC';
|
|
8113
|
+
}
|
|
8114
|
+
return undefined;
|
|
8115
|
+
}
|
|
8116
|
+
mapGranularityToBackend(granularity) {
|
|
8117
|
+
switch (granularity) {
|
|
8118
|
+
case 'hour':
|
|
8119
|
+
return 'HOUR';
|
|
8120
|
+
case 'day':
|
|
8121
|
+
return 'DAY';
|
|
8122
|
+
case 'week':
|
|
8123
|
+
return 'WEEK';
|
|
8124
|
+
case 'month':
|
|
8125
|
+
return 'MONTH';
|
|
8126
|
+
case 'quarter':
|
|
8127
|
+
return 'QUARTER';
|
|
8128
|
+
case 'year':
|
|
8129
|
+
return 'YEAR';
|
|
8130
|
+
}
|
|
8131
|
+
}
|
|
8132
|
+
getExecutionMetrics(projection) {
|
|
8133
|
+
return [
|
|
8134
|
+
...(projection.bindings.primaryMetrics ?? []),
|
|
8135
|
+
...(projection.bindings.secondaryMetrics ?? []),
|
|
8136
|
+
];
|
|
8137
|
+
}
|
|
8138
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: AnalyticsStatsRequestBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
8139
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: AnalyticsStatsRequestBuilderService, providedIn: 'root' });
|
|
8140
|
+
}
|
|
8141
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: AnalyticsStatsRequestBuilderService, decorators: [{
|
|
8142
|
+
type: Injectable,
|
|
8143
|
+
args: [{ providedIn: 'root' }]
|
|
8144
|
+
}] });
|
|
8145
|
+
|
|
8146
|
+
function provideFieldSelectorRegistryRuntime(map, opts) {
|
|
8147
|
+
return {
|
|
8148
|
+
provide: ENVIRONMENT_INITIALIZER,
|
|
8149
|
+
multi: true,
|
|
8150
|
+
useFactory: () => {
|
|
8151
|
+
const registry = inject(FieldSelectorRegistry);
|
|
8152
|
+
return () => registry.register(map, { overwrite: opts?.overwrite ?? false });
|
|
8153
|
+
},
|
|
8154
|
+
};
|
|
8155
|
+
}
|
|
8156
|
+
|
|
8157
|
+
function providePraxisToastGlobalActions(opts = {}) {
|
|
8158
|
+
return {
|
|
8159
|
+
provide: GLOBAL_TOAST_SERVICE,
|
|
8160
|
+
useFactory: () => {
|
|
8161
|
+
const snack = (() => { try {
|
|
8162
|
+
return inject(MatSnackBar);
|
|
8163
|
+
}
|
|
8164
|
+
catch {
|
|
8165
|
+
return null;
|
|
8166
|
+
} })();
|
|
8167
|
+
const successDuration = opts.successDurationMs ?? 2500;
|
|
8168
|
+
const errorDuration = opts.errorDurationMs ?? 3500;
|
|
8169
|
+
const successClass = opts.successPanelClass ?? ['pdx-toast-success'];
|
|
8170
|
+
const errorClass = opts.errorPanelClass ?? ['pdx-toast-error'];
|
|
8171
|
+
return {
|
|
8172
|
+
success: (message) => {
|
|
8173
|
+
if (snack) {
|
|
8174
|
+
snack.open(message, undefined, { duration: successDuration, panelClass: successClass });
|
|
8175
|
+
}
|
|
8176
|
+
else {
|
|
8177
|
+
console.log('[Toast]', message);
|
|
8178
|
+
}
|
|
8179
|
+
},
|
|
8180
|
+
error: (message) => {
|
|
8181
|
+
if (snack) {
|
|
8182
|
+
snack.open(message, undefined, { duration: errorDuration, panelClass: errorClass });
|
|
8183
|
+
}
|
|
8184
|
+
else {
|
|
8185
|
+
console.error('[Toast]', message);
|
|
8186
|
+
}
|
|
8187
|
+
},
|
|
8188
|
+
};
|
|
8189
|
+
},
|
|
8190
|
+
};
|
|
8191
|
+
}
|
|
8192
|
+
|
|
8193
|
+
function providePraxisAnalyticsGlobalActions(opts = {}) {
|
|
8194
|
+
return {
|
|
8195
|
+
provide: GLOBAL_ANALYTICS_SERVICE,
|
|
8196
|
+
useFactory: () => {
|
|
8197
|
+
const telemetry = (() => { try {
|
|
8198
|
+
return inject(TelemetryService);
|
|
8199
|
+
}
|
|
8200
|
+
catch {
|
|
8201
|
+
return null;
|
|
8202
|
+
} })();
|
|
8203
|
+
const prefix = opts.prefix ? `${opts.prefix}.` : '';
|
|
8204
|
+
return {
|
|
8205
|
+
track: (eventName, payload) => {
|
|
8206
|
+
if (telemetry) {
|
|
8207
|
+
telemetry.record(`${prefix}${eventName}`, payload);
|
|
8208
|
+
}
|
|
8209
|
+
else {
|
|
8210
|
+
console.log('[Analytics]', `${prefix}${eventName}`, payload ?? null);
|
|
8211
|
+
}
|
|
8212
|
+
},
|
|
8213
|
+
};
|
|
8214
|
+
},
|
|
8215
|
+
};
|
|
8216
|
+
}
|
|
8217
|
+
|
|
8218
|
+
/**
|
|
8219
|
+
* Registers only the default visual renderer for Praxis loading.
|
|
8220
|
+
*
|
|
8221
|
+
* This does not wire any HTTP interceptor by itself. Use this when the host
|
|
8222
|
+
* wants a custom HTTP integration path but still wants the stock Praxis UI.
|
|
8223
|
+
*/
|
|
8224
|
+
function providePraxisLoadingDefaults() {
|
|
8225
|
+
return [
|
|
8226
|
+
{
|
|
8227
|
+
provide: PRAXIS_LOADING_RENDERER,
|
|
8228
|
+
useClass: DefaultLoadingRenderer,
|
|
8229
|
+
},
|
|
8230
|
+
];
|
|
8231
|
+
}
|
|
8232
|
+
/**
|
|
8233
|
+
* Official DI-based entrypoint to enable Praxis HTTP loading.
|
|
8234
|
+
*
|
|
8235
|
+
* Recommended when the host already uses DI interceptors, e.g.:
|
|
8236
|
+
*
|
|
8237
|
+
* ```ts
|
|
8238
|
+
* providers: [
|
|
8239
|
+
* provideHttpClient(withInterceptorsFromDi()),
|
|
8240
|
+
* ...providePraxisHttpLoading(),
|
|
8241
|
+
* ]
|
|
8242
|
+
* ```
|
|
8243
|
+
*
|
|
8244
|
+
* By default this provider does not register any renderer implementation.
|
|
8245
|
+
* Add `...providePraxisLoadingDefaults()` or a custom `PRAXIS_LOADING_RENDERER`
|
|
8246
|
+
* explicitly so hosts keep full control over visual composition.
|
|
8247
|
+
*
|
|
8248
|
+
* Requests remain opt-in and only show loading when they carry
|
|
8249
|
+
* `PRAXIS_LOADING_CTX` in the `HttpContext`.
|
|
8250
|
+
*/
|
|
8251
|
+
function providePraxisHttpLoading(opts = {}) {
|
|
8252
|
+
const providers = [
|
|
8253
|
+
{
|
|
8254
|
+
provide: HTTP_INTERCEPTORS,
|
|
8255
|
+
useClass: PraxisLoadingInterceptor,
|
|
8256
|
+
multi: true,
|
|
8257
|
+
},
|
|
8258
|
+
];
|
|
8259
|
+
if (opts.includeDefaultRenderer === true) {
|
|
8260
|
+
providers.unshift(...providePraxisLoadingDefaults());
|
|
8261
|
+
}
|
|
8262
|
+
return providers;
|
|
8263
|
+
}
|
|
8264
|
+
/**
|
|
8265
|
+
* Angular modern helper for `provideHttpClient(...)`.
|
|
8266
|
+
*
|
|
8267
|
+
* Usage:
|
|
8268
|
+
*
|
|
8269
|
+
* ```ts
|
|
8270
|
+
* providers: [
|
|
8271
|
+
* provideHttpClient(
|
|
8272
|
+
* withInterceptors([authInterceptor]),
|
|
8273
|
+
* withPraxisHttpLoading(),
|
|
8274
|
+
* ),
|
|
8275
|
+
* ...providePraxisLoadingDefaults(),
|
|
8276
|
+
* ]
|
|
8277
|
+
* ```
|
|
8278
|
+
*
|
|
8279
|
+
* Use this helper or `providePraxisHttpLoading()`, never both in the same host.
|
|
8280
|
+
*/
|
|
8281
|
+
function withPraxisHttpLoading() {
|
|
8282
|
+
return withInterceptors([praxisLoadingInterceptorFn]);
|
|
8283
|
+
}
|
|
8284
|
+
|
|
8285
|
+
const LOGGER_LEVEL_PRIORITY = {
|
|
8286
|
+
error: 0,
|
|
8287
|
+
warn: 1,
|
|
8288
|
+
info: 2,
|
|
8289
|
+
debug: 3,
|
|
8290
|
+
trace: 4,
|
|
8291
|
+
};
|
|
8292
|
+
const LOGGER_LEVEL_BY_ENV = {
|
|
8293
|
+
prod: 'warn',
|
|
8294
|
+
qa: 'warn',
|
|
8295
|
+
hml: 'info',
|
|
8296
|
+
dev: 'debug',
|
|
8297
|
+
};
|
|
8298
|
+
const PRAXIS_CORPORATE_SENSITIVE_KEYS = [
|
|
8299
|
+
'password',
|
|
8300
|
+
'pass',
|
|
8301
|
+
'token',
|
|
8302
|
+
'accessToken',
|
|
8303
|
+
'refreshToken',
|
|
8304
|
+
'authorization',
|
|
8305
|
+
'secret',
|
|
8306
|
+
'apiKey',
|
|
8307
|
+
'cpf',
|
|
8308
|
+
'cnpj',
|
|
8309
|
+
'document',
|
|
8310
|
+
'ssn',
|
|
8311
|
+
'email',
|
|
8312
|
+
'phone',
|
|
8313
|
+
];
|
|
8314
|
+
const PRAXIS_CORPORATE_THROTTLE = {
|
|
8315
|
+
enabled: true,
|
|
8316
|
+
windowMs: 5000,
|
|
8317
|
+
maxOccurrences: 3,
|
|
8318
|
+
};
|
|
8319
|
+
function createCorporateLoggerConfig(environment = 'prod') {
|
|
8320
|
+
return {
|
|
8321
|
+
environment,
|
|
8322
|
+
minLevel: LOGGER_LEVEL_BY_ENV[environment],
|
|
8323
|
+
warnOnceEnabled: true,
|
|
8324
|
+
throttle: { ...PRAXIS_CORPORATE_THROTTLE },
|
|
8325
|
+
pii: {
|
|
8326
|
+
enabled: true,
|
|
8327
|
+
redactionText: '[REDACTED]',
|
|
8328
|
+
sensitiveKeys: [...PRAXIS_CORPORATE_SENSITIVE_KEYS],
|
|
8329
|
+
},
|
|
8330
|
+
};
|
|
8331
|
+
}
|
|
8332
|
+
function resolveLoggerConfig(options = {}) {
|
|
8333
|
+
const environment = options.environment ?? 'prod';
|
|
8334
|
+
const corporate = createCorporateLoggerConfig(environment);
|
|
8335
|
+
const overridePII = options.pii ?? {};
|
|
8336
|
+
return {
|
|
8337
|
+
...corporate,
|
|
8338
|
+
minLevel: options.minLevel ?? corporate.minLevel,
|
|
8339
|
+
warnOnceEnabled: options.warnOnceEnabled ?? corporate.warnOnceEnabled,
|
|
8340
|
+
throttle: {
|
|
8341
|
+
...corporate.throttle,
|
|
8342
|
+
...(options.throttle ?? {}),
|
|
8343
|
+
},
|
|
8344
|
+
pii: {
|
|
8345
|
+
...corporate.pii,
|
|
8346
|
+
...overridePII,
|
|
8347
|
+
sensitiveKeys: overridePII.sensitiveKeys
|
|
8348
|
+
? [...overridePII.sensitiveKeys]
|
|
8349
|
+
: [...corporate.pii.sensitiveKeys],
|
|
8350
|
+
},
|
|
8351
|
+
defaultContext: options.defaultContext
|
|
8352
|
+
? { ...options.defaultContext }
|
|
8353
|
+
: corporate.defaultContext,
|
|
8354
|
+
environment,
|
|
8355
|
+
};
|
|
8356
|
+
}
|
|
8357
|
+
|
|
8358
|
+
class ConsoleLoggerSink {
|
|
8359
|
+
log(event) {
|
|
8360
|
+
const print = this.resolveMethod(event.level);
|
|
8361
|
+
const prefix = `[Praxis][${event.level.toUpperCase()}]`;
|
|
8362
|
+
const envelope = {
|
|
8363
|
+
environment: event.environment,
|
|
8364
|
+
timestamp: event.timestamp,
|
|
8365
|
+
context: event.context ?? null,
|
|
8366
|
+
data: event.data ?? null,
|
|
8367
|
+
};
|
|
8368
|
+
if (event.context || event.data !== undefined) {
|
|
8369
|
+
print(`${prefix} ${event.message}`, envelope);
|
|
8370
|
+
return;
|
|
8371
|
+
}
|
|
8372
|
+
print(`${prefix} ${event.message}`);
|
|
8373
|
+
}
|
|
8374
|
+
resolveMethod(level) {
|
|
8375
|
+
if (level === 'error' && typeof console.error === 'function') {
|
|
8376
|
+
return console.error.bind(console);
|
|
8377
|
+
}
|
|
8378
|
+
if (level === 'warn' && typeof console.warn === 'function') {
|
|
8379
|
+
return console.warn.bind(console);
|
|
8380
|
+
}
|
|
8381
|
+
if (level === 'info' && typeof console.info === 'function') {
|
|
8382
|
+
return console.info.bind(console);
|
|
8383
|
+
}
|
|
8384
|
+
if (level === 'debug' && typeof console.debug === 'function') {
|
|
8385
|
+
return console.debug.bind(console);
|
|
8386
|
+
}
|
|
8387
|
+
if (level === 'trace') {
|
|
8388
|
+
if (typeof console.trace === 'function') {
|
|
8389
|
+
return console.trace.bind(console);
|
|
8390
|
+
}
|
|
8391
|
+
if (typeof console.debug === 'function') {
|
|
8392
|
+
return console.debug.bind(console);
|
|
8393
|
+
}
|
|
8394
|
+
}
|
|
8395
|
+
return console.log.bind(console);
|
|
8396
|
+
}
|
|
8397
|
+
}
|
|
8398
|
+
|
|
8399
|
+
const PRAXIS_LOGGER_CONFIG = new InjectionToken('PRAXIS_LOGGER_CONFIG', {
|
|
7347
8400
|
providedIn: 'root',
|
|
7348
8401
|
factory: () => createCorporateLoggerConfig('prod'),
|
|
7349
8402
|
});
|
|
@@ -9078,16 +10131,98 @@ const SURFACE_OPEN_I18N_CONFIG = {
|
|
|
9078
10131
|
},
|
|
9079
10132
|
};
|
|
9080
10133
|
|
|
10134
|
+
/**
|
|
10135
|
+
* Authoring/editor drawer bridge.
|
|
10136
|
+
*
|
|
10137
|
+
* Use this token for settings/configuration flows that depend on
|
|
10138
|
+
* `SettingsValueProvider` semantics (`apply/save/reset/cancel`).
|
|
10139
|
+
*
|
|
10140
|
+
* Runtime surfaces opened by `surface.open` should migrate to
|
|
10141
|
+
* `SURFACE_DRAWER_BRIDGE`, which carries runtime-oriented semantics instead of
|
|
10142
|
+
* editor semantics.
|
|
10143
|
+
*/
|
|
9081
10144
|
const SETTINGS_PANEL_BRIDGE = new InjectionToken('SETTINGS_PANEL_BRIDGE');
|
|
9082
10145
|
// Optional data token for consumers that still use DI-based data passing.
|
|
9083
10146
|
// Prefer using component inputs when opening via SettingsPanelBridge.
|
|
9084
10147
|
const SETTINGS_PANEL_DATA = new InjectionToken('SETTINGS_PANEL_DATA');
|
|
9085
10148
|
|
|
10149
|
+
const SURFACE_DRAWER_BRIDGE = new InjectionToken('SURFACE_DRAWER_BRIDGE');
|
|
10150
|
+
|
|
9086
10151
|
const TABLE_CONFIG_EDITOR = new InjectionToken('TABLE_CONFIG_EDITOR');
|
|
9087
10152
|
const STEPPER_CONFIG_EDITOR = new InjectionToken('STEPPER_CONFIG_EDITOR');
|
|
9088
10153
|
const DYNAMIC_PAGE_SHELL_EDITOR = new InjectionToken('DYNAMIC_PAGE_SHELL_EDITOR');
|
|
9089
10154
|
const DYNAMIC_PAGE_CONFIG_EDITOR = new InjectionToken('DYNAMIC_PAGE_CONFIG_EDITOR');
|
|
9090
10155
|
|
|
10156
|
+
const RESOURCE_DISCOVERY_I18N_NAMESPACE = 'resourceDiscovery';
|
|
10157
|
+
const RESOURCE_AVAILABILITY_REASON_KEY_BY_CODE = {
|
|
10158
|
+
'resource-state-blocked': 'availability.reason.resource-state-blocked',
|
|
10159
|
+
'missing-authority': 'availability.reason.missing-authority',
|
|
10160
|
+
'resource-context-required': 'availability.reason.resource-context-required',
|
|
10161
|
+
'resource-not-found': 'availability.reason.resource-not-found',
|
|
10162
|
+
};
|
|
10163
|
+
const RESOURCE_DISCOVERY_I18N_CONFIG = {
|
|
10164
|
+
namespaces: {
|
|
10165
|
+
[RESOURCE_DISCOVERY_I18N_NAMESPACE]: {
|
|
10166
|
+
'pt-BR': {
|
|
10167
|
+
'workflow.unavailable.default': 'A\u00e7\u00e3o indispon\u00edvel no contexto atual.',
|
|
10168
|
+
'workflow.unavailable.withReason': 'A\u00e7\u00e3o indispon\u00edvel: {{reason}}',
|
|
10169
|
+
'rowActions.menu.loading': 'Carregando a\u00e7\u00f5es contextuais',
|
|
10170
|
+
'rowActions.menu.more': 'Mais a\u00e7\u00f5es',
|
|
10171
|
+
'availability.reason.resource-state-blocked': 'Dependente do estado atual do registro.',
|
|
10172
|
+
'availability.reason.missing-authority': 'Voc\u00ea n\u00e3o tem permiss\u00e3o para executar esta a\u00e7\u00e3o.',
|
|
10173
|
+
'availability.reason.resource-context-required': 'Abra um item espec\u00edfico para continuar.',
|
|
10174
|
+
'availability.reason.resource-not-found': 'O registro n\u00e3o est\u00e1 dispon\u00edvel.',
|
|
10175
|
+
'availability.reason.unknown': 'O contexto atual n\u00e3o permite esta a\u00e7\u00e3o.',
|
|
10176
|
+
},
|
|
10177
|
+
'en-US': {
|
|
10178
|
+
'workflow.unavailable.default': 'Action is unavailable in the current context.',
|
|
10179
|
+
'workflow.unavailable.withReason': 'Action unavailable: {{reason}}',
|
|
10180
|
+
'rowActions.menu.loading': 'Loading contextual actions',
|
|
10181
|
+
'rowActions.menu.more': 'More actions',
|
|
10182
|
+
'availability.reason.resource-state-blocked': 'Blocked by the current resource state.',
|
|
10183
|
+
'availability.reason.missing-authority': 'You do not have permission to perform this action.',
|
|
10184
|
+
'availability.reason.resource-context-required': 'Open a specific item to continue.',
|
|
10185
|
+
'availability.reason.resource-not-found': 'The record is not available.',
|
|
10186
|
+
'availability.reason.unknown': 'The current context does not allow this action.',
|
|
10187
|
+
},
|
|
10188
|
+
},
|
|
10189
|
+
},
|
|
10190
|
+
};
|
|
10191
|
+
function normalizeResourceAvailabilityReasonCode(reason) {
|
|
10192
|
+
return String(reason || '').trim().toLowerCase();
|
|
10193
|
+
}
|
|
10194
|
+
function resolveResourceAvailabilityReasonKey(reason) {
|
|
10195
|
+
const normalized = normalizeResourceAvailabilityReasonCode(reason);
|
|
10196
|
+
return (RESOURCE_AVAILABILITY_REASON_KEY_BY_CODE[normalized] ||
|
|
10197
|
+
'availability.reason.unknown');
|
|
10198
|
+
}
|
|
10199
|
+
function translateResourceDiscoveryText(i18n, key, params, fallback) {
|
|
10200
|
+
return i18n.t(key, params, fallback, RESOURCE_DISCOVERY_I18N_NAMESPACE);
|
|
10201
|
+
}
|
|
10202
|
+
function translateResourceAvailabilityReason(i18n, reason) {
|
|
10203
|
+
const key = resolveResourceAvailabilityReasonKey(reason);
|
|
10204
|
+
const fallback = key === 'availability.reason.resource-state-blocked'
|
|
10205
|
+
? 'Dependente do estado atual do registro.'
|
|
10206
|
+
: key === 'availability.reason.missing-authority'
|
|
10207
|
+
? 'Voc\u00ea n\u00e3o tem permiss\u00e3o para executar esta a\u00e7\u00e3o.'
|
|
10208
|
+
: key === 'availability.reason.resource-context-required'
|
|
10209
|
+
? 'Abra um item espec\u00edfico para continuar.'
|
|
10210
|
+
: key === 'availability.reason.resource-not-found'
|
|
10211
|
+
? 'O registro n\u00e3o est\u00e1 dispon\u00edvel.'
|
|
10212
|
+
: 'O contexto atual n\u00e3o permite esta a\u00e7\u00e3o.';
|
|
10213
|
+
return translateResourceDiscoveryText(i18n, key, undefined, fallback);
|
|
10214
|
+
}
|
|
10215
|
+
function translateUnavailableWorkflowMessage(i18n, availability) {
|
|
10216
|
+
const reason = normalizeResourceAvailabilityReasonCode(availability?.reason);
|
|
10217
|
+
if (!reason) {
|
|
10218
|
+
return translateResourceDiscoveryText(i18n, 'workflow.unavailable.default', undefined, 'A\u00e7\u00e3o indispon\u00edvel no contexto atual.');
|
|
10219
|
+
}
|
|
10220
|
+
const translatedReason = translateResourceAvailabilityReason(i18n, reason);
|
|
10221
|
+
return translateResourceDiscoveryText(i18n, 'workflow.unavailable.withReason', {
|
|
10222
|
+
reason: translatedReason,
|
|
10223
|
+
}, `A\u00e7\u00e3o indispon\u00edvel: ${translatedReason}`);
|
|
10224
|
+
}
|
|
10225
|
+
|
|
9091
10226
|
const DEFAULT_LOCALE = 'en-US';
|
|
9092
10227
|
const DEFAULT_DATE_TIME = {
|
|
9093
10228
|
dateFormat: 'shortDate',
|
|
@@ -11693,6 +12828,196 @@ function getEditorialSolutionPresetById(presetId) {
|
|
|
11693
12828
|
return match ? structuredClone(match) : undefined;
|
|
11694
12829
|
}
|
|
11695
12830
|
|
|
12831
|
+
const WIDGET_PAGE_COMPOSITION_SCHEMA_VERSION = '1.0.0';
|
|
12832
|
+
/**
|
|
12833
|
+
* Normalizes a CompositionLink for deterministic persistence.
|
|
12834
|
+
* Ensures explicit ordering and strips compatibility-only legacy residues.
|
|
12835
|
+
*/
|
|
12836
|
+
function normalizeCompositionLink(link) {
|
|
12837
|
+
const normalized = {
|
|
12838
|
+
id: link.id,
|
|
12839
|
+
from: normalizeEndpoint$1(link.from),
|
|
12840
|
+
to: normalizeEndpoint$1(link.to),
|
|
12841
|
+
intent: link.intent,
|
|
12842
|
+
};
|
|
12843
|
+
if (link.transform) {
|
|
12844
|
+
normalized.transform = clone(link.transform);
|
|
12845
|
+
}
|
|
12846
|
+
const conditions = normalizeConditions(link.conditions);
|
|
12847
|
+
if (conditions) {
|
|
12848
|
+
normalized.conditions = conditions;
|
|
12849
|
+
}
|
|
12850
|
+
const policy = normalizePolicy(link.policy);
|
|
12851
|
+
if (policy) {
|
|
12852
|
+
normalized.policy = policy;
|
|
12853
|
+
}
|
|
12854
|
+
const metadata = normalizeMetadata(link.metadata);
|
|
12855
|
+
if (metadata) {
|
|
12856
|
+
normalized.metadata = metadata;
|
|
12857
|
+
}
|
|
12858
|
+
return normalized;
|
|
12859
|
+
}
|
|
12860
|
+
/**
|
|
12861
|
+
* Normalizes an array of CompositionLinks for deterministic persistence.
|
|
12862
|
+
*/
|
|
12863
|
+
function normalizeCompositionLinks(links) {
|
|
12864
|
+
return links
|
|
12865
|
+
.map(normalizeCompositionLink)
|
|
12866
|
+
.sort(compareNormalizedLinks);
|
|
12867
|
+
}
|
|
12868
|
+
/**
|
|
12869
|
+
* Canonical persisted write surface for CompositionLink[].
|
|
12870
|
+
* New saved shapes must serialize links under `composition.links`.
|
|
12871
|
+
*/
|
|
12872
|
+
function serializeCompositionLinks(links) {
|
|
12873
|
+
return {
|
|
12874
|
+
version: WIDGET_PAGE_COMPOSITION_SCHEMA_VERSION,
|
|
12875
|
+
links: normalizeCompositionLinks(links),
|
|
12876
|
+
};
|
|
12877
|
+
}
|
|
12878
|
+
/**
|
|
12879
|
+
* Writes the canonical persisted composition surface into a page shape.
|
|
12880
|
+
* The canonical writer omits legacy `connections` to avoid dual-write ambiguity.
|
|
12881
|
+
*/
|
|
12882
|
+
function writeCompositionLinksToPersistedPage(page, links) {
|
|
12883
|
+
const { composition: _legacyComposition, ...rest } = clone(page);
|
|
12884
|
+
return {
|
|
12885
|
+
...rest,
|
|
12886
|
+
composition: serializeCompositionLinks(links),
|
|
12887
|
+
};
|
|
12888
|
+
}
|
|
12889
|
+
function normalizeEndpoint$1(endpoint) {
|
|
12890
|
+
if (endpoint.kind === 'component-port') {
|
|
12891
|
+
return {
|
|
12892
|
+
kind: 'component-port',
|
|
12893
|
+
ref: {
|
|
12894
|
+
widget: endpoint.ref.widget,
|
|
12895
|
+
port: endpoint.ref.port,
|
|
12896
|
+
direction: endpoint.ref.direction,
|
|
12897
|
+
...(endpoint.ref.componentType ? { componentType: endpoint.ref.componentType } : {}),
|
|
12898
|
+
...(endpoint.ref.bindingPath ? { bindingPath: endpoint.ref.bindingPath } : {}),
|
|
12899
|
+
},
|
|
12900
|
+
};
|
|
12901
|
+
}
|
|
12902
|
+
return {
|
|
12903
|
+
kind: 'state',
|
|
12904
|
+
ref: {
|
|
12905
|
+
path: endpoint.ref.path,
|
|
12906
|
+
...(endpoint.ref.layer ? { layer: endpoint.ref.layer } : {}),
|
|
12907
|
+
},
|
|
12908
|
+
};
|
|
12909
|
+
}
|
|
12910
|
+
function normalizeConditions(conditions) {
|
|
12911
|
+
if (!conditions?.length) {
|
|
12912
|
+
return undefined;
|
|
12913
|
+
}
|
|
12914
|
+
return conditions
|
|
12915
|
+
.map((condition) => ({
|
|
12916
|
+
kind: condition.kind,
|
|
12917
|
+
...(condition.expression ? { expression: condition.expression } : {}),
|
|
12918
|
+
...(condition.path ? { path: condition.path } : {}),
|
|
12919
|
+
...(condition.value !== undefined ? { value: clone(condition.value) } : {}),
|
|
12920
|
+
...(condition.negate !== undefined ? { negate: condition.negate } : {}),
|
|
12921
|
+
...(condition.description ? { description: condition.description } : {}),
|
|
12922
|
+
}))
|
|
12923
|
+
.sort(compareConditions);
|
|
12924
|
+
}
|
|
12925
|
+
function normalizePolicy(policy) {
|
|
12926
|
+
if (!policy) {
|
|
12927
|
+
return undefined;
|
|
12928
|
+
}
|
|
12929
|
+
const normalized = {
|
|
12930
|
+
...(policy.debounceMs !== undefined ? { debounceMs: policy.debounceMs } : {}),
|
|
12931
|
+
...(policy.distinct !== undefined ? { distinct: policy.distinct } : {}),
|
|
12932
|
+
...(policy.distinctBy ? { distinctBy: policy.distinctBy } : {}),
|
|
12933
|
+
...(policy.delivery ? { delivery: policy.delivery } : {}),
|
|
12934
|
+
...(policy.missingValuePolicy ? { missingValuePolicy: policy.missingValuePolicy } : {}),
|
|
12935
|
+
...(policy.errorPolicy ? { errorPolicy: policy.errorPolicy } : {}),
|
|
12936
|
+
};
|
|
12937
|
+
return Object.keys(normalized).length ? normalized : undefined;
|
|
12938
|
+
}
|
|
12939
|
+
function normalizeMetadata(metadata) {
|
|
12940
|
+
if (!metadata) {
|
|
12941
|
+
return undefined;
|
|
12942
|
+
}
|
|
12943
|
+
const tags = metadata.tags?.length
|
|
12944
|
+
? [...metadata.tags].sort((a, b) => a.localeCompare(b))
|
|
12945
|
+
: undefined;
|
|
12946
|
+
const source = metadata.source === 'legacy-widget-connection'
|
|
12947
|
+
? undefined
|
|
12948
|
+
: metadata.source;
|
|
12949
|
+
const normalized = {
|
|
12950
|
+
...(metadata.label ? { label: metadata.label } : {}),
|
|
12951
|
+
...(metadata.description ? { description: metadata.description } : {}),
|
|
12952
|
+
...(tags?.length ? { tags } : {}),
|
|
12953
|
+
...(metadata.deprecated !== undefined ? { deprecated: metadata.deprecated } : {}),
|
|
12954
|
+
...(source ? { source } : {}),
|
|
12955
|
+
};
|
|
12956
|
+
return Object.keys(normalized).length ? normalized : undefined;
|
|
12957
|
+
}
|
|
12958
|
+
function compareConditions(a, b) {
|
|
12959
|
+
return compareValues([
|
|
12960
|
+
a.kind,
|
|
12961
|
+
a.expression || '',
|
|
12962
|
+
a.path || '',
|
|
12963
|
+
JSON.stringify(a.value ?? null),
|
|
12964
|
+
String(a.negate ?? ''),
|
|
12965
|
+
a.description || '',
|
|
12966
|
+
], [
|
|
12967
|
+
b.kind,
|
|
12968
|
+
b.expression || '',
|
|
12969
|
+
b.path || '',
|
|
12970
|
+
JSON.stringify(b.value ?? null),
|
|
12971
|
+
String(b.negate ?? ''),
|
|
12972
|
+
b.description || '',
|
|
12973
|
+
]);
|
|
12974
|
+
}
|
|
12975
|
+
function compareNormalizedLinks(a, b) {
|
|
12976
|
+
return compareValues([
|
|
12977
|
+
a.id,
|
|
12978
|
+
a.intent,
|
|
12979
|
+
endpointSortKey(a.from),
|
|
12980
|
+
endpointSortKey(a.to),
|
|
12981
|
+
], [
|
|
12982
|
+
b.id,
|
|
12983
|
+
b.intent,
|
|
12984
|
+
endpointSortKey(b.from),
|
|
12985
|
+
endpointSortKey(b.to),
|
|
12986
|
+
]);
|
|
12987
|
+
}
|
|
12988
|
+
function endpointSortKey(endpoint) {
|
|
12989
|
+
if (endpoint.kind === 'component-port') {
|
|
12990
|
+
return [
|
|
12991
|
+
endpoint.kind,
|
|
12992
|
+
endpoint.ref.widget,
|
|
12993
|
+
endpoint.ref.port,
|
|
12994
|
+
endpoint.ref.direction,
|
|
12995
|
+
endpoint.ref.bindingPath || '',
|
|
12996
|
+
endpoint.ref.componentType || '',
|
|
12997
|
+
].join('|');
|
|
12998
|
+
}
|
|
12999
|
+
return [
|
|
13000
|
+
endpoint.kind,
|
|
13001
|
+
endpoint.ref.path,
|
|
13002
|
+
endpoint.ref.layer || '',
|
|
13003
|
+
].join('|');
|
|
13004
|
+
}
|
|
13005
|
+
function compareValues(left, right) {
|
|
13006
|
+
for (let index = 0; index < Math.max(left.length, right.length); index += 1) {
|
|
13007
|
+
const comparison = (left[index] || '').localeCompare(right[index] || '');
|
|
13008
|
+
if (comparison !== 0) {
|
|
13009
|
+
return comparison;
|
|
13010
|
+
}
|
|
13011
|
+
}
|
|
13012
|
+
return 0;
|
|
13013
|
+
}
|
|
13014
|
+
function clone(value) {
|
|
13015
|
+
if (value == null || typeof value !== 'object') {
|
|
13016
|
+
return value;
|
|
13017
|
+
}
|
|
13018
|
+
return JSON.parse(JSON.stringify(value));
|
|
13019
|
+
}
|
|
13020
|
+
|
|
11696
13021
|
/** Utility: generate a random id using crypto.randomUUID or fallback. */
|
|
11697
13022
|
function generateId() {
|
|
11698
13023
|
const g = globalThis.crypto?.randomUUID?.();
|
|
@@ -11732,7 +13057,8 @@ function ensurePageIds(page) {
|
|
|
11732
13057
|
* Create a persisted page record from an in-memory page definition and identity.
|
|
11733
13058
|
*/
|
|
11734
13059
|
function createPersistedPage(identity, page, opts) {
|
|
11735
|
-
const
|
|
13060
|
+
const persistedPage = writeCompositionLinksToPersistedPage(page, page.composition?.links || []);
|
|
13061
|
+
const { page: pageWithIds } = ensurePageIds(persistedPage);
|
|
11736
13062
|
const now = new Date().toISOString();
|
|
11737
13063
|
return {
|
|
11738
13064
|
id: opts?.id || generateId(),
|
|
@@ -12977,104 +14303,29 @@ const GLOBAL_ACTION_UI_SCHEMAS = [
|
|
|
12977
14303
|
],
|
|
12978
14304
|
},
|
|
12979
14305
|
{
|
|
12980
|
-
id: 'copyToClipboard',
|
|
12981
|
-
label: 'Copiar para clipboard',
|
|
12982
|
-
fields: [
|
|
12983
|
-
{ key: 'text', label: 'Texto', type: 'text' },
|
|
12984
|
-
{ key: 'useFieldValue', label: 'Usar valor do campo', type: 'toggle' },
|
|
12985
|
-
],
|
|
12986
|
-
},
|
|
12987
|
-
{
|
|
12988
|
-
id: 'refreshOptions',
|
|
12989
|
-
label: 'Recarregar opções',
|
|
12990
|
-
fields: [{ key: 'field', label: 'Campo', type: 'text', required: true }],
|
|
12991
|
-
},
|
|
12992
|
-
{
|
|
12993
|
-
id: 'loadDependentData',
|
|
12994
|
-
label: 'Carregar dependentes',
|
|
12995
|
-
fields: [{ key: 'field', label: 'Campo alvo', type: 'text', required: true }],
|
|
12996
|
-
},
|
|
12997
|
-
];
|
|
12998
|
-
function getGlobalActionUiSchema(id) {
|
|
12999
|
-
if (!id)
|
|
13000
|
-
return undefined;
|
|
13001
|
-
return GLOBAL_ACTION_UI_SCHEMAS.find((schema) => schema.id === id);
|
|
13002
|
-
}
|
|
13003
|
-
|
|
13004
|
-
const SURFACE_OPEN_PRESETS = [
|
|
13005
|
-
{
|
|
13006
|
-
id: 'praxis-dynamic-form',
|
|
13007
|
-
label: 'Formulário',
|
|
13008
|
-
description: 'Abre um formulário dinâmico com resourcePath, formId e resourceId.',
|
|
13009
|
-
payload: {
|
|
13010
|
-
presentation: 'drawer',
|
|
13011
|
-
widget: {
|
|
13012
|
-
id: 'praxis-dynamic-form',
|
|
13013
|
-
bindingOrder: ['resourcePath', 'formId', 'resourceId'],
|
|
13014
|
-
inputs: {
|
|
13015
|
-
resourcePath: '',
|
|
13016
|
-
formId: '',
|
|
13017
|
-
mode: 'view',
|
|
13018
|
-
},
|
|
13019
|
-
},
|
|
13020
|
-
bindings: [],
|
|
13021
|
-
},
|
|
13022
|
-
},
|
|
13023
|
-
{
|
|
13024
|
-
id: 'praxis-table',
|
|
13025
|
-
label: 'Tabela',
|
|
13026
|
-
description: 'Abre uma tabela filtrável usando inputs declarativos e queryContext.',
|
|
13027
|
-
payload: {
|
|
13028
|
-
presentation: 'drawer',
|
|
13029
|
-
widget: {
|
|
13030
|
-
id: 'praxis-table',
|
|
13031
|
-
bindingOrder: ['resourcePath', 'tableId', 'queryContext'],
|
|
13032
|
-
inputs: {
|
|
13033
|
-
resourcePath: '',
|
|
13034
|
-
tableId: '',
|
|
13035
|
-
queryContext: {
|
|
13036
|
-
filters: {},
|
|
13037
|
-
},
|
|
13038
|
-
},
|
|
13039
|
-
},
|
|
13040
|
-
bindings: [],
|
|
13041
|
-
},
|
|
13042
|
-
},
|
|
13043
|
-
{
|
|
13044
|
-
id: 'praxis-list',
|
|
13045
|
-
label: 'Lista',
|
|
13046
|
-
description: 'Abre uma lista com config/listId e bindings configuráveis.',
|
|
13047
|
-
payload: {
|
|
13048
|
-
presentation: 'drawer',
|
|
13049
|
-
widget: {
|
|
13050
|
-
id: 'praxis-list',
|
|
13051
|
-
bindingOrder: ['listId', 'config'],
|
|
13052
|
-
inputs: {
|
|
13053
|
-
listId: '',
|
|
13054
|
-
config: {},
|
|
13055
|
-
},
|
|
13056
|
-
},
|
|
13057
|
-
bindings: [],
|
|
13058
|
-
},
|
|
13059
|
-
},
|
|
13060
|
-
{
|
|
13061
|
-
id: 'praxis-crud',
|
|
13062
|
-
label: 'CRUD',
|
|
13063
|
-
description: 'Abre a surface de CRUD com inputs mínimos e bindings configuráveis.',
|
|
13064
|
-
payload: {
|
|
13065
|
-
presentation: 'drawer',
|
|
13066
|
-
widget: {
|
|
13067
|
-
id: 'praxis-crud',
|
|
13068
|
-
bindingOrder: ['resourcePath', 'formId', 'resourceId'],
|
|
13069
|
-
inputs: {
|
|
13070
|
-
resourcePath: '',
|
|
13071
|
-
formId: '',
|
|
13072
|
-
},
|
|
13073
|
-
},
|
|
13074
|
-
bindings: [],
|
|
13075
|
-
},
|
|
14306
|
+
id: 'copyToClipboard',
|
|
14307
|
+
label: 'Copiar para clipboard',
|
|
14308
|
+
fields: [
|
|
14309
|
+
{ key: 'text', label: 'Texto', type: 'text' },
|
|
14310
|
+
{ key: 'useFieldValue', label: 'Usar valor do campo', type: 'toggle' },
|
|
14311
|
+
],
|
|
14312
|
+
},
|
|
14313
|
+
{
|
|
14314
|
+
id: 'refreshOptions',
|
|
14315
|
+
label: 'Recarregar opções',
|
|
14316
|
+
fields: [{ key: 'field', label: 'Campo', type: 'text', required: true }],
|
|
14317
|
+
},
|
|
14318
|
+
{
|
|
14319
|
+
id: 'loadDependentData',
|
|
14320
|
+
label: 'Carregar dependentes',
|
|
14321
|
+
fields: [{ key: 'field', label: 'Campo alvo', type: 'text', required: true }],
|
|
13076
14322
|
},
|
|
13077
14323
|
];
|
|
14324
|
+
function getGlobalActionUiSchema(id) {
|
|
14325
|
+
if (!id)
|
|
14326
|
+
return undefined;
|
|
14327
|
+
return GLOBAL_ACTION_UI_SCHEMAS.find((schema) => schema.id === id);
|
|
14328
|
+
}
|
|
13078
14329
|
|
|
13079
14330
|
class SurfaceOpenActionEditorComponent {
|
|
13080
14331
|
value;
|
|
@@ -13806,7 +15057,7 @@ class SurfaceOpenActionEditorComponent {
|
|
|
13806
15057
|
</mat-form-field>
|
|
13807
15058
|
</div>
|
|
13808
15059
|
</div>
|
|
13809
|
-
`, 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:
|
|
15060
|
+
`, 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: i3$1.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: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
13810
15061
|
}
|
|
13811
15062
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SurfaceOpenActionEditorComponent, decorators: [{
|
|
13812
15063
|
type: Component,
|
|
@@ -15078,11 +16329,11 @@ const ENUMS = {
|
|
|
15078
16329
|
actionPlacement: ['header', 'window'],
|
|
15079
16330
|
};
|
|
15080
16331
|
const CAPS = [
|
|
15081
|
-
{ path: 'page', category: 'page', valueKind: 'object', description: '
|
|
16332
|
+
{ path: 'page', category: 'page', valueKind: 'object', description: 'Definicao da pagina dinamica.' },
|
|
15082
16333
|
{ path: 'page.context', category: 'context', valueKind: 'object', description: 'Contexto compartilhado entre widgets.' },
|
|
15083
|
-
{ path: 'page.layout', category: 'layout', valueKind: 'object', description: 'Layout base da
|
|
15084
|
-
{ path: 'page.layout.orientation', category: 'layout', valueKind: 'enum', allowedValues: ENUMS.layoutOrientation, description: '
|
|
15085
|
-
{ path: 'page.layout.columns', category: 'layout', valueKind: 'number', description: '
|
|
16334
|
+
{ path: 'page.layout', category: 'layout', valueKind: 'object', description: 'Layout base da pagina.' },
|
|
16335
|
+
{ path: 'page.layout.orientation', category: 'layout', valueKind: 'enum', allowedValues: ENUMS.layoutOrientation, description: 'Orientacao do grid (vertical/columns).' },
|
|
16336
|
+
{ path: 'page.layout.columns', category: 'layout', valueKind: 'number', description: 'Numero de colunas (quando orientation=columns).' },
|
|
15086
16337
|
{ path: 'page.layout.gap', category: 'layout', valueKind: 'string', description: 'Gap entre widgets (ex: 16px).' },
|
|
15087
16338
|
{ path: 'page.layout.breakpoints', category: 'layout', valueKind: 'object', description: 'Colunas por breakpoint.' },
|
|
15088
16339
|
{ path: 'page.layout.breakpoints.sm', category: 'layout', valueKind: 'number', description: 'Colunas para breakpoint sm.' },
|
|
@@ -15090,46 +16341,49 @@ const CAPS = [
|
|
|
15090
16341
|
{ path: 'page.layout.breakpoints.lg', category: 'layout', valueKind: 'number', description: 'Colunas para breakpoint lg.' },
|
|
15091
16342
|
{ path: 'page.layout.breakpoints.xl', category: 'layout', valueKind: 'number', description: 'Colunas para breakpoint xl.' },
|
|
15092
16343
|
{ path: 'page.widgets', category: 'widgets', valueKind: 'array', description: 'Lista de widgets renderizados.' },
|
|
15093
|
-
{ path: 'page.widgets[].key', category: 'widgets', valueKind: 'string', description: 'Identificador
|
|
16344
|
+
{ path: 'page.widgets[].key', category: 'widgets', valueKind: 'string', description: 'Identificador unico do widget.' },
|
|
15094
16345
|
{ path: 'page.widgets[].className', category: 'widgets', valueKind: 'string', description: 'Classe CSS opcional do widget.' },
|
|
15095
16346
|
{ path: 'page.widgets[].definition.id', category: 'widgets', valueKind: 'string', description: 'ID do componente do widget (ex: praxis-table).' },
|
|
15096
16347
|
{ path: 'page.widgets[].definition.inputs', category: 'widgets', valueKind: 'object', description: 'Inputs iniciais do widget.' },
|
|
15097
16348
|
{ path: 'page.widgets[].definition.bindingOrder', category: 'widgets', valueKind: 'array', description: 'Ordem de binding de inputs.' },
|
|
15098
|
-
{ path: 'page.widgets[].shell', category: 'shell', valueKind: 'object', description: '
|
|
16349
|
+
{ path: 'page.widgets[].shell', category: 'shell', valueKind: 'object', description: 'Configuracao do shell do widget.' },
|
|
15099
16350
|
{ path: 'page.widgets[].shell.kind', category: 'shell', valueKind: 'enum', allowedValues: ENUMS.shellKind, description: 'Tipo de shell.' },
|
|
15100
|
-
{ path: 'page.widgets[].shell.title', category: 'shell', valueKind: 'string', description: '
|
|
15101
|
-
{ path: 'page.widgets[].shell.subtitle', category: 'shell', valueKind: 'string', description: '
|
|
15102
|
-
{ path: 'page.widgets[].shell.icon', category: 'shell', valueKind: 'string', description: '
|
|
16351
|
+
{ path: 'page.widgets[].shell.title', category: 'shell', valueKind: 'string', description: 'Titulo do shell.' },
|
|
16352
|
+
{ path: 'page.widgets[].shell.subtitle', category: 'shell', valueKind: 'string', description: 'Subtitulo do shell.' },
|
|
16353
|
+
{ path: 'page.widgets[].shell.icon', category: 'shell', valueKind: 'string', description: 'Icone do shell.' },
|
|
15103
16354
|
{ path: 'page.widgets[].shell.showHeader', category: 'shell', valueKind: 'boolean', description: 'Exibe o header do shell.' },
|
|
15104
|
-
{ path: 'page.widgets[].shell.actions', category: 'shell', valueKind: 'array', description: '
|
|
15105
|
-
{ path: 'page.widgets[].shell.actions[].id', category: 'shell', valueKind: 'string', description: 'ID da
|
|
15106
|
-
{ path: 'page.widgets[].shell.actions[].label', category: 'shell', valueKind: 'string', description: 'Label da
|
|
15107
|
-
{ path: 'page.widgets[].shell.actions[].icon', category: 'shell', valueKind: 'string', description: '
|
|
15108
|
-
{ path: 'page.widgets[].shell.actions[].variant', category: 'shell', valueKind: 'enum', allowedValues: ENUMS.actionVariant, description: 'Estilo visual da
|
|
15109
|
-
{ path: 'page.widgets[].shell.actions[].placement', category: 'shell', valueKind: 'enum', allowedValues: ENUMS.actionPlacement, description: 'Posicionamento da
|
|
15110
|
-
{ path: 'page.widgets[].shell.actions[].emit', category: 'shell', valueKind: 'string', description: 'Evento emitido ao acionar a
|
|
15111
|
-
{ path: 'page.
|
|
15112
|
-
{ path: 'page.
|
|
15113
|
-
{ path: 'page.
|
|
15114
|
-
{ path: 'page.
|
|
15115
|
-
{ path: 'page.
|
|
15116
|
-
{ path: 'page.
|
|
15117
|
-
{ path: 'page.
|
|
15118
|
-
{ path: 'page.
|
|
16355
|
+
{ path: 'page.widgets[].shell.actions', category: 'shell', valueKind: 'array', description: 'Acoes do shell.' },
|
|
16356
|
+
{ path: 'page.widgets[].shell.actions[].id', category: 'shell', valueKind: 'string', description: 'ID da acao.' },
|
|
16357
|
+
{ path: 'page.widgets[].shell.actions[].label', category: 'shell', valueKind: 'string', description: 'Label da acao.' },
|
|
16358
|
+
{ path: 'page.widgets[].shell.actions[].icon', category: 'shell', valueKind: 'string', description: 'Icone da acao.' },
|
|
16359
|
+
{ path: 'page.widgets[].shell.actions[].variant', category: 'shell', valueKind: 'enum', allowedValues: ENUMS.actionVariant, description: 'Estilo visual da acao.' },
|
|
16360
|
+
{ path: 'page.widgets[].shell.actions[].placement', category: 'shell', valueKind: 'enum', allowedValues: ENUMS.actionPlacement, description: 'Posicionamento da acao.' },
|
|
16361
|
+
{ path: 'page.widgets[].shell.actions[].emit', category: 'shell', valueKind: 'string', description: 'Evento emitido ao acionar a acao.' },
|
|
16362
|
+
{ path: 'page.composition', category: 'connections', valueKind: 'object', description: 'Envelope canonico da composicao persistida.' },
|
|
16363
|
+
{ path: 'page.composition.version', category: 'connections', valueKind: 'string', description: 'Versao do envelope de composicao.' },
|
|
16364
|
+
{ path: 'page.composition.links', category: 'connections', valueKind: 'array', description: 'Links canonicos entre widgets e estado.' },
|
|
16365
|
+
{ path: 'page.composition.links[].id', category: 'connections', valueKind: 'string', description: 'Identificador estavel do link.' },
|
|
16366
|
+
{ path: 'page.composition.links[].from', category: 'connections', valueKind: 'object', description: 'Endpoint de origem do link.' },
|
|
16367
|
+
{ path: 'page.composition.links[].to', category: 'connections', valueKind: 'object', description: 'Endpoint de destino do link.' },
|
|
16368
|
+
{ path: 'page.composition.links[].intent', category: 'connections', valueKind: 'string', description: 'Intencao semantica do link.' },
|
|
16369
|
+
{ path: 'page.composition.links[].transform', category: 'connections', valueKind: 'object', description: 'Pipeline de transformacao do link.' },
|
|
16370
|
+
{ path: 'page.composition.links[].conditions', category: 'connections', valueKind: 'array', description: 'Condicoes opcionais de entrega.' },
|
|
16371
|
+
{ path: 'page.composition.links[].policy', category: 'connections', valueKind: 'object', description: 'Politicas opcionais de entrega.' },
|
|
16372
|
+
{ path: 'page.composition.links[].metadata', category: 'connections', valueKind: 'object', description: 'Metadados opcionais do link.' },
|
|
15119
16373
|
];
|
|
15120
16374
|
const DYNAMIC_PAGE_AI_CAPABILITIES = {
|
|
15121
16375
|
version: 'v1.0',
|
|
15122
16376
|
enums: ENUMS,
|
|
15123
16377
|
targets: ['praxis-dynamic-page'],
|
|
15124
16378
|
notes: [
|
|
15125
|
-
'Este
|
|
15126
|
-
'Widgets e
|
|
15127
|
-
'Para
|
|
15128
|
-
'Para
|
|
15129
|
-
'Inputs de widgets dependem do componente (ex: praxis-table, praxis-dynamic-form). Evite inventar campos; prefira pedir
|
|
15130
|
-
'Use
|
|
15131
|
-
'Objetivo: compor widgets e relacionamentos (ex.: master-detail).',
|
|
15132
|
-
'
|
|
16379
|
+
'Este catalogo e especifico para o componente praxis-dynamic-page.',
|
|
16380
|
+
'Widgets e page.composition.links sao arrays; o adapter faz merge por key estavel.',
|
|
16381
|
+
'Para remocao/replace, use flags {_remove:true} ou {_replace:true} no item.',
|
|
16382
|
+
'Para renomear um link, inclua {_beforeKey:"link-id-anterior"} no item.',
|
|
16383
|
+
'Inputs de widgets dependem do componente (ex: praxis-table, praxis-dynamic-form). Evite inventar campos; prefira pedir confirmacao.',
|
|
16384
|
+
'Use ids estaveis para links e keys estaveis para widgets.',
|
|
16385
|
+
'Objetivo: compor widgets e relacionamentos canonicos (ex.: master-detail).',
|
|
16386
|
+
'Link tipico de master-detail: component-port(table.rowClick) -> component-port(form.resourceId) com transform map payload.row.id.',
|
|
15133
16387
|
],
|
|
15134
16388
|
capabilities: CAPS,
|
|
15135
16389
|
};
|
|
@@ -15154,7 +16408,7 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
15154
16408
|
'page.widgets[].shell.actions[].variant': {
|
|
15155
16409
|
mode: 'enum',
|
|
15156
16410
|
options: [
|
|
15157
|
-
{ value: 'icon', label: '
|
|
16411
|
+
{ value: 'icon', label: 'Icone' },
|
|
15158
16412
|
{ value: 'text', label: 'Texto' },
|
|
15159
16413
|
{ value: 'outlined', label: 'Outlined' },
|
|
15160
16414
|
],
|
|
@@ -15166,25 +16420,39 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
15166
16420
|
{ value: 'window', label: 'Janela' },
|
|
15167
16421
|
],
|
|
15168
16422
|
},
|
|
15169
|
-
'page.
|
|
16423
|
+
'page.composition.version': {
|
|
16424
|
+
mode: 'enum',
|
|
16425
|
+
options: [
|
|
16426
|
+
{ value: '1.0.0', label: 'Schema canonico 1.0.0' },
|
|
16427
|
+
],
|
|
16428
|
+
},
|
|
16429
|
+
'page.composition.links[].intent': {
|
|
16430
|
+
mode: 'enum',
|
|
16431
|
+
options: [
|
|
16432
|
+
{ value: 'event-propagation', label: 'Propagacao de evento' },
|
|
16433
|
+
{ value: 'state-read', label: 'Leitura de estado' },
|
|
16434
|
+
{ value: 'state-write', label: 'Escrita de estado' },
|
|
16435
|
+
],
|
|
16436
|
+
},
|
|
16437
|
+
'page.composition.links[].from.ref.port': {
|
|
15170
16438
|
mode: 'suggested',
|
|
15171
16439
|
options: [
|
|
15172
|
-
{ value: 'rowClick', label: 'Clique na linha (praxis-table)', example: 'Usar table.rowClick -> form.resourceId' },
|
|
15173
|
-
{ value: 'rowAction', label: '
|
|
15174
|
-
{ value: 'formSubmit', label: 'Submit do
|
|
16440
|
+
{ value: 'rowClick', label: 'Clique na linha (praxis-table)', example: 'Usar table.rowClick -> form.resourceId via transform pick-path payload.row.id' },
|
|
16441
|
+
{ value: 'rowAction', label: 'Acao da linha (praxis-table)' },
|
|
16442
|
+
{ value: 'formSubmit', label: 'Submit do formulario (praxis-dynamic-form)' },
|
|
15175
16443
|
],
|
|
15176
16444
|
},
|
|
15177
|
-
'page.
|
|
16445
|
+
'page.composition.links[].to.ref.port': {
|
|
15178
16446
|
mode: 'suggested',
|
|
15179
16447
|
options: [
|
|
15180
|
-
{ value: 'resourceId', label: 'ID do registro (praxis-dynamic-form)', example: '
|
|
15181
|
-
{ value: 'mode', label: 'Modo do
|
|
16448
|
+
{ value: 'resourceId', label: 'ID do registro (praxis-dynamic-form)', example: 'transform pick-path payload.row.id' },
|
|
16449
|
+
{ value: 'mode', label: 'Modo do formulario (create|edit|view)' },
|
|
15182
16450
|
],
|
|
15183
16451
|
},
|
|
15184
|
-
'page.
|
|
16452
|
+
'page.composition.links[].transform.steps[].config.path': {
|
|
15185
16453
|
mode: 'suggested',
|
|
15186
16454
|
options: [
|
|
15187
|
-
{ value: 'payload.row.id', label: 'ID
|
|
16455
|
+
{ value: 'payload.row.id', label: 'ID padrao do registro', example: 'rowClick -> resourceId' },
|
|
15188
16456
|
],
|
|
15189
16457
|
},
|
|
15190
16458
|
},
|
|
@@ -15208,21 +16476,20 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
15208
16476
|
requiresExistingTarget: true,
|
|
15209
16477
|
scope: 'ROW',
|
|
15210
16478
|
params: [
|
|
15211
|
-
{ name: '
|
|
15212
|
-
{ name: 'fromOutput', type: 'STRING' },
|
|
15213
|
-
{ name: 'toWidget', type: 'STRING' },
|
|
15214
|
-
{ name: 'toInput', type: 'STRING' },
|
|
16479
|
+
{ name: 'linkId', type: 'STRING' },
|
|
15215
16480
|
],
|
|
15216
16481
|
patchTemplate: {
|
|
15217
16482
|
page: {
|
|
15218
|
-
|
|
15219
|
-
|
|
15220
|
-
|
|
15221
|
-
|
|
15222
|
-
|
|
15223
|
-
|
|
15224
|
-
|
|
15225
|
-
|
|
16483
|
+
composition: {
|
|
16484
|
+
version: '1.0.0',
|
|
16485
|
+
links: [
|
|
16486
|
+
{
|
|
16487
|
+
_beforeKey: '{{target}}',
|
|
16488
|
+
id: '{{params.linkId}}',
|
|
16489
|
+
_remove: true,
|
|
16490
|
+
},
|
|
16491
|
+
],
|
|
16492
|
+
},
|
|
15226
16493
|
},
|
|
15227
16494
|
},
|
|
15228
16495
|
},
|
|
@@ -15323,14 +16590,40 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
15323
16590
|
],
|
|
15324
16591
|
patchTemplate: {
|
|
15325
16592
|
page: {
|
|
15326
|
-
|
|
15327
|
-
|
|
15328
|
-
|
|
15329
|
-
|
|
15330
|
-
|
|
15331
|
-
|
|
15332
|
-
|
|
15333
|
-
|
|
16593
|
+
composition: {
|
|
16594
|
+
version: '1.0.0',
|
|
16595
|
+
links: [
|
|
16596
|
+
{
|
|
16597
|
+
id: '{{params.fromWidget}}.{{params.fromOutput}}->{{params.toWidget}}.{{params.toInput}}',
|
|
16598
|
+
from: {
|
|
16599
|
+
kind: 'component-port',
|
|
16600
|
+
ref: { widget: '{{params.fromWidget}}', port: '{{params.fromOutput}}', direction: 'output' },
|
|
16601
|
+
},
|
|
16602
|
+
to: {
|
|
16603
|
+
kind: 'component-port',
|
|
16604
|
+
ref: { widget: '{{params.toWidget}}', port: '{{params.toInput}}', direction: 'input' },
|
|
16605
|
+
},
|
|
16606
|
+
intent: 'event-propagation',
|
|
16607
|
+
transform: {
|
|
16608
|
+
version: '2.0',
|
|
16609
|
+
phase: 'link-propagation',
|
|
16610
|
+
mode: 'single-value',
|
|
16611
|
+
steps: [
|
|
16612
|
+
{
|
|
16613
|
+
id: 'constant-value',
|
|
16614
|
+
kind: 'constant',
|
|
16615
|
+
phase: 'link-propagation',
|
|
16616
|
+
config: { value: '{{params.value}}' },
|
|
16617
|
+
},
|
|
16618
|
+
],
|
|
16619
|
+
},
|
|
16620
|
+
metadata: {
|
|
16621
|
+
source: 'persisted-composition-link',
|
|
16622
|
+
},
|
|
16623
|
+
_replace: true,
|
|
16624
|
+
},
|
|
16625
|
+
],
|
|
16626
|
+
},
|
|
15334
16627
|
},
|
|
15335
16628
|
},
|
|
15336
16629
|
},
|
|
@@ -15372,13 +16665,27 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
15372
16665
|
],
|
|
15373
16666
|
patchTemplate: {
|
|
15374
16667
|
page: {
|
|
15375
|
-
|
|
15376
|
-
|
|
15377
|
-
|
|
15378
|
-
|
|
15379
|
-
|
|
15380
|
-
|
|
15381
|
-
|
|
16668
|
+
composition: {
|
|
16669
|
+
version: '1.0.0',
|
|
16670
|
+
links: [
|
|
16671
|
+
{
|
|
16672
|
+
_beforeKey: '{{params.beforeFromWidget}}.{{params.beforeFromOutput}}->{{params.beforeToWidget}}.{{params.beforeToInput}}',
|
|
16673
|
+
id: '{{params.fromWidget}}.{{params.fromOutput}}->{{params.toWidget}}.{{params.toInput}}',
|
|
16674
|
+
from: {
|
|
16675
|
+
kind: 'component-port',
|
|
16676
|
+
ref: { widget: '{{params.fromWidget}}', port: '{{params.fromOutput}}', direction: 'output' },
|
|
16677
|
+
},
|
|
16678
|
+
to: {
|
|
16679
|
+
kind: 'component-port',
|
|
16680
|
+
ref: { widget: '{{params.toWidget}}', port: '{{params.toInput}}', direction: 'input' },
|
|
16681
|
+
},
|
|
16682
|
+
intent: 'event-propagation',
|
|
16683
|
+
metadata: {
|
|
16684
|
+
source: 'persisted-composition-link',
|
|
16685
|
+
},
|
|
16686
|
+
},
|
|
16687
|
+
],
|
|
16688
|
+
},
|
|
15382
16689
|
},
|
|
15383
16690
|
},
|
|
15384
16691
|
},
|
|
@@ -15392,7 +16699,7 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
15392
16699
|
{ name: 'widgetKey', type: 'STRING' },
|
|
15393
16700
|
{ name: 'resourcePath', type: 'STRING' },
|
|
15394
16701
|
],
|
|
15395
|
-
safetyNotes: 'Use apenas resourcePath base. Evite inventar colunas; deixe config
|
|
16702
|
+
safetyNotes: 'Use apenas resourcePath base. Evite inventar colunas; deixe config minima.',
|
|
15396
16703
|
patchTemplate: {
|
|
15397
16704
|
page: {
|
|
15398
16705
|
widgets: [
|
|
@@ -15457,17 +16764,44 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
15457
16764
|
{ name: 'toInput', type: 'STRING' },
|
|
15458
16765
|
{ name: 'map', type: 'STRING' },
|
|
15459
16766
|
],
|
|
15460
|
-
safetyNotes: 'Use
|
|
16767
|
+
safetyNotes: 'Use transform pick-path payload.row.id para master-detail padrao.',
|
|
15461
16768
|
patchTemplate: {
|
|
15462
16769
|
page: {
|
|
15463
|
-
|
|
15464
|
-
|
|
15465
|
-
|
|
15466
|
-
|
|
15467
|
-
|
|
15468
|
-
|
|
15469
|
-
|
|
15470
|
-
|
|
16770
|
+
composition: {
|
|
16771
|
+
version: '1.0.0',
|
|
16772
|
+
links: [
|
|
16773
|
+
{
|
|
16774
|
+
id: '{{params.fromWidget}}.{{params.fromOutput}}->{{params.toWidget}}.{{params.toInput}}',
|
|
16775
|
+
from: {
|
|
16776
|
+
kind: 'component-port',
|
|
16777
|
+
ref: { widget: '{{params.fromWidget}}', port: '{{params.fromOutput}}', direction: 'output' },
|
|
16778
|
+
},
|
|
16779
|
+
to: {
|
|
16780
|
+
kind: 'component-port',
|
|
16781
|
+
ref: { widget: '{{params.toWidget}}', port: '{{params.toInput}}', direction: 'input' },
|
|
16782
|
+
},
|
|
16783
|
+
intent: 'event-propagation',
|
|
16784
|
+
transform: {
|
|
16785
|
+
version: '2.0',
|
|
16786
|
+
phase: 'link-propagation',
|
|
16787
|
+
mode: 'single-value',
|
|
16788
|
+
steps: [
|
|
16789
|
+
{
|
|
16790
|
+
id: 'pick-master-detail-value',
|
|
16791
|
+
kind: 'pick-path',
|
|
16792
|
+
phase: 'link-propagation',
|
|
16793
|
+
input: { source: 'event' },
|
|
16794
|
+
config: { path: '{{params.map}}' },
|
|
16795
|
+
},
|
|
16796
|
+
],
|
|
16797
|
+
},
|
|
16798
|
+
metadata: {
|
|
16799
|
+
source: 'persisted-composition-link',
|
|
16800
|
+
},
|
|
16801
|
+
_replace: true,
|
|
16802
|
+
},
|
|
16803
|
+
],
|
|
16804
|
+
},
|
|
15471
16805
|
},
|
|
15472
16806
|
},
|
|
15473
16807
|
},
|
|
@@ -15481,17 +16815,44 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
15481
16815
|
{ name: 'fromWidget', type: 'STRING' },
|
|
15482
16816
|
{ name: 'toWidget', type: 'STRING' },
|
|
15483
16817
|
],
|
|
15484
|
-
safetyNotes: 'Padrao master-detail: rowClick -> resourceId com
|
|
16818
|
+
safetyNotes: 'Padrao master-detail: rowClick -> resourceId com transform pick-path payload.row.id.',
|
|
15485
16819
|
patchTemplate: {
|
|
15486
16820
|
page: {
|
|
15487
|
-
|
|
15488
|
-
|
|
15489
|
-
|
|
15490
|
-
|
|
15491
|
-
|
|
15492
|
-
|
|
15493
|
-
|
|
15494
|
-
|
|
16821
|
+
composition: {
|
|
16822
|
+
version: '1.0.0',
|
|
16823
|
+
links: [
|
|
16824
|
+
{
|
|
16825
|
+
id: '{{params.fromWidget}}.rowClick->{{params.toWidget}}.resourceId',
|
|
16826
|
+
from: {
|
|
16827
|
+
kind: 'component-port',
|
|
16828
|
+
ref: { widget: '{{params.fromWidget}}', port: 'rowClick', direction: 'output' },
|
|
16829
|
+
},
|
|
16830
|
+
to: {
|
|
16831
|
+
kind: 'component-port',
|
|
16832
|
+
ref: { widget: '{{params.toWidget}}', port: 'resourceId', direction: 'input' },
|
|
16833
|
+
},
|
|
16834
|
+
intent: 'event-propagation',
|
|
16835
|
+
transform: {
|
|
16836
|
+
version: '2.0',
|
|
16837
|
+
phase: 'link-propagation',
|
|
16838
|
+
mode: 'single-value',
|
|
16839
|
+
steps: [
|
|
16840
|
+
{
|
|
16841
|
+
id: 'pick-master-row-id',
|
|
16842
|
+
kind: 'pick-path',
|
|
16843
|
+
phase: 'link-propagation',
|
|
16844
|
+
input: { source: 'event' },
|
|
16845
|
+
config: { path: 'payload.row.id' },
|
|
16846
|
+
},
|
|
16847
|
+
],
|
|
16848
|
+
},
|
|
16849
|
+
metadata: {
|
|
16850
|
+
source: 'persisted-composition-link',
|
|
16851
|
+
},
|
|
16852
|
+
_replace: true,
|
|
16853
|
+
},
|
|
16854
|
+
],
|
|
16855
|
+
},
|
|
15495
16856
|
},
|
|
15496
16857
|
},
|
|
15497
16858
|
},
|
|
@@ -15506,7 +16867,7 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
15506
16867
|
{ name: 'formId', type: 'STRING' },
|
|
15507
16868
|
{ name: 'resourcePath', type: 'STRING' },
|
|
15508
16869
|
],
|
|
15509
|
-
safetyNotes: 'Padrao master-detail: tabela (rowClick) -> formulario (resourceId) com
|
|
16870
|
+
safetyNotes: 'Padrao master-detail: tabela (rowClick) -> formulario (resourceId) com transform pick-path payload.row.id.',
|
|
15510
16871
|
patchTemplate: {
|
|
15511
16872
|
page: {
|
|
15512
16873
|
widgets: [
|
|
@@ -15537,45 +16898,72 @@ const DYNAMIC_PAGE_COMPONENT_CONTEXT_PACK = {
|
|
|
15537
16898
|
_replace: true,
|
|
15538
16899
|
},
|
|
15539
16900
|
],
|
|
15540
|
-
|
|
15541
|
-
|
|
15542
|
-
|
|
15543
|
-
|
|
15544
|
-
|
|
15545
|
-
|
|
15546
|
-
|
|
15547
|
-
|
|
16901
|
+
composition: {
|
|
16902
|
+
version: '1.0.0',
|
|
16903
|
+
links: [
|
|
16904
|
+
{
|
|
16905
|
+
id: '{{params.tableId}}.rowClick->{{params.formId}}.resourceId',
|
|
16906
|
+
from: {
|
|
16907
|
+
kind: 'component-port',
|
|
16908
|
+
ref: { widget: '{{params.tableId}}', port: 'rowClick', direction: 'output' },
|
|
16909
|
+
},
|
|
16910
|
+
to: {
|
|
16911
|
+
kind: 'component-port',
|
|
16912
|
+
ref: { widget: '{{params.formId}}', port: 'resourceId', direction: 'input' },
|
|
16913
|
+
},
|
|
16914
|
+
intent: 'event-propagation',
|
|
16915
|
+
transform: {
|
|
16916
|
+
version: '2.0',
|
|
16917
|
+
phase: 'link-propagation',
|
|
16918
|
+
mode: 'single-value',
|
|
16919
|
+
steps: [
|
|
16920
|
+
{
|
|
16921
|
+
id: 'pick-master-row-id',
|
|
16922
|
+
kind: 'pick-path',
|
|
16923
|
+
phase: 'link-propagation',
|
|
16924
|
+
input: { source: 'event' },
|
|
16925
|
+
config: { path: 'payload.row.id' },
|
|
16926
|
+
},
|
|
16927
|
+
],
|
|
16928
|
+
},
|
|
16929
|
+
metadata: {
|
|
16930
|
+
source: 'persisted-composition-link',
|
|
16931
|
+
},
|
|
16932
|
+
_replace: true,
|
|
16933
|
+
},
|
|
16934
|
+
],
|
|
16935
|
+
},
|
|
15548
16936
|
},
|
|
15549
16937
|
},
|
|
15550
16938
|
},
|
|
15551
16939
|
],
|
|
15552
16940
|
fieldResolvers: {
|
|
15553
16941
|
'page.widgets[]': ['key'],
|
|
15554
|
-
'page.
|
|
16942
|
+
'page.composition.links[]': ['id'],
|
|
15555
16943
|
},
|
|
15556
16944
|
hints: [
|
|
15557
|
-
'praxis-dynamic-page
|
|
15558
|
-
'Widgets e
|
|
15559
|
-
'Preferir
|
|
15560
|
-
'Para remover um item, envie {_remove: true} junto ao widget/
|
|
16945
|
+
'praxis-dynamic-page e um host de composicao: cria widgets, conecta ports canonicos e mantem relacoes em page.composition.links.',
|
|
16946
|
+
'Widgets e composition.links sao arrays; o patching deve fazer merge por key (widgets) e por id (links).',
|
|
16947
|
+
'Preferir mudancas incrementais: alterar/estender em vez de substituir toda a pagina.',
|
|
16948
|
+
'Para remover um item, envie {_remove: true} junto ao widget/link.',
|
|
15561
16949
|
'Para substituir um item inteiro, envie {_replace: true}.',
|
|
15562
|
-
'Para alterar origem/destino de
|
|
15563
|
-
'Use keys
|
|
15564
|
-
'resourcePath sempre
|
|
16950
|
+
'Para alterar origem/destino de link, use {_beforeKey} com o id antigo.',
|
|
16951
|
+
'Use keys estaveis para widgets e ids estaveis para links ao criar composicoes.',
|
|
16952
|
+
'resourcePath sempre e o path base do recurso (sem /filter, /all).',
|
|
15565
16953
|
'Praxis Table gera colunas dinamicamente a partir do resourcePath quando columns nao forem definidas.',
|
|
15566
16954
|
'Praxis Dynamic Form gera campos dinamicamente a partir do resourcePath quando config nao for definida.',
|
|
15567
16955
|
'Praxis List pode filtrar via config.dataSource.query (enviado para /filter).',
|
|
15568
16956
|
'Quando houver recursos secundarios (ex.: enderecos), use contextHints.addressResourcePath.',
|
|
15569
|
-
'Exemplo master-detail: tabela emite rowClick -> form.resourceId
|
|
15570
|
-
'Pattern Master-Detail: { "from":
|
|
15571
|
-
'Ao criar widgets, use inputs
|
|
15572
|
-
'Quando widgets
|
|
15573
|
-
'
|
|
15574
|
-
'
|
|
15575
|
-
'Exemplo de
|
|
15576
|
-
'Exemplo de widget tabela (
|
|
15577
|
-
'Exemplo de widget
|
|
15578
|
-
'Se houver idField conhecido, use
|
|
16957
|
+
'Exemplo master-detail: tabela emite rowClick -> form.resourceId via transform pick-path payload.row.id.',
|
|
16958
|
+
'Pattern Master-Detail: { "id":"master.rowClick->detail.resourceId", "from":{"kind":"component-port","ref":{"port":"rowClick","direction":"output"}}, "to":{"kind":"component-port","ref":{"port":"resourceId","direction":"input"}}, "transform":{"steps":[{"kind":"pick-path","config":{"path":"payload.row.id"}}]}}',
|
|
16959
|
+
'Ao criar widgets, use inputs minimos e complemente depois (evite inventar campos).',
|
|
16960
|
+
'Quando widgets ja existem, interpretar ports de origem/destino antes de conectar.',
|
|
16961
|
+
'Intencao comum: criar pagina master-detail = criar tabela + criar formulario + conectar selecao via composition.links.',
|
|
16962
|
+
'Intencao comum: ajustar pagina existente = modificar apenas widgets/inputs necessarios.',
|
|
16963
|
+
'Exemplo de link canonico (master-detail): { id:"masterTable.rowClick->detailForm.resourceId", from:{kind:"component-port",ref:{widget:"masterTable",port:"rowClick",direction:"output"}}, to:{kind:"component-port",ref:{widget:"detailForm",port:"resourceId",direction:"input"}}, intent:"event-propagation", transform:{version:"2.0",phase:"link-propagation",mode:"single-value",steps:[{kind:"pick-path",phase:"link-propagation",input:{source:"event"},config:{path:"payload.row.id"}}]}}',
|
|
16964
|
+
'Exemplo de widget tabela (minimo): { key:"masterTable", definition:{ id:"praxis-table", inputs:{ resourcePath:"/api/x" }}}',
|
|
16965
|
+
'Exemplo de widget formulario (minimo): { key:"detailForm", definition:{ id:"praxis-dynamic-form", inputs:{ resourcePath:"/api/x", mode:"view" }}}',
|
|
16966
|
+
'Se houver idField conhecido, use transform pick-path payload.row.{idField} em links canonicos.',
|
|
15579
16967
|
],
|
|
15580
16968
|
};
|
|
15581
16969
|
|
|
@@ -16072,7 +17460,7 @@ class PraxisRichTextBlockComponent {
|
|
|
16072
17460
|
|
|
16073
17461
|
<div class="prt-content" [innerHTML]="renderedContent"></div>
|
|
16074
17462
|
</section>
|
|
16075
|
-
`, 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:
|
|
17463
|
+
`, 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: i3$1.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 });
|
|
16076
17464
|
}
|
|
16077
17465
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisRichTextBlockComponent, decorators: [{
|
|
16078
17466
|
type: Component,
|
|
@@ -17313,7 +18701,7 @@ class WidgetShellComponent {
|
|
|
17313
18701
|
@if (expanded || fullscreen) {
|
|
17314
18702
|
<div class="pdx-shell-backdrop" (click)="closeOverlay()"></div>
|
|
17315
18703
|
}
|
|
17316
|
-
`, 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-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.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:
|
|
18704
|
+
`, 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-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.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:var(--praxis-layer-widget-shell-expanded, 1290);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:var(--praxis-layer-widget-shell-fullscreen, 1291);box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:var(--praxis-layer-widget-shell-backdrop, 1280);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: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4.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.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4.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: i8.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 });
|
|
17317
18705
|
}
|
|
17318
18706
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: WidgetShellComponent, decorators: [{
|
|
17319
18707
|
type: Component,
|
|
@@ -17449,7 +18837,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
17449
18837
|
@if (expanded || fullscreen) {
|
|
17450
18838
|
<div class="pdx-shell-backdrop" (click)="closeOverlay()"></div>
|
|
17451
18839
|
}
|
|
17452
|
-
`, changeDetection: ChangeDetectionStrategy.OnPush, 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-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.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:
|
|
18840
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, 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-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.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:var(--praxis-layer-widget-shell-expanded, 1290);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:var(--praxis-layer-widget-shell-fullscreen, 1291);box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:var(--praxis-layer-widget-shell-backdrop, 1280);background:#0000008c;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}\n"] }]
|
|
17453
18841
|
}], propDecorators: { shell: [{
|
|
17454
18842
|
type: Input
|
|
17455
18843
|
}], context: [{
|
|
@@ -17824,10 +19212,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
17824
19212
|
}] });
|
|
17825
19213
|
|
|
17826
19214
|
class WidgetPageStateRuntimeService {
|
|
17827
|
-
connections;
|
|
17828
|
-
constructor(connections) {
|
|
17829
|
-
this.connections = connections;
|
|
17830
|
-
}
|
|
19215
|
+
connections = new ConnectionManagerService();
|
|
17831
19216
|
normalizeState(state) {
|
|
17832
19217
|
if (!state)
|
|
17833
19218
|
return { values: {} };
|
|
@@ -17855,12 +19240,19 @@ class WidgetPageStateRuntimeService {
|
|
|
17855
19240
|
const node = normalized.derived?.[key];
|
|
17856
19241
|
if (!node)
|
|
17857
19242
|
continue;
|
|
17858
|
-
|
|
17859
|
-
|
|
17860
|
-
|
|
17861
|
-
|
|
17862
|
-
|
|
17863
|
-
|
|
19243
|
+
let value;
|
|
19244
|
+
try {
|
|
19245
|
+
value = this.computeDerivedNode(node, {
|
|
19246
|
+
state: effectiveValues,
|
|
19247
|
+
values: primaryValues,
|
|
19248
|
+
derived: derivedValues,
|
|
19249
|
+
context: this.clone(context) || {},
|
|
19250
|
+
}, diagnostics, key);
|
|
19251
|
+
}
|
|
19252
|
+
catch (error) {
|
|
19253
|
+
diagnostics.push(`Derived state '${key}' failed: ${this.describeError(error)}`);
|
|
19254
|
+
continue;
|
|
19255
|
+
}
|
|
17864
19256
|
if (value === undefined)
|
|
17865
19257
|
continue;
|
|
17866
19258
|
effectiveValues = this.connections.setValueAtPath(effectiveValues, key, this.clone(value));
|
|
@@ -17909,7 +19301,8 @@ class WidgetPageStateRuntimeService {
|
|
|
17909
19301
|
visiting.add(key);
|
|
17910
19302
|
const deps = derived[key]?.dependsOn || [];
|
|
17911
19303
|
for (const dep of deps) {
|
|
17912
|
-
const
|
|
19304
|
+
const normalizedDependency = this.normalizeDependencyPath(dep);
|
|
19305
|
+
const dependencyKey = keys.find((candidate) => (normalizedDependency === candidate || normalizedDependency.startsWith(`${candidate}.`)));
|
|
17913
19306
|
if (!dependencyKey)
|
|
17914
19307
|
continue;
|
|
17915
19308
|
visit(dependencyKey, [...stack, key]);
|
|
@@ -17924,8 +19317,10 @@ class WidgetPageStateRuntimeService {
|
|
|
17924
19317
|
}
|
|
17925
19318
|
computeDerivedNode(node, env, diagnostics, key) {
|
|
17926
19319
|
const compute = node.compute;
|
|
17927
|
-
if (!compute)
|
|
19320
|
+
if (!compute) {
|
|
19321
|
+
diagnostics.push(`Derived state '${key}' is missing compute definition.`);
|
|
17928
19322
|
return undefined;
|
|
19323
|
+
}
|
|
17929
19324
|
if (compute.kind === 'template') {
|
|
17930
19325
|
return this.resolveTemplate(compute.value, env);
|
|
17931
19326
|
}
|
|
@@ -17936,9 +19331,16 @@ class WidgetPageStateRuntimeService {
|
|
|
17936
19331
|
diagnostics.push(`Derived state '${key}' references transformer '${compute.transformerId}', but transformer runtime is not implemented yet.`);
|
|
17937
19332
|
return undefined;
|
|
17938
19333
|
}
|
|
17939
|
-
if (compute.kind !== 'operator')
|
|
19334
|
+
if (compute.kind !== 'operator') {
|
|
19335
|
+
const computeKind = compute.kind;
|
|
19336
|
+
diagnostics.push(`Derived state '${key}' uses unsupported compute kind '${String(computeKind ?? '')}'.`);
|
|
17940
19337
|
return undefined;
|
|
19338
|
+
}
|
|
17941
19339
|
const operator = (compute.operator || '').trim();
|
|
19340
|
+
if (!operator) {
|
|
19341
|
+
diagnostics.push(`Derived state '${key}' uses operator compute without a valid operator.`);
|
|
19342
|
+
return undefined;
|
|
19343
|
+
}
|
|
17942
19344
|
const options = compute.options || {};
|
|
17943
19345
|
const sources = this.resolveSourceValues(node.dependsOn, env.state);
|
|
17944
19346
|
switch (operator) {
|
|
@@ -18048,13 +19450,17 @@ class WidgetPageStateRuntimeService {
|
|
|
18048
19450
|
}
|
|
18049
19451
|
}
|
|
18050
19452
|
resolveNamedSource(sourcePath, sources, effectiveState) {
|
|
18051
|
-
|
|
18052
|
-
|
|
19453
|
+
const normalizedSourcePath = this.normalizeDependencyPath(sourcePath);
|
|
19454
|
+
if (normalizedSourcePath) {
|
|
19455
|
+
return this.readPath(effectiveState, normalizedSourcePath);
|
|
18053
19456
|
}
|
|
18054
19457
|
return sources[0];
|
|
18055
19458
|
}
|
|
18056
19459
|
resolveSourceValues(paths, state) {
|
|
18057
|
-
return (paths || [])
|
|
19460
|
+
return (paths || [])
|
|
19461
|
+
.map((path) => this.normalizeDependencyPath(path))
|
|
19462
|
+
.filter(Boolean)
|
|
19463
|
+
.map((path) => this.readPath(state, path));
|
|
18058
19464
|
}
|
|
18059
19465
|
aggregateArray(rows, metrics) {
|
|
18060
19466
|
const output = {};
|
|
@@ -18217,6 +19623,22 @@ class WidgetPageStateRuntimeService {
|
|
|
18217
19623
|
}
|
|
18218
19624
|
return node;
|
|
18219
19625
|
}
|
|
19626
|
+
normalizeDependencyPath(path) {
|
|
19627
|
+
if (typeof path !== 'string')
|
|
19628
|
+
return '';
|
|
19629
|
+
const trimmed = path.trim();
|
|
19630
|
+
if (!trimmed)
|
|
19631
|
+
return '';
|
|
19632
|
+
const exactTemplate = trimmed.match(/^\$\{([^}]+)\}$/);
|
|
19633
|
+
const normalized = exactTemplate ? exactTemplate[1].trim() : trimmed;
|
|
19634
|
+
if (normalized.startsWith('state.')) {
|
|
19635
|
+
return normalized.slice('state.'.length);
|
|
19636
|
+
}
|
|
19637
|
+
if (normalized.startsWith('derived.')) {
|
|
19638
|
+
return normalized.slice('derived.'.length);
|
|
19639
|
+
}
|
|
19640
|
+
return normalized;
|
|
19641
|
+
}
|
|
18220
19642
|
readPath(source, path) {
|
|
18221
19643
|
if (!path)
|
|
18222
19644
|
return source;
|
|
@@ -18292,213 +19714,20 @@ class WidgetPageStateRuntimeService {
|
|
|
18292
19714
|
return value;
|
|
18293
19715
|
return JSON.parse(JSON.stringify(value));
|
|
18294
19716
|
}
|
|
18295
|
-
|
|
19717
|
+
describeError(error) {
|
|
19718
|
+
if (error instanceof Error)
|
|
19719
|
+
return error.message;
|
|
19720
|
+
if (typeof error === 'string')
|
|
19721
|
+
return error;
|
|
19722
|
+
return 'Unknown runtime error';
|
|
19723
|
+
}
|
|
19724
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: WidgetPageStateRuntimeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
18296
19725
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: WidgetPageStateRuntimeService, providedIn: 'root' });
|
|
18297
19726
|
}
|
|
18298
19727
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: WidgetPageStateRuntimeService, decorators: [{
|
|
18299
19728
|
type: Injectable,
|
|
18300
19729
|
args: [{ providedIn: 'root' }]
|
|
18301
|
-
}]
|
|
18302
|
-
|
|
18303
|
-
function adaptWidgetConnectionToCompositionLink(connection) {
|
|
18304
|
-
const from = adaptSource(connection);
|
|
18305
|
-
const to = adaptTarget(connection);
|
|
18306
|
-
return {
|
|
18307
|
-
id: buildLinkId(connection),
|
|
18308
|
-
from,
|
|
18309
|
-
to,
|
|
18310
|
-
intent: resolveIntent(from, to),
|
|
18311
|
-
transform: adaptTransform(connection),
|
|
18312
|
-
conditions: adaptConditions(connection),
|
|
18313
|
-
policy: adaptPolicy(connection),
|
|
18314
|
-
metadata: {
|
|
18315
|
-
source: 'legacy-widget-connection',
|
|
18316
|
-
traceKey: buildTraceKey(connection),
|
|
18317
|
-
},
|
|
18318
|
-
};
|
|
18319
|
-
}
|
|
18320
|
-
function adaptWidgetConnectionsToCompositionLinks(connections) {
|
|
18321
|
-
return (connections || []).map((connection) => adaptWidgetConnectionToCompositionLink(connection));
|
|
18322
|
-
}
|
|
18323
|
-
function adaptSource(connection) {
|
|
18324
|
-
if ('widget' in connection.from) {
|
|
18325
|
-
return {
|
|
18326
|
-
kind: 'component-port',
|
|
18327
|
-
ref: {
|
|
18328
|
-
widget: connection.from.widget,
|
|
18329
|
-
port: connection.from.output,
|
|
18330
|
-
direction: 'output',
|
|
18331
|
-
},
|
|
18332
|
-
};
|
|
18333
|
-
}
|
|
18334
|
-
return {
|
|
18335
|
-
kind: 'state',
|
|
18336
|
-
ref: {
|
|
18337
|
-
path: connection.from.state,
|
|
18338
|
-
writable: false,
|
|
18339
|
-
},
|
|
18340
|
-
};
|
|
18341
|
-
}
|
|
18342
|
-
function adaptTarget(connection) {
|
|
18343
|
-
if ('widget' in connection.to) {
|
|
18344
|
-
const binding = normalizeBindingPath(connection.to.input);
|
|
18345
|
-
return {
|
|
18346
|
-
kind: 'component-port',
|
|
18347
|
-
ref: {
|
|
18348
|
-
widget: connection.to.widget,
|
|
18349
|
-
port: binding.port,
|
|
18350
|
-
direction: 'input',
|
|
18351
|
-
bindingPath: binding.bindingPath,
|
|
18352
|
-
},
|
|
18353
|
-
};
|
|
18354
|
-
}
|
|
18355
|
-
return {
|
|
18356
|
-
kind: 'state',
|
|
18357
|
-
ref: {
|
|
18358
|
-
path: connection.to.state,
|
|
18359
|
-
layer: 'values',
|
|
18360
|
-
writable: true,
|
|
18361
|
-
},
|
|
18362
|
-
};
|
|
18363
|
-
}
|
|
18364
|
-
function adaptTransform(connection) {
|
|
18365
|
-
if (connection.set !== undefined) {
|
|
18366
|
-
return {
|
|
18367
|
-
version: '2.0',
|
|
18368
|
-
phase: 'link-propagation',
|
|
18369
|
-
mode: inferPipelineMode(connection.set),
|
|
18370
|
-
sourceBindings: [{ source: 'constant', value: connection.set }],
|
|
18371
|
-
steps: [
|
|
18372
|
-
{
|
|
18373
|
-
id: 'constant',
|
|
18374
|
-
kind: 'constant',
|
|
18375
|
-
phase: 'link-propagation',
|
|
18376
|
-
input: {
|
|
18377
|
-
source: 'constant',
|
|
18378
|
-
value: connection.set,
|
|
18379
|
-
},
|
|
18380
|
-
},
|
|
18381
|
-
],
|
|
18382
|
-
};
|
|
18383
|
-
}
|
|
18384
|
-
if (!connection.map) {
|
|
18385
|
-
return undefined;
|
|
18386
|
-
}
|
|
18387
|
-
const trimmed = connection.map.trim();
|
|
18388
|
-
const kind = resolveMapTransformKind(trimmed);
|
|
18389
|
-
return {
|
|
18390
|
-
version: '2.0',
|
|
18391
|
-
phase: 'link-propagation',
|
|
18392
|
-
mode: kind === 'array-template'
|
|
18393
|
-
? 'collection'
|
|
18394
|
-
: kind === 'object-template'
|
|
18395
|
-
? 'object-fragment'
|
|
18396
|
-
: 'single-value',
|
|
18397
|
-
sourceBindings: [{ source: 'event' }],
|
|
18398
|
-
steps: [
|
|
18399
|
-
{
|
|
18400
|
-
id: 'legacy-map',
|
|
18401
|
-
kind,
|
|
18402
|
-
phase: 'link-propagation',
|
|
18403
|
-
input: { source: 'event' },
|
|
18404
|
-
config: buildMapConfig(kind, trimmed),
|
|
18405
|
-
},
|
|
18406
|
-
],
|
|
18407
|
-
};
|
|
18408
|
-
}
|
|
18409
|
-
function adaptConditions(connection) {
|
|
18410
|
-
const conditions = [];
|
|
18411
|
-
if (connection.meta?.filterExpr) {
|
|
18412
|
-
conditions.push({
|
|
18413
|
-
kind: 'expression',
|
|
18414
|
-
expression: connection.meta.filterExpr,
|
|
18415
|
-
description: 'Adaptado de WidgetConnection.meta.filterExpr',
|
|
18416
|
-
});
|
|
18417
|
-
}
|
|
18418
|
-
return conditions.length ? conditions : undefined;
|
|
18419
|
-
}
|
|
18420
|
-
function adaptPolicy(connection) {
|
|
18421
|
-
const policy = {};
|
|
18422
|
-
if (typeof connection.meta?.debounceMs === 'number') {
|
|
18423
|
-
policy.debounceMs = connection.meta.debounceMs;
|
|
18424
|
-
}
|
|
18425
|
-
if (typeof connection.meta?.distinct === 'boolean') {
|
|
18426
|
-
policy.distinct = connection.meta.distinct;
|
|
18427
|
-
}
|
|
18428
|
-
if (typeof connection.meta?.distinctBy === 'string' && connection.meta.distinctBy.trim()) {
|
|
18429
|
-
policy.distinctBy = connection.meta.distinctBy.trim();
|
|
18430
|
-
}
|
|
18431
|
-
return Object.keys(policy).length ? policy : undefined;
|
|
18432
|
-
}
|
|
18433
|
-
function resolveIntent(from, to) {
|
|
18434
|
-
if (from.kind === 'component-port' && to.kind === 'state') {
|
|
18435
|
-
return 'state-write';
|
|
18436
|
-
}
|
|
18437
|
-
if (from.kind === 'state' && to.kind === 'component-port') {
|
|
18438
|
-
return 'state-read';
|
|
18439
|
-
}
|
|
18440
|
-
if (from.kind === 'state' && to.kind === 'state') {
|
|
18441
|
-
return 'data-projection';
|
|
18442
|
-
}
|
|
18443
|
-
return 'event-propagation';
|
|
18444
|
-
}
|
|
18445
|
-
function normalizeBindingPath(rawInput) {
|
|
18446
|
-
const trimmed = (rawInput || '').trim();
|
|
18447
|
-
const dotIndex = trimmed.search(/[.[]/);
|
|
18448
|
-
if (dotIndex <= 0) {
|
|
18449
|
-
return { port: trimmed };
|
|
18450
|
-
}
|
|
18451
|
-
return {
|
|
18452
|
-
port: trimmed.slice(0, dotIndex),
|
|
18453
|
-
bindingPath: trimmed,
|
|
18454
|
-
};
|
|
18455
|
-
}
|
|
18456
|
-
function resolveMapTransformKind(map) {
|
|
18457
|
-
if (isQuotedLiteral(map)) {
|
|
18458
|
-
return 'template';
|
|
18459
|
-
}
|
|
18460
|
-
if (map.startsWith('{')) {
|
|
18461
|
-
return 'object-template';
|
|
18462
|
-
}
|
|
18463
|
-
if (map.startsWith('[')) {
|
|
18464
|
-
return 'array-template';
|
|
18465
|
-
}
|
|
18466
|
-
return 'pick-path';
|
|
18467
|
-
}
|
|
18468
|
-
function buildMapConfig(kind, map) {
|
|
18469
|
-
if (kind === 'pick-path') {
|
|
18470
|
-
return { path: map };
|
|
18471
|
-
}
|
|
18472
|
-
if (kind === 'template') {
|
|
18473
|
-
return { value: map };
|
|
18474
|
-
}
|
|
18475
|
-
return { template: map };
|
|
18476
|
-
}
|
|
18477
|
-
function inferPipelineMode(value) {
|
|
18478
|
-
if (Array.isArray(value)) {
|
|
18479
|
-
return 'collection';
|
|
18480
|
-
}
|
|
18481
|
-
if (value != null && typeof value === 'object') {
|
|
18482
|
-
return 'object-fragment';
|
|
18483
|
-
}
|
|
18484
|
-
return 'single-value';
|
|
18485
|
-
}
|
|
18486
|
-
function isQuotedLiteral(value) {
|
|
18487
|
-
return (value.startsWith('"') && value.endsWith('"'))
|
|
18488
|
-
|| (value.startsWith('\'') && value.endsWith('\''));
|
|
18489
|
-
}
|
|
18490
|
-
function buildLinkId(connection) {
|
|
18491
|
-
return `legacy:${buildTraceKey(connection)}`;
|
|
18492
|
-
}
|
|
18493
|
-
function buildTraceKey(connection) {
|
|
18494
|
-
const from = 'widget' in connection.from
|
|
18495
|
-
? `widget:${connection.from.widget}.${connection.from.output}`
|
|
18496
|
-
: `state:${connection.from.state}`;
|
|
18497
|
-
const to = 'widget' in connection.to
|
|
18498
|
-
? `widget:${connection.to.widget}.${connection.to.input}`
|
|
18499
|
-
: `state:${connection.to.state}`;
|
|
18500
|
-
return `${from}->${to}`;
|
|
18501
|
-
}
|
|
19730
|
+
}] });
|
|
18502
19731
|
|
|
18503
19732
|
class CompositionRuntimeStore {
|
|
18504
19733
|
snapshot;
|
|
@@ -18606,13 +19835,18 @@ function applyLinkPatches(current, patches) {
|
|
|
18606
19835
|
return {
|
|
18607
19836
|
...cloneLink(link),
|
|
18608
19837
|
status: patch.status ?? link.status,
|
|
18609
|
-
lastEventAt: patch
|
|
18610
|
-
lastDispatchTraceId: patch
|
|
18611
|
-
lastDeliveredValuePreview: patch
|
|
19838
|
+
lastEventAt: pickPatchedValue(patch, 'lastEventAt', link.lastEventAt),
|
|
19839
|
+
lastDispatchTraceId: pickPatchedValue(patch, 'lastDispatchTraceId', link.lastDispatchTraceId),
|
|
19840
|
+
lastDeliveredValuePreview: pickPatchedValue(patch, 'lastDeliveredValuePreview', link.lastDeliveredValuePreview),
|
|
18612
19841
|
diagnostics: cloneDiagnostics$1(patch.diagnostics ?? link.diagnostics),
|
|
18613
19842
|
};
|
|
18614
19843
|
});
|
|
18615
19844
|
}
|
|
19845
|
+
function pickPatchedValue(patch, key, fallback) {
|
|
19846
|
+
return Object.prototype.hasOwnProperty.call(patch, key)
|
|
19847
|
+
? patch[key]
|
|
19848
|
+
: fallback;
|
|
19849
|
+
}
|
|
18616
19850
|
function cloneLinks(links) {
|
|
18617
19851
|
return links.map((link) => cloneLink(link));
|
|
18618
19852
|
}
|
|
@@ -18779,19 +20013,33 @@ class TransformRuntimeService {
|
|
|
18779
20013
|
const env = this.buildEnvironment(runtime);
|
|
18780
20014
|
let current = this.resolvePipelineSeed(pipeline, env);
|
|
18781
20015
|
for (const [index, step] of pipeline.steps.entries()) {
|
|
18782
|
-
|
|
18783
|
-
|
|
20016
|
+
try {
|
|
20017
|
+
if (!this.matchesStepCondition(step.when, env)) {
|
|
20018
|
+
continue;
|
|
20019
|
+
}
|
|
20020
|
+
if (!isSupportedTransformKind(step.kind)) {
|
|
20021
|
+
diagnostics.push(this.createDiagnostic('RUNTIME_TRANSFORM_UNSUPPORTED', `O transform ${step.kind} ainda nao e suportado pelo runtime da Wave 1.`, {
|
|
20022
|
+
kind: 'transform-step',
|
|
20023
|
+
transformIndex: index,
|
|
20024
|
+
label: step.id,
|
|
20025
|
+
}, { transformKind: step.kind, pipelineId: pipeline.id, stepId: step.id }, undefined, 'unsupported-kind'));
|
|
20026
|
+
continue;
|
|
20027
|
+
}
|
|
20028
|
+
current = this.executeStep(step, current, env, diagnostics, index);
|
|
20029
|
+
env.current = this.clone(current);
|
|
18784
20030
|
}
|
|
18785
|
-
|
|
18786
|
-
diagnostics.push(this.createDiagnostic('
|
|
20031
|
+
catch (error) {
|
|
20032
|
+
diagnostics.push(this.createDiagnostic('RUNTIME_TRANSFORM_STEP_FAILED', `O transform ${step.kind} falhou no passo '${step.id || index}'. ${this.describeError(error)}`, {
|
|
18787
20033
|
kind: 'transform-step',
|
|
18788
20034
|
transformIndex: index,
|
|
18789
20035
|
label: step.id,
|
|
18790
|
-
}, {
|
|
18791
|
-
|
|
20036
|
+
}, {
|
|
20037
|
+
transformKind: step.kind,
|
|
20038
|
+
pipelineId: pipeline.id,
|
|
20039
|
+
stepId: step.id,
|
|
20040
|
+
errorMessage: this.describeError(error),
|
|
20041
|
+
}, undefined, 'step-failed'));
|
|
18792
20042
|
}
|
|
18793
|
-
current = this.executeStep(step, current, env, diagnostics, index);
|
|
18794
|
-
env.current = this.clone(current);
|
|
18795
20043
|
}
|
|
18796
20044
|
if (current === undefined && pipeline.fallbackValue !== undefined) {
|
|
18797
20045
|
current = this.clone(pipeline.fallbackValue);
|
|
@@ -18846,9 +20094,9 @@ class TransformRuntimeService {
|
|
|
18846
20094
|
case 'array-template':
|
|
18847
20095
|
return this.resolveStructuredTemplate(step, inputs[0], env);
|
|
18848
20096
|
case 'coalesce':
|
|
18849
|
-
return this.resolveCoalesce(step, inputs, env);
|
|
20097
|
+
return this.resolveCoalesce(step, inputs, env, diagnostics, index);
|
|
18850
20098
|
case 'merge-objects':
|
|
18851
|
-
return this.resolveMergeObjects(step, inputs, env);
|
|
20099
|
+
return this.resolveMergeObjects(step, inputs, env, diagnostics, index);
|
|
18852
20100
|
case 'select-case':
|
|
18853
20101
|
return this.resolveSelectCase(step, inputs[0], env);
|
|
18854
20102
|
default:
|
|
@@ -18856,7 +20104,7 @@ class TransformRuntimeService {
|
|
|
18856
20104
|
kind: 'transform-step',
|
|
18857
20105
|
transformIndex: index,
|
|
18858
20106
|
label: step.id,
|
|
18859
|
-
}, { transformKind: step.kind }));
|
|
20107
|
+
}, { transformKind: step.kind }, undefined, 'unsupported-kind'));
|
|
18860
20108
|
return current;
|
|
18861
20109
|
}
|
|
18862
20110
|
}
|
|
@@ -18958,14 +20206,11 @@ class TransformRuntimeService {
|
|
|
18958
20206
|
const template = step.config?.['template'] ?? source;
|
|
18959
20207
|
return this.templateResolver.resolveTemplate(template, this.buildTemplateContext(env, source));
|
|
18960
20208
|
}
|
|
18961
|
-
resolveCoalesce(step, inputs, env) {
|
|
18962
|
-
const
|
|
18963
|
-
|
|
18964
|
-
|
|
18965
|
-
const
|
|
18966
|
-
? this.pathAccessor.extractByPath({ state: env['state'], payload: env['payload'], context: env['context'] }, path)
|
|
18967
|
-
: undefined);
|
|
18968
|
-
for (const value of [...inputs, ...candidates]) {
|
|
20209
|
+
resolveCoalesce(step, inputs, env, diagnostics, index) {
|
|
20210
|
+
const configuredValues = this.resolveConfiguredValues(step, env, diagnostics, index);
|
|
20211
|
+
const explicitInputs = step.inputs?.length || step.input ? inputs : [];
|
|
20212
|
+
const fallbackInputs = explicitInputs.length ? [] : inputs;
|
|
20213
|
+
for (const value of [...explicitInputs, ...configuredValues, ...fallbackInputs]) {
|
|
18969
20214
|
if (value == null) {
|
|
18970
20215
|
continue;
|
|
18971
20216
|
}
|
|
@@ -18976,16 +20221,11 @@ class TransformRuntimeService {
|
|
|
18976
20221
|
}
|
|
18977
20222
|
return this.clone(step.config?.['fallback']);
|
|
18978
20223
|
}
|
|
18979
|
-
resolveMergeObjects(step, inputs, env) {
|
|
18980
|
-
const
|
|
18981
|
-
|
|
18982
|
-
|
|
18983
|
-
const values = [
|
|
18984
|
-
...inputs,
|
|
18985
|
-
...configuredPaths.map((path) => typeof path === 'string'
|
|
18986
|
-
? this.pathAccessor.extractByPath({ state: env['state'], payload: env['payload'], context: env['context'] }, path)
|
|
18987
|
-
: undefined),
|
|
18988
|
-
];
|
|
20224
|
+
resolveMergeObjects(step, inputs, env, diagnostics, index) {
|
|
20225
|
+
const configuredValues = this.resolveConfiguredValues(step, env, diagnostics, index);
|
|
20226
|
+
const explicitInputs = step.inputs?.length || step.input ? inputs : [];
|
|
20227
|
+
const fallbackInputs = explicitInputs.length || configuredValues.length ? [] : inputs;
|
|
20228
|
+
const values = [...explicitInputs, ...configuredValues, ...fallbackInputs];
|
|
18989
20229
|
return values.reduce((acc, value) => {
|
|
18990
20230
|
if (!this.isPlainObject(value)) {
|
|
18991
20231
|
return acc;
|
|
@@ -18993,6 +20233,59 @@ class TransformRuntimeService {
|
|
|
18993
20233
|
return deepMerge(acc, this.clone(value));
|
|
18994
20234
|
}, {});
|
|
18995
20235
|
}
|
|
20236
|
+
resolveConfiguredValues(step, env, diagnostics, index) {
|
|
20237
|
+
if (!Array.isArray(step.config?.['paths'])) {
|
|
20238
|
+
return [];
|
|
20239
|
+
}
|
|
20240
|
+
const rawPaths = step.config?.['paths'];
|
|
20241
|
+
const validPaths = [];
|
|
20242
|
+
const invalidEntries = [];
|
|
20243
|
+
for (const item of rawPaths) {
|
|
20244
|
+
if (typeof item === 'string' && item.trim()) {
|
|
20245
|
+
validPaths.push(item);
|
|
20246
|
+
}
|
|
20247
|
+
else {
|
|
20248
|
+
invalidEntries.push(item);
|
|
20249
|
+
}
|
|
20250
|
+
}
|
|
20251
|
+
if (invalidEntries.length) {
|
|
20252
|
+
diagnostics.push(this.createDiagnostic('RUNTIME_TRANSFORM_CONFIG_INVALID', `O transform ${step.kind} recebeu entradas invalidas em config.paths no passo '${step.id || index}'.`, {
|
|
20253
|
+
kind: 'transform-step',
|
|
20254
|
+
transformIndex: index,
|
|
20255
|
+
label: step.id,
|
|
20256
|
+
}, {
|
|
20257
|
+
transformKind: step.kind,
|
|
20258
|
+
stepId: step.id,
|
|
20259
|
+
invalidPathEntries: this.clone(invalidEntries),
|
|
20260
|
+
}, 'warning', 'invalid-path-entries'));
|
|
20261
|
+
}
|
|
20262
|
+
if (!validPaths.length) {
|
|
20263
|
+
if (rawPaths.length) {
|
|
20264
|
+
diagnostics.push(this.createDiagnostic('RUNTIME_TRANSFORM_CONFIG_INVALID', `O transform ${step.kind} nao encontrou nenhum path valido em config.paths no passo '${step.id || index}'.`, {
|
|
20265
|
+
kind: 'transform-step',
|
|
20266
|
+
transformIndex: index,
|
|
20267
|
+
label: step.id,
|
|
20268
|
+
}, {
|
|
20269
|
+
transformKind: step.kind,
|
|
20270
|
+
stepId: step.id,
|
|
20271
|
+
}, 'warning', 'missing-valid-paths'));
|
|
20272
|
+
}
|
|
20273
|
+
return [];
|
|
20274
|
+
}
|
|
20275
|
+
const resolved = validPaths.map((path) => this.resolveConfiguredPath(path, env));
|
|
20276
|
+
if (resolved.every((value) => value === undefined)) {
|
|
20277
|
+
diagnostics.push(this.createDiagnostic('RUNTIME_TRANSFORM_PATHS_UNRESOLVED', `O transform ${step.kind} nao resolveu nenhum dos paths configurados no passo '${step.id || index}'.`, {
|
|
20278
|
+
kind: 'transform-step',
|
|
20279
|
+
transformIndex: index,
|
|
20280
|
+
label: step.id,
|
|
20281
|
+
}, {
|
|
20282
|
+
transformKind: step.kind,
|
|
20283
|
+
stepId: step.id,
|
|
20284
|
+
paths: validPaths,
|
|
20285
|
+
}, 'warning', `paths-unresolved:${this.hashIdParts(validPaths)}`));
|
|
20286
|
+
}
|
|
20287
|
+
return resolved;
|
|
20288
|
+
}
|
|
18996
20289
|
resolveSelectCase(step, source, env) {
|
|
18997
20290
|
const cases = Array.isArray(step.config?.['cases'])
|
|
18998
20291
|
? step.config?.['cases']
|
|
@@ -19018,7 +20311,7 @@ class TransformRuntimeService {
|
|
|
19018
20311
|
? conditionRecord['path'].trim()
|
|
19019
20312
|
: '';
|
|
19020
20313
|
const value = path
|
|
19021
|
-
? this.
|
|
20314
|
+
? this.resolveCasePath(path, env, source)
|
|
19022
20315
|
: source;
|
|
19023
20316
|
if ('equals' in conditionRecord) {
|
|
19024
20317
|
return value === conditionRecord['equals'];
|
|
@@ -19036,12 +20329,38 @@ class TransformRuntimeService {
|
|
|
19036
20329
|
}
|
|
19037
20330
|
resolveCaseValue(item, env, source) {
|
|
19038
20331
|
if (typeof item['path'] === 'string' && item['path'].trim()) {
|
|
19039
|
-
return this.
|
|
20332
|
+
return this.resolveCasePath(item['path'], env, source);
|
|
19040
20333
|
}
|
|
19041
20334
|
if (item['template'] !== undefined) {
|
|
19042
20335
|
return this.templateResolver.resolveTemplate(item['template'], this.buildTemplateContext(env, source));
|
|
19043
20336
|
}
|
|
19044
|
-
return this.
|
|
20337
|
+
return this.templateResolver.resolveTemplate(item['value'], this.buildTemplateContext(env, source));
|
|
20338
|
+
}
|
|
20339
|
+
resolveCasePath(path, env, source) {
|
|
20340
|
+
if (/^(event|payload|state|context|current|source)\b/.test(path)) {
|
|
20341
|
+
return this.pathAccessor.extractByPath({
|
|
20342
|
+
event: env['event'],
|
|
20343
|
+
payload: env['payload'],
|
|
20344
|
+
state: env['state'],
|
|
20345
|
+
context: env['context'],
|
|
20346
|
+
current: source,
|
|
20347
|
+
source,
|
|
20348
|
+
}, path);
|
|
20349
|
+
}
|
|
20350
|
+
return this.pathAccessor.extractByPath(source, path);
|
|
20351
|
+
}
|
|
20352
|
+
resolveConfiguredPath(path, env) {
|
|
20353
|
+
if (/^(event|payload|state|context|current|source)\b/.test(path)) {
|
|
20354
|
+
return this.pathAccessor.extractByPath({
|
|
20355
|
+
event: env['event'],
|
|
20356
|
+
payload: env['payload'],
|
|
20357
|
+
state: env['state'],
|
|
20358
|
+
context: env['context'],
|
|
20359
|
+
current: env['current'],
|
|
20360
|
+
source: env['current'],
|
|
20361
|
+
}, path);
|
|
20362
|
+
}
|
|
20363
|
+
return this.pathAccessor.extractByPath(env['current'], path);
|
|
19045
20364
|
}
|
|
19046
20365
|
buildEffectiveState(state, derived, transient) {
|
|
19047
20366
|
return deepMerge(deepMerge(this.clone(state) || {}, this.clone(derived) || {}), this.clone(transient) || {});
|
|
@@ -19080,26 +20399,65 @@ class TransformRuntimeService {
|
|
|
19080
20399
|
}
|
|
19081
20400
|
return false;
|
|
19082
20401
|
}
|
|
19083
|
-
createDiagnostic(code, message, subject, details) {
|
|
20402
|
+
createDiagnostic(code, message, subject, details, severity = 'error', occurrenceKey) {
|
|
19084
20403
|
return {
|
|
19085
|
-
id:
|
|
20404
|
+
id: this.buildDiagnosticId(code, subject, occurrenceKey),
|
|
19086
20405
|
code,
|
|
19087
|
-
severity
|
|
20406
|
+
severity,
|
|
19088
20407
|
phase: 'runtime-transform',
|
|
19089
20408
|
message,
|
|
19090
20409
|
summary: message,
|
|
19091
20410
|
subject,
|
|
19092
20411
|
details,
|
|
19093
20412
|
source: 'runtime-engine',
|
|
19094
|
-
blocking:
|
|
20413
|
+
blocking: severity === 'error' || severity === 'fatal',
|
|
19095
20414
|
createdAt: new Date().toISOString(),
|
|
19096
20415
|
};
|
|
19097
20416
|
}
|
|
19098
|
-
clone(value) {
|
|
19099
|
-
if (value == null || typeof value !== 'object') {
|
|
19100
|
-
return value;
|
|
20417
|
+
clone(value) {
|
|
20418
|
+
if (value == null || typeof value !== 'object') {
|
|
20419
|
+
return value;
|
|
20420
|
+
}
|
|
20421
|
+
return JSON.parse(JSON.stringify(value));
|
|
20422
|
+
}
|
|
20423
|
+
describeError(error) {
|
|
20424
|
+
if (error instanceof Error) {
|
|
20425
|
+
return error.message;
|
|
20426
|
+
}
|
|
20427
|
+
if (typeof error === 'string') {
|
|
20428
|
+
return error;
|
|
20429
|
+
}
|
|
20430
|
+
return 'Erro desconhecido.';
|
|
20431
|
+
}
|
|
20432
|
+
buildDiagnosticId(code, subject, occurrenceKey) {
|
|
20433
|
+
const parts = [
|
|
20434
|
+
code,
|
|
20435
|
+
String(subject.transformIndex ?? 'root'),
|
|
20436
|
+
];
|
|
20437
|
+
if (subject.label) {
|
|
20438
|
+
parts.push(this.sanitizeIdPart(subject.label));
|
|
20439
|
+
}
|
|
20440
|
+
if (occurrenceKey) {
|
|
20441
|
+
parts.push(this.sanitizeIdPart(occurrenceKey));
|
|
20442
|
+
}
|
|
20443
|
+
return parts.filter(Boolean).join(':');
|
|
20444
|
+
}
|
|
20445
|
+
sanitizeIdPart(value) {
|
|
20446
|
+
return value
|
|
20447
|
+
.trim()
|
|
20448
|
+
.toLowerCase()
|
|
20449
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
20450
|
+
.replace(/^-+|-+$/g, '')
|
|
20451
|
+
.slice(0, 48);
|
|
20452
|
+
}
|
|
20453
|
+
hashIdParts(values) {
|
|
20454
|
+
let hash = 0;
|
|
20455
|
+
for (const value of values) {
|
|
20456
|
+
for (const char of value) {
|
|
20457
|
+
hash = ((hash * 31) + char.charCodeAt(0)) >>> 0;
|
|
20458
|
+
}
|
|
19101
20459
|
}
|
|
19102
|
-
return
|
|
20460
|
+
return hash.toString(36);
|
|
19103
20461
|
}
|
|
19104
20462
|
}
|
|
19105
20463
|
|
|
@@ -19153,7 +20511,7 @@ class LinkExecutorService {
|
|
|
19153
20511
|
skippedReason: missingResolution.reason,
|
|
19154
20512
|
};
|
|
19155
20513
|
}
|
|
19156
|
-
const policySkip = this.resolvePolicySkip(link, value, context, now);
|
|
20514
|
+
const policySkip = this.resolvePolicySkip(link, sourceValue, value, context, now);
|
|
19157
20515
|
if (policySkip) {
|
|
19158
20516
|
return {
|
|
19159
20517
|
status: 'skipped',
|
|
@@ -19189,13 +20547,34 @@ class LinkExecutorService {
|
|
|
19189
20547
|
if (endpoint.kind === 'state') {
|
|
19190
20548
|
return this.readStatePath(snapshot, endpoint.ref.path, endpoint.ref.layer);
|
|
19191
20549
|
}
|
|
19192
|
-
|
|
19193
|
-
|
|
20550
|
+
const payload = context.payload !== undefined
|
|
20551
|
+
? context.payload
|
|
20552
|
+
: (context.event && typeof context.event === 'object' && 'payload' in context.event)
|
|
20553
|
+
? context.event['payload']
|
|
20554
|
+
: context.event;
|
|
20555
|
+
if (endpoint.ref.bindingPath) {
|
|
20556
|
+
const extracted = this.extractComponentSourceBinding(endpoint.ref.bindingPath, payload, context);
|
|
20557
|
+
if (extracted !== undefined) {
|
|
20558
|
+
return this.clone(extracted);
|
|
20559
|
+
}
|
|
20560
|
+
}
|
|
20561
|
+
return this.clone(payload);
|
|
20562
|
+
}
|
|
20563
|
+
extractComponentSourceBinding(bindingPath, payload, context) {
|
|
20564
|
+
const normalized = String(bindingPath || '').trim();
|
|
20565
|
+
if (!normalized) {
|
|
20566
|
+
return undefined;
|
|
19194
20567
|
}
|
|
19195
|
-
|
|
19196
|
-
|
|
20568
|
+
const fromPayload = this.pathAccessor.extractByPath(payload, normalized);
|
|
20569
|
+
if (fromPayload !== undefined) {
|
|
20570
|
+
return fromPayload;
|
|
19197
20571
|
}
|
|
19198
|
-
return this.
|
|
20572
|
+
return this.pathAccessor.extractByPath({
|
|
20573
|
+
source: payload,
|
|
20574
|
+
payload,
|
|
20575
|
+
event: context.event,
|
|
20576
|
+
context: context.context || {},
|
|
20577
|
+
}, normalized);
|
|
19199
20578
|
}
|
|
19200
20579
|
matchesConditions(link, sourceValue, context, snapshot, diagnostics) {
|
|
19201
20580
|
for (const condition of link.conditions || []) {
|
|
@@ -19321,7 +20700,7 @@ class LinkExecutorService {
|
|
|
19321
20700
|
};
|
|
19322
20701
|
}
|
|
19323
20702
|
resolveMissingValuePolicy(link, value) {
|
|
19324
|
-
if (value !== undefined) {
|
|
20703
|
+
if (value !== undefined && value !== null) {
|
|
19325
20704
|
return { value, skipped: false };
|
|
19326
20705
|
}
|
|
19327
20706
|
switch (link.policy?.missingValuePolicy) {
|
|
@@ -19336,13 +20715,22 @@ class LinkExecutorService {
|
|
|
19336
20715
|
return { value, skipped: false };
|
|
19337
20716
|
}
|
|
19338
20717
|
}
|
|
19339
|
-
resolvePolicySkip(link, value, context, now) {
|
|
20718
|
+
resolvePolicySkip(link, sourceValue, value, context, now) {
|
|
19340
20719
|
if (link.policy?.distinct) {
|
|
19341
20720
|
const currentValue = link.policy.distinctBy
|
|
19342
|
-
? this.
|
|
20721
|
+
? this.resolveDistinctValue(link.policy.distinctBy, {
|
|
20722
|
+
sourceValue,
|
|
20723
|
+
transformedValue: value,
|
|
20724
|
+
payload: context.payload,
|
|
20725
|
+
event: context.event,
|
|
20726
|
+
context: context.context,
|
|
20727
|
+
})
|
|
19343
20728
|
: value;
|
|
19344
20729
|
const previousValue = link.policy.distinctBy
|
|
19345
|
-
? this.
|
|
20730
|
+
? this.resolveDistinctValue(link.policy.distinctBy, {
|
|
20731
|
+
sourceValue: context.lastDeliveredValue,
|
|
20732
|
+
transformedValue: context.lastDeliveredValue,
|
|
20733
|
+
})
|
|
19346
20734
|
: context.lastDeliveredValue;
|
|
19347
20735
|
if (this.isEqual(currentValue, previousValue)) {
|
|
19348
20736
|
return 'distinct-skip';
|
|
@@ -19389,6 +20777,45 @@ class LinkExecutorService {
|
|
|
19389
20777
|
bindingPath: link.to.ref.bindingPath,
|
|
19390
20778
|
};
|
|
19391
20779
|
}
|
|
20780
|
+
resolveDistinctValue(distinctBy, options) {
|
|
20781
|
+
const normalized = String(distinctBy || '').trim();
|
|
20782
|
+
if (!normalized) {
|
|
20783
|
+
return options.transformedValue;
|
|
20784
|
+
}
|
|
20785
|
+
const payload = options.payload !== undefined
|
|
20786
|
+
? options.payload
|
|
20787
|
+
: (options.event && typeof options.event === 'object'
|
|
20788
|
+
? options.event['payload']
|
|
20789
|
+
: undefined);
|
|
20790
|
+
const envelopes = [
|
|
20791
|
+
{
|
|
20792
|
+
source: options.sourceValue,
|
|
20793
|
+
value: options.transformedValue,
|
|
20794
|
+
payload,
|
|
20795
|
+
event: options.event,
|
|
20796
|
+
context: options.context || {},
|
|
20797
|
+
original: {
|
|
20798
|
+
source: options.sourceValue,
|
|
20799
|
+
payload,
|
|
20800
|
+
event: options.event,
|
|
20801
|
+
},
|
|
20802
|
+
},
|
|
20803
|
+
{
|
|
20804
|
+
source: options.sourceValue,
|
|
20805
|
+
value: options.transformedValue,
|
|
20806
|
+
payload: options.transformedValue,
|
|
20807
|
+
event: options.event,
|
|
20808
|
+
context: options.context || {},
|
|
20809
|
+
},
|
|
20810
|
+
];
|
|
20811
|
+
for (const envelope of envelopes) {
|
|
20812
|
+
const extracted = this.pathAccessor.extractByPath(envelope, normalized);
|
|
20813
|
+
if (extracted !== undefined) {
|
|
20814
|
+
return extracted;
|
|
20815
|
+
}
|
|
20816
|
+
}
|
|
20817
|
+
return options.transformedValue;
|
|
20818
|
+
}
|
|
19392
20819
|
readStatePath(snapshot, path, preferredLayer) {
|
|
19393
20820
|
const lookup = (layer) => {
|
|
19394
20821
|
switch (layer) {
|
|
@@ -19556,8 +20983,9 @@ class CompositionRuntimeEngine {
|
|
|
19556
20983
|
this.definition = definition;
|
|
19557
20984
|
const generatedAt = this.now();
|
|
19558
20985
|
const stateSnapshot = this.materializeDerivedState(definition.state.primaryValues, definition);
|
|
20986
|
+
const bootstrapDiagnostics = uniqueDiagnosticsById(stateSnapshot.diagnostics);
|
|
19559
20987
|
const init = {
|
|
19560
|
-
status:
|
|
20988
|
+
status: bootstrapDiagnostics.some(isBlockingDiagnostic) ? 'degraded' : 'ready',
|
|
19561
20989
|
generatedAt,
|
|
19562
20990
|
links: definition.links.map((link) => this.createLinkSnapshot(link)),
|
|
19563
20991
|
state: {
|
|
@@ -19565,9 +20993,9 @@ class CompositionRuntimeEngine {
|
|
|
19565
20993
|
derivedValues: stateSnapshot.derivedValues,
|
|
19566
20994
|
transientValues: stateSnapshot.transientValues,
|
|
19567
20995
|
changedPaths: [],
|
|
19568
|
-
diagnostics:
|
|
20996
|
+
diagnostics: bootstrapDiagnostics,
|
|
19569
20997
|
},
|
|
19570
|
-
diagnostics:
|
|
20998
|
+
diagnostics: bootstrapDiagnostics,
|
|
19571
20999
|
traceTail: [
|
|
19572
21000
|
this.traceService.createEntry('bootstrap', 0, {
|
|
19573
21001
|
timestamp: generatedAt,
|
|
@@ -19581,9 +21009,9 @@ class CompositionRuntimeEngine {
|
|
|
19581
21009
|
linkCount: definition.links.length,
|
|
19582
21010
|
derivedDefinitionCount: Object.keys(definition.state.derivedDefinitions || {}).length,
|
|
19583
21011
|
},
|
|
19584
|
-
diagnostics:
|
|
21012
|
+
diagnostics: bootstrapDiagnostics.map((item) => item.code),
|
|
19585
21013
|
}),
|
|
19586
|
-
...
|
|
21014
|
+
...bootstrapDiagnostics.map((diagnostic, index) => this.traceService.createEntry('bootstrap', index + 1, {
|
|
19587
21015
|
timestamp: diagnostic.createdAt,
|
|
19588
21016
|
phase: 'diagnostic-emitted',
|
|
19589
21017
|
subject: diagnostic.subject,
|
|
@@ -19610,6 +21038,7 @@ class CompositionRuntimeEngine {
|
|
|
19610
21038
|
const runtimeDiagnostics = [];
|
|
19611
21039
|
const linkResults = new Map();
|
|
19612
21040
|
const trace = [];
|
|
21041
|
+
const emittedDiagnosticIds = new Set();
|
|
19613
21042
|
let sequence = 0;
|
|
19614
21043
|
trace.push(this.traceService.createEntry(event.eventId, sequence++, {
|
|
19615
21044
|
timestamp: occurredAt,
|
|
@@ -19719,53 +21148,28 @@ class CompositionRuntimeEngine {
|
|
|
19719
21148
|
},
|
|
19720
21149
|
diagnostics: result.diagnostics.map((item) => item.code),
|
|
19721
21150
|
}));
|
|
19722
|
-
|
|
19723
|
-
trace.push(this.traceService.createEntry(event.eventId, sequence++, {
|
|
19724
|
-
timestamp: diagnostic.createdAt,
|
|
19725
|
-
phase: 'diagnostic-emitted',
|
|
19726
|
-
linkId: link.id,
|
|
19727
|
-
subject: diagnostic.subject,
|
|
19728
|
-
details: {
|
|
19729
|
-
code: diagnostic.code,
|
|
19730
|
-
severity: diagnostic.severity,
|
|
19731
|
-
phase: diagnostic.phase,
|
|
19732
|
-
},
|
|
19733
|
-
diagnostics: [diagnostic.code],
|
|
19734
|
-
}));
|
|
19735
|
-
}
|
|
21151
|
+
sequence = this.appendDiagnosticTraceEntries(trace, emittedDiagnosticIds, event.eventId, sequence, result.diagnostics, link.id);
|
|
19736
21152
|
}
|
|
19737
21153
|
const materializedState = this.materializeDerivedState(workingState.primaryValues, this.definition, workingState.transientValues);
|
|
19738
|
-
const diagnostics = [
|
|
21154
|
+
const diagnostics = uniqueDiagnosticsById([
|
|
19739
21155
|
...runtimeDiagnostics,
|
|
19740
21156
|
...materializedState.diagnostics,
|
|
19741
|
-
];
|
|
21157
|
+
]);
|
|
19742
21158
|
materializedState.changedPaths = Array.from(new Set([
|
|
19743
21159
|
...(workingState.changedPaths ?? []),
|
|
19744
21160
|
...this.stateRuntime.collectChangedPaths(this.store.getSnapshot().state.derivedValues, materializedState.derivedValues, Object.keys(this.definition.state.derivedDefinitions || {})),
|
|
19745
21161
|
]));
|
|
19746
21162
|
materializedState.diagnostics = cloneDiagnostics(diagnostics);
|
|
19747
|
-
|
|
19748
|
-
trace.push(this.traceService.createEntry(event.eventId, sequence++, {
|
|
19749
|
-
timestamp: diagnostic.createdAt,
|
|
19750
|
-
phase: 'diagnostic-emitted',
|
|
19751
|
-
subject: diagnostic.subject,
|
|
19752
|
-
details: {
|
|
19753
|
-
code: diagnostic.code,
|
|
19754
|
-
severity: diagnostic.severity,
|
|
19755
|
-
phase: diagnostic.phase,
|
|
19756
|
-
},
|
|
19757
|
-
diagnostics: [diagnostic.code],
|
|
19758
|
-
}));
|
|
19759
|
-
}
|
|
21163
|
+
sequence = this.appendDiagnosticTraceEntries(trace, emittedDiagnosticIds, event.eventId, sequence, materializedState.diagnostics.filter((item) => !runtimeDiagnostics.some((runtimeItem) => runtimeItem.id === item.id)));
|
|
19760
21164
|
const snapshot = this.store.applyCycle({
|
|
19761
21165
|
generatedAt: occurredAt,
|
|
19762
21166
|
status: diagnostics.some(isBlockingDiagnostic)
|
|
19763
21167
|
? 'degraded'
|
|
19764
21168
|
: 'ready',
|
|
19765
21169
|
stateSnapshot: materializedState,
|
|
19766
|
-
linkPatches:
|
|
21170
|
+
linkPatches: matchedLinks.map((link) => ({
|
|
19767
21171
|
linkId: link.id,
|
|
19768
|
-
status: linkResults.get(link.id)?.status
|
|
21172
|
+
status: linkResults.get(link.id)?.status,
|
|
19769
21173
|
lastEventAt: linkResults.has(link.id) ? occurredAt : undefined,
|
|
19770
21174
|
lastDispatchTraceId: linkResults.has(link.id) ? event.eventId : undefined,
|
|
19771
21175
|
lastDeliveredValuePreview: linkResults.get(link.id)?.value,
|
|
@@ -19802,7 +21206,6 @@ class CompositionRuntimeEngine {
|
|
|
19802
21206
|
if (link.from.kind !== 'state' || link.to.kind !== 'component-port') {
|
|
19803
21207
|
continue;
|
|
19804
21208
|
}
|
|
19805
|
-
matchedLinkIds.push(link.id);
|
|
19806
21209
|
const result = this.linkExecutor.executeLink(link, {
|
|
19807
21210
|
snapshot: { state: runtimeState },
|
|
19808
21211
|
context: definition.context,
|
|
@@ -19816,16 +21219,17 @@ class CompositionRuntimeEngine {
|
|
|
19816
21219
|
if (widgetIndex < 0) {
|
|
19817
21220
|
continue;
|
|
19818
21221
|
}
|
|
19819
|
-
const
|
|
19820
|
-
if (!
|
|
21222
|
+
const previewBindingPath = resolvePreviewBindingPath(result.delivery.portId, result.delivery.bindingPath);
|
|
21223
|
+
if (!previewBindingPath) {
|
|
19821
21224
|
continue;
|
|
19822
21225
|
}
|
|
21226
|
+
matchedLinkIds.push(link.id);
|
|
19823
21227
|
const currentInputs = widgets[widgetIndex].definition.inputs || {};
|
|
19824
21228
|
widgets[widgetIndex] = {
|
|
19825
21229
|
...widgets[widgetIndex],
|
|
19826
21230
|
definition: {
|
|
19827
21231
|
...widgets[widgetIndex].definition,
|
|
19828
|
-
inputs: this.pathAccessor.setValueAtPath(this.cloneJson(currentInputs),
|
|
21232
|
+
inputs: this.pathAccessor.setValueAtPath(this.cloneJson(currentInputs), previewBindingPath, this.cloneJson(result.value)),
|
|
19829
21233
|
},
|
|
19830
21234
|
};
|
|
19831
21235
|
}
|
|
@@ -19853,6 +21257,9 @@ class CompositionRuntimeEngine {
|
|
|
19853
21257
|
const linkResults = new Map();
|
|
19854
21258
|
const diagnostics = [...snapshot.diagnostics];
|
|
19855
21259
|
const trace = [...snapshot.traceTail];
|
|
21260
|
+
const emittedDiagnosticIds = new Set(trace
|
|
21261
|
+
.filter((entry) => entry.phase === 'diagnostic-emitted')
|
|
21262
|
+
.flatMap((entry) => entry.diagnostics || []));
|
|
19856
21263
|
let sequence = trace.length;
|
|
19857
21264
|
for (const link of hydrationLinks) {
|
|
19858
21265
|
const stateBefore = cloneStateSnapshot(workingState);
|
|
@@ -19916,24 +21323,12 @@ class CompositionRuntimeEngine {
|
|
|
19916
21323
|
},
|
|
19917
21324
|
diagnostics: result.diagnostics.map((item) => item.code),
|
|
19918
21325
|
}));
|
|
19919
|
-
|
|
19920
|
-
trace.push(this.traceService.createEntry('bootstrap', sequence++, {
|
|
19921
|
-
timestamp: diagnostic.createdAt,
|
|
19922
|
-
phase: 'diagnostic-emitted',
|
|
19923
|
-
linkId: link.id,
|
|
19924
|
-
subject: diagnostic.subject,
|
|
19925
|
-
details: {
|
|
19926
|
-
code: diagnostic.code,
|
|
19927
|
-
severity: diagnostic.severity,
|
|
19928
|
-
phase: diagnostic.phase,
|
|
19929
|
-
},
|
|
19930
|
-
diagnostics: [diagnostic.code],
|
|
19931
|
-
}));
|
|
19932
|
-
}
|
|
21326
|
+
sequence = this.appendDiagnosticTraceEntries(trace, emittedDiagnosticIds, 'bootstrap', sequence, result.diagnostics, link.id);
|
|
19933
21327
|
}
|
|
21328
|
+
const dedupedDiagnostics = uniqueDiagnosticsById(diagnostics);
|
|
19934
21329
|
return this.store.applyCycle({
|
|
19935
21330
|
generatedAt: occurredAt,
|
|
19936
|
-
status:
|
|
21331
|
+
status: dedupedDiagnostics.some(isBlockingDiagnostic) ? 'degraded' : 'ready',
|
|
19937
21332
|
stateSnapshot: {
|
|
19938
21333
|
...workingState,
|
|
19939
21334
|
changedPaths: [],
|
|
@@ -19947,7 +21342,7 @@ class CompositionRuntimeEngine {
|
|
|
19947
21342
|
lastDeliveredValuePreview: linkResults.get(link.id)?.value,
|
|
19948
21343
|
diagnostics: linkResults.get(link.id)?.diagnostics,
|
|
19949
21344
|
})),
|
|
19950
|
-
diagnostics,
|
|
21345
|
+
diagnostics: dedupedDiagnostics,
|
|
19951
21346
|
traceTail: trace,
|
|
19952
21347
|
});
|
|
19953
21348
|
}
|
|
@@ -19966,26 +21361,30 @@ class CompositionRuntimeEngine {
|
|
|
19966
21361
|
};
|
|
19967
21362
|
}
|
|
19968
21363
|
createDerivedDiagnostic(definition, message, index) {
|
|
21364
|
+
const nodeKey = this.extractDerivedNodeKey(message);
|
|
21365
|
+
const classification = classifyDerivedDiagnosticMessage(message);
|
|
19969
21366
|
return {
|
|
19970
21367
|
id: `derived:${index}:${message}`,
|
|
19971
|
-
code:
|
|
19972
|
-
|
|
19973
|
-
: message.includes('transformer')
|
|
19974
|
-
? 'RUNTIME_DERIVED_TRANSFORMER_UNSUPPORTED'
|
|
19975
|
-
: 'RUNTIME_DERIVED_STATE_WARNING',
|
|
19976
|
-
severity: message.includes('cycle') || message.includes('not implemented')
|
|
19977
|
-
? 'warning'
|
|
19978
|
-
: 'info',
|
|
21368
|
+
code: classification.code,
|
|
21369
|
+
severity: classification.severity,
|
|
19979
21370
|
phase: 'runtime-state',
|
|
19980
21371
|
message,
|
|
19981
21372
|
summary: message,
|
|
19982
|
-
subject:
|
|
19983
|
-
|
|
19984
|
-
|
|
19985
|
-
|
|
21373
|
+
subject: nodeKey
|
|
21374
|
+
? {
|
|
21375
|
+
kind: 'derived-state',
|
|
21376
|
+
statePath: nodeKey,
|
|
21377
|
+
path: nodeKey,
|
|
21378
|
+
label: nodeKey,
|
|
21379
|
+
}
|
|
21380
|
+
: {
|
|
21381
|
+
kind: 'runtime-snapshot',
|
|
21382
|
+
label: definition.widgetOrder.join(', '),
|
|
21383
|
+
},
|
|
19986
21384
|
source: 'runtime-engine',
|
|
19987
|
-
blocking:
|
|
21385
|
+
blocking: classification.severity === 'error' || classification.severity === 'fatal',
|
|
19988
21386
|
createdAt: this.now(),
|
|
21387
|
+
details: nodeKey ? { nodeKey } : undefined,
|
|
19989
21388
|
};
|
|
19990
21389
|
}
|
|
19991
21390
|
clonePreviewWidgets(widgets) {
|
|
@@ -19997,6 +21396,31 @@ class CompositionRuntimeEngine {
|
|
|
19997
21396
|
}
|
|
19998
21397
|
return JSON.parse(JSON.stringify(value));
|
|
19999
21398
|
}
|
|
21399
|
+
extractDerivedNodeKey(message) {
|
|
21400
|
+
const match = message.match(/Derived state '([^']+)'/);
|
|
21401
|
+
return match?.[1];
|
|
21402
|
+
}
|
|
21403
|
+
appendDiagnosticTraceEntries(trace, emittedDiagnosticIds, traceId, sequence, diagnostics, linkId) {
|
|
21404
|
+
for (const diagnostic of diagnostics) {
|
|
21405
|
+
if (emittedDiagnosticIds.has(diagnostic.id)) {
|
|
21406
|
+
continue;
|
|
21407
|
+
}
|
|
21408
|
+
emittedDiagnosticIds.add(diagnostic.id);
|
|
21409
|
+
trace.push(this.traceService.createEntry(traceId, sequence++, {
|
|
21410
|
+
timestamp: diagnostic.createdAt,
|
|
21411
|
+
phase: 'diagnostic-emitted',
|
|
21412
|
+
linkId,
|
|
21413
|
+
subject: diagnostic.subject,
|
|
21414
|
+
details: {
|
|
21415
|
+
code: diagnostic.code,
|
|
21416
|
+
severity: diagnostic.severity,
|
|
21417
|
+
phase: diagnostic.phase,
|
|
21418
|
+
},
|
|
21419
|
+
diagnostics: [diagnostic.code],
|
|
21420
|
+
}));
|
|
21421
|
+
}
|
|
21422
|
+
return sequence;
|
|
21423
|
+
}
|
|
20000
21424
|
}
|
|
20001
21425
|
function createDefaultLinkExecutor() {
|
|
20002
21426
|
const connections = new ConnectionManagerService();
|
|
@@ -20004,7 +21428,7 @@ function createDefaultLinkExecutor() {
|
|
|
20004
21428
|
return new LinkExecutorService(transforms, connections);
|
|
20005
21429
|
}
|
|
20006
21430
|
function createDefaultStateRuntime() {
|
|
20007
|
-
return new WidgetPageStateRuntimeService(
|
|
21431
|
+
return new WidgetPageStateRuntimeService();
|
|
20008
21432
|
}
|
|
20009
21433
|
function cloneStateSnapshot(snapshot) {
|
|
20010
21434
|
return {
|
|
@@ -20026,9 +21450,92 @@ function cloneDiagnostics(diagnostics) {
|
|
|
20026
21450
|
details: item.details ? { ...item.details } : undefined,
|
|
20027
21451
|
}));
|
|
20028
21452
|
}
|
|
21453
|
+
function uniqueDiagnosticsById(diagnostics) {
|
|
21454
|
+
const deduped = [];
|
|
21455
|
+
const seen = new Set();
|
|
21456
|
+
for (const diagnostic of diagnostics) {
|
|
21457
|
+
if (seen.has(diagnostic.id)) {
|
|
21458
|
+
continue;
|
|
21459
|
+
}
|
|
21460
|
+
seen.add(diagnostic.id);
|
|
21461
|
+
deduped.push(diagnostic);
|
|
21462
|
+
}
|
|
21463
|
+
return deduped;
|
|
21464
|
+
}
|
|
20029
21465
|
function isBlockingDiagnostic(item) {
|
|
20030
21466
|
return item.severity === 'error' || item.severity === 'fatal';
|
|
20031
21467
|
}
|
|
21468
|
+
function resolvePreviewBindingPath(portId, bindingPath) {
|
|
21469
|
+
const normalizedPortId = String(portId || '').trim();
|
|
21470
|
+
const normalizedBindingPath = String(bindingPath || '').trim();
|
|
21471
|
+
if (!normalizedPortId && !normalizedBindingPath) {
|
|
21472
|
+
return undefined;
|
|
21473
|
+
}
|
|
21474
|
+
if (!normalizedBindingPath) {
|
|
21475
|
+
return normalizedPortId || undefined;
|
|
21476
|
+
}
|
|
21477
|
+
if (!normalizedPortId) {
|
|
21478
|
+
return normalizedBindingPath;
|
|
21479
|
+
}
|
|
21480
|
+
if (normalizedBindingPath === normalizedPortId
|
|
21481
|
+
|| normalizedBindingPath.startsWith(`${normalizedPortId}.`)
|
|
21482
|
+
|| normalizedBindingPath.startsWith(`${normalizedPortId}[`)) {
|
|
21483
|
+
return normalizedBindingPath;
|
|
21484
|
+
}
|
|
21485
|
+
if (normalizedBindingPath.startsWith('.')
|
|
21486
|
+
|| normalizedBindingPath.startsWith('[')) {
|
|
21487
|
+
return `${normalizedPortId}${normalizedBindingPath}`;
|
|
21488
|
+
}
|
|
21489
|
+
return `${normalizedPortId}.${normalizedBindingPath}`;
|
|
21490
|
+
}
|
|
21491
|
+
function classifyDerivedDiagnosticMessage(message) {
|
|
21492
|
+
if (message.includes('cycle')) {
|
|
21493
|
+
return {
|
|
21494
|
+
code: 'RUNTIME_DERIVED_STATE_CYCLE',
|
|
21495
|
+
severity: 'warning',
|
|
21496
|
+
};
|
|
21497
|
+
}
|
|
21498
|
+
if (message.includes('transformer')) {
|
|
21499
|
+
return {
|
|
21500
|
+
code: 'RUNTIME_DERIVED_TRANSFORMER_UNSUPPORTED',
|
|
21501
|
+
severity: 'warning',
|
|
21502
|
+
};
|
|
21503
|
+
}
|
|
21504
|
+
if (message.includes('missing compute definition')) {
|
|
21505
|
+
return {
|
|
21506
|
+
code: 'RUNTIME_DERIVED_COMPUTE_MISSING',
|
|
21507
|
+
severity: 'warning',
|
|
21508
|
+
};
|
|
21509
|
+
}
|
|
21510
|
+
if (message.includes('unsupported compute kind')) {
|
|
21511
|
+
return {
|
|
21512
|
+
code: 'RUNTIME_DERIVED_COMPUTE_KIND_UNSUPPORTED',
|
|
21513
|
+
severity: 'warning',
|
|
21514
|
+
};
|
|
21515
|
+
}
|
|
21516
|
+
if (message.includes('without a valid operator')) {
|
|
21517
|
+
return {
|
|
21518
|
+
code: 'RUNTIME_DERIVED_OPERATOR_MISSING',
|
|
21519
|
+
severity: 'warning',
|
|
21520
|
+
};
|
|
21521
|
+
}
|
|
21522
|
+
if (message.includes('uses unsupported operator')) {
|
|
21523
|
+
return {
|
|
21524
|
+
code: 'RUNTIME_DERIVED_OPERATOR_UNSUPPORTED',
|
|
21525
|
+
severity: 'warning',
|
|
21526
|
+
};
|
|
21527
|
+
}
|
|
21528
|
+
if (message.includes(' failed: ')) {
|
|
21529
|
+
return {
|
|
21530
|
+
code: 'RUNTIME_DERIVED_STATE_FAILED',
|
|
21531
|
+
severity: 'error',
|
|
21532
|
+
};
|
|
21533
|
+
}
|
|
21534
|
+
return {
|
|
21535
|
+
code: 'RUNTIME_DERIVED_STATE_WARNING',
|
|
21536
|
+
severity: 'info',
|
|
21537
|
+
};
|
|
21538
|
+
}
|
|
20032
21539
|
function matchesEndpoint(expected, actual) {
|
|
20033
21540
|
if (expected.kind !== actual.kind) {
|
|
20034
21541
|
return false;
|
|
@@ -20154,7 +21661,7 @@ class WidgetPageCompositionFactory {
|
|
|
20154
21661
|
return {
|
|
20155
21662
|
widgetOrder: page.widgets.map((widget) => widget.key),
|
|
20156
21663
|
widgetsByKey,
|
|
20157
|
-
links:
|
|
21664
|
+
links: this.readCanonicalLinks(page),
|
|
20158
21665
|
state: {
|
|
20159
21666
|
primaryValues: this.materializePrimaryValues(normalizedState),
|
|
20160
21667
|
schema: this.clone(normalizedState.schema) || {},
|
|
@@ -20163,6 +21670,9 @@ class WidgetPageCompositionFactory {
|
|
|
20163
21670
|
context: this.clone(page.context) || {},
|
|
20164
21671
|
};
|
|
20165
21672
|
}
|
|
21673
|
+
readCanonicalLinks(page) {
|
|
21674
|
+
return this.clone(page.composition?.links) || [];
|
|
21675
|
+
}
|
|
20166
21676
|
indexWidgets(widgets) {
|
|
20167
21677
|
const widgetsByKey = {};
|
|
20168
21678
|
for (const widget of widgets) {
|
|
@@ -20252,11 +21762,6 @@ const CANVAS_RESIZE_HANDLES = [
|
|
|
20252
21762
|
{ id: 'south-west', className: 'pdx-canvas-resize--south-west' },
|
|
20253
21763
|
];
|
|
20254
21764
|
class DynamicWidgetPageComponent {
|
|
20255
|
-
conn;
|
|
20256
|
-
stateRuntime;
|
|
20257
|
-
settingsPanel;
|
|
20258
|
-
defaultShellEditor;
|
|
20259
|
-
defaultPageEditor;
|
|
20260
21765
|
pageCanvasHost;
|
|
20261
21766
|
page;
|
|
20262
21767
|
context = null;
|
|
@@ -20310,6 +21815,7 @@ class DynamicWidgetPageComponent {
|
|
|
20310
21815
|
isHydrating = false;
|
|
20311
21816
|
persistenceReady = false;
|
|
20312
21817
|
warnedMissingKey = false;
|
|
21818
|
+
runtimeEventSequence = 0;
|
|
20313
21819
|
compositionFactory = new WidgetPageCompositionFactory();
|
|
20314
21820
|
compositionRuntime = new CompositionRuntimeFacade();
|
|
20315
21821
|
compositionDefinition;
|
|
@@ -20323,13 +21829,12 @@ class DynamicWidgetPageComponent {
|
|
|
20323
21829
|
catch {
|
|
20324
21830
|
return undefined;
|
|
20325
21831
|
} })();
|
|
20326
|
-
|
|
20327
|
-
|
|
20328
|
-
|
|
20329
|
-
|
|
20330
|
-
|
|
20331
|
-
|
|
20332
|
-
}
|
|
21832
|
+
conn = inject(ConnectionManagerService);
|
|
21833
|
+
stateRuntime = inject(WidgetPageStateRuntimeService);
|
|
21834
|
+
settingsPanel = inject(SETTINGS_PANEL_BRIDGE, { optional: true });
|
|
21835
|
+
defaultShellEditor = inject(DYNAMIC_PAGE_SHELL_EDITOR, { optional: true });
|
|
21836
|
+
defaultPageEditor = inject(DYNAMIC_PAGE_CONFIG_EDITOR, { optional: true });
|
|
21837
|
+
constructor() { }
|
|
20333
21838
|
ngOnDestroy() {
|
|
20334
21839
|
this.compositionRuntime.destroy();
|
|
20335
21840
|
}
|
|
@@ -20337,6 +21842,7 @@ class DynamicWidgetPageComponent {
|
|
|
20337
21842
|
if (changes['page'] || changes['context'] || changes['enableCustomization']) {
|
|
20338
21843
|
const parsed = this.parsePage(this.page);
|
|
20339
21844
|
const resolvedPage = parsed ? this.resolvePagePresets(parsed) : parsed;
|
|
21845
|
+
this.assertNoLegacyConnections(resolvedPage);
|
|
20340
21846
|
this.widgetDiagnostics = {};
|
|
20341
21847
|
this.widgetDiagnosticsChange.emit({});
|
|
20342
21848
|
this.pageDefinition = resolvedPage ? { ...resolvedPage, state: this.stateRuntime.normalizeState(resolvedPage.state) } : resolvedPage;
|
|
@@ -20374,7 +21880,7 @@ class DynamicWidgetPageComponent {
|
|
|
20374
21880
|
if (!cycle || !cycle.matchedLinkIds.length)
|
|
20375
21881
|
return;
|
|
20376
21882
|
const state = this.stateFromCompositionSnapshot(page.state, cycle.snapshot.state.primaryValues);
|
|
20377
|
-
const runtimeStatePaths = Array.from(new Set(cycle.snapshot.state.changedPaths || []));
|
|
21883
|
+
const runtimeStatePaths = Array.from(new Set((cycle.snapshot.state.changedPaths || []).filter((path) => typeof path === 'string')));
|
|
20378
21884
|
const updatedPrimaryStatePaths = runtimeStatePaths.filter((path) => (!this.areStateValuesEqual(this.conn.extractByPath(this.stateRuntime.normalizeState(page.state).values || {}, path), this.conn.extractByPath(state.values || {}, path))));
|
|
20379
21885
|
let widgets = this.cloneWidgets(page.widgets || []);
|
|
20380
21886
|
const directDelivery = this.applyCompositionWidgetDeliveries(widgets, cycle);
|
|
@@ -20392,6 +21898,220 @@ class DynamicWidgetPageComponent {
|
|
|
20392
21898
|
}
|
|
20393
21899
|
this.applyPageUpdate({ ...page, widgets, state }, true, nextRuntime, false);
|
|
20394
21900
|
}
|
|
21901
|
+
buildStateRuntime(state, pageContext) {
|
|
21902
|
+
return this.stateRuntime.buildRuntimeSnapshot(state, this.buildStateContext(pageContext));
|
|
21903
|
+
}
|
|
21904
|
+
bootstrapCompositionAdapter(page) {
|
|
21905
|
+
if (!page) {
|
|
21906
|
+
this.compositionDefinition = undefined;
|
|
21907
|
+
return undefined;
|
|
21908
|
+
}
|
|
21909
|
+
this.compositionDefinition = this.compositionFactory.create(page);
|
|
21910
|
+
return this.compositionRuntime.bootstrap(this.compositionDefinition);
|
|
21911
|
+
}
|
|
21912
|
+
applyEditShellActions(widgets) {
|
|
21913
|
+
return this.cloneWidgets(widgets).map((widget) => {
|
|
21914
|
+
if (!this.shouldInjectWidgetSettings(widget)) {
|
|
21915
|
+
return widget;
|
|
21916
|
+
}
|
|
21917
|
+
const existingActions = widget.shell?.actions || [];
|
|
21918
|
+
if (existingActions.some((action) => action.id === 'widget-settings')) {
|
|
21919
|
+
return widget;
|
|
21920
|
+
}
|
|
21921
|
+
const widgetSettingsAction = {
|
|
21922
|
+
id: 'widget-settings',
|
|
21923
|
+
icon: 'settings',
|
|
21924
|
+
variant: 'icon',
|
|
21925
|
+
placement: 'header',
|
|
21926
|
+
label: this.t('controls.widgetSettings', 'Configurar widget'),
|
|
21927
|
+
tooltip: this.t('controls.widgetSettingsTooltip', 'Abrir configurações do widget'),
|
|
21928
|
+
};
|
|
21929
|
+
return {
|
|
21930
|
+
...widget,
|
|
21931
|
+
shell: {
|
|
21932
|
+
...(widget.shell || {}),
|
|
21933
|
+
actions: [...existingActions, widgetSettingsAction],
|
|
21934
|
+
},
|
|
21935
|
+
};
|
|
21936
|
+
});
|
|
21937
|
+
}
|
|
21938
|
+
applyBootstrapCompositionHydration(widgets, bootstrapSnapshot) {
|
|
21939
|
+
if (!this.compositionDefinition || !bootstrapSnapshot) {
|
|
21940
|
+
return this.cloneWidgets(widgets);
|
|
21941
|
+
}
|
|
21942
|
+
return this.compositionRuntime.projectStateWidgetInputs(this.compositionDefinition, {
|
|
21943
|
+
widgets,
|
|
21944
|
+
state: bootstrapSnapshot.state,
|
|
21945
|
+
now: bootstrapSnapshot.generatedAt,
|
|
21946
|
+
}).widgets;
|
|
21947
|
+
}
|
|
21948
|
+
reportStateDiagnostics(diagnostics) {
|
|
21949
|
+
if (!diagnostics?.length)
|
|
21950
|
+
return;
|
|
21951
|
+
console.warn('[DynamicWidgetPage] State runtime diagnostics', diagnostics);
|
|
21952
|
+
}
|
|
21953
|
+
dispatchWidgetEventToComposition(page, fromKey, evt) {
|
|
21954
|
+
const output = String(evt?.output || '').trim();
|
|
21955
|
+
if (!output)
|
|
21956
|
+
return undefined;
|
|
21957
|
+
const definition = this.compositionDefinition ?? this.compositionFactory.create(page);
|
|
21958
|
+
this.compositionDefinition = definition;
|
|
21959
|
+
if (!definition.links.some((link) => (link.from.kind === 'component-port'
|
|
21960
|
+
&& link.from.ref.widget === fromKey
|
|
21961
|
+
&& link.from.ref.port === output
|
|
21962
|
+
&& link.from.ref.direction === 'output'))) {
|
|
21963
|
+
return undefined;
|
|
21964
|
+
}
|
|
21965
|
+
let payload;
|
|
21966
|
+
try {
|
|
21967
|
+
payload = this.cloneStateValues(evt?.payload);
|
|
21968
|
+
}
|
|
21969
|
+
catch (error) {
|
|
21970
|
+
const message = `DynamicWidgetPageComponent could not serialize widget event payload for "${fromKey}.${output}". ` +
|
|
21971
|
+
`Composition links only support JSON-safe payloads.`;
|
|
21972
|
+
const wrapped = new Error(message);
|
|
21973
|
+
wrapped.cause = error;
|
|
21974
|
+
throw wrapped;
|
|
21975
|
+
}
|
|
21976
|
+
return this.compositionRuntime.dispatch({
|
|
21977
|
+
eventId: this.buildRuntimeEventId(fromKey, output),
|
|
21978
|
+
source: {
|
|
21979
|
+
kind: 'component-port',
|
|
21980
|
+
ref: {
|
|
21981
|
+
widget: fromKey,
|
|
21982
|
+
port: output,
|
|
21983
|
+
direction: 'output',
|
|
21984
|
+
componentType: evt.sourceComponentId,
|
|
21985
|
+
},
|
|
21986
|
+
},
|
|
21987
|
+
payload,
|
|
21988
|
+
});
|
|
21989
|
+
}
|
|
21990
|
+
stateFromCompositionSnapshot(previousState, primaryValues) {
|
|
21991
|
+
const normalized = this.stateRuntime.normalizeState(previousState);
|
|
21992
|
+
return {
|
|
21993
|
+
...normalized,
|
|
21994
|
+
values: this.cloneStateValues(primaryValues) || {},
|
|
21995
|
+
};
|
|
21996
|
+
}
|
|
21997
|
+
applyCompositionWidgetDeliveries(widgets, cycle) {
|
|
21998
|
+
if (!this.compositionDefinition) {
|
|
21999
|
+
return {
|
|
22000
|
+
widgets: this.cloneWidgets(widgets),
|
|
22001
|
+
changed: false,
|
|
22002
|
+
};
|
|
22003
|
+
}
|
|
22004
|
+
const linksById = new Map(this.compositionDefinition.links.map((link) => [link.id, link]));
|
|
22005
|
+
const runtimeLinks = cycle.snapshot.links.filter((link) => (link.lastDispatchTraceId === cycle.cycleId && link.status === 'delivered'));
|
|
22006
|
+
let nextWidgets = this.cloneWidgets(widgets);
|
|
22007
|
+
let changed = false;
|
|
22008
|
+
for (const runtimeLink of runtimeLinks) {
|
|
22009
|
+
const link = linksById.get(runtimeLink.linkId);
|
|
22010
|
+
if (!link || link.from.kind === 'state' || link.to.kind !== 'component-port') {
|
|
22011
|
+
continue;
|
|
22012
|
+
}
|
|
22013
|
+
const targetRef = link.to.ref;
|
|
22014
|
+
const bindingPath = this.resolveComponentBindingPath(targetRef.port, targetRef.bindingPath);
|
|
22015
|
+
if (!bindingPath) {
|
|
22016
|
+
continue;
|
|
22017
|
+
}
|
|
22018
|
+
const widgetIndex = nextWidgets.findIndex((widget) => widget.key === targetRef.widget);
|
|
22019
|
+
if (widgetIndex < 0) {
|
|
22020
|
+
continue;
|
|
22021
|
+
}
|
|
22022
|
+
const widget = nextWidgets[widgetIndex];
|
|
22023
|
+
const currentInputs = this.cloneStateValues(widget.definition.inputs || {});
|
|
22024
|
+
const nextInputs = this.conn.setValueAtPath(currentInputs, bindingPath, this.cloneStateValues(runtimeLink.lastDeliveredValuePreview));
|
|
22025
|
+
if (this.areStateValuesEqual(currentInputs, nextInputs)) {
|
|
22026
|
+
continue;
|
|
22027
|
+
}
|
|
22028
|
+
nextWidgets[widgetIndex] = {
|
|
22029
|
+
...widget,
|
|
22030
|
+
definition: {
|
|
22031
|
+
...widget.definition,
|
|
22032
|
+
inputs: nextInputs,
|
|
22033
|
+
},
|
|
22034
|
+
};
|
|
22035
|
+
changed = true;
|
|
22036
|
+
}
|
|
22037
|
+
return { widgets: nextWidgets, changed };
|
|
22038
|
+
}
|
|
22039
|
+
buildStateContext(pageContext) {
|
|
22040
|
+
return {
|
|
22041
|
+
...(this.cloneStateValues(pageContext) || {}),
|
|
22042
|
+
...(this.cloneStateValues(this.context) || {}),
|
|
22043
|
+
};
|
|
22044
|
+
}
|
|
22045
|
+
cloneStateValues(value) {
|
|
22046
|
+
if (value == null || typeof value !== 'object') {
|
|
22047
|
+
return value;
|
|
22048
|
+
}
|
|
22049
|
+
return JSON.parse(JSON.stringify(value));
|
|
22050
|
+
}
|
|
22051
|
+
cloneGrouping(grouping) {
|
|
22052
|
+
return this.cloneStateValues(grouping);
|
|
22053
|
+
}
|
|
22054
|
+
resolveShellTemplates(widgets, runtime) {
|
|
22055
|
+
const templateContext = {
|
|
22056
|
+
context: this.buildStateContext(this.pageDefinition?.context),
|
|
22057
|
+
pageContext: this.buildStateContext(this.pageDefinition?.context),
|
|
22058
|
+
state: this.cloneStateValues(runtime.effectiveValues),
|
|
22059
|
+
values: this.cloneStateValues(runtime.primaryValues),
|
|
22060
|
+
derived: this.cloneStateValues(runtime.derivedValues),
|
|
22061
|
+
pageState: this.cloneStateValues(runtime.primaryValues),
|
|
22062
|
+
pageStateDerived: this.cloneStateValues(runtime.derivedValues),
|
|
22063
|
+
pageStateEffective: this.cloneStateValues(runtime.effectiveValues),
|
|
22064
|
+
};
|
|
22065
|
+
return this.cloneWidgets(widgets).map((widget) => {
|
|
22066
|
+
if (!widget.shell) {
|
|
22067
|
+
return widget;
|
|
22068
|
+
}
|
|
22069
|
+
return {
|
|
22070
|
+
...widget,
|
|
22071
|
+
shell: this.resolveTemplate(widget.shell, templateContext),
|
|
22072
|
+
};
|
|
22073
|
+
});
|
|
22074
|
+
}
|
|
22075
|
+
resolveComponentBindingPath(portId, bindingPath) {
|
|
22076
|
+
const normalizedPortId = String(portId || '').trim();
|
|
22077
|
+
const normalizedBindingPath = String(bindingPath || '').trim();
|
|
22078
|
+
if (!normalizedPortId && !normalizedBindingPath) {
|
|
22079
|
+
return undefined;
|
|
22080
|
+
}
|
|
22081
|
+
if (!normalizedBindingPath) {
|
|
22082
|
+
return normalizedPortId || undefined;
|
|
22083
|
+
}
|
|
22084
|
+
if (!normalizedPortId) {
|
|
22085
|
+
return normalizedBindingPath;
|
|
22086
|
+
}
|
|
22087
|
+
if (normalizedBindingPath === normalizedPortId
|
|
22088
|
+
|| normalizedBindingPath.startsWith(`${normalizedPortId}.`)
|
|
22089
|
+
|| normalizedBindingPath.startsWith(`${normalizedPortId}[`)) {
|
|
22090
|
+
return normalizedBindingPath;
|
|
22091
|
+
}
|
|
22092
|
+
if (normalizedBindingPath.startsWith('.')
|
|
22093
|
+
|| normalizedBindingPath.startsWith('[')) {
|
|
22094
|
+
return `${normalizedPortId}${normalizedBindingPath}`;
|
|
22095
|
+
}
|
|
22096
|
+
return `${normalizedPortId}.${normalizedBindingPath}`;
|
|
22097
|
+
}
|
|
22098
|
+
buildRuntimeEventId(fromKey, output) {
|
|
22099
|
+
const sequence = ++this.runtimeEventSequence;
|
|
22100
|
+
const timestamp = Date.now();
|
|
22101
|
+
if (typeof globalThis !== 'undefined' && globalThis.crypto?.randomUUID) {
|
|
22102
|
+
return `widget:${fromKey}:${output}:${sequence}:${globalThis.crypto.randomUUID()}`;
|
|
22103
|
+
}
|
|
22104
|
+
return `widget:${fromKey}:${output}:${timestamp}:${sequence}`;
|
|
22105
|
+
}
|
|
22106
|
+
shouldInjectWidgetSettings(widget) {
|
|
22107
|
+
if (!this.enableCustomization || !this.settingsPanel) {
|
|
22108
|
+
return false;
|
|
22109
|
+
}
|
|
22110
|
+
if (!(this.shellEditorComponent || this.defaultShellEditor)) {
|
|
22111
|
+
return false;
|
|
22112
|
+
}
|
|
22113
|
+
return !!widget.shell && widget.shell.kind !== 'none';
|
|
22114
|
+
}
|
|
20395
22115
|
areStateValuesEqual(left, right) {
|
|
20396
22116
|
if (left === right)
|
|
20397
22117
|
return true;
|
|
@@ -20651,6 +22371,7 @@ class DynamicWidgetPageComponent {
|
|
|
20651
22371
|
}, persist);
|
|
20652
22372
|
}
|
|
20653
22373
|
applyPageUpdate(next, persist = true, runtime = this.buildStateRuntime(next.state, next.context), syncCompositionAdapter = true) {
|
|
22374
|
+
this.assertNoLegacyConnections(next);
|
|
20654
22375
|
const normalized = { ...next, state: runtime.state };
|
|
20655
22376
|
const normalizedWidgets = this.applyEditShellActions(normalized.widgets || []);
|
|
20656
22377
|
const bootstrapSnapshot = syncCompositionAdapter
|
|
@@ -20828,12 +22549,15 @@ class DynamicWidgetPageComponent {
|
|
|
20828
22549
|
return undefined;
|
|
20829
22550
|
if (typeof input === 'string') {
|
|
20830
22551
|
try {
|
|
20831
|
-
|
|
22552
|
+
const parsed = JSON.parse(input);
|
|
22553
|
+
this.assertNoLegacyConnections(parsed);
|
|
22554
|
+
return parsed;
|
|
20832
22555
|
}
|
|
20833
22556
|
catch {
|
|
20834
22557
|
return undefined;
|
|
20835
22558
|
}
|
|
20836
22559
|
}
|
|
22560
|
+
this.assertNoLegacyConnections(input);
|
|
20837
22561
|
return input;
|
|
20838
22562
|
}
|
|
20839
22563
|
resolvePagePresets(page) {
|
|
@@ -21518,9 +23242,9 @@ class DynamicWidgetPageComponent {
|
|
|
21518
23242
|
if (!grouping?.length)
|
|
21519
23243
|
return grouping;
|
|
21520
23244
|
if (!overrides?.length)
|
|
21521
|
-
return this.cloneGrouping(grouping);
|
|
23245
|
+
return this.cloneGrouping(grouping) || [];
|
|
21522
23246
|
const overridesById = new Map(overrides.map((item) => [item.id, item]));
|
|
21523
|
-
return this.cloneGrouping(grouping)
|
|
23247
|
+
return (this.cloneGrouping(grouping) || [])
|
|
21524
23248
|
.map((group) => {
|
|
21525
23249
|
const override = overridesById.get(group.id);
|
|
21526
23250
|
if (!override || override.hidden)
|
|
@@ -21658,35 +23382,16 @@ class DynamicWidgetPageComponent {
|
|
|
21658
23382
|
resolveRenderedCanvasItem(widget) {
|
|
21659
23383
|
return this.transientCanvasItemsState()[widget.key] || widget.renderCanvasItem;
|
|
21660
23384
|
}
|
|
21661
|
-
|
|
21662
|
-
|
|
21663
|
-
|
|
21664
|
-
return widgets.map((w) => {
|
|
21665
|
-
if (!w.shell || w.shell.kind === 'none')
|
|
21666
|
-
return w;
|
|
21667
|
-
const shell = { ...w.shell };
|
|
21668
|
-
const actions = [...(shell.actions || [])];
|
|
21669
|
-
if (!actions.some((a) => a.id === 'widget-settings')) {
|
|
21670
|
-
actions.push({
|
|
21671
|
-
id: 'widget-settings',
|
|
21672
|
-
icon: 'settings',
|
|
21673
|
-
label: 'Configurar Card',
|
|
21674
|
-
placement: 'window',
|
|
21675
|
-
variant: 'icon',
|
|
21676
|
-
tooltip: 'Configurar Card',
|
|
21677
|
-
});
|
|
21678
|
-
}
|
|
21679
|
-
if (shell.showHeader === false)
|
|
21680
|
-
shell.showHeader = true;
|
|
21681
|
-
return { ...w, shell: { ...shell, actions } };
|
|
21682
|
-
});
|
|
23385
|
+
toPersistedCanonicalPage(page) {
|
|
23386
|
+
this.assertNoLegacyConnections(page);
|
|
23387
|
+
return writeCompositionLinksToPersistedPage(page, page.composition?.links || []);
|
|
21683
23388
|
}
|
|
21684
23389
|
savePage(page) {
|
|
21685
23390
|
const key = this.storageKey();
|
|
21686
23391
|
if (!key)
|
|
21687
23392
|
return;
|
|
21688
23393
|
try {
|
|
21689
|
-
this.storage.saveConfig(key, page).pipe(take(1)).subscribe({ error: () => { } });
|
|
23394
|
+
this.storage.saveConfig(key, this.toPersistedCanonicalPage(page)).pipe(take(1)).subscribe({ error: () => { } });
|
|
21690
23395
|
}
|
|
21691
23396
|
catch { }
|
|
21692
23397
|
}
|
|
@@ -21761,135 +23466,15 @@ class DynamicWidgetPageComponent {
|
|
|
21761
23466
|
return '';
|
|
21762
23467
|
return String(value).trim().replace(/[\r\n\t|:]/g, '-');
|
|
21763
23468
|
}
|
|
21764
|
-
|
|
21765
|
-
|
|
21766
|
-
|
|
21767
|
-
|
|
21768
|
-
|
|
21769
|
-
return value;
|
|
21770
|
-
}
|
|
21771
|
-
return JSON.parse(JSON.stringify(value));
|
|
21772
|
-
}
|
|
21773
|
-
cloneGrouping(grouping) {
|
|
21774
|
-
return grouping ? JSON.parse(JSON.stringify(grouping)) : [];
|
|
21775
|
-
}
|
|
21776
|
-
buildStateRuntime(state, pageContext) {
|
|
21777
|
-
return this.stateRuntime.buildRuntimeSnapshot(state, this.buildStateContext(pageContext));
|
|
21778
|
-
}
|
|
21779
|
-
buildStateContext(pageContext) {
|
|
21780
|
-
return {
|
|
21781
|
-
...(pageContext || {}),
|
|
21782
|
-
...(this.context || {}),
|
|
21783
|
-
};
|
|
21784
|
-
}
|
|
21785
|
-
resolveShellTemplates(widgets, runtime) {
|
|
21786
|
-
const context = {
|
|
21787
|
-
...(this.mergedContext || {}),
|
|
21788
|
-
state: this.cloneStateValues(runtime.effectiveValues),
|
|
21789
|
-
pageState: this.cloneStateValues(runtime.primaryValues),
|
|
21790
|
-
pageStateDerived: this.cloneStateValues(runtime.derivedValues),
|
|
21791
|
-
pageStateEffective: this.cloneStateValues(runtime.effectiveValues),
|
|
21792
|
-
};
|
|
21793
|
-
return widgets.map((widget) => (widget.shell
|
|
21794
|
-
? { ...widget, shell: this.resolveTemplate(widget.shell, context) }
|
|
21795
|
-
: widget));
|
|
21796
|
-
}
|
|
21797
|
-
reportStateDiagnostics(diagnostics) {
|
|
21798
|
-
for (const diagnostic of diagnostics || []) {
|
|
21799
|
-
console.warn(`[DynamicWidgetPage] ${diagnostic}`);
|
|
21800
|
-
}
|
|
21801
|
-
}
|
|
21802
|
-
applyBootstrapCompositionHydration(widgets, snapshot) {
|
|
21803
|
-
const matchedLinkIds = (snapshot?.links || [])
|
|
21804
|
-
.filter((link) => link.status === 'delivered')
|
|
21805
|
-
.map((link) => link.linkId);
|
|
21806
|
-
if (!snapshot || !matchedLinkIds.length) {
|
|
21807
|
-
return widgets;
|
|
21808
|
-
}
|
|
21809
|
-
return this.applyCompositionWidgetDeliveries(widgets, {
|
|
21810
|
-
cycleId: 'bootstrap',
|
|
21811
|
-
matchedLinkIds,
|
|
21812
|
-
snapshot,
|
|
21813
|
-
diagnostics: snapshot.diagnostics,
|
|
21814
|
-
}).widgets;
|
|
21815
|
-
}
|
|
21816
|
-
bootstrapCompositionAdapter(page) {
|
|
21817
|
-
if (!page) {
|
|
21818
|
-
this.compositionDefinition = undefined;
|
|
21819
|
-
return undefined;
|
|
21820
|
-
}
|
|
21821
|
-
this.compositionDefinition = this.compositionFactory.create({
|
|
21822
|
-
...page,
|
|
21823
|
-
state: this.stateRuntime.normalizeState(page.state),
|
|
21824
|
-
});
|
|
21825
|
-
return this.compositionRuntime.bootstrap(this.compositionDefinition);
|
|
21826
|
-
}
|
|
21827
|
-
dispatchWidgetEventToComposition(page, fromKey, evt) {
|
|
21828
|
-
if (!evt?.output) {
|
|
21829
|
-
return null;
|
|
21830
|
-
}
|
|
21831
|
-
if (!this.compositionDefinition) {
|
|
21832
|
-
this.bootstrapCompositionAdapter(page);
|
|
21833
|
-
}
|
|
21834
|
-
return this.compositionRuntime.dispatch({
|
|
21835
|
-
eventId: `widget:${evt.ownerWidgetKey || fromKey}:${evt.output}:${Date.now()}`,
|
|
21836
|
-
source: {
|
|
21837
|
-
kind: 'component-port',
|
|
21838
|
-
ref: {
|
|
21839
|
-
widget: evt.ownerWidgetKey || fromKey,
|
|
21840
|
-
port: evt.output,
|
|
21841
|
-
direction: 'output',
|
|
21842
|
-
componentType: evt.sourceComponentId,
|
|
21843
|
-
},
|
|
21844
|
-
},
|
|
21845
|
-
payload: evt.payload,
|
|
21846
|
-
occurredAt: new Date().toISOString(),
|
|
21847
|
-
});
|
|
21848
|
-
}
|
|
21849
|
-
stateFromCompositionSnapshot(baseState, primaryValues) {
|
|
21850
|
-
const normalized = this.stateRuntime.normalizeState(baseState);
|
|
21851
|
-
return {
|
|
21852
|
-
...normalized,
|
|
21853
|
-
values: this.cloneStateValues(primaryValues),
|
|
21854
|
-
};
|
|
21855
|
-
}
|
|
21856
|
-
applyCompositionWidgetDeliveries(widgets, cycle) {
|
|
21857
|
-
if (!this.compositionDefinition) {
|
|
21858
|
-
return { widgets, changed: false };
|
|
21859
|
-
}
|
|
21860
|
-
const linkMap = new Map(this.compositionDefinition.links.map((link) => [link.id, link]));
|
|
21861
|
-
const snapshotMap = new Map(cycle.snapshot.links.map((link) => [link.linkId, link]));
|
|
21862
|
-
let changed = false;
|
|
21863
|
-
for (const linkId of cycle.matchedLinkIds) {
|
|
21864
|
-
const link = linkMap.get(linkId);
|
|
21865
|
-
const linkSnapshot = snapshotMap.get(linkId);
|
|
21866
|
-
if (!link || !linkSnapshot || linkSnapshot.status !== 'delivered' || link.to.kind !== 'component-port') {
|
|
21867
|
-
continue;
|
|
21868
|
-
}
|
|
21869
|
-
const targetRef = link.to.ref;
|
|
21870
|
-
const widgetIndex = widgets.findIndex((widget) => widget.key === targetRef.widget);
|
|
21871
|
-
if (widgetIndex < 0) {
|
|
21872
|
-
continue;
|
|
21873
|
-
}
|
|
21874
|
-
const bindingPath = targetRef.bindingPath || targetRef.port;
|
|
21875
|
-
const currentInputs = widgets[widgetIndex].definition.inputs || {};
|
|
21876
|
-
const nextValue = this.cloneValue(linkSnapshot.lastDeliveredValuePreview);
|
|
21877
|
-
const currentValue = this.conn.extractByPath(currentInputs, bindingPath);
|
|
21878
|
-
if (this.areStateValuesEqual(currentValue, nextValue)) {
|
|
21879
|
-
continue;
|
|
21880
|
-
}
|
|
21881
|
-
widgets[widgetIndex] = {
|
|
21882
|
-
...widgets[widgetIndex],
|
|
21883
|
-
definition: {
|
|
21884
|
-
...widgets[widgetIndex].definition,
|
|
21885
|
-
inputs: this.conn.setValueAtPath(this.cloneStateValues(currentInputs), bindingPath, nextValue),
|
|
21886
|
-
},
|
|
21887
|
-
};
|
|
21888
|
-
changed = true;
|
|
23469
|
+
assertNoLegacyConnections(page) {
|
|
23470
|
+
if (!page)
|
|
23471
|
+
return;
|
|
23472
|
+
if (!Object.prototype.hasOwnProperty.call(page, 'connections')) {
|
|
23473
|
+
return;
|
|
21889
23474
|
}
|
|
21890
|
-
|
|
23475
|
+
throw new Error('DynamicWidgetPageComponent no longer accepts `page.connections`. Use `composition.links` only.');
|
|
21891
23476
|
}
|
|
21892
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DynamicWidgetPageComponent, deps: [
|
|
23477
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DynamicWidgetPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
21893
23478
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: DynamicWidgetPageComponent, isStandalone: true, selector: "praxis-dynamic-page", inputs: { page: "page", context: "context", strictValidation: "strictValidation", enableCustomization: "enableCustomization", showPageSettingsButton: "showPageSettingsButton", shellEditorComponent: "shellEditorComponent", pageEditorComponent: "pageEditorComponent", autoPersist: "autoPersist", pageIdentity: "pageIdentity", componentInstanceId: "componentInstanceId" }, outputs: { pageChange: "pageChange", widgetDiagnosticsChange: "widgetDiagnosticsChange" }, host: { listeners: { "window:resize": "onWindowResize()", "window:pointermove": "onCanvasPointerMove($event)", "window:pointerup": "onCanvasPointerUp($event)", "window:pointercancel": "onCanvasPointerCancel($event)" } }, providers: [providePraxisI18nConfig(DYNAMIC_WIDGET_PAGE_I18N_CONFIG)], viewQueries: [{ propertyName: "pageCanvasHost", first: true, predicate: ["pageCanvasHost"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
21894
23479
|
<div class="pdx-page-wrapper" [class.editing]="enableCustomization">
|
|
21895
23480
|
@if (enableCustomization && showPageSettingsButton) {
|
|
@@ -22073,7 +23658,7 @@ class DynamicWidgetPageComponent {
|
|
|
22073
23658
|
<div class="pdx-sr-only" aria-live="polite">{{ layoutAnnouncement }}</div>
|
|
22074
23659
|
}
|
|
22075
23660
|
</div>
|
|
22076
|
-
`, isInline: true, styles: [".pdx-page-wrapper{position:relative;display:block}.pdx-page{display:grid;gap:16px;grid-template-columns:minmax(0,1fr)}.pdx-page--canvas{align-items:start;grid-auto-flow:dense}.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;min-width:0;min-height:0}.pdx-widget--canvas{align-self:stretch;--pdx-resize-gradient-horizontal: linear-gradient( 90deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-vertical: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-diagonal-se: linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-diagonal-sw: linear-gradient( 225deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-se)}.pdx-widget--canvas:after{content:\"\";position:absolute;inset:0;padding:2px;border-radius:14px;background:var(--pdx-active-resize-gradient);opacity:0;pointer-events:none;transition:opacity .14s ease,filter .14s ease;filter:saturate(1.02) drop-shadow(0 0 5px color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent));-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude}.pdx-widget--canvas-selected:before,.pdx-widget--canvas-blocked:before{content:\"\";position:absolute;inset:0;border-radius:14px;pointer-events:none;z-index:1;transition:opacity .14s ease,box-shadow .14s ease,border-color .14s ease}.pdx-widget--canvas-selected:before{border:1px dashed color-mix(in srgb,var(--md-sys-color-primary) 34%,transparent);box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 6%,transparent),0 8px 20px color-mix(in srgb,var(--md-sys-color-primary) 6%,transparent)}.pdx-widget--canvas-blocked:before{border:1px solid color-mix(in srgb,var(--md-sys-color-error) 74%,transparent);box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-error) 20%,transparent),0 10px 24px color-mix(in srgb,var(--md-sys-color-error) 12%,transparent)}.pdx-widget--canvas:has(.pdx-canvas-resize:hover):after,.pdx-widget--canvas:has(.pdx-canvas-resize:focus-visible):after{opacity:.82}.pdx-widget--canvas:has(.pdx-canvas-resize--north:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-horizontal)}.pdx-widget--canvas:has(.pdx-canvas-resize--east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--east:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--west:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-vertical)}.pdx-widget--canvas:has(.pdx-canvas-resize--north-east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north-east:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south-west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south-west:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-sw)}.pdx-widget--canvas:has(.pdx-canvas-resize--north-west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north-west:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south-east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south-east:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-se)}.pdx-canvas-resize{position:absolute;z-index:7;border:0;padding:0;margin:0;background:transparent;touch-action:none;cursor:pointer;opacity:0;pointer-events:none;transform:scale(.94);transition:opacity .14s ease,transform .14s ease,filter .14s ease;filter:saturate(.9)}.pdx-widget--canvas:hover .pdx-canvas-resize,.pdx-widget--canvas:focus-within .pdx-canvas-resize,.pdx-widget--canvas-selected .pdx-canvas-resize{opacity:.88;pointer-events:auto;transform:scale(1);filter:saturate(1)}.pdx-canvas-resize-grip{display:block;width:9px;height:9px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 42%,var(--md-sys-color-outline-variant) 58%);background:color-mix(in srgb,var(--md-sys-color-surface) 92%,var(--md-sys-color-primary) 8%);box-shadow:0 1px 4px color-mix(in srgb,var(--md-sys-color-shadow) 10%,transparent);transition:transform .14s ease,border-color .14s ease,background .14s ease,box-shadow .14s ease}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{border-color:color-mix(in srgb,var(--md-sys-color-primary) 58%,var(--md-sys-color-outline-variant) 42%);background:color-mix(in srgb,var(--md-sys-color-surface) 84%,var(--md-sys-color-primary) 16%);box-shadow:0 2px 7px color-mix(in srgb,var(--md-sys-color-primary) 14%,transparent);transform:scale(1.04)}.pdx-canvas-resize--north,.pdx-canvas-resize--south{left:50%;width:40px;height:18px;margin-left:-20px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--north{top:-8px;cursor:ns-resize}.pdx-canvas-resize--south{bottom:-8px;cursor:ns-resize}.pdx-canvas-resize--east,.pdx-canvas-resize--west{top:50%;width:18px;height:40px;margin-top:-20px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--east{right:-8px;cursor:ew-resize}.pdx-canvas-resize--west{left:-8px;cursor:ew-resize}.pdx-canvas-resize--north-east,.pdx-canvas-resize--north-west,.pdx-canvas-resize--south-east,.pdx-canvas-resize--south-west{width:18px;height:18px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--north-east{top:-8px;right:-8px;cursor:nesw-resize}.pdx-canvas-resize--north-west{top:-8px;left:-8px;cursor:nwse-resize}.pdx-canvas-resize--south-east{bottom:-8px;right:-8px;cursor:nwse-resize}.pdx-canvas-resize--south-west{bottom:-8px;left:-8px;cursor:nesw-resize}.pdx-canvas-snap-preview{position:relative;align-self:stretch;border-radius:12px;pointer-events:none;z-index:0;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent),color-mix(in srgb,var(--md-sys-color-tertiary) 12%,transparent));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 42%,transparent),inset 0 0 0 2px color-mix(in srgb,var(--md-sys-color-surface) 55%,transparent);animation:pdx-snap-preview-pulse .48s ease-out infinite alternate}.pdx-canvas-snap-preview:before,.pdx-canvas-snap-preview:after{content:\"\";position:absolute;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary) 82%,var(--md-sys-color-tertiary) 18%);opacity:.72}.pdx-canvas-snap-preview:before{inset:0 auto 0 0;width:3px}.pdx-canvas-snap-preview:after{inset:0 0 auto;height:3px}.pdx-canvas-snap-preview--invalid{background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-error) 18%,transparent),color-mix(in srgb,var(--md-sys-color-error-container) 22%,transparent));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-error) 58%,transparent),inset 0 0 0 2px color-mix(in srgb,var(--md-sys-color-surface) 40%,transparent)}.pdx-canvas-snap-preview--invalid:before,.pdx-canvas-snap-preview--invalid:after{background:color-mix(in srgb,var(--md-sys-color-error) 86%,var(--md-sys-color-error-container) 14%)}.pdx-canvas-resize:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{border-color:transparent;box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 20%,transparent),var(--mat-elevation-level3)}.pdx-canvas-resize--north:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-horizontal)}.pdx-canvas-resize--east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--east:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--west:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-vertical)}.pdx-canvas-resize--north-east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north-east:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south-west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south-west:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-diagonal-sw)}.pdx-canvas-resize--north-west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north-west:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south-east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south-east:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-diagonal-se)}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{transform:scale(1.08)}@keyframes pdx-snap-preview-pulse{0%{opacity:.72;transform:scale(.996)}to{opacity:1;transform:scale(1)}}.pdx-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.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: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: DynamicWidgetLoaderDirective, selector: "[dynamicWidgetLoader]", inputs: ["dynamicWidgetLoader", "ownerWidgetKey", "context", "strictValidation", "autoWireOutputs"], outputs: ["widgetEvent", "widgetDiagnostic"], exportAs: ["dynamicWidgetLoader"] }, { kind: "component", type: WidgetShellComponent, selector: "praxis-widget-shell", inputs: ["shell", "context", "dragSurfaceEnabled", "dragSurfaceLabel"], outputs: ["action", "dragSurfacePointerDown", "dragSurfaceKeydown"] }] });
|
|
23661
|
+
`, isInline: true, styles: [".pdx-page-wrapper{position:relative;display:block}.pdx-page{display:grid;gap:16px;grid-template-columns:minmax(0,1fr)}.pdx-page--canvas{align-items:start;grid-auto-flow:dense}.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;min-width:0;min-height:0}.pdx-widget--canvas{align-self:stretch;--pdx-resize-gradient-horizontal: linear-gradient( 90deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-vertical: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-diagonal-se: linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-diagonal-sw: linear-gradient( 225deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-se)}.pdx-widget--canvas:after{content:\"\";position:absolute;inset:0;padding:2px;border-radius:14px;background:var(--pdx-active-resize-gradient);opacity:0;pointer-events:none;transition:opacity .14s ease,filter .14s ease;filter:saturate(1.02) drop-shadow(0 0 5px color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent));-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude}.pdx-widget--canvas-selected:before,.pdx-widget--canvas-blocked:before{content:\"\";position:absolute;inset:0;border-radius:14px;pointer-events:none;z-index:1;transition:opacity .14s ease,box-shadow .14s ease,border-color .14s ease}.pdx-widget--canvas-selected:before{border:1px dashed color-mix(in srgb,var(--md-sys-color-primary) 34%,transparent);box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 6%,transparent),0 8px 20px color-mix(in srgb,var(--md-sys-color-primary) 6%,transparent)}.pdx-widget--canvas-blocked:before{border:1px solid color-mix(in srgb,var(--md-sys-color-error) 74%,transparent);box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-error) 20%,transparent),0 10px 24px color-mix(in srgb,var(--md-sys-color-error) 12%,transparent)}.pdx-widget--canvas:has(.pdx-canvas-resize:hover):after,.pdx-widget--canvas:has(.pdx-canvas-resize:focus-visible):after{opacity:.82}.pdx-widget--canvas:has(.pdx-canvas-resize--north:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-horizontal)}.pdx-widget--canvas:has(.pdx-canvas-resize--east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--east:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--west:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-vertical)}.pdx-widget--canvas:has(.pdx-canvas-resize--north-east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north-east:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south-west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south-west:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-sw)}.pdx-widget--canvas:has(.pdx-canvas-resize--north-west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north-west:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south-east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south-east:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-se)}.pdx-canvas-resize{position:absolute;z-index:7;border:0;padding:0;margin:0;background:transparent;touch-action:none;cursor:pointer;opacity:0;pointer-events:none;transform:scale(.94);transition:opacity .14s ease,transform .14s ease,filter .14s ease;filter:saturate(.9)}.pdx-widget--canvas:hover .pdx-canvas-resize,.pdx-widget--canvas:focus-within .pdx-canvas-resize,.pdx-widget--canvas-selected .pdx-canvas-resize{opacity:.88;pointer-events:auto;transform:scale(1);filter:saturate(1)}.pdx-canvas-resize-grip{display:block;width:9px;height:9px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 42%,var(--md-sys-color-outline-variant) 58%);background:color-mix(in srgb,var(--md-sys-color-surface) 92%,var(--md-sys-color-primary) 8%);box-shadow:0 1px 4px color-mix(in srgb,var(--md-sys-color-shadow) 10%,transparent);transition:transform .14s ease,border-color .14s ease,background .14s ease,box-shadow .14s ease}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{border-color:color-mix(in srgb,var(--md-sys-color-primary) 58%,var(--md-sys-color-outline-variant) 42%);background:color-mix(in srgb,var(--md-sys-color-surface) 84%,var(--md-sys-color-primary) 16%);box-shadow:0 2px 7px color-mix(in srgb,var(--md-sys-color-primary) 14%,transparent);transform:scale(1.04)}.pdx-canvas-resize--north,.pdx-canvas-resize--south{left:50%;width:40px;height:18px;margin-left:-20px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--north{top:-8px;cursor:ns-resize}.pdx-canvas-resize--south{bottom:-8px;cursor:ns-resize}.pdx-canvas-resize--east,.pdx-canvas-resize--west{top:50%;width:18px;height:40px;margin-top:-20px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--east{right:-8px;cursor:ew-resize}.pdx-canvas-resize--west{left:-8px;cursor:ew-resize}.pdx-canvas-resize--north-east,.pdx-canvas-resize--north-west,.pdx-canvas-resize--south-east,.pdx-canvas-resize--south-west{width:18px;height:18px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--north-east{top:-8px;right:-8px;cursor:nesw-resize}.pdx-canvas-resize--north-west{top:-8px;left:-8px;cursor:nwse-resize}.pdx-canvas-resize--south-east{bottom:-8px;right:-8px;cursor:nwse-resize}.pdx-canvas-resize--south-west{bottom:-8px;left:-8px;cursor:nesw-resize}.pdx-canvas-snap-preview{position:relative;align-self:stretch;border-radius:12px;pointer-events:none;z-index:0;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent),color-mix(in srgb,var(--md-sys-color-tertiary) 12%,transparent));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 42%,transparent),inset 0 0 0 2px color-mix(in srgb,var(--md-sys-color-surface) 55%,transparent);animation:pdx-snap-preview-pulse .48s ease-out infinite alternate}.pdx-canvas-snap-preview:before,.pdx-canvas-snap-preview:after{content:\"\";position:absolute;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary) 82%,var(--md-sys-color-tertiary) 18%);opacity:.72}.pdx-canvas-snap-preview:before{inset:0 auto 0 0;width:3px}.pdx-canvas-snap-preview:after{inset:0 0 auto;height:3px}.pdx-canvas-snap-preview--invalid{background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-error) 18%,transparent),color-mix(in srgb,var(--md-sys-color-error-container) 22%,transparent));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-error) 58%,transparent),inset 0 0 0 2px color-mix(in srgb,var(--md-sys-color-surface) 40%,transparent)}.pdx-canvas-snap-preview--invalid:before,.pdx-canvas-snap-preview--invalid:after{background:color-mix(in srgb,var(--md-sys-color-error) 86%,var(--md-sys-color-error-container) 14%)}.pdx-canvas-resize:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{border-color:transparent;box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 20%,transparent),var(--mat-elevation-level3)}.pdx-canvas-resize--north:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-horizontal)}.pdx-canvas-resize--east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--east:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--west:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-vertical)}.pdx-canvas-resize--north-east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north-east:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south-west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south-west:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-diagonal-sw)}.pdx-canvas-resize--north-west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north-west:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south-east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south-east:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-diagonal-se)}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{transform:scale(1.08)}@keyframes pdx-snap-preview-pulse{0%{opacity:.72;transform:scale(.996)}to{opacity:1;transform:scale(1)}}.pdx-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.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: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: DynamicWidgetLoaderDirective, selector: "[dynamicWidgetLoader]", inputs: ["dynamicWidgetLoader", "ownerWidgetKey", "context", "strictValidation", "autoWireOutputs"], outputs: ["widgetEvent", "widgetDiagnostic"], exportAs: ["dynamicWidgetLoader"] }, { kind: "component", type: WidgetShellComponent, selector: "praxis-widget-shell", inputs: ["shell", "context", "dragSurfaceEnabled", "dragSurfaceLabel"], outputs: ["action", "dragSurfacePointerDown", "dragSurfaceKeydown"] }] });
|
|
22077
23662
|
}
|
|
22078
23663
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DynamicWidgetPageComponent, decorators: [{
|
|
22079
23664
|
type: Component,
|
|
@@ -22261,22 +23846,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
22261
23846
|
}
|
|
22262
23847
|
</div>
|
|
22263
23848
|
`, styles: [".pdx-page-wrapper{position:relative;display:block}.pdx-page{display:grid;gap:16px;grid-template-columns:minmax(0,1fr)}.pdx-page--canvas{align-items:start;grid-auto-flow:dense}.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;min-width:0;min-height:0}.pdx-widget--canvas{align-self:stretch;--pdx-resize-gradient-horizontal: linear-gradient( 90deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-vertical: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-diagonal-se: linear-gradient( 135deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-resize-gradient-diagonal-sw: linear-gradient( 225deg, color-mix(in srgb, var(--md-sys-color-primary) 94%, white 6%), color-mix(in srgb, var(--md-sys-color-tertiary) 90%, white 10%), color-mix(in srgb, var(--md-sys-color-secondary) 88%, white 12%) );--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-se)}.pdx-widget--canvas:after{content:\"\";position:absolute;inset:0;padding:2px;border-radius:14px;background:var(--pdx-active-resize-gradient);opacity:0;pointer-events:none;transition:opacity .14s ease,filter .14s ease;filter:saturate(1.02) drop-shadow(0 0 5px color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent));-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude}.pdx-widget--canvas-selected:before,.pdx-widget--canvas-blocked:before{content:\"\";position:absolute;inset:0;border-radius:14px;pointer-events:none;z-index:1;transition:opacity .14s ease,box-shadow .14s ease,border-color .14s ease}.pdx-widget--canvas-selected:before{border:1px dashed color-mix(in srgb,var(--md-sys-color-primary) 34%,transparent);box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 6%,transparent),0 8px 20px color-mix(in srgb,var(--md-sys-color-primary) 6%,transparent)}.pdx-widget--canvas-blocked:before{border:1px solid color-mix(in srgb,var(--md-sys-color-error) 74%,transparent);box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-error) 20%,transparent),0 10px 24px color-mix(in srgb,var(--md-sys-color-error) 12%,transparent)}.pdx-widget--canvas:has(.pdx-canvas-resize:hover):after,.pdx-widget--canvas:has(.pdx-canvas-resize:focus-visible):after{opacity:.82}.pdx-widget--canvas:has(.pdx-canvas-resize--north:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-horizontal)}.pdx-widget--canvas:has(.pdx-canvas-resize--east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--east:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--west:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-vertical)}.pdx-widget--canvas:has(.pdx-canvas-resize--north-east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north-east:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south-west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south-west:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-sw)}.pdx-widget--canvas:has(.pdx-canvas-resize--north-west:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--north-west:focus-visible),.pdx-widget--canvas:has(.pdx-canvas-resize--south-east:hover),.pdx-widget--canvas:has(.pdx-canvas-resize--south-east:focus-visible){--pdx-active-resize-gradient: var(--pdx-resize-gradient-diagonal-se)}.pdx-canvas-resize{position:absolute;z-index:7;border:0;padding:0;margin:0;background:transparent;touch-action:none;cursor:pointer;opacity:0;pointer-events:none;transform:scale(.94);transition:opacity .14s ease,transform .14s ease,filter .14s ease;filter:saturate(.9)}.pdx-widget--canvas:hover .pdx-canvas-resize,.pdx-widget--canvas:focus-within .pdx-canvas-resize,.pdx-widget--canvas-selected .pdx-canvas-resize{opacity:.88;pointer-events:auto;transform:scale(1);filter:saturate(1)}.pdx-canvas-resize-grip{display:block;width:9px;height:9px;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-primary) 42%,var(--md-sys-color-outline-variant) 58%);background:color-mix(in srgb,var(--md-sys-color-surface) 92%,var(--md-sys-color-primary) 8%);box-shadow:0 1px 4px color-mix(in srgb,var(--md-sys-color-shadow) 10%,transparent);transition:transform .14s ease,border-color .14s ease,background .14s ease,box-shadow .14s ease}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{border-color:color-mix(in srgb,var(--md-sys-color-primary) 58%,var(--md-sys-color-outline-variant) 42%);background:color-mix(in srgb,var(--md-sys-color-surface) 84%,var(--md-sys-color-primary) 16%);box-shadow:0 2px 7px color-mix(in srgb,var(--md-sys-color-primary) 14%,transparent);transform:scale(1.04)}.pdx-canvas-resize--north,.pdx-canvas-resize--south{left:50%;width:40px;height:18px;margin-left:-20px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--north{top:-8px;cursor:ns-resize}.pdx-canvas-resize--south{bottom:-8px;cursor:ns-resize}.pdx-canvas-resize--east,.pdx-canvas-resize--west{top:50%;width:18px;height:40px;margin-top:-20px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--east{right:-8px;cursor:ew-resize}.pdx-canvas-resize--west{left:-8px;cursor:ew-resize}.pdx-canvas-resize--north-east,.pdx-canvas-resize--north-west,.pdx-canvas-resize--south-east,.pdx-canvas-resize--south-west{width:18px;height:18px;display:flex;align-items:center;justify-content:center}.pdx-canvas-resize--north-east{top:-8px;right:-8px;cursor:nesw-resize}.pdx-canvas-resize--north-west{top:-8px;left:-8px;cursor:nwse-resize}.pdx-canvas-resize--south-east{bottom:-8px;right:-8px;cursor:nwse-resize}.pdx-canvas-resize--south-west{bottom:-8px;left:-8px;cursor:nesw-resize}.pdx-canvas-snap-preview{position:relative;align-self:stretch;border-radius:12px;pointer-events:none;z-index:0;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-primary) 10%,transparent),color-mix(in srgb,var(--md-sys-color-tertiary) 12%,transparent));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 42%,transparent),inset 0 0 0 2px color-mix(in srgb,var(--md-sys-color-surface) 55%,transparent);animation:pdx-snap-preview-pulse .48s ease-out infinite alternate}.pdx-canvas-snap-preview:before,.pdx-canvas-snap-preview:after{content:\"\";position:absolute;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary) 82%,var(--md-sys-color-tertiary) 18%);opacity:.72}.pdx-canvas-snap-preview:before{inset:0 auto 0 0;width:3px}.pdx-canvas-snap-preview:after{inset:0 0 auto;height:3px}.pdx-canvas-snap-preview--invalid{background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-error) 18%,transparent),color-mix(in srgb,var(--md-sys-color-error-container) 22%,transparent));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--md-sys-color-error) 58%,transparent),inset 0 0 0 2px color-mix(in srgb,var(--md-sys-color-surface) 40%,transparent)}.pdx-canvas-snap-preview--invalid:before,.pdx-canvas-snap-preview--invalid:after{background:color-mix(in srgb,var(--md-sys-color-error) 86%,var(--md-sys-color-error-container) 14%)}.pdx-canvas-resize:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{border-color:transparent;box-shadow:0 0 0 1px color-mix(in srgb,var(--md-sys-color-primary) 20%,transparent),var(--mat-elevation-level3)}.pdx-canvas-resize--north:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-horizontal)}.pdx-canvas-resize--east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--east:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--west:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-vertical)}.pdx-canvas-resize--north-east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north-east:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south-west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south-west:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-diagonal-sw)}.pdx-canvas-resize--north-west:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--north-west:focus-visible .pdx-canvas-resize-grip,.pdx-canvas-resize--south-east:hover .pdx-canvas-resize-grip,.pdx-canvas-resize--south-east:focus-visible .pdx-canvas-resize-grip{background:var(--pdx-resize-gradient-diagonal-se)}.pdx-canvas-resize:hover .pdx-canvas-resize-grip,.pdx-canvas-resize:focus-visible .pdx-canvas-resize-grip{transform:scale(1.08)}@keyframes pdx-snap-preview-pulse{0%{opacity:.72;transform:scale(.996)}to{opacity:1;transform:scale(1)}}.pdx-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.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"] }]
|
|
22264
|
-
}], ctorParameters: () => [
|
|
22265
|
-
type: Optional
|
|
22266
|
-
}, {
|
|
22267
|
-
type: Inject,
|
|
22268
|
-
args: [SETTINGS_PANEL_BRIDGE]
|
|
22269
|
-
}] }, { type: i0.Type, decorators: [{
|
|
22270
|
-
type: Optional
|
|
22271
|
-
}, {
|
|
22272
|
-
type: Inject,
|
|
22273
|
-
args: [DYNAMIC_PAGE_SHELL_EDITOR]
|
|
22274
|
-
}] }, { type: i0.Type, decorators: [{
|
|
22275
|
-
type: Optional
|
|
22276
|
-
}, {
|
|
22277
|
-
type: Inject,
|
|
22278
|
-
args: [DYNAMIC_PAGE_CONFIG_EDITOR]
|
|
22279
|
-
}] }], propDecorators: { pageCanvasHost: [{
|
|
23849
|
+
}], ctorParameters: () => [], propDecorators: { pageCanvasHost: [{
|
|
22280
23850
|
type: ViewChild,
|
|
22281
23851
|
args: ['pageCanvasHost']
|
|
22282
23852
|
}], page: [{
|
|
@@ -22323,23 +23893,23 @@ const PRAXIS_DYNAMIC_PAGE_COMPONENT_METADATA = {
|
|
|
22323
23893
|
selector: 'praxis-dynamic-page',
|
|
22324
23894
|
component: DynamicWidgetPageComponent,
|
|
22325
23895
|
friendlyName: 'Dynamic Page',
|
|
22326
|
-
description: '
|
|
23896
|
+
description: 'Pagina dinamica com widgets e composition.links em layout de grid responsivo.',
|
|
22327
23897
|
icon: 'dashboard',
|
|
22328
23898
|
inputs: [
|
|
22329
|
-
{ name: 'page', type: 'WidgetPageDefinition', description: '
|
|
23899
|
+
{ name: 'page', type: 'WidgetPageDefinition', description: 'Definicao da pagina (widgets, layout e composition.links).' },
|
|
22330
23900
|
{ name: 'context', type: 'Record<string, any>', description: 'Contexto adicional compartilhado entre widgets.' },
|
|
22331
|
-
{ name: 'strictValidation', type: 'boolean', description: 'Habilita
|
|
22332
|
-
{ name: 'enableCustomization', type: 'boolean', description: 'Habilita affordances de
|
|
22333
|
-
{ name: 'showPageSettingsButton', type: 'boolean', description: 'Exibe
|
|
23901
|
+
{ name: 'strictValidation', type: 'boolean', description: 'Habilita validacao estrita de inputs.' },
|
|
23902
|
+
{ name: 'enableCustomization', type: 'boolean', description: 'Habilita affordances de edicao na pagina.' },
|
|
23903
|
+
{ name: 'showPageSettingsButton', type: 'boolean', description: 'Exibe botao de configuracao da pagina.' },
|
|
22334
23904
|
{ name: 'shellEditorComponent', type: 'Type<any>', description: 'Override do editor de shell dos widgets.' },
|
|
22335
|
-
{ name: 'pageEditorComponent', type: 'Type<any>', description: 'Override do editor de
|
|
22336
|
-
{ name: 'autoPersist', type: 'boolean', description: 'Ativa
|
|
22337
|
-
{ name: 'pageIdentity', type: 'PageIdentity', description: 'Identidade de
|
|
22338
|
-
{ name: 'componentInstanceId', type: 'string', description: 'Identificador opcional para
|
|
23905
|
+
{ name: 'pageEditorComponent', type: 'Type<any>', description: 'Override do editor de configuracao da pagina.' },
|
|
23906
|
+
{ name: 'autoPersist', type: 'boolean', description: 'Ativa persistencia automatica (load/save) da pagina.' },
|
|
23907
|
+
{ name: 'pageIdentity', type: 'PageIdentity', description: 'Identidade de persistencia (tenant/usuario/rota/locale).' },
|
|
23908
|
+
{ name: 'componentInstanceId', type: 'string', description: 'Identificador opcional para multiplas instancias na mesma rota.' },
|
|
22339
23909
|
],
|
|
22340
23910
|
outputs: [
|
|
22341
|
-
{ name: 'pageChange', type: 'WidgetPageDefinition', description: 'Emitido ao alterar a
|
|
22342
|
-
{ name: 'widgetDiagnosticsChange', type: 'Record<string, WidgetResolutionDiagnostic>', description: 'Emitido quando o runtime detecta widgets resolvidos ou falhos durante o carregamento
|
|
23911
|
+
{ name: 'pageChange', type: 'WidgetPageDefinition', description: 'Emitido ao alterar a definicao da pagina.' },
|
|
23912
|
+
{ name: 'widgetDiagnosticsChange', type: 'Record<string, WidgetResolutionDiagnostic>', description: 'Emitido quando o runtime detecta widgets resolvidos ou falhos durante o carregamento dinamico.' },
|
|
22343
23913
|
],
|
|
22344
23914
|
tags: ['widget', 'page', 'dynamic', 'layout'],
|
|
22345
23915
|
lib: '@praxisui/core',
|
|
@@ -22481,7 +24051,7 @@ class EmptyStateCardComponent {
|
|
|
22481
24051
|
</div>
|
|
22482
24052
|
</mat-card-content>
|
|
22483
24053
|
</mat-card>
|
|
22484
|
-
`, 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$
|
|
24054
|
+
`, 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$2.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3$2.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: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
|
|
22485
24055
|
}
|
|
22486
24056
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: EmptyStateCardComponent, decorators: [{
|
|
22487
24057
|
type: Component,
|
|
@@ -22586,7 +24156,7 @@ class ResourceQuickConnectComponent {
|
|
|
22586
24156
|
Rota normalizada: {{ normalizedPath() }}
|
|
22587
24157
|
</small>
|
|
22588
24158
|
</div>
|
|
22589
|
-
`, 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
|
|
24159
|
+
`, 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: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }] });
|
|
22590
24160
|
}
|
|
22591
24161
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ResourceQuickConnectComponent, decorators: [{
|
|
22592
24162
|
type: Component,
|
|
@@ -22814,7 +24384,7 @@ class PraxisIconPickerComponent {
|
|
|
22814
24384
|
<span class="pip-typed" *ngIf="query.trim()">{{ previewValue() }}</span>
|
|
22815
24385
|
</div>
|
|
22816
24386
|
</div>
|
|
22817
|
-
`, 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
|
|
24387
|
+
`, 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: i3$1.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$1.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "component", type: i8$1.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: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
|
|
22818
24388
|
}
|
|
22819
24389
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisIconPickerComponent, decorators: [{
|
|
22820
24390
|
type: Component,
|
|
@@ -23158,7 +24728,7 @@ class SchemaViewerComponent {
|
|
|
23158
24728
|
</mat-tab-group>
|
|
23159
24729
|
</mat-card-content>
|
|
23160
24730
|
</mat-card>
|
|
23161
|
-
`, 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$
|
|
24731
|
+
`, 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$2.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3$2.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i3$2.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: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: i1$2.JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
23162
24732
|
}
|
|
23163
24733
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: SchemaViewerComponent, decorators: [{
|
|
23164
24734
|
type: Component,
|
|
@@ -23269,162 +24839,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
23269
24839
|
type: Input
|
|
23270
24840
|
}] } });
|
|
23271
24841
|
|
|
23272
|
-
async function parseJsonResponseOrEmpty(res, context = 'response') {
|
|
23273
|
-
const raw = await res.text();
|
|
23274
|
-
if (!raw || !raw.trim()) {
|
|
23275
|
-
return {};
|
|
23276
|
-
}
|
|
23277
|
-
try {
|
|
23278
|
-
return JSON.parse(raw);
|
|
23279
|
-
}
|
|
23280
|
-
catch (error) {
|
|
23281
|
-
const e = new Error(`${context}: invalid JSON payload`);
|
|
23282
|
-
e.cause = error;
|
|
23283
|
-
throw e;
|
|
23284
|
-
}
|
|
23285
|
-
}
|
|
23286
|
-
async function fetchWithETag(params) {
|
|
23287
|
-
const headers = { Accept: 'application/json' };
|
|
23288
|
-
if (params.schemaHash)
|
|
23289
|
-
headers['If-None-Match'] = `"${params.schemaHash}"`;
|
|
23290
|
-
if (params.tenant)
|
|
23291
|
-
headers['X-Tenant'] = params.tenant;
|
|
23292
|
-
if (params.locale)
|
|
23293
|
-
headers['Accept-Language'] = params.locale;
|
|
23294
|
-
// Allow host apps to provide additional headers (e.g., Authorization) without coupling
|
|
23295
|
-
try {
|
|
23296
|
-
const extra = globalThis?.PAX_FETCH_HEADERS?.();
|
|
23297
|
-
if (extra && typeof extra === 'object') {
|
|
23298
|
-
for (const [k, v] of Object.entries(extra)) {
|
|
23299
|
-
const key = String(k);
|
|
23300
|
-
const val = Array.isArray(v) ? String(v[0]) : String(v);
|
|
23301
|
-
if (val && !headers[key])
|
|
23302
|
-
headers[key] = val;
|
|
23303
|
-
}
|
|
23304
|
-
}
|
|
23305
|
-
}
|
|
23306
|
-
catch {
|
|
23307
|
-
// ignore header hook errors
|
|
23308
|
-
}
|
|
23309
|
-
const res = await fetch(params.url, {
|
|
23310
|
-
headers,
|
|
23311
|
-
cache: 'no-cache',
|
|
23312
|
-
credentials: params.credentials ?? 'include',
|
|
23313
|
-
signal: params.signal,
|
|
23314
|
-
});
|
|
23315
|
-
if (res.status === 304)
|
|
23316
|
-
return { status: 304 };
|
|
23317
|
-
if (!res.ok) {
|
|
23318
|
-
const raw = await res.text().catch(() => '');
|
|
23319
|
-
const bodyHint = raw?.trim() ? `: ${raw.trim().slice(0, 240)}` : '';
|
|
23320
|
-
throw new Error(`fetchWithETag failed (${res.status} ${res.statusText || 'HTTP error'})${bodyHint}`);
|
|
23321
|
-
}
|
|
23322
|
-
const etag = res.headers.get('ETag') || '';
|
|
23323
|
-
const newHash = etag.replace(/^W\//, '').replace(/^\"|\"$/g, '');
|
|
23324
|
-
const xSchemaHash = res.headers.get('X-Schema-Hash');
|
|
23325
|
-
const schemaHash = xSchemaHash || newHash; // prefer explicit header when available
|
|
23326
|
-
const schema = await parseJsonResponseOrEmpty(res, 'fetchWithETag');
|
|
23327
|
-
return { status: 200, schema, schemaHash };
|
|
23328
|
-
}
|
|
23329
|
-
|
|
23330
|
-
class SchemaMetadataClient {
|
|
23331
|
-
cache;
|
|
23332
|
-
inFlight = new Map();
|
|
23333
|
-
constructor(cache) {
|
|
23334
|
-
this.cache = cache;
|
|
23335
|
-
}
|
|
23336
|
-
async getSchema(params) {
|
|
23337
|
-
// Bind identity to API origin to avoid cross-origin collisions
|
|
23338
|
-
let apiOrigin = '';
|
|
23339
|
-
try {
|
|
23340
|
-
apiOrigin = new URL(params.baseUrl).origin;
|
|
23341
|
-
}
|
|
23342
|
-
catch {
|
|
23343
|
-
try {
|
|
23344
|
-
apiOrigin = globalThis?.location?.origin || '';
|
|
23345
|
-
}
|
|
23346
|
-
catch { }
|
|
23347
|
-
}
|
|
23348
|
-
const schemaId = buildSchemaId({ ...params, apiOrigin });
|
|
23349
|
-
const cached = await this.cache.get(schemaId);
|
|
23350
|
-
// Build URL with query params
|
|
23351
|
-
let u;
|
|
23352
|
-
try {
|
|
23353
|
-
u = new URL(params.baseUrl);
|
|
23354
|
-
}
|
|
23355
|
-
catch (err) {
|
|
23356
|
-
// Accept relative baseUrl by resolving against the app origin when available
|
|
23357
|
-
const origin = (() => {
|
|
23358
|
-
try {
|
|
23359
|
-
return globalThis?.location?.origin;
|
|
23360
|
-
}
|
|
23361
|
-
catch {
|
|
23362
|
-
return undefined;
|
|
23363
|
-
}
|
|
23364
|
-
})();
|
|
23365
|
-
if (origin && origin.startsWith('http')) {
|
|
23366
|
-
u = new URL(params.baseUrl, origin);
|
|
23367
|
-
}
|
|
23368
|
-
else {
|
|
23369
|
-
// Friendly error for hosts: instruct to set absolute baseUrl or provide runtime origin
|
|
23370
|
-
const e = new Error(`Failed to construct schema URL. API_URL.baseUrl appears relative and no runtime origin is available. ` +
|
|
23371
|
-
`Set API_URL.baseUrl to an absolute URL (e.g., http://localhost:4200/api) or run in a browser context. ` +
|
|
23372
|
-
`Received baseUrl="${params.baseUrl}".`);
|
|
23373
|
-
e.cause = err;
|
|
23374
|
-
throw e;
|
|
23375
|
-
}
|
|
23376
|
-
}
|
|
23377
|
-
u.searchParams.set('path', params.path);
|
|
23378
|
-
u.searchParams.set('operation', (params.operation || 'get').toLowerCase());
|
|
23379
|
-
u.searchParams.set('schemaType', (params.schemaType || 'response').toLowerCase());
|
|
23380
|
-
u.searchParams.set('includeInternalSchemas', String(!!params.includeInternalSchemas));
|
|
23381
|
-
const key = schemaId;
|
|
23382
|
-
if (this.inFlight.has(key))
|
|
23383
|
-
return this.inFlight.get(key);
|
|
23384
|
-
const p = (async () => {
|
|
23385
|
-
const res = await fetchWithETag({
|
|
23386
|
-
url: u.toString(),
|
|
23387
|
-
schemaHash: cached?.schemaHash,
|
|
23388
|
-
tenant: params.tenant,
|
|
23389
|
-
locale: params.locale,
|
|
23390
|
-
});
|
|
23391
|
-
if (res.status === 304) {
|
|
23392
|
-
if (cached)
|
|
23393
|
-
return cached;
|
|
23394
|
-
// No cache: refetch without If-None-Match
|
|
23395
|
-
const refetch = await fetch(u.toString(), { cache: 'no-cache', credentials: 'include' });
|
|
23396
|
-
if (!refetch.ok) {
|
|
23397
|
-
const raw = await refetch.text().catch(() => '');
|
|
23398
|
-
const bodyHint = raw?.trim() ? `: ${raw.trim().slice(0, 240)}` : '';
|
|
23399
|
-
throw new Error(`SchemaMetadataClient refetch failed (${refetch.status} ${refetch.statusText || 'HTTP error'})${bodyHint}`);
|
|
23400
|
-
}
|
|
23401
|
-
const etag = refetch.headers.get('ETag') || '';
|
|
23402
|
-
const xHash = refetch.headers.get('X-Schema-Hash') || '';
|
|
23403
|
-
const schemaHash = (xHash || etag).replace(/^W\//, '').replace(/^\"|\"$/g, '');
|
|
23404
|
-
const schema = await parseJsonResponseOrEmpty(refetch, 'SchemaMetadataClient refetch');
|
|
23405
|
-
const fallback = { schema, schemaHash };
|
|
23406
|
-
await this.cache.set(schemaId, fallback);
|
|
23407
|
-
return fallback;
|
|
23408
|
-
}
|
|
23409
|
-
// res.status === 200
|
|
23410
|
-
const entry = {
|
|
23411
|
-
schema: res.schema,
|
|
23412
|
-
schemaHash: res.schemaHash,
|
|
23413
|
-
};
|
|
23414
|
-
await this.cache.set(schemaId, entry);
|
|
23415
|
-
return entry;
|
|
23416
|
-
})();
|
|
23417
|
-
this.inFlight.set(key, p);
|
|
23418
|
-
try {
|
|
23419
|
-
const result = await p;
|
|
23420
|
-
return result;
|
|
23421
|
-
}
|
|
23422
|
-
finally {
|
|
23423
|
-
this.inFlight.delete(key);
|
|
23424
|
-
}
|
|
23425
|
-
}
|
|
23426
|
-
}
|
|
23427
|
-
|
|
23428
24842
|
function buildBaseFormField(def) {
|
|
23429
24843
|
const meta = mapFieldDefinitionsToMetadata([def])[0];
|
|
23430
24844
|
return meta;
|
|
@@ -23913,9 +25327,6 @@ function provideHookWhitelist(allowed) {
|
|
|
23913
25327
|
return [{ provide: FORM_HOOKS_WHITELIST, useValue: allowed, multi: true }];
|
|
23914
25328
|
}
|
|
23915
25329
|
|
|
23916
|
-
/*
|
|
23917
|
-
* Public API Surface of praxis-core
|
|
23918
|
-
*/
|
|
23919
25330
|
/*
|
|
23920
25331
|
* Public API Surface of praxis-core
|
|
23921
25332
|
*/
|
|
@@ -23924,4 +25335,4 @@ function provideHookWhitelist(allowed) {
|
|
|
23924
25335
|
* Generated bundle index. Do not edit.
|
|
23925
25336
|
*/
|
|
23926
25337
|
|
|
23927
|
-
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, CompositionRuntimeFacade,
|
|
25338
|
+
export { API_CONFIG_STORAGE_OPTIONS, API_URL, ASYNC_CONFIG_STORAGE, AllowedFileTypes, AnalyticsPresentationResolver, AnalyticsSchemaContractService, AnalyticsStatsRequestBuilderService, ApiConfigStorage, ApiEndpoint, BUILTIN_PAGE_LAYOUT_PRESETS, BUILTIN_PAGE_THEME_PRESETS, BUILTIN_SHELL_PRESETS, CONFIG_STORAGE, CONNECTION_STORAGE, ComponentKeyService, ComponentMetadataRegistry, CompositionRuntimeFacade, 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, 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_LAYER_SCALE_DEFAULTS, PRAXIS_LAYER_SCALE_VARS, 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, PraxisLayerScaleStyleService, PraxisLegalNoticeComponent, PraxisLoadingInterceptor, PraxisRichTextBlockComponent, PraxisSurfaceHostComponent, PraxisUserContextSummaryComponent, RESOURCE_DISCOVERY_I18N_CONFIG, RESOURCE_DISCOVERY_I18N_NAMESPACE, RULE_PROPERTY_SCHEMA, RemoteConfigStorage, ResourceActionOpenAdapterService, ResourceDiscoveryService, ResourceQuickConnectComponent, ResourceSurfaceOpenAdapterService, SCHEMA_VIEWER_CONTEXT, SETTINGS_PANEL_BRIDGE, SETTINGS_PANEL_DATA, STEPPER_CONFIG_EDITOR, SURFACE_DRAWER_BRIDGE, 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, buildPraxisLayerScaleCss, 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, normalizeResourceAvailabilityReasonCode, 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, resolveResourceAvailabilityReasonKey, resolveSpan, resolveValuePresentation, resolveValuePresentationLocale, slugify, stripMasksHook, supportsImplicitValuePresentation, syncWithServerMetadata, toCamel, toCapitalize, toKebab, toPascal, toSentenceCase, toSnake, toTitleCase, translateResourceAvailabilityReason, translateResourceDiscoveryText, translateUnavailableWorkflowMessage, trim, uniqueAsyncValidator, urlValidator, withMessage, withPraxisHttpLoading };
|