@praxisui/core 1.0.0-beta.3 → 1.0.0-beta.30
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 +58 -0
- package/fesm2022/praxisui-core.mjs +346 -47
- package/fesm2022/praxisui-core.mjs.map +1 -1
- package/index.d.ts +299 -5
- package/package.json +4 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component, InjectionToken, Injectable, inject, APP_INITIALIZER, Inject, makeEnvironmentProviders, ViewContainerRef, EventEmitter, Output, Input, Directive, signal, computed, HostListener, Optional } from '@angular/core';
|
|
2
|
+
import { Component, InjectionToken, Injectable, inject, APP_INITIALIZER, Inject, makeEnvironmentProviders, ViewContainerRef, EventEmitter, Output, Input, Directive, signal, computed, HostListener, Optional, ChangeDetectionStrategy } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common/http';
|
|
4
4
|
import { HttpHeaders, HttpClient, HttpParams } from '@angular/common/http';
|
|
5
5
|
import { BehaviorSubject, from, of, EMPTY, throwError, firstValueFrom } from 'rxjs';
|
|
@@ -8,20 +8,22 @@ import * as i1$1 from '@angular/forms';
|
|
|
8
8
|
import { Validators, FormGroup, FormControl, FormsModule } from '@angular/forms';
|
|
9
9
|
import * as i2 from '@angular/common';
|
|
10
10
|
import { CommonModule } from '@angular/common';
|
|
11
|
-
import * as
|
|
11
|
+
import * as i3 from '@angular/material/card';
|
|
12
12
|
import { MatCardModule } from '@angular/material/card';
|
|
13
|
-
import * as i3 from '@angular/material/button';
|
|
13
|
+
import * as i3$1 from '@angular/material/button';
|
|
14
14
|
import { MatButtonModule } from '@angular/material/button';
|
|
15
15
|
import * as i4 from '@angular/material/icon';
|
|
16
16
|
import { MatIconModule } from '@angular/material/icon';
|
|
17
|
-
import * as i2$
|
|
17
|
+
import * as i2$1 from '@angular/material/form-field';
|
|
18
18
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
19
|
-
import * as i3$
|
|
19
|
+
import * as i3$2 from '@angular/material/input';
|
|
20
20
|
import { MatInputModule } from '@angular/material/input';
|
|
21
21
|
import * as i8 from '@angular/material/chips';
|
|
22
22
|
import { MatChipsModule } from '@angular/material/chips';
|
|
23
23
|
import * as i1$2 from '@angular/material/dialog';
|
|
24
24
|
import { MAT_DIALOG_DATA, MatDialogModule, MatDialog } from '@angular/material/dialog';
|
|
25
|
+
import * as i2$2 from '@angular/material/tabs';
|
|
26
|
+
import { MatTabsModule } from '@angular/material/tabs';
|
|
25
27
|
|
|
26
28
|
class PraxisCore {
|
|
27
29
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisCore, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
@@ -849,6 +851,16 @@ class SchemaNormalizerService {
|
|
|
849
851
|
// -------------------------------------------------------------------
|
|
850
852
|
// Layout and presentation
|
|
851
853
|
// -------------------------------------------------------------------
|
|
854
|
+
// Visibility flags (x-ui)
|
|
855
|
+
if (ui.hidden !== undefined) {
|
|
856
|
+
field.hidden = this.parseBoolean(ui.hidden);
|
|
857
|
+
}
|
|
858
|
+
if (ui.tableHidden !== undefined) {
|
|
859
|
+
field.tableHidden = this.parseBoolean(ui.tableHidden);
|
|
860
|
+
}
|
|
861
|
+
if (ui.formHidden !== undefined) {
|
|
862
|
+
field.formHidden = this.parseBoolean(ui.formHidden);
|
|
863
|
+
}
|
|
852
864
|
if (ui.width !== undefined) {
|
|
853
865
|
field.width = ui.width;
|
|
854
866
|
}
|
|
@@ -1127,20 +1139,14 @@ class GenericCrudService {
|
|
|
1127
1139
|
const schemaId = buildSchemaId({ path, operation, schemaType, includeInternalSchemas: false, tenant, locale, apiOrigin });
|
|
1128
1140
|
const headersBase = composeHeadersWithVersion(entry);
|
|
1129
1141
|
return from(this._schemaCache.get(schemaId)).pipe(concatMap((cached) => {
|
|
1130
|
-
let headers = headersBase;
|
|
1142
|
+
let headers = (headersBase instanceof HttpHeaders ? headersBase : new HttpHeaders(headersBase));
|
|
1131
1143
|
if (cached?.schemaHash) {
|
|
1132
|
-
headers = (
|
|
1133
|
-
.set('If-None-Match', `"${cached.schemaHash}"`)
|
|
1134
|
-
.set('Accept-Language', locale || '')
|
|
1135
|
-
.set('X-Tenant', tenant || '');
|
|
1136
|
-
}
|
|
1137
|
-
else {
|
|
1138
|
-
headers = (headersBase instanceof HttpHeaders ? headersBase : new HttpHeaders(headersBase));
|
|
1139
|
-
if (locale)
|
|
1140
|
-
headers = headers.set('Accept-Language', locale);
|
|
1141
|
-
if (tenant)
|
|
1142
|
-
headers = headers.set('X-Tenant', tenant);
|
|
1144
|
+
headers = headers.set('If-None-Match', `"${cached.schemaHash}"`);
|
|
1143
1145
|
}
|
|
1146
|
+
if (locale)
|
|
1147
|
+
headers = headers.set('Accept-Language', locale);
|
|
1148
|
+
if (tenant)
|
|
1149
|
+
headers = headers.set('X-Tenant', tenant);
|
|
1144
1150
|
console.debug('[CRUD:Service] getSchema (filtered fallback):request', { filteredUrl, path, hasCached: !!cached });
|
|
1145
1151
|
return this.http.get(filteredUrl, { params: httpParams, headers, observe: 'response' });
|
|
1146
1152
|
}), concatMap((resp) => {
|
|
@@ -1217,9 +1223,9 @@ class GenericCrudService {
|
|
|
1217
1223
|
catch { }
|
|
1218
1224
|
return of(this.schemaNormalizer.normalizeSchema(body));
|
|
1219
1225
|
}),
|
|
1220
|
-
// Angular HttpClient treats 304 as error; handle
|
|
1226
|
+
// Angular HttpClient treats 304 as error; also handle status 0 (CORS/network) by reusing cache
|
|
1221
1227
|
catchError((err) => {
|
|
1222
|
-
if (err?.status === 304) {
|
|
1228
|
+
if (err?.status === 304 || err?.status === 0) {
|
|
1223
1229
|
return from(this._schemaCache.get(schemaId)).pipe(concatMap((cached) => {
|
|
1224
1230
|
if (cached?.schema) {
|
|
1225
1231
|
try {
|
|
@@ -1437,9 +1443,9 @@ class GenericCrudService {
|
|
|
1437
1443
|
this._schemaCache.set(schemaId, entryToCache);
|
|
1438
1444
|
return of(this.schemaNormalizer.normalizeSchema(body));
|
|
1439
1445
|
}),
|
|
1440
|
-
// Angular HttpClient may surface 304 as error; handle
|
|
1446
|
+
// Angular HttpClient may surface 304 as error; also handle status 0 (CORS/network) by reusing cache
|
|
1441
1447
|
catchError((err) => {
|
|
1442
|
-
if (err?.status === 304) {
|
|
1448
|
+
if (err?.status === 304 || err?.status === 0) {
|
|
1443
1449
|
return from(this._schemaCache.get(schemaId)).pipe(concatMap((cached) => {
|
|
1444
1450
|
if (cached?.schema) {
|
|
1445
1451
|
try {
|
|
@@ -1958,10 +1964,19 @@ class GenericCrudService {
|
|
|
1958
1964
|
const baseUrl = buildApiUrl(entry);
|
|
1959
1965
|
try {
|
|
1960
1966
|
const origin = new URL(baseUrl).origin;
|
|
1961
|
-
return `${origin}/schemas/filtered`;
|
|
1967
|
+
return `${origin.replace(/\/+$/, '')}/schemas/filtered`;
|
|
1962
1968
|
}
|
|
1963
1969
|
catch {
|
|
1964
|
-
|
|
1970
|
+
// Tolerate relative baseUrl (e.g., '/api') by resolving against app origin when available
|
|
1971
|
+
try {
|
|
1972
|
+
const appOrigin = globalThis?.location?.origin;
|
|
1973
|
+
if (appOrigin && typeof appOrigin === 'string' && appOrigin.startsWith('http')) {
|
|
1974
|
+
return `${appOrigin.replace(/\/+$/, '')}/schemas/filtered`;
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
catch { }
|
|
1978
|
+
// Last resort: localhost origin to build an absolute URL (document SSR guidance in docs)
|
|
1979
|
+
return 'http://localhost/schemas/filtered';
|
|
1965
1980
|
}
|
|
1966
1981
|
}
|
|
1967
1982
|
/**
|
|
@@ -2134,27 +2149,12 @@ function createDefaultTableConfig() {
|
|
|
2134
2149
|
},
|
|
2135
2150
|
actions: {
|
|
2136
2151
|
row: {
|
|
2137
|
-
enabled:
|
|
2152
|
+
enabled: false,
|
|
2138
2153
|
position: 'end',
|
|
2139
2154
|
width: '120px',
|
|
2140
2155
|
display: 'icons',
|
|
2141
2156
|
trigger: 'hover',
|
|
2142
|
-
actions: [
|
|
2143
|
-
{
|
|
2144
|
-
id: 'view',
|
|
2145
|
-
label: 'Visualizar',
|
|
2146
|
-
icon: 'visibility',
|
|
2147
|
-
action: 'view',
|
|
2148
|
-
},
|
|
2149
|
-
{ id: 'edit', label: 'Editar', icon: 'edit', action: 'edit' },
|
|
2150
|
-
{
|
|
2151
|
-
id: 'delete',
|
|
2152
|
-
label: 'Excluir',
|
|
2153
|
-
icon: 'delete',
|
|
2154
|
-
action: 'delete',
|
|
2155
|
-
autoDelete: false,
|
|
2156
|
-
},
|
|
2157
|
-
],
|
|
2157
|
+
actions: [],
|
|
2158
2158
|
},
|
|
2159
2159
|
bulk: {
|
|
2160
2160
|
enabled: false,
|
|
@@ -4126,6 +4126,13 @@ function normalizeFormConfig(config) {
|
|
|
4126
4126
|
return config;
|
|
4127
4127
|
const normalized = { ...config };
|
|
4128
4128
|
normalized.fieldMetadata = normalizeFormMetadata(config.fieldMetadata);
|
|
4129
|
+
// Ensure hints exist and fill missing values with defaults
|
|
4130
|
+
try {
|
|
4131
|
+
const defaults = getDefaultFormHints();
|
|
4132
|
+
const current = normalized.hints;
|
|
4133
|
+
normalized.hints = fillUndefined(current || {}, defaults);
|
|
4134
|
+
}
|
|
4135
|
+
catch { }
|
|
4129
4136
|
return normalized;
|
|
4130
4137
|
}
|
|
4131
4138
|
/**
|
|
@@ -4257,6 +4264,8 @@ function createDefaultFormConfig() {
|
|
|
4257
4264
|
],
|
|
4258
4265
|
},
|
|
4259
4266
|
],
|
|
4267
|
+
// Default mode hints (didactic tooltips)
|
|
4268
|
+
hints: getDefaultFormHints(),
|
|
4260
4269
|
};
|
|
4261
4270
|
return ensureIds(config);
|
|
4262
4271
|
}
|
|
@@ -4269,6 +4278,24 @@ function isValidFormConfig(config) {
|
|
|
4269
4278
|
function createEmptyFormConfig() {
|
|
4270
4279
|
return { sections: [] };
|
|
4271
4280
|
}
|
|
4281
|
+
/**
|
|
4282
|
+
* Default hint texts for data and UI modes.
|
|
4283
|
+
*/
|
|
4284
|
+
function getDefaultFormHints() {
|
|
4285
|
+
return {
|
|
4286
|
+
dataModes: {
|
|
4287
|
+
create: 'Criar novo registro. Campos editáveis e ações de salvar habilitadas.',
|
|
4288
|
+
edit: 'Editar registro existente. Campos editáveis e ações de salvar habilitadas.',
|
|
4289
|
+
view: 'Visualizar registro. Sem edição por padrão; combine com Modo Leitura ou Apresentação.',
|
|
4290
|
+
},
|
|
4291
|
+
uiModes: {
|
|
4292
|
+
presentation: 'Modo apresentação: exibe rótulo + valor formatado e oculta inputs/ações. Efetivo apenas em Visualizar.',
|
|
4293
|
+
readonly: 'Modo leitura: mantém os inputs visíveis, porém bloqueados (sem interação). Continua participando da validação e do envio.',
|
|
4294
|
+
disabled: 'Desabilitado: aparência inativa; ideal para bloquear interação visualmente. Evite desativar campos essenciais.',
|
|
4295
|
+
visible: 'Visibilidade: controla exibição sem destruir controles (útil para regras condicionais).',
|
|
4296
|
+
},
|
|
4297
|
+
};
|
|
4298
|
+
}
|
|
4272
4299
|
/**
|
|
4273
4300
|
* Merges field metadata into a FormConfig
|
|
4274
4301
|
* Useful when combining layout with server-loaded metadata
|
|
@@ -4711,6 +4738,8 @@ function mapFieldDefinitionToMetadata(field) {
|
|
|
4711
4738
|
'disabled',
|
|
4712
4739
|
'readOnly',
|
|
4713
4740
|
'hidden',
|
|
4741
|
+
'formHidden',
|
|
4742
|
+
'tableHidden',
|
|
4714
4743
|
'unique',
|
|
4715
4744
|
'mask',
|
|
4716
4745
|
'inlineEditing',
|
|
@@ -5750,7 +5779,7 @@ class EmptyStateCardComponent {
|
|
|
5750
5779
|
</div>
|
|
5751
5780
|
</mat-card-content>
|
|
5752
5781
|
</mat-card>
|
|
5753
|
-
`, isInline: true, styles: [".empty-card{display:block;margin:12px}.empty-card.empty-inline{margin:8px 0}.content{display:flex;align-items:center;gap:12px}.icon{font-size:32px;width:32px;height:32px;opacity:.9}.title{margin:0;font-size:16px;font-weight:600}.desc{margin:4px 0 0;opacity:.76}.actions{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type:
|
|
5782
|
+
`, isInline: true, styles: [".empty-card{display:block;margin:12px}.empty-card.empty-inline{margin:8px 0}.content{display:flex;align-items:center;gap:12px}.icon{font-size:32px;width:32px;height:32px;opacity:.9}.title{margin:0;font-size:16px;font-weight:600}.desc{margin:4px 0 0;opacity:.76}.actions{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i3.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3.MatCardContent, selector: "mat-card-content" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
|
|
5754
5783
|
}
|
|
5755
5784
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: EmptyStateCardComponent, decorators: [{
|
|
5756
5785
|
type: Component,
|
|
@@ -5904,7 +5933,7 @@ class ResourceQuickConnectComponent {
|
|
|
5904
5933
|
</mat-form-field>
|
|
5905
5934
|
<small style="opacity:.75">Conecte o componente à fonte de dados (ex.: /api/<rota-do-recurso>)</small>
|
|
5906
5935
|
</div>
|
|
5907
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: i2$
|
|
5936
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }] });
|
|
5908
5937
|
}
|
|
5909
5938
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: ResourceQuickConnectComponent, decorators: [{
|
|
5910
5939
|
type: Component,
|
|
@@ -6093,7 +6122,7 @@ class PraxisIconPickerComponent {
|
|
|
6093
6122
|
<span class="pip-typed" *ngIf="query.trim()">{{ previewValue() }}</span>
|
|
6094
6123
|
</div>
|
|
6095
6124
|
</div>
|
|
6096
|
-
`, isInline: true, styles: [".pip-root{display:flex;flex-direction:column;min-width:340px;max-width:760px;max-height:80vh;overflow:hidden;padding:16px}.pip-head{display:flex;gap:12px;align-items:center;margin-bottom:12px}.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 rgba(0,0,0,.
|
|
6125
|
+
`, isInline: true, styles: [".pip-root{display:flex;flex-direction:column;min-width:340px;max-width:760px;max-height:80vh;overflow:hidden;padding:16px}.pip-head{display:flex;gap:12px;align-items:center;margin-bottom:12px}.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, rgba(0,0,0,.14));border-radius:10px;background:var(--md-sys-color-surface);color:var(--md-sys-color-on-surface);cursor:pointer}.pip-item:hover{background:color-mix(in oklab,var(--md-sys-color-on-surface) 8%,transparent)}.pip-name{font-size:12px;color:var(--md-sys-color-on-surface-variant, rgba(0,0,0,.6));white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.pip-hint{font-size:12px;color:var(--md-sys-color-on-surface-variant, rgba(0,0,0,.6));margin:-6px 0 8px}.pip-footer{display:flex;gap:12px;align-items:center;margin-top:10px}.pip-typed{font-family:monospace;font-size:12px;color:var(--md-sys-color-on-surface, rgba(0,0,0,.7))}.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: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.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: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i8.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "component", type: i8.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "ngmodule", type: MatDialogModule }] });
|
|
6097
6126
|
}
|
|
6098
6127
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisIconPickerComponent, decorators: [{
|
|
6099
6128
|
type: Component,
|
|
@@ -6137,7 +6166,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
6137
6166
|
<span class="pip-typed" *ngIf="query.trim()">{{ previewValue() }}</span>
|
|
6138
6167
|
</div>
|
|
6139
6168
|
</div>
|
|
6140
|
-
`, styles: [".pip-root{display:flex;flex-direction:column;min-width:340px;max-width:760px;max-height:80vh;overflow:hidden;padding:16px}.pip-head{display:flex;gap:12px;align-items:center;margin-bottom:12px}.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 rgba(0,0,0,.
|
|
6169
|
+
`, styles: [".pip-root{display:flex;flex-direction:column;min-width:340px;max-width:760px;max-height:80vh;overflow:hidden;padding:16px}.pip-head{display:flex;gap:12px;align-items:center;margin-bottom:12px}.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, rgba(0,0,0,.14));border-radius:10px;background:var(--md-sys-color-surface);color:var(--md-sys-color-on-surface);cursor:pointer}.pip-item:hover{background:color-mix(in oklab,var(--md-sys-color-on-surface) 8%,transparent)}.pip-name{font-size:12px;color:var(--md-sys-color-on-surface-variant, rgba(0,0,0,.6));white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.pip-hint{font-size:12px;color:var(--md-sys-color-on-surface-variant, rgba(0,0,0,.6));margin:-6px 0 8px}.pip-footer{display:flex;gap:12px;align-items:center;margin-top:10px}.pip-typed{font-family:monospace;font-size:12px;color:var(--md-sys-color-on-surface, rgba(0,0,0,.7))}.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"] }]
|
|
6141
6170
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
6142
6171
|
type: Optional
|
|
6143
6172
|
}, {
|
|
@@ -6196,6 +6225,246 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
6196
6225
|
args: [{ providedIn: 'root' }]
|
|
6197
6226
|
}] });
|
|
6198
6227
|
|
|
6228
|
+
/** Optional DI token used by SchemaViewer when input is not provided. */
|
|
6229
|
+
const SCHEMA_VIEWER_CONTEXT = new InjectionToken('SCHEMA_VIEWER_CONTEXT');
|
|
6230
|
+
|
|
6231
|
+
class SchemaViewerComponent {
|
|
6232
|
+
registry = inject(ComponentMetadataRegistry);
|
|
6233
|
+
normalizer = inject(SchemaNormalizerService);
|
|
6234
|
+
injected = inject(SCHEMA_VIEWER_CONTEXT, { optional: true });
|
|
6235
|
+
context;
|
|
6236
|
+
// Internal reactive state
|
|
6237
|
+
_ctx = signal(undefined, ...(ngDevMode ? [{ debugName: "_ctx" }] : []));
|
|
6238
|
+
ctx = computed(() => this._ctx(), ...(ngDevMode ? [{ debugName: "ctx" }] : []));
|
|
6239
|
+
_componentMeta = signal(undefined, ...(ngDevMode ? [{ debugName: "_componentMeta" }] : []));
|
|
6240
|
+
componentMeta = computed(() => this._componentMeta(), ...(ngDevMode ? [{ debugName: "componentMeta" }] : []));
|
|
6241
|
+
_normalizedFields = signal([], ...(ngDevMode ? [{ debugName: "_normalizedFields" }] : []));
|
|
6242
|
+
normalizedFields = computed(() => this._normalizedFields(), ...(ngDevMode ? [{ debugName: "normalizedFields" }] : []));
|
|
6243
|
+
ngOnChanges(changes) {
|
|
6244
|
+
if ('context' in changes) {
|
|
6245
|
+
this.refresh();
|
|
6246
|
+
}
|
|
6247
|
+
}
|
|
6248
|
+
refresh() {
|
|
6249
|
+
const ctx = this.context || this.injected || undefined;
|
|
6250
|
+
this._ctx.set(ctx);
|
|
6251
|
+
if (!ctx) {
|
|
6252
|
+
this._componentMeta.set(undefined);
|
|
6253
|
+
this._normalizedFields.set([]);
|
|
6254
|
+
return;
|
|
6255
|
+
}
|
|
6256
|
+
const meta = ctx.componentId ? this.registry.get(ctx.componentId) : undefined;
|
|
6257
|
+
this._componentMeta.set(meta);
|
|
6258
|
+
// Compute normalized fields if needed
|
|
6259
|
+
if (ctx.normalizedFields && ctx.normalizedFields.length) {
|
|
6260
|
+
this._normalizedFields.set(ctx.normalizedFields);
|
|
6261
|
+
}
|
|
6262
|
+
else if (ctx.backendSchema) {
|
|
6263
|
+
try {
|
|
6264
|
+
const defs = this.normalizer.normalizeSchema(ctx.backendSchema);
|
|
6265
|
+
this._normalizedFields.set(defs || []);
|
|
6266
|
+
}
|
|
6267
|
+
catch {
|
|
6268
|
+
this._normalizedFields.set([]);
|
|
6269
|
+
}
|
|
6270
|
+
}
|
|
6271
|
+
else {
|
|
6272
|
+
this._normalizedFields.set([]);
|
|
6273
|
+
}
|
|
6274
|
+
}
|
|
6275
|
+
hasAnyData() {
|
|
6276
|
+
const c = this._ctx();
|
|
6277
|
+
return !!(c?.rawConfig || c?.effectiveConfig || c?.backendSchema || (this._normalizedFields()?.length));
|
|
6278
|
+
}
|
|
6279
|
+
copyAll() {
|
|
6280
|
+
const c = this._ctx();
|
|
6281
|
+
const payload = {
|
|
6282
|
+
component: this._componentMeta(),
|
|
6283
|
+
config: { raw: c?.rawConfig, effective: c?.effectiveConfig },
|
|
6284
|
+
backendSchema: { meta: c?.schemaMeta, body: c?.backendSchema },
|
|
6285
|
+
fields: this._normalizedFields(),
|
|
6286
|
+
};
|
|
6287
|
+
try {
|
|
6288
|
+
const text = JSON.stringify(payload, null, 2);
|
|
6289
|
+
if (typeof navigator !== 'undefined' && navigator.clipboard?.writeText) {
|
|
6290
|
+
navigator.clipboard.writeText(text);
|
|
6291
|
+
}
|
|
6292
|
+
else {
|
|
6293
|
+
// Fallback: create a temp textarea
|
|
6294
|
+
const ta = document.createElement('textarea');
|
|
6295
|
+
ta.value = text;
|
|
6296
|
+
document.body.appendChild(ta);
|
|
6297
|
+
ta.select();
|
|
6298
|
+
document.execCommand('copy');
|
|
6299
|
+
document.body.removeChild(ta);
|
|
6300
|
+
}
|
|
6301
|
+
}
|
|
6302
|
+
catch { }
|
|
6303
|
+
}
|
|
6304
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: SchemaViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6305
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: SchemaViewerComponent, isStandalone: true, selector: "praxis-schema-viewer", inputs: { context: "context" }, usesOnChanges: true, ngImport: i0, template: `
|
|
6306
|
+
<mat-card class="schema-viewer" appearance="outlined">
|
|
6307
|
+
<mat-card-header>
|
|
6308
|
+
<div class="header">
|
|
6309
|
+
<div class="title">
|
|
6310
|
+
<mat-icon fontIcon="schema"></mat-icon>
|
|
6311
|
+
<h3>{{ ctx()?.title || 'Schema & Metadata' }}</h3>
|
|
6312
|
+
</div>
|
|
6313
|
+
<div class="actions">
|
|
6314
|
+
<button mat-stroked-button color="primary" (click)="copyAll()" [disabled]="!hasAnyData()">
|
|
6315
|
+
<mat-icon>content_copy</mat-icon>
|
|
6316
|
+
Copiar tudo
|
|
6317
|
+
</button>
|
|
6318
|
+
</div>
|
|
6319
|
+
</div>
|
|
6320
|
+
<div class="notes" *ngIf="ctx()?.notes">{{ ctx()?.notes }}</div>
|
|
6321
|
+
</mat-card-header>
|
|
6322
|
+
<mat-card-content>
|
|
6323
|
+
<mat-tab-group>
|
|
6324
|
+
<mat-tab label="Component">
|
|
6325
|
+
<div class="section">
|
|
6326
|
+
<div class="kv"><span>Id</span><code>{{ componentMeta()?.id }}</code></div>
|
|
6327
|
+
<div class="kv"><span>Selector</span><code>{{ componentMeta()?.selector }}</code></div>
|
|
6328
|
+
<div class="kv"><span>Lib</span><code>{{ componentMeta()?.lib || '—' }}</code></div>
|
|
6329
|
+
<div class="kv"><span>Friendly</span><code>{{ componentMeta()?.friendlyName }}</code></div>
|
|
6330
|
+
<div class="kv" *ngIf="componentMeta()?.description"><span>Descrição</span><code>{{ componentMeta()?.description }}</code></div>
|
|
6331
|
+
|
|
6332
|
+
<div class="sub">Inputs</div>
|
|
6333
|
+
<pre class="pretty" *ngIf="componentMeta()?.inputs?.length; else noInputs">{{ componentMeta()?.inputs | json }}</pre>
|
|
6334
|
+
<ng-template #noInputs><div class="muted">Sem inputs documentados.</div></ng-template>
|
|
6335
|
+
|
|
6336
|
+
<div class="sub">Outputs</div>
|
|
6337
|
+
<pre class="pretty" *ngIf="componentMeta()?.outputs?.length; else noOutputs">{{ componentMeta()?.outputs | json }}</pre>
|
|
6338
|
+
<ng-template #noOutputs><div class="muted">Sem outputs documentados.</div></ng-template>
|
|
6339
|
+
</div>
|
|
6340
|
+
</mat-tab>
|
|
6341
|
+
|
|
6342
|
+
<mat-tab label="Config">
|
|
6343
|
+
<div class="section">
|
|
6344
|
+
<div class="sub">Raw</div>
|
|
6345
|
+
<pre class="pretty" *ngIf="ctx()?.rawConfig as rc; else noRaw">{{ rc | json }}</pre>
|
|
6346
|
+
<ng-template #noRaw><div class="muted">Sem configuração fornecida.</div></ng-template>
|
|
6347
|
+
|
|
6348
|
+
<div class="sub">Effective</div>
|
|
6349
|
+
<pre class="pretty" *ngIf="ctx()?.effectiveConfig as ec; else noEff">{{ ec | json }}</pre>
|
|
6350
|
+
<ng-template #noEff><div class="muted">Sem configuração efetiva (usando raw/defaults do componente).</div></ng-template>
|
|
6351
|
+
</div>
|
|
6352
|
+
</mat-tab>
|
|
6353
|
+
|
|
6354
|
+
<mat-tab label="Backend Schema">
|
|
6355
|
+
<div class="section">
|
|
6356
|
+
<div class="kv" *ngIf="ctx()?.schemaMeta as m">
|
|
6357
|
+
<span>Path</span><code>{{ m.path }}</code>
|
|
6358
|
+
</div>
|
|
6359
|
+
<div class="kv" *ngIf="ctx()?.schemaMeta as m">
|
|
6360
|
+
<span>Operation</span><code>{{ m.operation }}</code>
|
|
6361
|
+
</div>
|
|
6362
|
+
<div class="kv" *ngIf="ctx()?.schemaMeta as m">
|
|
6363
|
+
<span>Schema Type</span><code>{{ m.schemaType }}</code>
|
|
6364
|
+
</div>
|
|
6365
|
+
<div class="kv" *ngIf="ctx()?.schemaMeta?.schemaHash">
|
|
6366
|
+
<span>Server Hash</span><code>{{ ctx()?.schemaMeta?.schemaHash }}</code>
|
|
6367
|
+
</div>
|
|
6368
|
+
<pre class="pretty" *ngIf="ctx()?.backendSchema as bs; else noSchema">{{ bs | json }}</pre>
|
|
6369
|
+
<ng-template #noSchema><div class="muted">Sem schema de backend.</div></ng-template>
|
|
6370
|
+
</div>
|
|
6371
|
+
</mat-tab>
|
|
6372
|
+
|
|
6373
|
+
<mat-tab label="Fields">
|
|
6374
|
+
<div class="section">
|
|
6375
|
+
<div class="muted" *ngIf="!normalizedFields()?.length">Sem campos normalizados.</div>
|
|
6376
|
+
<pre class="pretty" *ngIf="normalizedFields()?.length">{{ normalizedFields() | json }}</pre>
|
|
6377
|
+
</div>
|
|
6378
|
+
</mat-tab>
|
|
6379
|
+
</mat-tab-group>
|
|
6380
|
+
</mat-card-content>
|
|
6381
|
+
</mat-card>
|
|
6382
|
+
`, isInline: true, styles: [".schema-viewer{display:block}.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}.notes{margin-top:6px;opacity:.78;font-size:12px}.section{padding:12px}.sub{font-weight:600;margin:12px 0 4px;opacity:.9}.pretty{background:#0b0b0b0d;padding:8px;border-radius:4px;overflow:auto}.kv{display:grid;grid-template-columns:140px 1fr;align-items:baseline;gap:8px;margin:2px 0}.kv>span{opacity:.75}.kv>code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.muted{opacity:.6}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i2$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2$2.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.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i3.MatCardHeader, selector: "mat-card-header" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: i2.JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6383
|
+
}
|
|
6384
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: SchemaViewerComponent, decorators: [{
|
|
6385
|
+
type: Component,
|
|
6386
|
+
args: [{ selector: 'praxis-schema-viewer', standalone: true, imports: [CommonModule, MatTabsModule, MatCardModule, MatButtonModule, MatIconModule], template: `
|
|
6387
|
+
<mat-card class="schema-viewer" appearance="outlined">
|
|
6388
|
+
<mat-card-header>
|
|
6389
|
+
<div class="header">
|
|
6390
|
+
<div class="title">
|
|
6391
|
+
<mat-icon fontIcon="schema"></mat-icon>
|
|
6392
|
+
<h3>{{ ctx()?.title || 'Schema & Metadata' }}</h3>
|
|
6393
|
+
</div>
|
|
6394
|
+
<div class="actions">
|
|
6395
|
+
<button mat-stroked-button color="primary" (click)="copyAll()" [disabled]="!hasAnyData()">
|
|
6396
|
+
<mat-icon>content_copy</mat-icon>
|
|
6397
|
+
Copiar tudo
|
|
6398
|
+
</button>
|
|
6399
|
+
</div>
|
|
6400
|
+
</div>
|
|
6401
|
+
<div class="notes" *ngIf="ctx()?.notes">{{ ctx()?.notes }}</div>
|
|
6402
|
+
</mat-card-header>
|
|
6403
|
+
<mat-card-content>
|
|
6404
|
+
<mat-tab-group>
|
|
6405
|
+
<mat-tab label="Component">
|
|
6406
|
+
<div class="section">
|
|
6407
|
+
<div class="kv"><span>Id</span><code>{{ componentMeta()?.id }}</code></div>
|
|
6408
|
+
<div class="kv"><span>Selector</span><code>{{ componentMeta()?.selector }}</code></div>
|
|
6409
|
+
<div class="kv"><span>Lib</span><code>{{ componentMeta()?.lib || '—' }}</code></div>
|
|
6410
|
+
<div class="kv"><span>Friendly</span><code>{{ componentMeta()?.friendlyName }}</code></div>
|
|
6411
|
+
<div class="kv" *ngIf="componentMeta()?.description"><span>Descrição</span><code>{{ componentMeta()?.description }}</code></div>
|
|
6412
|
+
|
|
6413
|
+
<div class="sub">Inputs</div>
|
|
6414
|
+
<pre class="pretty" *ngIf="componentMeta()?.inputs?.length; else noInputs">{{ componentMeta()?.inputs | json }}</pre>
|
|
6415
|
+
<ng-template #noInputs><div class="muted">Sem inputs documentados.</div></ng-template>
|
|
6416
|
+
|
|
6417
|
+
<div class="sub">Outputs</div>
|
|
6418
|
+
<pre class="pretty" *ngIf="componentMeta()?.outputs?.length; else noOutputs">{{ componentMeta()?.outputs | json }}</pre>
|
|
6419
|
+
<ng-template #noOutputs><div class="muted">Sem outputs documentados.</div></ng-template>
|
|
6420
|
+
</div>
|
|
6421
|
+
</mat-tab>
|
|
6422
|
+
|
|
6423
|
+
<mat-tab label="Config">
|
|
6424
|
+
<div class="section">
|
|
6425
|
+
<div class="sub">Raw</div>
|
|
6426
|
+
<pre class="pretty" *ngIf="ctx()?.rawConfig as rc; else noRaw">{{ rc | json }}</pre>
|
|
6427
|
+
<ng-template #noRaw><div class="muted">Sem configuração fornecida.</div></ng-template>
|
|
6428
|
+
|
|
6429
|
+
<div class="sub">Effective</div>
|
|
6430
|
+
<pre class="pretty" *ngIf="ctx()?.effectiveConfig as ec; else noEff">{{ ec | json }}</pre>
|
|
6431
|
+
<ng-template #noEff><div class="muted">Sem configuração efetiva (usando raw/defaults do componente).</div></ng-template>
|
|
6432
|
+
</div>
|
|
6433
|
+
</mat-tab>
|
|
6434
|
+
|
|
6435
|
+
<mat-tab label="Backend Schema">
|
|
6436
|
+
<div class="section">
|
|
6437
|
+
<div class="kv" *ngIf="ctx()?.schemaMeta as m">
|
|
6438
|
+
<span>Path</span><code>{{ m.path }}</code>
|
|
6439
|
+
</div>
|
|
6440
|
+
<div class="kv" *ngIf="ctx()?.schemaMeta as m">
|
|
6441
|
+
<span>Operation</span><code>{{ m.operation }}</code>
|
|
6442
|
+
</div>
|
|
6443
|
+
<div class="kv" *ngIf="ctx()?.schemaMeta as m">
|
|
6444
|
+
<span>Schema Type</span><code>{{ m.schemaType }}</code>
|
|
6445
|
+
</div>
|
|
6446
|
+
<div class="kv" *ngIf="ctx()?.schemaMeta?.schemaHash">
|
|
6447
|
+
<span>Server Hash</span><code>{{ ctx()?.schemaMeta?.schemaHash }}</code>
|
|
6448
|
+
</div>
|
|
6449
|
+
<pre class="pretty" *ngIf="ctx()?.backendSchema as bs; else noSchema">{{ bs | json }}</pre>
|
|
6450
|
+
<ng-template #noSchema><div class="muted">Sem schema de backend.</div></ng-template>
|
|
6451
|
+
</div>
|
|
6452
|
+
</mat-tab>
|
|
6453
|
+
|
|
6454
|
+
<mat-tab label="Fields">
|
|
6455
|
+
<div class="section">
|
|
6456
|
+
<div class="muted" *ngIf="!normalizedFields()?.length">Sem campos normalizados.</div>
|
|
6457
|
+
<pre class="pretty" *ngIf="normalizedFields()?.length">{{ normalizedFields() | json }}</pre>
|
|
6458
|
+
</div>
|
|
6459
|
+
</mat-tab>
|
|
6460
|
+
</mat-tab-group>
|
|
6461
|
+
</mat-card-content>
|
|
6462
|
+
</mat-card>
|
|
6463
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".schema-viewer{display:block}.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}.notes{margin-top:6px;opacity:.78;font-size:12px}.section{padding:12px}.sub{font-weight:600;margin:12px 0 4px;opacity:.9}.pretty{background:#0b0b0b0d;padding:8px;border-radius:4px;overflow:auto}.kv{display:grid;grid-template-columns:140px 1fr;align-items:baseline;gap:8px;margin:2px 0}.kv>span{opacity:.75}.kv>code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.muted{opacity:.6}\n"] }]
|
|
6464
|
+
}], propDecorators: { context: [{
|
|
6465
|
+
type: Input
|
|
6466
|
+
}] } });
|
|
6467
|
+
|
|
6199
6468
|
async function fetchWithETag(params) {
|
|
6200
6469
|
const headers = { Accept: 'application/json' };
|
|
6201
6470
|
if (params.schemaHash)
|
|
@@ -6247,11 +6516,41 @@ class SchemaMetadataClient {
|
|
|
6247
6516
|
try {
|
|
6248
6517
|
apiOrigin = new URL(params.baseUrl).origin;
|
|
6249
6518
|
}
|
|
6250
|
-
catch {
|
|
6519
|
+
catch {
|
|
6520
|
+
try {
|
|
6521
|
+
apiOrigin = globalThis?.location?.origin || '';
|
|
6522
|
+
}
|
|
6523
|
+
catch { }
|
|
6524
|
+
}
|
|
6251
6525
|
const schemaId = buildSchemaId({ ...params, apiOrigin });
|
|
6252
6526
|
const cached = await this.cache.get(schemaId);
|
|
6253
6527
|
// Build URL with query params
|
|
6254
|
-
|
|
6528
|
+
let u;
|
|
6529
|
+
try {
|
|
6530
|
+
u = new URL(params.baseUrl);
|
|
6531
|
+
}
|
|
6532
|
+
catch (err) {
|
|
6533
|
+
// Accept relative baseUrl by resolving against the app origin when available
|
|
6534
|
+
const origin = (() => {
|
|
6535
|
+
try {
|
|
6536
|
+
return globalThis?.location?.origin;
|
|
6537
|
+
}
|
|
6538
|
+
catch {
|
|
6539
|
+
return undefined;
|
|
6540
|
+
}
|
|
6541
|
+
})();
|
|
6542
|
+
if (origin && origin.startsWith('http')) {
|
|
6543
|
+
u = new URL(params.baseUrl, origin);
|
|
6544
|
+
}
|
|
6545
|
+
else {
|
|
6546
|
+
// Friendly error for hosts: instruct to set absolute baseUrl or provide runtime origin
|
|
6547
|
+
const e = new Error(`Failed to construct schema URL. API_URL.baseUrl appears relative and no runtime origin is available. ` +
|
|
6548
|
+
`Set API_URL.baseUrl to an absolute URL (e.g., http://localhost:4200/api) or run in a browser context. ` +
|
|
6549
|
+
`Received baseUrl="${params.baseUrl}".`);
|
|
6550
|
+
e.cause = err;
|
|
6551
|
+
throw e;
|
|
6552
|
+
}
|
|
6553
|
+
}
|
|
6255
6554
|
u.searchParams.set('path', params.path);
|
|
6256
6555
|
u.searchParams.set('operation', (params.operation || 'get').toLowerCase());
|
|
6257
6556
|
u.searchParams.set('schemaType', (params.schemaType || 'response').toLowerCase());
|
|
@@ -6794,5 +7093,5 @@ function provideHookWhitelist(allowed) {
|
|
|
6794
7093
|
* Generated bundle index. Do not edit.
|
|
6795
7094
|
*/
|
|
6796
7095
|
|
|
6797
|
-
export { API_URL, AllowedFileTypes, ApiEndpoint, CONFIG_STORAGE, CONNECTION_STORAGE, ComponentMetadataRegistry, ConnectionManagerService, DEFAULT_TABLE_CONFIG, DynamicFormService, DynamicGridPageComponent, DynamicWidgetLoaderDirective, DynamicWidgetPageComponent, EmptyStateCardComponent, ErrorMessageService, FORM_HOOKS, FORM_HOOKS_PRESETS, FORM_HOOKS_WHITELIST, FORM_HOOK_RESOLVERS, FieldControlType, FieldDataType, FormHooksRegistry, GLOBAL_CONFIG, GenericCrudService, GlobalConfigService, IconPickerService, IconPosition, IconSize, LocalConnectionStorage, LocalStorageCacheAdapter, LocalStorageConfigService, NumericFormat, OVERLAY_DECIDER_DEBUG, OVERLAY_DECISION_MATRIX, OverlayDeciderService, PraxisCore, PraxisIconDirective, PraxisIconPickerComponent, ResourceQuickConnectComponent, SETTINGS_PANEL_BRIDGE, SETTINGS_PANEL_DATA, STEPPER_CONFIG_EDITOR, SchemaMetadataClient, SchemaNormalizerService, TABLE_CONFIG_EDITOR, TableConfigService, TelemetryService, ValidationPattern, applyLocalCustomizations$2 as applyLocalCustomizations, applyLocalCustomizations$1 as applyLocalFormCustomizations, buildAngularValidators, buildApiUrl, buildBaseColumnFromDef, buildBaseFormField, buildHeaders, buildPageKey, buildSchemaId, buildValidatorsFromValidatorOptions, cancelIfCpfInvalidHook, cloneTableConfig, cnpjAlphaValidator, collapseWhitespace, composeHeadersWithVersion, conditionalAsyncValidator, convertFormLayoutToConfig, createCpfCnpjValidator, createDefaultFormConfig, createDefaultTableConfig, createEmptyFormConfig, createPersistedPage, customAsyncValidatorFn, customValidatorFn, debounceAsyncValidator, deepMerge, ensureIds, ensureNoConflictsHookFactory, ensurePageIds, fetchWithETag, fileTypeValidator, fillUndefined, generateId, getEssentialConfig, getReferencedFieldMetadata, getTextTransformer, isCssTextTransform, isTableConfigV2, isValidFormConfig, isValidTableConfig, legacyCnpjValidator, legacyCpfValidator, logOnErrorHook, mapFieldDefinitionToMetadata, mapFieldDefinitionsToMetadata, matchFieldValidator, maxFileSizeValidator, mergeFieldMetadata, mergeTableConfigs, minWordsValidator, normalizeFieldConstraints, normalizeFormConfig, normalizeFormMetadata, normalizePath, notifySuccessHook, prefillFromContextHook, provideDefaultFormHooks, provideFormHookPresets, provideFormHooks, provideGlobalConfig, provideGlobalConfigSeed, provideGlobalConfigTenant, provideHookResolvers, provideHookWhitelist, provideOverlayDecisionMatrix, provideRemoteGlobalConfig, reconcileFilterConfig, reconcileFormConfig, reconcileTableConfig, removeDiacritics, reportTelemetryHookFactory, requiredCheckedValidator, resolveHidden, resolveOffset, resolveOrder, resolveSpan, slugify, stripMasksHook, syncWithServerMetadata, toCamel, toCapitalize, toKebab, toPascal, toSentenceCase, toSnake, toTitleCase, trim, uniqueAsyncValidator, urlValidator, withMessage };
|
|
7096
|
+
export { API_URL, AllowedFileTypes, ApiEndpoint, CONFIG_STORAGE, CONNECTION_STORAGE, ComponentMetadataRegistry, ConnectionManagerService, DEFAULT_TABLE_CONFIG, DynamicFormService, DynamicGridPageComponent, DynamicWidgetLoaderDirective, DynamicWidgetPageComponent, EmptyStateCardComponent, ErrorMessageService, FORM_HOOKS, FORM_HOOKS_PRESETS, FORM_HOOKS_WHITELIST, FORM_HOOK_RESOLVERS, FieldControlType, FieldDataType, FormHooksRegistry, GLOBAL_CONFIG, GenericCrudService, GlobalConfigService, IconPickerService, IconPosition, IconSize, LocalConnectionStorage, LocalStorageCacheAdapter, LocalStorageConfigService, NumericFormat, OVERLAY_DECIDER_DEBUG, OVERLAY_DECISION_MATRIX, OverlayDeciderService, PraxisCore, PraxisIconDirective, PraxisIconPickerComponent, ResourceQuickConnectComponent, SCHEMA_VIEWER_CONTEXT, SETTINGS_PANEL_BRIDGE, SETTINGS_PANEL_DATA, STEPPER_CONFIG_EDITOR, SchemaMetadataClient, SchemaNormalizerService, SchemaViewerComponent, TABLE_CONFIG_EDITOR, TableConfigService, TelemetryService, ValidationPattern, applyLocalCustomizations$2 as applyLocalCustomizations, applyLocalCustomizations$1 as applyLocalFormCustomizations, buildAngularValidators, buildApiUrl, buildBaseColumnFromDef, buildBaseFormField, buildHeaders, buildPageKey, buildSchemaId, buildValidatorsFromValidatorOptions, cancelIfCpfInvalidHook, cloneTableConfig, cnpjAlphaValidator, collapseWhitespace, composeHeadersWithVersion, conditionalAsyncValidator, convertFormLayoutToConfig, createCpfCnpjValidator, createDefaultFormConfig, createDefaultTableConfig, createEmptyFormConfig, createPersistedPage, customAsyncValidatorFn, customValidatorFn, debounceAsyncValidator, deepMerge, ensureIds, ensureNoConflictsHookFactory, ensurePageIds, fetchWithETag, fileTypeValidator, fillUndefined, generateId, getDefaultFormHints, getEssentialConfig, getReferencedFieldMetadata, getTextTransformer, isCssTextTransform, isTableConfigV2, isValidFormConfig, isValidTableConfig, legacyCnpjValidator, legacyCpfValidator, logOnErrorHook, mapFieldDefinitionToMetadata, mapFieldDefinitionsToMetadata, matchFieldValidator, maxFileSizeValidator, mergeFieldMetadata, mergeTableConfigs, minWordsValidator, normalizeFieldConstraints, normalizeFormConfig, normalizeFormMetadata, normalizePath, notifySuccessHook, prefillFromContextHook, provideDefaultFormHooks, provideFormHookPresets, provideFormHooks, provideGlobalConfig, provideGlobalConfigSeed, provideGlobalConfigTenant, provideHookResolvers, provideHookWhitelist, provideOverlayDecisionMatrix, provideRemoteGlobalConfig, reconcileFilterConfig, reconcileFormConfig, reconcileTableConfig, removeDiacritics, reportTelemetryHookFactory, requiredCheckedValidator, resolveHidden, resolveOffset, resolveOrder, resolveSpan, slugify, stripMasksHook, syncWithServerMetadata, toCamel, toCapitalize, toKebab, toPascal, toSentenceCase, toSnake, toTitleCase, trim, uniqueAsyncValidator, urlValidator, withMessage };
|
|
6798
7097
|
//# sourceMappingURL=praxisui-core.mjs.map
|