@praxisui/dynamic-form 10.0.0-rc.32 → 10.0.0-rc.34
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/ai/component-registry.json +590 -138
- package/fesm2022/praxisui-dynamic-form.mjs +854 -55
- package/package.json +8 -8
- package/types/praxisui-dynamic-form.d.ts +68 -2
|
@@ -20,10 +20,10 @@ import * as i9 from '@angular/material/snack-bar';
|
|
|
20
20
|
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
|
21
21
|
import * as i19 from '@angular/material/badge';
|
|
22
22
|
import { MatBadgeModule } from '@angular/material/badge';
|
|
23
|
-
import { map, Subscription, merge, of, timer, NEVER, EMPTY, defer, TimeoutError, Subject, firstValueFrom, BehaviorSubject, throwError, combineLatest, Observable, race, from, debounceTime as debounceTime$1, takeUntil as takeUntil$1 } from 'rxjs';
|
|
23
|
+
import { map, Subscription, merge, of, timer, NEVER, EMPTY, defer, TimeoutError, Subject, firstValueFrom, BehaviorSubject, throwError, combineLatest, Observable, race, from, debounceTime as debounceTime$1, takeUntil as takeUntil$1, defaultIfEmpty, switchMap as switchMap$1, catchError as catchError$1, take as take$1, finalize as finalize$1 } from 'rxjs';
|
|
24
24
|
import { filter, map as map$1, switchMap, take, timeout, throwIfEmpty, tap, catchError, ignoreElements, finalize, takeUntil, skip, debounceTime, startWith } from 'rxjs/operators';
|
|
25
25
|
import * as i1 from '@praxisui/core';
|
|
26
|
-
import { serializeEntityLookupValueForPayload, PraxisI18nService, PraxisIconButtonComponent, PraxisIconDirective, providePraxisI18nConfig, RULE_PROPERTY_SCHEMA, FIELD_METADATA_CAPABILITIES, migrateFormLayoutRule, PraxisJsonLogicService, normalizeFormLayoutItems, deepMerge, createDefaultFormConfig, normalizeFormConfig as normalizeFormConfig$1, ensureIds, createEmptyRichContentDocument, formIdentityIssues, resolveHidden, resolveOrder, resolveSpan, projectGroupedCommandPartialRows, isPraxisRuntimeGlobalActionEffect, ASYNC_CONFIG_STORAGE, withFormConfigSections, createFieldLayoutItem, getFormLayoutFieldNames, LoggerService, createCorporateLoggerConfig, ConsoleLoggerSink, ResourceDiscoveryService, GlobalActionService, SCHEMA_METADATA_CLIENT_OPTIONS, ResourceQuickConnectComponent, composeHeadersWithVersion, buildApiUrl, readStrongResourceEtag, ApiEndpoint, mapFieldDefinitionsToMetadata, reconcileFormConfig, applyLocalFormCustomizations, materializeFormLayoutFromMetadata, syncWithServerMetadata, PRAXIS_LOADING_CTX, evaluateFieldAccess, normalizeControlTypeKey, normalizePraxisEffectPolicy, buildPraxisEffectDistinctKey, getFormColumnFieldNames, resolveGroupedCommandPartialRowSpans, resolveOffset, buildSchemaIdStorageKeySegment, buildSchemaId, fetchWithETag, resolveControlTypeAlias, getTextTransformer, MemoryCacheAdapter, LocalStorageCacheAdapter, SchemaMetadataClient, DEFAULT_SCHEMA_REQUEST_TIMEOUT_MS, normalizeReactiveDeterminations, CONNECTION_STORAGE, API_URL, PRAXIS_LOADING_RENDERER, FORM_HOOKS_PRESETS, EmptyStateCardComponent, isValidFormConfig, ComponentMetadataRegistry, FieldControlType, isRequiredGlobalActionPayloadMissing, GLOBAL_ACTION_CATALOG, PRAXIS_GLOBAL_ACTION_CATALOG, getGlobalActionCatalog, SURFACE_OPEN_I18N_NAMESPACE, getGlobalActionUiSchema, getRequiredGlobalActionPayloadKeys, hasMeaningfulGlobalActionPayloadValue, SurfaceOpenActionEditorComponent, SURFACE_OPEN_I18N_CONFIG, IconPickerService, validateGlobalActionRefs, normalizeFormMetadata, DynamicFormService, projectComponentAuthoringManifest } from '@praxisui/core';
|
|
26
|
+
import { serializeEntityLookupValueForPayload, PraxisI18nService, PraxisIconButtonComponent, PraxisIconDirective, providePraxisI18nConfig, RULE_PROPERTY_SCHEMA, FIELD_METADATA_CAPABILITIES, migrateFormLayoutRule, PraxisJsonLogicService, normalizeFormLayoutItems, deepMerge, createDefaultFormConfig, normalizeFormConfig as normalizeFormConfig$1, ensureIds, createEmptyRichContentDocument, formIdentityIssues, resolveHidden, resolveOrder, resolveSpan, projectGroupedCommandPartialRows, isPraxisRuntimeGlobalActionEffect, ASYNC_CONFIG_STORAGE, withFormConfigSections, createFieldLayoutItem, getFormLayoutFieldNames, LoggerService, createCorporateLoggerConfig, ConsoleLoggerSink, ResourceDiscoveryService, GlobalActionService, SCHEMA_METADATA_CLIENT_OPTIONS, ResourceQuickConnectComponent, composeHeadersWithVersion, buildApiUrl, readStrongResourceEtag, ApiEndpoint, mapFieldDefinitionsToMetadata, reconcileFormConfig, applyLocalFormCustomizations, materializeFormLayoutFromMetadata, syncWithServerMetadata, PRAXIS_LOADING_CTX, evaluateFieldAccess, normalizeControlTypeKey, normalizePraxisEffectPolicy, buildPraxisEffectDistinctKey, getFormColumnFieldNames, resolveGroupedCommandPartialRowSpans, resolveOffset, buildSchemaIdStorageKeySegment, buildSchemaId, fetchWithETag, resolveControlTypeAlias, getTextTransformer, MemoryCacheAdapter, LocalStorageCacheAdapter, SchemaMetadataClient, DEFAULT_SCHEMA_REQUEST_TIMEOUT_MS, normalizeReactiveDeterminations, CONNECTION_STORAGE, API_URL, PRAXIS_LOADING_RENDERER, FORM_HOOKS_PRESETS, EmptyStateCardComponent, isValidFormConfig, ComponentMetadataRegistry, FieldControlType, isRequiredGlobalActionPayloadMissing, GLOBAL_ACTION_CATALOG, PRAXIS_GLOBAL_ACTION_CATALOG, getGlobalActionCatalog, SURFACE_OPEN_I18N_NAMESPACE, getGlobalActionUiSchema, getRequiredGlobalActionPayloadKeys, hasMeaningfulGlobalActionPayloadValue, SurfaceOpenActionEditorComponent, SURFACE_OPEN_I18N_CONFIG, IconPickerService, validateGlobalActionRefs, normalizeFormMetadata, GenericCrudService, DynamicFormService, projectComponentAuthoringManifest } from '@praxisui/core';
|
|
27
27
|
import * as i1$1 from '@praxisui/dynamic-fields';
|
|
28
28
|
import { getControlTypeCatalog, SelectOptionRegistry, ConfirmDialogComponent, DynamicFieldLoaderDirective } from '@praxisui/dynamic-fields';
|
|
29
29
|
import { BaseAiAdapter, AgenticAuthoringTurnClientService, PraxisAssistantSessionRegistryService, PraxisAssistantTurnOrchestratorService, createPraxisAssistantViewportLayout, PraxisAiAssistantShellComponent } from '@praxisui/ai';
|
|
@@ -12363,6 +12363,9 @@ class PraxisDynamicForm {
|
|
|
12363
12363
|
component: ResourceQuickConnectComponent,
|
|
12364
12364
|
inputs: {
|
|
12365
12365
|
resourcePath: this.resourcePath,
|
|
12366
|
+
intent: 'crud',
|
|
12367
|
+
endpointKey: this.apiEndpointKey ?? undefined,
|
|
12368
|
+
apiUrlEntry: this.apiUrlEntry ?? undefined,
|
|
12366
12369
|
},
|
|
12367
12370
|
},
|
|
12368
12371
|
});
|
|
@@ -13474,6 +13477,16 @@ class PraxisDynamicForm {
|
|
|
13474
13477
|
if (this.hasRenderableConfig(hostConfig)) {
|
|
13475
13478
|
await this.reconcileLoadedConfigWithServerSchema(false);
|
|
13476
13479
|
}
|
|
13480
|
+
else if (localConfig && this.hasRenderableConfig(localConfig)) {
|
|
13481
|
+
const hostTitle = hostConfig.title;
|
|
13482
|
+
this.config = normalizeFormConfig$1({
|
|
13483
|
+
...localConfig,
|
|
13484
|
+
...(hostTitle ? { title: hostTitle } : {}),
|
|
13485
|
+
...(hostConfig.actions ? { actions: hostConfig.actions } : {}),
|
|
13486
|
+
...(hostConfig.helpPresentation ? { helpPresentation: hostConfig.helpPresentation } : {}),
|
|
13487
|
+
});
|
|
13488
|
+
await this.reconcileLoadedConfigWithServerSchema();
|
|
13489
|
+
}
|
|
13477
13490
|
else {
|
|
13478
13491
|
await this.createDefaultConfig();
|
|
13479
13492
|
}
|
|
@@ -21340,34 +21353,125 @@ class PraxisDynamicForm {
|
|
|
21340
21353
|
? new MemoryCacheAdapter()
|
|
21341
21354
|
: new LocalStorageCacheAdapter({ ttlMs: 30 * 60 * 1000, maxEntries: 200 });
|
|
21342
21355
|
const client = new SchemaMetadataClient(adapter, this.schemaTransportOptions);
|
|
21343
|
-
|
|
21356
|
+
let discoveryAttempted = false;
|
|
21357
|
+
const loadDiscoverySchema = async (reason) => {
|
|
21358
|
+
discoveryAttempted = true;
|
|
21344
21359
|
if (this.isDestroyed)
|
|
21345
21360
|
throw new PraxisDynamicFormDestroyedError();
|
|
21346
|
-
|
|
21347
|
-
|
|
21348
|
-
|
|
21349
|
-
|
|
21350
|
-
|
|
21351
|
-
|
|
21361
|
+
const rp = String(this.resourcePath || '').trim();
|
|
21362
|
+
const discoveryOptions = {
|
|
21363
|
+
...(this.apiEndpointKey ? { endpointKey: this.apiEndpointKey } : {}),
|
|
21364
|
+
...(this.apiUrlEntry ? { apiUrlEntry: this.apiUrlEntry } : {}),
|
|
21365
|
+
};
|
|
21366
|
+
const canLoadViaDiscovery = !!rp &&
|
|
21367
|
+
typeof this.resourceDiscovery?.getResourceSchemaFields === 'function' &&
|
|
21368
|
+
(typeof this.resourceDiscovery.canResolveSchemas !== 'function' ||
|
|
21369
|
+
this.resourceDiscovery.canResolveSchemas(discoveryOptions));
|
|
21370
|
+
if (!canLoadViaDiscovery) {
|
|
21352
21371
|
throw reason instanceof Error
|
|
21353
21372
|
? reason
|
|
21354
21373
|
: new Error('Schema metadata unavailable and legacy crud.getSchema() not found.');
|
|
21355
21374
|
}
|
|
21356
|
-
const
|
|
21375
|
+
const inferredFilter = /(^|[-_])filter($|[-_])/i.test(this.formId || '');
|
|
21376
|
+
const useFilterSchema = this.schemaSource === 'filter' || inferredFilter;
|
|
21377
|
+
const hasDedicatedOptions = !!(discoveryOptions.endpointKey || discoveryOptions.apiUrlEntry);
|
|
21378
|
+
const discoveryCall$ = useFilterSchema && typeof this.resourceDiscovery.getResourceFilterSchemaFields === 'function'
|
|
21379
|
+
? (hasDedicatedOptions
|
|
21380
|
+
? this.resourceDiscovery.getResourceFilterSchemaFields(rp, discoveryOptions)
|
|
21381
|
+
: this.resourceDiscovery.getResourceFilterSchemaFields(rp))
|
|
21382
|
+
: (hasDedicatedOptions
|
|
21383
|
+
? this.resourceDiscovery.getResourceSchemaFields(rp, discoveryOptions)
|
|
21384
|
+
: this.resourceDiscovery.getResourceSchemaFields(rp));
|
|
21357
21385
|
controller.signal.throwIfAborted();
|
|
21358
21386
|
const cancelled$ = new Observable(subscriber => {
|
|
21359
21387
|
const abort = () => subscriber.error(controller.signal.reason ?? new DOMException('Schema read cancelled.', 'AbortError'));
|
|
21360
21388
|
controller.signal.addEventListener('abort', abort, { once: true });
|
|
21361
21389
|
return () => controller.signal.removeEventListener('abort', abort);
|
|
21362
21390
|
});
|
|
21363
|
-
let
|
|
21391
|
+
let discoveryRead$ = race(from(discoveryCall$), cancelled$).pipe(take(1));
|
|
21364
21392
|
const timeoutMs = this.schemaTransportOptions.requestTimeoutMs ?? DEFAULT_SCHEMA_REQUEST_TIMEOUT_MS;
|
|
21365
21393
|
if (timeoutMs > 0)
|
|
21366
|
-
|
|
21367
|
-
const
|
|
21394
|
+
discoveryRead$ = discoveryRead$.pipe(timeout(timeoutMs));
|
|
21395
|
+
const discoveryDefs = await firstValueFrom(discoveryRead$);
|
|
21396
|
+
controller.signal.throwIfAborted();
|
|
21397
|
+
if (this.isDestroyed)
|
|
21398
|
+
throw new PraxisDynamicFormDestroyedError();
|
|
21399
|
+
if (!Array.isArray(discoveryDefs) || discoveryDefs.length === 0) {
|
|
21400
|
+
throw reason instanceof Error
|
|
21401
|
+
? reason
|
|
21402
|
+
: new Error('Schema metadata unavailable via ResourceDiscoveryService.');
|
|
21403
|
+
}
|
|
21404
|
+
try {
|
|
21405
|
+
const schemaId = buildSchemaId(schemaContext);
|
|
21406
|
+
this.lastSchemaMeta = { schemaId, context: schemaContext };
|
|
21407
|
+
}
|
|
21408
|
+
catch { }
|
|
21409
|
+
this.schemaCache = discoveryDefs;
|
|
21410
|
+
this.emitLoadingState('schema', 'success', 'Schema carregado.');
|
|
21411
|
+
return discoveryDefs;
|
|
21412
|
+
};
|
|
21413
|
+
const loadLegacySchema = async (reason) => {
|
|
21414
|
+
if (this.isDestroyed)
|
|
21415
|
+
throw new PraxisDynamicFormDestroyedError();
|
|
21416
|
+
try {
|
|
21417
|
+
this.warnLog('[PDF] schema:metadata-fallback', reason);
|
|
21418
|
+
}
|
|
21419
|
+
catch { }
|
|
21420
|
+
const legacyGetSchema = this.crud?.getSchema;
|
|
21421
|
+
if (typeof legacyGetSchema !== 'function') {
|
|
21422
|
+
if (discoveryAttempted) {
|
|
21423
|
+
throw reason instanceof Error
|
|
21424
|
+
? reason
|
|
21425
|
+
: new Error('Schema metadata unavailable and legacy crud.getSchema() not found.');
|
|
21426
|
+
}
|
|
21427
|
+
return await loadDiscoverySchema(reason);
|
|
21428
|
+
}
|
|
21429
|
+
const isMockedLegacy = !!legacyGetSchema?.and;
|
|
21430
|
+
let legacyDefs;
|
|
21431
|
+
try {
|
|
21432
|
+
const legacyResult = legacyGetSchema.call(this.crud);
|
|
21433
|
+
controller.signal.throwIfAborted();
|
|
21434
|
+
const cancelled$ = new Observable(subscriber => {
|
|
21435
|
+
const abort = () => subscriber.error(controller.signal.reason ?? new DOMException('Schema read cancelled.', 'AbortError'));
|
|
21436
|
+
controller.signal.addEventListener('abort', abort, { once: true });
|
|
21437
|
+
return () => controller.signal.removeEventListener('abort', abort);
|
|
21438
|
+
});
|
|
21439
|
+
let legacyRead$ = race(from(legacyResult), cancelled$).pipe(take(1));
|
|
21440
|
+
const timeoutMs = this.schemaTransportOptions.requestTimeoutMs ?? DEFAULT_SCHEMA_REQUEST_TIMEOUT_MS;
|
|
21441
|
+
if (timeoutMs > 0)
|
|
21442
|
+
legacyRead$ = legacyRead$.pipe(timeout(timeoutMs));
|
|
21443
|
+
legacyDefs = await firstValueFrom(legacyRead$);
|
|
21444
|
+
}
|
|
21445
|
+
catch (legacyError) {
|
|
21446
|
+
if (this.isDestroyed || legacyError instanceof PraxisDynamicFormDestroyedError) {
|
|
21447
|
+
throw new PraxisDynamicFormDestroyedError();
|
|
21448
|
+
}
|
|
21449
|
+
if (this.isSchemaTransportInterruption(legacyError) ||
|
|
21450
|
+
controller.signal.aborted ||
|
|
21451
|
+
isMockedLegacy ||
|
|
21452
|
+
discoveryAttempted) {
|
|
21453
|
+
throw legacyError;
|
|
21454
|
+
}
|
|
21455
|
+
return await loadDiscoverySchema(legacyError);
|
|
21456
|
+
}
|
|
21368
21457
|
controller.signal.throwIfAborted();
|
|
21369
21458
|
if (this.isDestroyed)
|
|
21370
21459
|
throw new PraxisDynamicFormDestroyedError();
|
|
21460
|
+
if (!isMockedLegacy &&
|
|
21461
|
+
!discoveryAttempted &&
|
|
21462
|
+
(!Array.isArray(legacyDefs) || legacyDefs.length === 0)) {
|
|
21463
|
+
try {
|
|
21464
|
+
return await loadDiscoverySchema(reason);
|
|
21465
|
+
}
|
|
21466
|
+
catch (discoveryError) {
|
|
21467
|
+
if (this.isDestroyed || discoveryError instanceof PraxisDynamicFormDestroyedError) {
|
|
21468
|
+
throw new PraxisDynamicFormDestroyedError();
|
|
21469
|
+
}
|
|
21470
|
+
if (this.isSchemaTransportInterruption(discoveryError) || controller.signal.aborted) {
|
|
21471
|
+
throw discoveryError;
|
|
21472
|
+
}
|
|
21473
|
+
}
|
|
21474
|
+
}
|
|
21371
21475
|
try {
|
|
21372
21476
|
const schemaId = buildSchemaId(schemaContext);
|
|
21373
21477
|
this.lastSchemaMeta = { schemaId, context: schemaContext };
|
|
@@ -21384,6 +21488,14 @@ class PraxisDynamicForm {
|
|
|
21384
21488
|
if (preferLegacySchema) {
|
|
21385
21489
|
return await loadLegacySchema(new Error('Using legacy schema source (mocked crud.getSchema).'));
|
|
21386
21490
|
}
|
|
21491
|
+
const rp = String(this.resourcePath || '').trim();
|
|
21492
|
+
const isCatalogResourceKey = !!rp &&
|
|
21493
|
+
!String(this.schemaUrl || '').trim() &&
|
|
21494
|
+
!rp.includes('/') &&
|
|
21495
|
+
rp.includes('.');
|
|
21496
|
+
if (isCatalogResourceKey) {
|
|
21497
|
+
return await loadDiscoverySchema(new Error(`Resolving catalog resourceKey "${rp}" via ResourceDiscoveryService.`));
|
|
21498
|
+
}
|
|
21387
21499
|
if (!ctx.baseUrl) {
|
|
21388
21500
|
return await loadLegacySchema(new Error('Missing schema metadata base URL.'));
|
|
21389
21501
|
}
|
|
@@ -33487,6 +33599,14 @@ class PraxisFilterForm {
|
|
|
33487
33599
|
config;
|
|
33488
33600
|
formId;
|
|
33489
33601
|
resourcePath;
|
|
33602
|
+
/**
|
|
33603
|
+
* Optional logical endpoint key for multi-gateway filter schema resolution.
|
|
33604
|
+
*/
|
|
33605
|
+
endpointKey;
|
|
33606
|
+
/**
|
|
33607
|
+
* Optional explicit API URL entry override for filter schema resolution.
|
|
33608
|
+
*/
|
|
33609
|
+
apiUrlEntry;
|
|
33490
33610
|
mode;
|
|
33491
33611
|
formReady = new EventEmitter();
|
|
33492
33612
|
valueChange = new EventEmitter();
|
|
@@ -33497,26 +33617,153 @@ class PraxisFilterForm {
|
|
|
33497
33617
|
form = new FormGroup({});
|
|
33498
33618
|
valueChangesSub;
|
|
33499
33619
|
statusChangesSub;
|
|
33620
|
+
schemaSub;
|
|
33621
|
+
hydratedFieldMetadata = [];
|
|
33622
|
+
lastHydratedResourceKey = '';
|
|
33500
33623
|
columnFieldsCache = new WeakMap();
|
|
33501
33624
|
singleFieldCache = new WeakMap();
|
|
33625
|
+
crudService = (() => {
|
|
33626
|
+
try {
|
|
33627
|
+
return inject(GenericCrudService, { optional: true });
|
|
33628
|
+
}
|
|
33629
|
+
catch {
|
|
33630
|
+
return null;
|
|
33631
|
+
}
|
|
33632
|
+
})();
|
|
33633
|
+
resourceDiscovery = (() => {
|
|
33634
|
+
try {
|
|
33635
|
+
return inject(ResourceDiscoveryService, { optional: true });
|
|
33636
|
+
}
|
|
33637
|
+
catch {
|
|
33638
|
+
return null;
|
|
33639
|
+
}
|
|
33640
|
+
})();
|
|
33641
|
+
cdr = (() => {
|
|
33642
|
+
try {
|
|
33643
|
+
return inject(ChangeDetectorRef, { optional: true });
|
|
33644
|
+
}
|
|
33645
|
+
catch {
|
|
33646
|
+
return null;
|
|
33647
|
+
}
|
|
33648
|
+
})();
|
|
33502
33649
|
constructor(dynamicForm) {
|
|
33503
33650
|
this.dynamicForm = dynamicForm;
|
|
33504
33651
|
}
|
|
33505
33652
|
ngOnChanges(changes) {
|
|
33653
|
+
const hasConfiguredFields = Array.isArray(this.config?.fieldMetadata) && this.config.fieldMetadata.length > 0;
|
|
33654
|
+
if (hasConfiguredFields) {
|
|
33655
|
+
this.schemaSub?.unsubscribe();
|
|
33656
|
+
this.hydratedFieldMetadata = [];
|
|
33657
|
+
this.lastHydratedResourceKey = '';
|
|
33658
|
+
}
|
|
33506
33659
|
if ('config' in changes && this.config?.fieldMetadata) {
|
|
33507
33660
|
this.buildForm();
|
|
33508
33661
|
}
|
|
33662
|
+
if (!hasConfiguredFields &&
|
|
33663
|
+
('config' in changes ||
|
|
33664
|
+
'resourcePath' in changes ||
|
|
33665
|
+
'endpointKey' in changes ||
|
|
33666
|
+
'apiUrlEntry' in changes)) {
|
|
33667
|
+
this.loadFilterSchemaFieldsIfNeeded();
|
|
33668
|
+
}
|
|
33509
33669
|
}
|
|
33510
33670
|
ngOnDestroy() {
|
|
33671
|
+
this.schemaSub?.unsubscribe();
|
|
33511
33672
|
this.valueChangesSub?.unsubscribe();
|
|
33512
33673
|
this.statusChangesSub?.unsubscribe();
|
|
33513
33674
|
}
|
|
33675
|
+
loadFilterSchemaFieldsIfNeeded() {
|
|
33676
|
+
const rp = String(this.resourcePath ||
|
|
33677
|
+
(this.config?.resourcePath ?? '')).trim();
|
|
33678
|
+
if (!rp) {
|
|
33679
|
+
this.schemaSub?.unsubscribe();
|
|
33680
|
+
if (this.hydratedFieldMetadata.length > 0) {
|
|
33681
|
+
this.hydratedFieldMetadata = [];
|
|
33682
|
+
this.lastHydratedResourceKey = '';
|
|
33683
|
+
this.buildForm();
|
|
33684
|
+
}
|
|
33685
|
+
return;
|
|
33686
|
+
}
|
|
33687
|
+
const discoveryOptions = this.endpointKey || this.apiUrlEntry
|
|
33688
|
+
? {
|
|
33689
|
+
...(this.endpointKey ? { endpointKey: this.endpointKey } : {}),
|
|
33690
|
+
...(this.apiUrlEntry ? { apiUrlEntry: this.apiUrlEntry } : {}),
|
|
33691
|
+
}
|
|
33692
|
+
: undefined;
|
|
33693
|
+
const hydrationKey = JSON.stringify({
|
|
33694
|
+
rp,
|
|
33695
|
+
endpointKey: this.endpointKey ?? null,
|
|
33696
|
+
apiUrlEntry: this.apiUrlEntry ?? null,
|
|
33697
|
+
});
|
|
33698
|
+
if (this.lastHydratedResourceKey === hydrationKey && this.hydratedFieldMetadata.length > 0) {
|
|
33699
|
+
return;
|
|
33700
|
+
}
|
|
33701
|
+
const canLoadViaDiscovery = typeof this.resourceDiscovery?.getResourceFilterSchemaFields === 'function' &&
|
|
33702
|
+
(typeof this.resourceDiscovery.canResolveSchemas !== 'function' ||
|
|
33703
|
+
this.resourceDiscovery.canResolveSchemas(discoveryOptions));
|
|
33704
|
+
const canLoadViaCrud = typeof this.crudService?.getFilterSchema === 'function' ||
|
|
33705
|
+
typeof this.crudService?.getSchema === 'function';
|
|
33706
|
+
if (!canLoadViaCrud && !canLoadViaDiscovery) {
|
|
33707
|
+
return;
|
|
33708
|
+
}
|
|
33709
|
+
const loadFromDiscovery = () => discoveryOptions
|
|
33710
|
+
? this.resourceDiscovery.getResourceFilterSchemaFields(rp, discoveryOptions)
|
|
33711
|
+
: this.resourceDiscovery.getResourceFilterSchemaFields(rp);
|
|
33712
|
+
const loadFromCrud = () => {
|
|
33713
|
+
if (!canLoadViaCrud || !this.crudService) {
|
|
33714
|
+
return of([]);
|
|
33715
|
+
}
|
|
33716
|
+
if (discoveryOptions) {
|
|
33717
|
+
this.crudService.configure?.(rp, discoveryOptions);
|
|
33718
|
+
}
|
|
33719
|
+
else {
|
|
33720
|
+
this.crudService.configure?.(rp);
|
|
33721
|
+
}
|
|
33722
|
+
return typeof this.crudService.getFilterSchema === 'function'
|
|
33723
|
+
? this.crudService.getFilterSchema()
|
|
33724
|
+
: this.crudService.getSchema();
|
|
33725
|
+
};
|
|
33726
|
+
const isCatalogResourceKey = !rp.includes('/') && rp.includes('.');
|
|
33727
|
+
let source$;
|
|
33728
|
+
if (isCatalogResourceKey && canLoadViaDiscovery) {
|
|
33729
|
+
source$ = loadFromDiscovery().pipe(defaultIfEmpty([]), switchMap$1((defs) => Array.isArray(defs) && defs.length === 0 && canLoadViaCrud
|
|
33730
|
+
? loadFromCrud()
|
|
33731
|
+
: of(defs)), catchError$1(() => (canLoadViaCrud ? loadFromCrud() : of([]))));
|
|
33732
|
+
}
|
|
33733
|
+
else if (canLoadViaCrud) {
|
|
33734
|
+
source$ = loadFromCrud().pipe(defaultIfEmpty([]), switchMap$1((defs) => Array.isArray(defs) && defs.length === 0 && canLoadViaDiscovery
|
|
33735
|
+
? loadFromDiscovery()
|
|
33736
|
+
: of(defs)), catchError$1(() => (canLoadViaDiscovery ? loadFromDiscovery() : of([]))));
|
|
33737
|
+
}
|
|
33738
|
+
else {
|
|
33739
|
+
source$ = loadFromDiscovery();
|
|
33740
|
+
}
|
|
33741
|
+
this.schemaSub?.unsubscribe();
|
|
33742
|
+
this.schemaSub = source$
|
|
33743
|
+
.pipe(take$1(1), catchError$1(() => of([])))
|
|
33744
|
+
.subscribe((defs) => {
|
|
33745
|
+
if (!Array.isArray(defs) || defs.length === 0) {
|
|
33746
|
+
return;
|
|
33747
|
+
}
|
|
33748
|
+
if (Array.isArray(this.config?.fieldMetadata) && this.config.fieldMetadata.length > 0) {
|
|
33749
|
+
return;
|
|
33750
|
+
}
|
|
33751
|
+
const metadata = mapFieldDefinitionsToMetadata(defs);
|
|
33752
|
+
if (!metadata.length) {
|
|
33753
|
+
return;
|
|
33754
|
+
}
|
|
33755
|
+
this.hydratedFieldMetadata = metadata;
|
|
33756
|
+
this.lastHydratedResourceKey = hydrationKey;
|
|
33757
|
+
this.buildForm();
|
|
33758
|
+
this.cdr?.markForCheck();
|
|
33759
|
+
});
|
|
33760
|
+
}
|
|
33514
33761
|
buildForm() {
|
|
33515
33762
|
this.valueChangesSub?.unsubscribe();
|
|
33516
33763
|
this.statusChangesSub?.unsubscribe();
|
|
33517
33764
|
this.columnFieldsCache = new WeakMap();
|
|
33518
33765
|
this.singleFieldCache = new WeakMap();
|
|
33519
|
-
const fields = this.
|
|
33766
|
+
const fields = this.fieldMetadata;
|
|
33520
33767
|
const previous = this.form.getRawValue?.() || {};
|
|
33521
33768
|
this.form = this.dynamicForm.createFormGroupFromMetadata(fields);
|
|
33522
33769
|
// Preserve previous values only for fields that did not declare a new explicit seed.
|
|
@@ -33576,7 +33823,9 @@ class PraxisFilterForm {
|
|
|
33576
33823
|
return className || null;
|
|
33577
33824
|
}
|
|
33578
33825
|
get fieldMetadata() {
|
|
33579
|
-
return this.config?.fieldMetadata
|
|
33826
|
+
return this.config?.fieldMetadata?.length
|
|
33827
|
+
? this.config.fieldMetadata
|
|
33828
|
+
: this.hydratedFieldMetadata;
|
|
33580
33829
|
}
|
|
33581
33830
|
get hasLayout() {
|
|
33582
33831
|
return (Array.isArray(this.config?.sections) && this.config.sections.length > 0);
|
|
@@ -33592,7 +33841,7 @@ class PraxisFilterForm {
|
|
|
33592
33841
|
return `col-${i}-${col.fields.join(',')}`;
|
|
33593
33842
|
}
|
|
33594
33843
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisFilterForm, deps: [{ token: i1.DynamicFormService }], target: i0.ɵɵFactoryTarget.Component });
|
|
33595
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisFilterForm, isStandalone: true, selector: "praxis-filter-form", inputs: { config: "config", formId: "formId", resourcePath: "resourcePath", mode: "mode" }, outputs: { formReady: "formReady", valueChange: "valueChange", submit: "submit", requestSearch: "requestSearch", validityChange: "validityChange" }, usesOnChanges: true, ngImport: i0, template: "<form\n [formGroup]=\"form\"\n class=\"praxis-filter-form\"\n (change)=\"$event.stopPropagation()\"\n (ngSubmit)=\"onFormSubmit(); $event.preventDefault(); $event.stopPropagation()\"\n>\n @if (hasLayout) { @for (section of (config.sections || []); track section?.id ??\n $index) {\n <div class=\"filter-section\">\n @if (section.title) {\n <h3>{{ section.title }}</h3>\n } @for (row of section.rows; track $index) {\n <div class=\"filter-row\">\n @for ( column of row.columns; track (column?.fields?.join(',') ?? $index)\n ) {\n <div class=\"filter-column\" [ngClass]=\"getColumnClasses(column)\">\n <ng-container\n dynamicFieldLoader\n [fields]=\"getColumnFields(column)\"\n [formGroup]=\"form\"\n [enableExternalControlBinding]=\"true\"\n ></ng-container>\n </div>\n }\n </div>\n }\n </div>\n } } @else {\n <div class=\"filter-row\">\n @for (field of fieldMetadata; track field?.name ?? $index) {\n <div class=\"filter-column\">\n <ng-container\n dynamicFieldLoader\n [fields]=\"getSingleField(field)\"\n [formGroup]=\"form\"\n [enableExternalControlBinding]=\"true\"\n ></ng-container>\n </div>\n }\n </div>\n }\n <!-- Bot\u00E3o de submit invis\u00EDvel para garantir submit ao pressionar Enter -->\n <button\n type=\"submit\"\n class=\"hidden-submit\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n ></button>\n</form>\n", styles: [":host{display:block}.praxis-filter-form{padding-top:6px}.filter-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px 16px}.filter-column{min-width:0}.filter-column--full{grid-column:1/-1}.hidden-submit{display:none;width:0;height:0;padding:0;border:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: DynamicFieldLoaderDirective, selector: "[dynamicFieldLoader]", inputs: ["fields", "formGroup", "enableExternalControlBinding", "itemTemplate", "debugTrace", "debugTraceLabel", "readonlyMode", "disabledMode", "presentationMode", "visible", "canvasMode"], outputs: ["componentsCreated", "fieldCreated", "fieldDestroyed", "renderError", "canvasMouseEnter", "canvasMouseLeave", "canvasClick", "canvasFocus"] }] });
|
|
33844
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisFilterForm, isStandalone: true, selector: "praxis-filter-form", inputs: { config: "config", formId: "formId", resourcePath: "resourcePath", endpointKey: "endpointKey", apiUrlEntry: "apiUrlEntry", mode: "mode" }, outputs: { formReady: "formReady", valueChange: "valueChange", submit: "submit", requestSearch: "requestSearch", validityChange: "validityChange" }, usesOnChanges: true, ngImport: i0, template: "<form\n [formGroup]=\"form\"\n class=\"praxis-filter-form\"\n (change)=\"$event.stopPropagation()\"\n (ngSubmit)=\"onFormSubmit(); $event.preventDefault(); $event.stopPropagation()\"\n>\n @if (hasLayout) { @for (section of (config.sections || []); track section?.id ??\n $index) {\n <div class=\"filter-section\">\n @if (section.title) {\n <h3>{{ section.title }}</h3>\n } @for (row of section.rows; track $index) {\n <div class=\"filter-row\">\n @for ( column of row.columns; track (column?.fields?.join(',') ?? $index)\n ) {\n <div class=\"filter-column\" [ngClass]=\"getColumnClasses(column)\">\n <ng-container\n dynamicFieldLoader\n [fields]=\"getColumnFields(column)\"\n [formGroup]=\"form\"\n [enableExternalControlBinding]=\"true\"\n ></ng-container>\n </div>\n }\n </div>\n }\n </div>\n } } @else {\n <div class=\"filter-row\">\n @for (field of fieldMetadata; track field?.name ?? $index) {\n <div class=\"filter-column\">\n <ng-container\n dynamicFieldLoader\n [fields]=\"getSingleField(field)\"\n [formGroup]=\"form\"\n [enableExternalControlBinding]=\"true\"\n ></ng-container>\n </div>\n }\n </div>\n }\n <!-- Bot\u00E3o de submit invis\u00EDvel para garantir submit ao pressionar Enter -->\n <button\n type=\"submit\"\n class=\"hidden-submit\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n ></button>\n</form>\n", styles: [":host{display:block}.praxis-filter-form{padding-top:6px}.filter-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px 16px}.filter-column{min-width:0}.filter-column--full{grid-column:1/-1}.hidden-submit{display:none;width:0;height:0;padding:0;border:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: DynamicFieldLoaderDirective, selector: "[dynamicFieldLoader]", inputs: ["fields", "formGroup", "enableExternalControlBinding", "itemTemplate", "debugTrace", "debugTraceLabel", "readonlyMode", "disabledMode", "presentationMode", "visible", "canvasMode"], outputs: ["componentsCreated", "fieldCreated", "fieldDestroyed", "renderError", "canvasMouseEnter", "canvasMouseLeave", "canvasClick", "canvasFocus"] }] });
|
|
33596
33845
|
}
|
|
33597
33846
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisFilterForm, decorators: [{
|
|
33598
33847
|
type: Component,
|
|
@@ -33604,6 +33853,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
33604
33853
|
type: Input
|
|
33605
33854
|
}], resourcePath: [{
|
|
33606
33855
|
type: Input
|
|
33856
|
+
}], endpointKey: [{
|
|
33857
|
+
type: Input
|
|
33858
|
+
}], apiUrlEntry: [{
|
|
33859
|
+
type: Input
|
|
33607
33860
|
}], mode: [{
|
|
33608
33861
|
type: Input
|
|
33609
33862
|
}], formReady: [{
|
|
@@ -33709,7 +33962,19 @@ const PRAXIS_FILTER_FORM_COMPONENT_METADATA = {
|
|
|
33709
33962
|
name: 'resourcePath',
|
|
33710
33963
|
type: 'string',
|
|
33711
33964
|
label: 'Resource',
|
|
33712
|
-
description: 'Resource path used
|
|
33965
|
+
description: 'Resource path or catalog resourceKey used to resolve the filter schema.',
|
|
33966
|
+
},
|
|
33967
|
+
{
|
|
33968
|
+
name: 'endpointKey',
|
|
33969
|
+
type: 'ApiEndpoint',
|
|
33970
|
+
label: 'Endpoint Key',
|
|
33971
|
+
description: 'Canonical endpoint key used to resolve the filter schema in multi-endpoint hosts.',
|
|
33972
|
+
},
|
|
33973
|
+
{
|
|
33974
|
+
name: 'apiUrlEntry',
|
|
33975
|
+
type: 'ApiUrlEntry | null',
|
|
33976
|
+
label: 'API URL Entry',
|
|
33977
|
+
description: 'Explicit API URL entry for detached hosts that render the filter form outside the route injector.',
|
|
33713
33978
|
},
|
|
33714
33979
|
{
|
|
33715
33980
|
name: 'mode',
|
|
@@ -33767,18 +34032,90 @@ class PraxisFilterFormWidgetConfigEditor {
|
|
|
33767
34032
|
isDirty$ = new BehaviorSubject(false);
|
|
33768
34033
|
isValid$ = new BehaviorSubject(true);
|
|
33769
34034
|
isBusy$ = new BehaviorSubject(false);
|
|
34035
|
+
schemaWarning = '';
|
|
33770
34036
|
subscription = new Subscription();
|
|
34037
|
+
schemaSubscription;
|
|
34038
|
+
childBusy = false;
|
|
34039
|
+
schemaLoading = false;
|
|
34040
|
+
resourcePathDraft;
|
|
34041
|
+
committedBaselineDocument;
|
|
34042
|
+
crudService = (() => {
|
|
34043
|
+
try {
|
|
34044
|
+
return inject(GenericCrudService, { optional: true });
|
|
34045
|
+
}
|
|
34046
|
+
catch {
|
|
34047
|
+
return null;
|
|
34048
|
+
}
|
|
34049
|
+
})();
|
|
34050
|
+
resourceDiscovery = (() => {
|
|
34051
|
+
try {
|
|
34052
|
+
return inject(ResourceDiscoveryService, { optional: true });
|
|
34053
|
+
}
|
|
34054
|
+
catch {
|
|
34055
|
+
return null;
|
|
34056
|
+
}
|
|
34057
|
+
})();
|
|
34058
|
+
cdr = (() => {
|
|
34059
|
+
try {
|
|
34060
|
+
return inject(ChangeDetectorRef, { optional: true });
|
|
34061
|
+
}
|
|
34062
|
+
catch {
|
|
34063
|
+
return null;
|
|
34064
|
+
}
|
|
34065
|
+
})();
|
|
34066
|
+
get effectiveResourcePath() {
|
|
34067
|
+
if (this.resourcePathDraft !== undefined) {
|
|
34068
|
+
return this.resourcePathDraft;
|
|
34069
|
+
}
|
|
34070
|
+
return String(this.inputs?.resourcePath || '').trim();
|
|
34071
|
+
}
|
|
34072
|
+
get effectiveEndpointKey() {
|
|
34073
|
+
return this.buildDiscoveryOptions()?.endpointKey;
|
|
34074
|
+
}
|
|
34075
|
+
get effectiveApiUrlEntry() {
|
|
34076
|
+
return this.buildDiscoveryOptions()?.apiUrlEntry;
|
|
34077
|
+
}
|
|
34078
|
+
onResourceQuickConnect(resourcePath) {
|
|
34079
|
+
const normalized = String(resourcePath ?? '').trim();
|
|
34080
|
+
if (!normalized) {
|
|
34081
|
+
this.onResourceQuickClear();
|
|
34082
|
+
return;
|
|
34083
|
+
}
|
|
34084
|
+
this.resourcePathDraft = normalized;
|
|
34085
|
+
this.updateDirtyState(this.formEditor?.isDirty$?.value ?? false);
|
|
34086
|
+
if (this.formEditor) {
|
|
34087
|
+
const currentDoc = parseLegacyOrDynamicFormDocument(this.formEditor.getSettingsValue?.() ?? this.createDocumentFromInputs());
|
|
34088
|
+
this.loadFilterSchemaFieldsIfNeeded(normalized, currentDoc, true);
|
|
34089
|
+
}
|
|
34090
|
+
}
|
|
34091
|
+
onResourceQuickClear() {
|
|
34092
|
+
this.schemaSubscription?.unsubscribe();
|
|
34093
|
+
this.schemaLoading = false;
|
|
34094
|
+
this.publishBusy();
|
|
34095
|
+
this.resourcePathDraft = '';
|
|
34096
|
+
this.schemaWarning = '';
|
|
34097
|
+
this.updateDirtyState(this.formEditor?.isDirty$?.value ?? false);
|
|
34098
|
+
}
|
|
34099
|
+
updateDirtyState(editorDirty) {
|
|
34100
|
+
const baseline = String(this.inputs?.resourcePath || '').trim();
|
|
34101
|
+
const resourceChanged = this.resourcePathDraft !== undefined && this.resourcePathDraft !== baseline;
|
|
34102
|
+
this.isDirty$.next(editorDirty || resourceChanged);
|
|
34103
|
+
}
|
|
33771
34104
|
ngAfterViewInit() {
|
|
33772
34105
|
if (!this.formEditor) {
|
|
33773
34106
|
return;
|
|
33774
34107
|
}
|
|
33775
34108
|
this.formEditor.supportsPresentationSettings = false;
|
|
33776
|
-
this.
|
|
33777
|
-
this.subscription.add(this.formEditor.isDirty$.subscribe((value) => this.isDirty$.next(value)));
|
|
34109
|
+
this.subscription.add(this.formEditor.isDirty$.subscribe((value) => this.updateDirtyState(value)));
|
|
33778
34110
|
this.subscription.add(this.formEditor.isValid$.subscribe((value) => this.isValid$.next(value)));
|
|
33779
|
-
this.subscription.add(this.formEditor.isBusy$.subscribe((value) =>
|
|
34111
|
+
this.subscription.add(this.formEditor.isBusy$.subscribe((value) => {
|
|
34112
|
+
this.childBusy = value;
|
|
34113
|
+
this.publishBusy();
|
|
34114
|
+
}));
|
|
34115
|
+
this.initializeChildEditor();
|
|
33780
34116
|
}
|
|
33781
34117
|
ngOnDestroy() {
|
|
34118
|
+
this.schemaSubscription?.unsubscribe();
|
|
33782
34119
|
this.subscription.unsubscribe();
|
|
33783
34120
|
}
|
|
33784
34121
|
getSettingsValue() {
|
|
@@ -33788,27 +34125,165 @@ class PraxisFilterFormWidgetConfigEditor {
|
|
|
33788
34125
|
return this.buildValue(this.formEditor?.onSave?.() ?? this.formEditor?.getSettingsValue());
|
|
33789
34126
|
}
|
|
33790
34127
|
reset() {
|
|
33791
|
-
this.
|
|
34128
|
+
this.schemaSubscription?.unsubscribe();
|
|
34129
|
+
this.schemaLoading = false;
|
|
34130
|
+
this.schemaWarning = '';
|
|
34131
|
+
this.resourcePathDraft = undefined;
|
|
34132
|
+
this.publishBusy();
|
|
34133
|
+
if (typeof this.formEditor?.reset === 'function') {
|
|
34134
|
+
this.formEditor.reset();
|
|
34135
|
+
}
|
|
34136
|
+
else if (this.formEditor && this.committedBaselineDocument) {
|
|
34137
|
+
this.applyBaselineDocumentToChildEditor(structuredClone(this.committedBaselineDocument), 'filter-form-widget-config-reset');
|
|
34138
|
+
}
|
|
34139
|
+
this.updateDirtyState(this.formEditor?.isDirty$?.value ?? false);
|
|
34140
|
+
}
|
|
34141
|
+
publishBusy() {
|
|
34142
|
+
this.isBusy$.next(this.childBusy || this.schemaLoading);
|
|
33792
34143
|
}
|
|
33793
34144
|
initializeChildEditor() {
|
|
33794
34145
|
const document = this.createDocumentFromInputs();
|
|
34146
|
+
this.committedBaselineDocument = structuredClone(document);
|
|
34147
|
+
this.applyBaselineDocumentToChildEditor(document, 'filter-form-widget-config-init');
|
|
34148
|
+
const resourcePath = this.effectiveResourcePath;
|
|
34149
|
+
if (resourcePath &&
|
|
34150
|
+
(!Array.isArray(document.config.fieldMetadata) || document.config.fieldMetadata.length === 0)) {
|
|
34151
|
+
this.loadFilterSchemaFieldsIfNeeded(resourcePath, document);
|
|
34152
|
+
}
|
|
34153
|
+
}
|
|
34154
|
+
applyBaselineDocumentToChildEditor(document, reason) {
|
|
33795
34155
|
const serialized = serializeDynamicFormAuthoringDocument(document);
|
|
33796
34156
|
const editor = this.formEditor;
|
|
33797
34157
|
editor.onJsonConfigChange?.(serialized);
|
|
33798
34158
|
editor.initialDocument = document;
|
|
33799
34159
|
editor.initialConfig = document.config;
|
|
33800
|
-
editor.updateDirtyState?.(
|
|
34160
|
+
editor.updateDirtyState?.(reason);
|
|
33801
34161
|
editor.isDirty$?.next(false);
|
|
33802
34162
|
editor.isValid$?.next(true);
|
|
33803
34163
|
}
|
|
34164
|
+
applyDraftDocumentToChildEditor(document, reason) {
|
|
34165
|
+
const serialized = serializeDynamicFormAuthoringDocument(document);
|
|
34166
|
+
const editor = this.formEditor;
|
|
34167
|
+
editor.onJsonConfigChange?.(serialized);
|
|
34168
|
+
editor.updateDirtyState?.(reason);
|
|
34169
|
+
}
|
|
34170
|
+
loadFilterSchemaFieldsIfNeeded(resourcePath, baselineDocument, forceReload = false) {
|
|
34171
|
+
const discoveryOptions = this.buildDiscoveryOptions();
|
|
34172
|
+
const canLoadViaDiscovery = typeof this.resourceDiscovery?.getResourceFilterSchemaFields === 'function' &&
|
|
34173
|
+
(typeof this.resourceDiscovery.canResolveSchemas !== 'function' ||
|
|
34174
|
+
this.resourceDiscovery.canResolveSchemas(discoveryOptions));
|
|
34175
|
+
const canLoadViaCrud = typeof this.crudService?.getFilterSchema === 'function' ||
|
|
34176
|
+
typeof this.crudService?.getSchema === 'function';
|
|
34177
|
+
if (!canLoadViaCrud && !canLoadViaDiscovery) {
|
|
34178
|
+
return;
|
|
34179
|
+
}
|
|
34180
|
+
const loadFromDiscovery = () => discoveryOptions
|
|
34181
|
+
? this.resourceDiscovery.getResourceFilterSchemaFields(resourcePath, discoveryOptions)
|
|
34182
|
+
: this.resourceDiscovery.getResourceFilterSchemaFields(resourcePath);
|
|
34183
|
+
const loadFromCrud = () => {
|
|
34184
|
+
if (!canLoadViaCrud || !this.crudService) {
|
|
34185
|
+
return of([]);
|
|
34186
|
+
}
|
|
34187
|
+
if (discoveryOptions?.endpointKey || discoveryOptions?.apiUrlEntry) {
|
|
34188
|
+
this.crudService.configure?.(resourcePath, {
|
|
34189
|
+
...(discoveryOptions.endpointKey ? { endpointKey: discoveryOptions.endpointKey } : {}),
|
|
34190
|
+
...(discoveryOptions.apiUrlEntry ? { apiUrlEntry: discoveryOptions.apiUrlEntry } : {}),
|
|
34191
|
+
});
|
|
34192
|
+
}
|
|
34193
|
+
else {
|
|
34194
|
+
this.crudService.configure?.(resourcePath);
|
|
34195
|
+
}
|
|
34196
|
+
return typeof this.crudService.getFilterSchema === 'function'
|
|
34197
|
+
? this.crudService.getFilterSchema()
|
|
34198
|
+
: this.crudService.getSchema();
|
|
34199
|
+
};
|
|
34200
|
+
const isCatalogResourceKey = !resourcePath.includes('/') && resourcePath.includes('.');
|
|
34201
|
+
let source$;
|
|
34202
|
+
if (isCatalogResourceKey && canLoadViaDiscovery) {
|
|
34203
|
+
source$ = loadFromDiscovery().pipe(defaultIfEmpty([]), switchMap$1((defs) => Array.isArray(defs) && defs.length === 0 && canLoadViaCrud
|
|
34204
|
+
? loadFromCrud()
|
|
34205
|
+
: of(defs)), catchError$1(() => (canLoadViaCrud ? loadFromCrud() : of([]))));
|
|
34206
|
+
}
|
|
34207
|
+
else if (canLoadViaCrud) {
|
|
34208
|
+
source$ = loadFromCrud().pipe(defaultIfEmpty([]), switchMap$1((defs) => Array.isArray(defs) && defs.length === 0 && canLoadViaDiscovery
|
|
34209
|
+
? loadFromDiscovery()
|
|
34210
|
+
: of(defs)), catchError$1(() => (canLoadViaDiscovery ? loadFromDiscovery() : of([]))));
|
|
34211
|
+
}
|
|
34212
|
+
else {
|
|
34213
|
+
source$ = loadFromDiscovery();
|
|
34214
|
+
}
|
|
34215
|
+
this.schemaSubscription?.unsubscribe();
|
|
34216
|
+
this.schemaWarning = '';
|
|
34217
|
+
this.schemaLoading = true;
|
|
34218
|
+
this.publishBusy();
|
|
34219
|
+
this.schemaSubscription = source$
|
|
34220
|
+
.pipe(take$1(1), catchError$1(() => of([])), finalize$1(() => {
|
|
34221
|
+
this.schemaLoading = false;
|
|
34222
|
+
this.publishBusy();
|
|
34223
|
+
this.cdr?.markForCheck();
|
|
34224
|
+
}))
|
|
34225
|
+
.subscribe((defs) => {
|
|
34226
|
+
if (!Array.isArray(defs) || defs.length === 0) {
|
|
34227
|
+
this.schemaWarning = `No filter schema fields were returned for resource "${resourcePath}".`;
|
|
34228
|
+
this.cdr?.markForCheck();
|
|
34229
|
+
return;
|
|
34230
|
+
}
|
|
34231
|
+
if ((!forceReload && this.isDirty$.value) || !this.formEditor) {
|
|
34232
|
+
return;
|
|
34233
|
+
}
|
|
34234
|
+
const fieldMetadata = mapFieldDefinitionsToMetadata(defs);
|
|
34235
|
+
if (!fieldMetadata.length) {
|
|
34236
|
+
this.schemaWarning = `No filter schema fields were returned for resource "${resourcePath}".`;
|
|
34237
|
+
this.cdr?.markForCheck();
|
|
34238
|
+
return;
|
|
34239
|
+
}
|
|
34240
|
+
const newFieldNames = new Set(fieldMetadata.map((f) => f.name));
|
|
34241
|
+
const existingSectionFields = (baselineDocument.config.sections ?? []).flatMap((section) => (section.rows ?? []).flatMap((row) => (row.columns ?? []).flatMap((col) => (col.fields ?? []).map((f) => typeof f === 'string' ? f : f?.name ?? '')))).filter(Boolean);
|
|
34242
|
+
const shouldResetSections = forceReload &&
|
|
34243
|
+
existingSectionFields.length > 0 &&
|
|
34244
|
+
!existingSectionFields.some((fieldName) => newFieldNames.has(fieldName));
|
|
34245
|
+
const nextDocument = {
|
|
34246
|
+
...baselineDocument,
|
|
34247
|
+
config: {
|
|
34248
|
+
...baselineDocument.config,
|
|
34249
|
+
...(shouldResetSections ? { sections: [] } : {}),
|
|
34250
|
+
fieldMetadata,
|
|
34251
|
+
},
|
|
34252
|
+
};
|
|
34253
|
+
if (forceReload) {
|
|
34254
|
+
this.applyDraftDocumentToChildEditor(nextDocument, 'filter-form-widget-config-schema-reload');
|
|
34255
|
+
}
|
|
34256
|
+
else {
|
|
34257
|
+
this.committedBaselineDocument = structuredClone(nextDocument);
|
|
34258
|
+
this.applyBaselineDocumentToChildEditor(nextDocument, 'filter-form-widget-config-schema');
|
|
34259
|
+
}
|
|
34260
|
+
this.updateDirtyState(this.formEditor.isDirty$.value);
|
|
34261
|
+
this.cdr?.markForCheck();
|
|
34262
|
+
});
|
|
34263
|
+
}
|
|
34264
|
+
buildDiscoveryOptions() {
|
|
34265
|
+
const rawEndpointKey = this.inputs?.apiEndpointKey ?? this.inputs?.endpointKey;
|
|
34266
|
+
const endpointKey = String(rawEndpointKey ?? '').trim();
|
|
34267
|
+
const apiUrlEntry = this.inputs?.apiUrlEntry;
|
|
34268
|
+
if (!endpointKey && !apiUrlEntry) {
|
|
34269
|
+
return undefined;
|
|
34270
|
+
}
|
|
34271
|
+
return {
|
|
34272
|
+
...(endpointKey ? { endpointKey } : {}),
|
|
34273
|
+
...(apiUrlEntry ? { apiUrlEntry } : {}),
|
|
34274
|
+
};
|
|
34275
|
+
}
|
|
33804
34276
|
buildValue(rawDocument) {
|
|
33805
34277
|
const document = parseLegacyOrDynamicFormDocument(rawDocument ?? this.createDocumentFromInputs());
|
|
34278
|
+
const resolvedResourcePath = this.resourcePathDraft !== undefined
|
|
34279
|
+
? this.resourcePathDraft || undefined
|
|
34280
|
+
: this.inputs?.resourcePath;
|
|
33806
34281
|
return {
|
|
33807
34282
|
inputs: {
|
|
33808
34283
|
...(this.inputs ?? {}),
|
|
33809
34284
|
config: document.config,
|
|
33810
34285
|
formId: this.inputs?.formId ?? this.widgetKey,
|
|
33811
|
-
resourcePath:
|
|
34286
|
+
resourcePath: resolvedResourcePath,
|
|
33812
34287
|
mode: document.bindings?.mode ?? this.inputs?.mode ?? 'create',
|
|
33813
34288
|
},
|
|
33814
34289
|
};
|
|
@@ -33829,25 +34304,47 @@ class PraxisFilterFormWidgetConfigEditor {
|
|
|
33829
34304
|
: undefined;
|
|
33830
34305
|
}
|
|
33831
34306
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisFilterFormWidgetConfigEditor, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
33832
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
34307
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisFilterFormWidgetConfigEditor, isStandalone: true, selector: "praxis-filter-form-widget-config-editor", inputs: { inputs: "inputs", widgetKey: "widgetKey" }, providers: [{ provide: SETTINGS_PANEL_DATA, useValue: null }], viewQueries: [{ propertyName: "formEditor", first: true, predicate: ["formEditor"], descendants: true }], ngImport: i0, template: `
|
|
33833
34308
|
<section data-testid="filter-form-widget-config-editor">
|
|
34309
|
+
<div class="filter-form-resource-quick-connect" data-testid="filter-form-resource-quick-connect">
|
|
34310
|
+
<praxis-resource-quick-connect
|
|
34311
|
+
[resourcePath]="effectiveResourcePath"
|
|
34312
|
+
[endpointKey]="effectiveEndpointKey"
|
|
34313
|
+
[apiUrlEntry]="effectiveApiUrlEntry"
|
|
34314
|
+
intent="filter"
|
|
34315
|
+
(resourcePathChange)="onResourceQuickConnect($event)"
|
|
34316
|
+
></praxis-resource-quick-connect>
|
|
34317
|
+
</div>
|
|
34318
|
+
@if (schemaWarning) {
|
|
34319
|
+
<p class="filter-form-editor-schema-warning" data-testid="filter-form-schema-warning" role="status">
|
|
34320
|
+
{{ schemaWarning }}
|
|
34321
|
+
</p>
|
|
34322
|
+
}
|
|
33834
34323
|
<praxis-dynamic-form-config-editor #formEditor />
|
|
33835
34324
|
</section>
|
|
33836
|
-
`, isInline: true, dependencies: [{ kind: "component", type: PraxisDynamicFormConfigEditor, selector: "praxis-dynamic-form-config-editor" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
34325
|
+
`, isInline: true, styles: [".filter-form-resource-quick-connect{padding:var(--p-space-4, 16px) var(--p-space-4, 16px) var(--p-space-2, 8px)}.filter-form-editor-schema-warning{margin:0 16px 8px;color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-body-small)}\n"], dependencies: [{ kind: "component", type: PraxisDynamicFormConfigEditor, selector: "praxis-dynamic-form-config-editor" }, { kind: "component", type: ResourceQuickConnectComponent, selector: "praxis-resource-quick-connect", inputs: ["resourcePath", "endpointKey", "apiUrlEntry", "intent", "resources", "label", "placeholder", "hint", "disabled"], outputs: ["resourcePathChange", "resourceSelected"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
33837
34326
|
}
|
|
33838
34327
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisFilterFormWidgetConfigEditor, decorators: [{
|
|
33839
34328
|
type: Component,
|
|
33840
|
-
args: [{
|
|
33841
|
-
selector: 'praxis-filter-form-widget-config-editor',
|
|
33842
|
-
standalone: true,
|
|
33843
|
-
imports: [PraxisDynamicFormConfigEditor],
|
|
33844
|
-
template: `
|
|
34329
|
+
args: [{ providers: [{ provide: SETTINGS_PANEL_DATA, useValue: null }], selector: 'praxis-filter-form-widget-config-editor', standalone: true, imports: [PraxisDynamicFormConfigEditor, ResourceQuickConnectComponent], template: `
|
|
33845
34330
|
<section data-testid="filter-form-widget-config-editor">
|
|
34331
|
+
<div class="filter-form-resource-quick-connect" data-testid="filter-form-resource-quick-connect">
|
|
34332
|
+
<praxis-resource-quick-connect
|
|
34333
|
+
[resourcePath]="effectiveResourcePath"
|
|
34334
|
+
[endpointKey]="effectiveEndpointKey"
|
|
34335
|
+
[apiUrlEntry]="effectiveApiUrlEntry"
|
|
34336
|
+
intent="filter"
|
|
34337
|
+
(resourcePathChange)="onResourceQuickConnect($event)"
|
|
34338
|
+
></praxis-resource-quick-connect>
|
|
34339
|
+
</div>
|
|
34340
|
+
@if (schemaWarning) {
|
|
34341
|
+
<p class="filter-form-editor-schema-warning" data-testid="filter-form-schema-warning" role="status">
|
|
34342
|
+
{{ schemaWarning }}
|
|
34343
|
+
</p>
|
|
34344
|
+
}
|
|
33846
34345
|
<praxis-dynamic-form-config-editor #formEditor />
|
|
33847
34346
|
</section>
|
|
33848
|
-
`,
|
|
33849
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
33850
|
-
}]
|
|
34347
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".filter-form-resource-quick-connect{padding:var(--p-space-4, 16px) var(--p-space-4, 16px) var(--p-space-2, 8px)}.filter-form-editor-schema-warning{margin:0 16px 8px;color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-body-small)}\n"] }]
|
|
33851
34348
|
}], propDecorators: { inputs: [{
|
|
33852
34349
|
type: Input
|
|
33853
34350
|
}], widgetKey: [{
|
|
@@ -33863,40 +34360,99 @@ var praxisFilterFormWidgetConfigEditor = /*#__PURE__*/Object.freeze({
|
|
|
33863
34360
|
});
|
|
33864
34361
|
|
|
33865
34362
|
class PraxisDynamicFormWidgetConfigEditor {
|
|
34363
|
+
crudService = this.optionalInject(GenericCrudService);
|
|
34364
|
+
resourceDiscovery = this.optionalInject(ResourceDiscoveryService);
|
|
34365
|
+
cdr = this.optionalInject(ChangeDetectorRef);
|
|
33866
34366
|
inputs = null;
|
|
33867
34367
|
widgetKey;
|
|
33868
34368
|
appliedValues$;
|
|
33869
34369
|
appliedSource;
|
|
34370
|
+
appliedResourcePath;
|
|
33870
34371
|
/** Runtime evidence supplied by the existing component editor context resolver. */
|
|
33871
34372
|
context = {};
|
|
33872
34373
|
formEditor;
|
|
33873
34374
|
isDirty$ = new BehaviorSubject(false);
|
|
33874
34375
|
isValid$ = new BehaviorSubject(true);
|
|
33875
34376
|
isBusy$ = new BehaviorSubject(false);
|
|
34377
|
+
schemaWarning = '';
|
|
33876
34378
|
subscription = new Subscription();
|
|
34379
|
+
schemaSubscription;
|
|
34380
|
+
childBusy = false;
|
|
34381
|
+
schemaLoading = false;
|
|
33877
34382
|
initialEditorConfig;
|
|
34383
|
+
committedBaselineConfig;
|
|
34384
|
+
committedBaselineDocument;
|
|
33878
34385
|
sourceDraft;
|
|
34386
|
+
resourcePathDraft;
|
|
34387
|
+
optionalInject(token) {
|
|
34388
|
+
try {
|
|
34389
|
+
return inject(token, { optional: true });
|
|
34390
|
+
}
|
|
34391
|
+
catch {
|
|
34392
|
+
return null;
|
|
34393
|
+
}
|
|
34394
|
+
}
|
|
33879
34395
|
get configurationSource() {
|
|
33880
34396
|
return this.sourceDraft ?? this.inputs?.configPersistenceStrategy ?? 'local-first';
|
|
33881
34397
|
}
|
|
34398
|
+
get effectiveResourcePath() {
|
|
34399
|
+
if (this.resourcePathDraft !== undefined) {
|
|
34400
|
+
return this.resourcePathDraft;
|
|
34401
|
+
}
|
|
34402
|
+
return String(this.inputs?.resourcePath ?? this.context['resourcePath'] ?? '').trim();
|
|
34403
|
+
}
|
|
34404
|
+
get effectiveEndpointKey() {
|
|
34405
|
+
return this.buildDiscoveryOptions()?.endpointKey;
|
|
34406
|
+
}
|
|
34407
|
+
get effectiveApiUrlEntry() {
|
|
34408
|
+
return this.buildDiscoveryOptions()?.apiUrlEntry;
|
|
34409
|
+
}
|
|
34410
|
+
get effectiveDiscoveryIntent() {
|
|
34411
|
+
return (this.inputs?.schemaSource ?? this.context['schemaSource']) === 'filter'
|
|
34412
|
+
? 'filter'
|
|
34413
|
+
: 'crud';
|
|
34414
|
+
}
|
|
33882
34415
|
changeConfigurationSource(value) {
|
|
33883
34416
|
if (value !== 'local-first' && value !== 'input-first')
|
|
33884
34417
|
return;
|
|
33885
34418
|
this.sourceDraft = value;
|
|
33886
|
-
this.updateDirtyState(this.formEditor?.isDirty
|
|
33887
|
-
}
|
|
33888
|
-
updateDirtyState(editorDirty) {
|
|
33889
|
-
this.isDirty$.next(editorDirty || (this.sourceDraft !== undefined &&
|
|
33890
|
-
this.sourceDraft !== (this.appliedSource ?? this.inputs?.configPersistenceStrategy ?? 'local-first')));
|
|
34419
|
+
this.updateDirtyState(this.formEditor?.isDirty$?.value ?? false);
|
|
33891
34420
|
}
|
|
33892
|
-
|
|
33893
|
-
|
|
33894
|
-
|
|
34421
|
+
onResourceQuickConnect(resourcePath) {
|
|
34422
|
+
const normalized = String(resourcePath ?? '').trim();
|
|
34423
|
+
if (!normalized) {
|
|
34424
|
+
this.onResourceQuickClear();
|
|
34425
|
+
return;
|
|
33895
34426
|
}
|
|
33896
|
-
|
|
33897
|
-
|
|
34427
|
+
this.resourcePathDraft = normalized;
|
|
34428
|
+
this.updateDirtyState(this.formEditor?.isDirty$?.value ?? false);
|
|
34429
|
+
this.loadResourceSchemaFieldsIfNeeded(true);
|
|
34430
|
+
}
|
|
34431
|
+
onResourceQuickClear() {
|
|
34432
|
+
this.schemaSubscription?.unsubscribe();
|
|
34433
|
+
this.schemaLoading = false;
|
|
34434
|
+
this.publishBusy();
|
|
34435
|
+
this.resourcePathDraft = '';
|
|
34436
|
+
this.schemaWarning = '';
|
|
34437
|
+
this.updateDirtyState(this.formEditor?.isDirty$?.value ?? false);
|
|
34438
|
+
}
|
|
34439
|
+
baselineResourcePath() {
|
|
34440
|
+
if (this.appliedResourcePath !== undefined) {
|
|
34441
|
+
return this.appliedResourcePath;
|
|
33898
34442
|
}
|
|
33899
|
-
|
|
34443
|
+
return String(this.inputs?.resourcePath ?? this.context['resourcePath'] ?? '').trim();
|
|
34444
|
+
}
|
|
34445
|
+
updateDirtyState(editorDirty) {
|
|
34446
|
+
const sourceChanged = this.sourceDraft !== undefined &&
|
|
34447
|
+
this.sourceDraft !==
|
|
34448
|
+
(this.appliedSource ?? this.inputs?.configPersistenceStrategy ?? 'local-first');
|
|
34449
|
+
const resourceChanged = this.resourcePathDraft !== undefined &&
|
|
34450
|
+
this.resourcePathDraft !== this.baselineResourcePath();
|
|
34451
|
+
this.isDirty$.next(editorDirty || sourceChanged || resourceChanged);
|
|
34452
|
+
}
|
|
34453
|
+
publishBusy() {
|
|
34454
|
+
this.isBusy$.next(this.childBusy || this.schemaLoading);
|
|
34455
|
+
}
|
|
33900
34456
|
ngAfterViewInit() {
|
|
33901
34457
|
if (!this.formEditor) {
|
|
33902
34458
|
return;
|
|
@@ -33906,12 +34462,20 @@ class PraxisDynamicFormWidgetConfigEditor {
|
|
|
33906
34462
|
this.subscription.add(this.appliedValues$.subscribe(value => this.acceptAppliedValue(value)));
|
|
33907
34463
|
// Finish child template normalization before capturing the authoring baseline.
|
|
33908
34464
|
this.cdr?.detectChanges();
|
|
33909
|
-
|
|
34465
|
+
const initialDoc = parseLegacyOrDynamicFormDocument(this.formEditor.getSettingsValue?.() ?? this.createDocumentFromInputs());
|
|
34466
|
+
this.initialEditorConfig = structuredClone(initialDoc.config);
|
|
34467
|
+
this.committedBaselineConfig = structuredClone(initialDoc.config);
|
|
34468
|
+
this.committedBaselineDocument = structuredClone(initialDoc);
|
|
33910
34469
|
this.subscription.add(this.formEditor.isDirty$.subscribe((value) => this.updateDirtyState(value)));
|
|
33911
34470
|
this.subscription.add(this.formEditor.isValid$.subscribe((value) => this.isValid$.next(value)));
|
|
33912
|
-
this.subscription.add(this.formEditor.isBusy$.subscribe((value) =>
|
|
34471
|
+
this.subscription.add(this.formEditor.isBusy$.subscribe((value) => {
|
|
34472
|
+
this.childBusy = value;
|
|
34473
|
+
this.publishBusy();
|
|
34474
|
+
}));
|
|
34475
|
+
this.loadResourceSchemaFieldsIfNeeded();
|
|
33913
34476
|
}
|
|
33914
34477
|
ngOnDestroy() {
|
|
34478
|
+
this.schemaSubscription?.unsubscribe();
|
|
33915
34479
|
this.subscription.unsubscribe();
|
|
33916
34480
|
}
|
|
33917
34481
|
getSettingsValue() {
|
|
@@ -33925,25 +34489,209 @@ class PraxisDynamicFormWidgetConfigEditor {
|
|
|
33925
34489
|
return;
|
|
33926
34490
|
// The owner acknowledges the current draft only after committing its inputs.
|
|
33927
34491
|
this.appliedSource = this.configurationSource;
|
|
33928
|
-
|
|
33929
|
-
|
|
34492
|
+
if (this.resourcePathDraft !== undefined) {
|
|
34493
|
+
this.appliedResourcePath = this.resourcePathDraft;
|
|
34494
|
+
}
|
|
34495
|
+
const currentSettings = this.formEditor?.getSettingsValue();
|
|
34496
|
+
this.formEditor?.acceptAppliedValue(currentSettings);
|
|
34497
|
+
const committedDoc = parseLegacyOrDynamicFormDocument(currentSettings ?? this.createDocumentFromInputs());
|
|
34498
|
+
this.initialEditorConfig = structuredClone(committedDoc.config);
|
|
34499
|
+
this.committedBaselineConfig = structuredClone(committedDoc.config);
|
|
34500
|
+
this.committedBaselineDocument = structuredClone(committedDoc);
|
|
34501
|
+
this.updateDirtyState(this.formEditor?.isDirty$?.value ?? false);
|
|
33930
34502
|
}
|
|
33931
34503
|
reset() {
|
|
34504
|
+
this.schemaSubscription?.unsubscribe();
|
|
34505
|
+
this.schemaLoading = false;
|
|
34506
|
+
this.schemaWarning = '';
|
|
34507
|
+
this.publishBusy();
|
|
33932
34508
|
this.sourceDraft = undefined;
|
|
33933
|
-
this.
|
|
33934
|
-
|
|
34509
|
+
this.resourcePathDraft = undefined;
|
|
34510
|
+
if (typeof this.formEditor?.reset === 'function') {
|
|
34511
|
+
this.formEditor.reset();
|
|
34512
|
+
}
|
|
34513
|
+
else if (this.formEditor && this.committedBaselineDocument) {
|
|
34514
|
+
this.applyBaselineDocumentToChildEditor(structuredClone(this.committedBaselineDocument), 'widget-config-reset');
|
|
34515
|
+
}
|
|
34516
|
+
if (this.committedBaselineConfig) {
|
|
34517
|
+
this.initialEditorConfig = structuredClone(this.committedBaselineConfig);
|
|
34518
|
+
}
|
|
34519
|
+
this.updateDirtyState(this.formEditor?.isDirty$?.value ?? false);
|
|
34520
|
+
this.loadResourceSchemaFieldsIfNeeded();
|
|
33935
34521
|
}
|
|
33936
34522
|
initializeChildEditor() {
|
|
33937
34523
|
const document = this.createDocumentFromInputs();
|
|
34524
|
+
this.applyBaselineDocumentToChildEditor(document, 'widget-config-init');
|
|
34525
|
+
}
|
|
34526
|
+
applyBaselineDocumentToChildEditor(document, reason) {
|
|
33938
34527
|
const serialized = serializeDynamicFormAuthoringDocument(document);
|
|
33939
34528
|
const editor = this.formEditor;
|
|
33940
34529
|
editor.onJsonConfigChange?.(serialized);
|
|
33941
34530
|
editor.initialDocument = document;
|
|
33942
34531
|
editor.initialConfig = document.config;
|
|
33943
|
-
editor.updateDirtyState?.(
|
|
34532
|
+
editor.updateDirtyState?.(reason);
|
|
33944
34533
|
editor.isDirty$?.next(false);
|
|
33945
34534
|
editor.isValid$?.next(true);
|
|
33946
34535
|
}
|
|
34536
|
+
applyDraftDocumentToChildEditor(document, reason) {
|
|
34537
|
+
const serialized = serializeDynamicFormAuthoringDocument(document);
|
|
34538
|
+
const editor = this.formEditor;
|
|
34539
|
+
editor.onJsonConfigChange?.(serialized);
|
|
34540
|
+
editor.updateDirtyState?.(reason);
|
|
34541
|
+
}
|
|
34542
|
+
loadResourceSchemaFieldsIfNeeded(forceReload = false) {
|
|
34543
|
+
if (!this.formEditor) {
|
|
34544
|
+
return;
|
|
34545
|
+
}
|
|
34546
|
+
const resourcePath = this.effectiveResourcePath;
|
|
34547
|
+
const currentDoc = parseLegacyOrDynamicFormDocument(this.formEditor.getSettingsValue?.() ?? this.createDocumentFromInputs());
|
|
34548
|
+
if (!resourcePath ||
|
|
34549
|
+
(!forceReload &&
|
|
34550
|
+
Array.isArray(currentDoc.config.fieldMetadata) &&
|
|
34551
|
+
currentDoc.config.fieldMetadata.length > 0)) {
|
|
34552
|
+
return;
|
|
34553
|
+
}
|
|
34554
|
+
const isFilterSource = (this.inputs?.schemaSource ?? this.context['schemaSource']) === 'filter';
|
|
34555
|
+
const discoveryOptions = this.buildDiscoveryOptions();
|
|
34556
|
+
const discoveryMethodName = isFilterSource
|
|
34557
|
+
? 'getResourceFilterSchemaFields'
|
|
34558
|
+
: 'getResourceSchemaFields';
|
|
34559
|
+
const canLoadViaDiscovery = typeof this.resourceDiscovery?.[discoveryMethodName] === 'function' &&
|
|
34560
|
+
(typeof this.resourceDiscovery?.canResolveSchemas !== 'function' ||
|
|
34561
|
+
this.resourceDiscovery.canResolveSchemas(discoveryOptions));
|
|
34562
|
+
const canLoadViaCrud = isFilterSource
|
|
34563
|
+
? typeof this.crudService?.getFilterSchema === 'function' ||
|
|
34564
|
+
typeof this.crudService?.getSchema === 'function'
|
|
34565
|
+
: typeof this.crudService?.getSchema === 'function';
|
|
34566
|
+
if (!canLoadViaCrud && !canLoadViaDiscovery) {
|
|
34567
|
+
return;
|
|
34568
|
+
}
|
|
34569
|
+
const loadFromDiscovery = () => {
|
|
34570
|
+
if (isFilterSource) {
|
|
34571
|
+
return discoveryOptions
|
|
34572
|
+
? this.resourceDiscovery.getResourceFilterSchemaFields(resourcePath, discoveryOptions)
|
|
34573
|
+
: this.resourceDiscovery.getResourceFilterSchemaFields(resourcePath);
|
|
34574
|
+
}
|
|
34575
|
+
return discoveryOptions
|
|
34576
|
+
? this.resourceDiscovery.getResourceSchemaFields(resourcePath, discoveryOptions)
|
|
34577
|
+
: this.resourceDiscovery.getResourceSchemaFields(resourcePath);
|
|
34578
|
+
};
|
|
34579
|
+
const loadFromCrud = () => {
|
|
34580
|
+
if (!canLoadViaCrud || !this.crudService) {
|
|
34581
|
+
return of([]);
|
|
34582
|
+
}
|
|
34583
|
+
if (discoveryOptions?.endpointKey || discoveryOptions?.apiUrlEntry) {
|
|
34584
|
+
this.crudService.configure?.(resourcePath, {
|
|
34585
|
+
...(discoveryOptions.endpointKey ? { endpointKey: discoveryOptions.endpointKey } : {}),
|
|
34586
|
+
...(discoveryOptions.apiUrlEntry ? { apiUrlEntry: discoveryOptions.apiUrlEntry } : {}),
|
|
34587
|
+
});
|
|
34588
|
+
}
|
|
34589
|
+
else {
|
|
34590
|
+
this.crudService.configure?.(resourcePath);
|
|
34591
|
+
}
|
|
34592
|
+
if (isFilterSource && typeof this.crudService.getFilterSchema === 'function') {
|
|
34593
|
+
return this.crudService.getFilterSchema();
|
|
34594
|
+
}
|
|
34595
|
+
return this.crudService.getSchema();
|
|
34596
|
+
};
|
|
34597
|
+
const isCatalogResourceKey = !resourcePath.includes('/') && resourcePath.includes('.');
|
|
34598
|
+
let source$;
|
|
34599
|
+
if (isCatalogResourceKey && canLoadViaDiscovery) {
|
|
34600
|
+
source$ = loadFromDiscovery().pipe(defaultIfEmpty([]), switchMap$1((defs) => Array.isArray(defs) && defs.length === 0 && canLoadViaCrud
|
|
34601
|
+
? loadFromCrud()
|
|
34602
|
+
: of(defs)), catchError$1(() => canLoadViaCrud ? loadFromCrud() : of([])));
|
|
34603
|
+
}
|
|
34604
|
+
else if (canLoadViaCrud) {
|
|
34605
|
+
source$ = loadFromCrud().pipe(defaultIfEmpty([]), switchMap$1((defs) => Array.isArray(defs) && defs.length === 0 && canLoadViaDiscovery
|
|
34606
|
+
? loadFromDiscovery()
|
|
34607
|
+
: of(defs)), catchError$1(() => canLoadViaDiscovery ? loadFromDiscovery() : of([])));
|
|
34608
|
+
}
|
|
34609
|
+
else {
|
|
34610
|
+
source$ = loadFromDiscovery();
|
|
34611
|
+
}
|
|
34612
|
+
this.schemaSubscription?.unsubscribe();
|
|
34613
|
+
this.schemaWarning = '';
|
|
34614
|
+
this.schemaLoading = true;
|
|
34615
|
+
this.publishBusy();
|
|
34616
|
+
this.schemaSubscription = source$
|
|
34617
|
+
.pipe(take$1(1), catchError$1(() => of([])), finalize$1(() => {
|
|
34618
|
+
this.schemaLoading = false;
|
|
34619
|
+
this.publishBusy();
|
|
34620
|
+
this.cdr?.markForCheck();
|
|
34621
|
+
}))
|
|
34622
|
+
.subscribe((defs) => {
|
|
34623
|
+
if (!Array.isArray(defs) || defs.length === 0) {
|
|
34624
|
+
this.schemaWarning = `No schema fields were returned for resource "${resourcePath}".`;
|
|
34625
|
+
this.cdr?.markForCheck();
|
|
34626
|
+
return;
|
|
34627
|
+
}
|
|
34628
|
+
if ((!forceReload && this.isDirty$.value) || !this.formEditor) {
|
|
34629
|
+
return;
|
|
34630
|
+
}
|
|
34631
|
+
const fieldMetadata = mapFieldDefinitionsToMetadata(defs);
|
|
34632
|
+
if (!fieldMetadata.length) {
|
|
34633
|
+
this.schemaWarning = `No schema fields were returned for resource "${resourcePath}".`;
|
|
34634
|
+
this.cdr?.markForCheck();
|
|
34635
|
+
return;
|
|
34636
|
+
}
|
|
34637
|
+
const latestDoc = parseLegacyOrDynamicFormDocument(this.formEditor.getSettingsValue?.() ?? currentDoc);
|
|
34638
|
+
if (!forceReload &&
|
|
34639
|
+
Array.isArray(latestDoc.config.fieldMetadata) &&
|
|
34640
|
+
latestDoc.config.fieldMetadata.length > 0) {
|
|
34641
|
+
return;
|
|
34642
|
+
}
|
|
34643
|
+
const newFieldNames = new Set(fieldMetadata.map((f) => f.name));
|
|
34644
|
+
const existingSectionFields = (latestDoc.config.sections ?? []).flatMap((section) => (section.rows ?? []).flatMap((row) => (row.columns ?? []).flatMap((col) => (col.fields ?? []).map((f) => typeof f === 'string' ? f : f?.name ?? '')))).filter(Boolean);
|
|
34645
|
+
const shouldResetSections = forceReload &&
|
|
34646
|
+
existingSectionFields.length > 0 &&
|
|
34647
|
+
!existingSectionFields.some((fieldName) => newFieldNames.has(fieldName));
|
|
34648
|
+
const nextDocument = {
|
|
34649
|
+
...latestDoc,
|
|
34650
|
+
config: {
|
|
34651
|
+
...latestDoc.config,
|
|
34652
|
+
...(shouldResetSections ? { sections: [] } : {}),
|
|
34653
|
+
fieldMetadata,
|
|
34654
|
+
},
|
|
34655
|
+
};
|
|
34656
|
+
if (forceReload) {
|
|
34657
|
+
this.applyDraftDocumentToChildEditor(nextDocument, 'widget-config-schema-reload');
|
|
34658
|
+
this.cdr?.detectChanges();
|
|
34659
|
+
const hydratedConfig = structuredClone(parseLegacyOrDynamicFormDocument(this.formEditor.getSettingsValue?.() ?? nextDocument).config);
|
|
34660
|
+
this.initialEditorConfig = {
|
|
34661
|
+
...hydratedConfig,
|
|
34662
|
+
...(this.committedBaselineConfig?.sections
|
|
34663
|
+
? { sections: structuredClone(this.committedBaselineConfig.sections) }
|
|
34664
|
+
: {}),
|
|
34665
|
+
};
|
|
34666
|
+
}
|
|
34667
|
+
else {
|
|
34668
|
+
this.applyBaselineDocumentToChildEditor(nextDocument, 'widget-config-schema-hydrate');
|
|
34669
|
+
this.cdr?.detectChanges();
|
|
34670
|
+
const hydratedDoc = parseLegacyOrDynamicFormDocument(this.formEditor.getSettingsValue?.() ?? nextDocument);
|
|
34671
|
+
this.initialEditorConfig = structuredClone(hydratedDoc.config);
|
|
34672
|
+
this.committedBaselineConfig = structuredClone(hydratedDoc.config);
|
|
34673
|
+
this.committedBaselineDocument = structuredClone(hydratedDoc);
|
|
34674
|
+
}
|
|
34675
|
+
this.updateDirtyState(this.formEditor.isDirty$.value);
|
|
34676
|
+
this.cdr?.markForCheck();
|
|
34677
|
+
});
|
|
34678
|
+
}
|
|
34679
|
+
buildDiscoveryOptions() {
|
|
34680
|
+
const rawEndpointKey = this.inputs?.apiEndpointKey ??
|
|
34681
|
+
this.inputs?.endpointKey ??
|
|
34682
|
+
this.context['apiEndpointKey'] ??
|
|
34683
|
+
this.context['endpointKey'];
|
|
34684
|
+
const endpointKey = String(rawEndpointKey ?? '').trim();
|
|
34685
|
+
const apiUrlEntry = this.inputs?.apiUrlEntry ??
|
|
34686
|
+
this.context['apiUrlEntry'];
|
|
34687
|
+
if (!endpointKey && !apiUrlEntry) {
|
|
34688
|
+
return undefined;
|
|
34689
|
+
}
|
|
34690
|
+
return {
|
|
34691
|
+
...(endpointKey ? { endpointKey } : {}),
|
|
34692
|
+
...(apiUrlEntry ? { apiUrlEntry } : {}),
|
|
34693
|
+
};
|
|
34694
|
+
}
|
|
33947
34695
|
buildValue(rawDocument) {
|
|
33948
34696
|
const document = parseLegacyOrDynamicFormDocument(rawDocument ?? this.createDocumentFromInputs());
|
|
33949
34697
|
const schemaPrefs = document.contextSnapshot?.schemaPrefs;
|
|
@@ -33955,6 +34703,9 @@ class PraxisDynamicFormWidgetConfigEditor {
|
|
|
33955
34703
|
inputs: {
|
|
33956
34704
|
...(this.inputs ?? {}),
|
|
33957
34705
|
...(this.sourceDraft !== undefined ? { configPersistenceStrategy: this.sourceDraft } : {}),
|
|
34706
|
+
...(this.resourcePathDraft !== undefined
|
|
34707
|
+
? { resourcePath: this.resourcePathDraft || null }
|
|
34708
|
+
: {}),
|
|
33958
34709
|
// An explicit layout edit authors sections; merely inspecting generated layout does not.
|
|
33959
34710
|
...(layoutChanged && layoutPolicy?.source === 'schema'
|
|
33960
34711
|
? { layoutPolicy: { ...layoutPolicy, source: 'authored' } } : {}),
|
|
@@ -34002,7 +34753,7 @@ class PraxisDynamicFormWidgetConfigEditor {
|
|
|
34002
34753
|
});
|
|
34003
34754
|
}
|
|
34004
34755
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisDynamicFormWidgetConfigEditor, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
34005
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
34756
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisDynamicFormWidgetConfigEditor, isStandalone: true, selector: "praxis-dynamic-form-widget-config-editor", inputs: { inputs: "inputs", widgetKey: "widgetKey", appliedValues$: "appliedValues$", context: "context" }, providers: [{ provide: SETTINGS_PANEL_DATA, useValue: null }], viewQueries: [{ propertyName: "formEditor", first: true, predicate: ["formEditor"], descendants: true }], ngImport: i0, template: `
|
|
34006
34757
|
<section data-testid="dynamic-form-widget-config-editor">
|
|
34007
34758
|
<div class="configuration-source">
|
|
34008
34759
|
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
|
@@ -34014,14 +34765,33 @@ class PraxisDynamicFormWidgetConfigEditor {
|
|
|
34014
34765
|
<mat-hint>{{ formEditor.tx(configurationSource === 'input-first' ? 'config.general.configurationSource.pageHelp' : 'config.general.configurationSource.preferencesHelp') }}</mat-hint>
|
|
34015
34766
|
</mat-form-field>
|
|
34016
34767
|
</div>
|
|
34768
|
+
<div class="resource-quick-connect-host" data-testid="form-widget-resource-quick-connect">
|
|
34769
|
+
<praxis-resource-quick-connect
|
|
34770
|
+
[resourcePath]="effectiveResourcePath"
|
|
34771
|
+
[endpointKey]="effectiveEndpointKey"
|
|
34772
|
+
[apiUrlEntry]="effectiveApiUrlEntry"
|
|
34773
|
+
[intent]="effectiveDiscoveryIntent"
|
|
34774
|
+
(resourcePathChange)="onResourceQuickConnect($event)"
|
|
34775
|
+
></praxis-resource-quick-connect>
|
|
34776
|
+
</div>
|
|
34777
|
+
@if (schemaWarning) {
|
|
34778
|
+
<p class="form-widget-schema-warning" data-testid="form-widget-schema-warning" role="status">
|
|
34779
|
+
{{ schemaWarning }}
|
|
34780
|
+
</p>
|
|
34781
|
+
}
|
|
34017
34782
|
<praxis-dynamic-form-config-editor #formEditor />
|
|
34018
34783
|
<p class="widget-save-hint">{{ formEditor.tx('config.general.pageSaveHint') }}</p>
|
|
34019
34784
|
</section>
|
|
34020
|
-
`, isInline: true, styles: [".configuration-source{padding:var(--p-space-4, 16px)}.configuration-source mat-form-field{width:100%}.widget-save-hint{margin:12px 20px;color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-body-small)}\n"], dependencies: [{ kind: "component", type: PraxisDynamicFormConfigEditor, selector: "praxis-dynamic-form-config-editor" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.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: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
34785
|
+
`, isInline: true, styles: [".configuration-source{padding:var(--p-space-4, 16px)}.configuration-source mat-form-field{width:100%}.resource-quick-connect-host{padding:0 var(--p-space-4, 16px) var(--p-space-3, 12px)}.form-widget-schema-warning{margin:0 16px 8px;color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-body-small)}.widget-save-hint{margin:12px 20px;color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-body-small)}\n"], dependencies: [{ kind: "component", type: PraxisDynamicFormConfigEditor, selector: "praxis-dynamic-form-config-editor" }, { kind: "component", type: ResourceQuickConnectComponent, selector: "praxis-resource-quick-connect", inputs: ["resourcePath", "endpointKey", "apiUrlEntry", "intent", "resources", "label", "placeholder", "hint", "disabled"], outputs: ["resourcePathChange", "resourceSelected"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.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: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
34021
34786
|
}
|
|
34022
34787
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisDynamicFormWidgetConfigEditor, decorators: [{
|
|
34023
34788
|
type: Component,
|
|
34024
|
-
args: [{ providers: [{ provide: SETTINGS_PANEL_DATA, useValue: null }], selector: 'praxis-dynamic-form-widget-config-editor', standalone: true, imports: [
|
|
34789
|
+
args: [{ providers: [{ provide: SETTINGS_PANEL_DATA, useValue: null }], selector: 'praxis-dynamic-form-widget-config-editor', standalone: true, imports: [
|
|
34790
|
+
PraxisDynamicFormConfigEditor,
|
|
34791
|
+
ResourceQuickConnectComponent,
|
|
34792
|
+
MatFormFieldModule,
|
|
34793
|
+
MatSelectModule,
|
|
34794
|
+
], template: `
|
|
34025
34795
|
<section data-testid="dynamic-form-widget-config-editor">
|
|
34026
34796
|
<div class="configuration-source">
|
|
34027
34797
|
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
|
@@ -34033,10 +34803,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
34033
34803
|
<mat-hint>{{ formEditor.tx(configurationSource === 'input-first' ? 'config.general.configurationSource.pageHelp' : 'config.general.configurationSource.preferencesHelp') }}</mat-hint>
|
|
34034
34804
|
</mat-form-field>
|
|
34035
34805
|
</div>
|
|
34806
|
+
<div class="resource-quick-connect-host" data-testid="form-widget-resource-quick-connect">
|
|
34807
|
+
<praxis-resource-quick-connect
|
|
34808
|
+
[resourcePath]="effectiveResourcePath"
|
|
34809
|
+
[endpointKey]="effectiveEndpointKey"
|
|
34810
|
+
[apiUrlEntry]="effectiveApiUrlEntry"
|
|
34811
|
+
[intent]="effectiveDiscoveryIntent"
|
|
34812
|
+
(resourcePathChange)="onResourceQuickConnect($event)"
|
|
34813
|
+
></praxis-resource-quick-connect>
|
|
34814
|
+
</div>
|
|
34815
|
+
@if (schemaWarning) {
|
|
34816
|
+
<p class="form-widget-schema-warning" data-testid="form-widget-schema-warning" role="status">
|
|
34817
|
+
{{ schemaWarning }}
|
|
34818
|
+
</p>
|
|
34819
|
+
}
|
|
34036
34820
|
<praxis-dynamic-form-config-editor #formEditor />
|
|
34037
34821
|
<p class="widget-save-hint">{{ formEditor.tx('config.general.pageSaveHint') }}</p>
|
|
34038
34822
|
</section>
|
|
34039
|
-
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".configuration-source{padding:var(--p-space-4, 16px)}.configuration-source mat-form-field{width:100%}.widget-save-hint{margin:12px 20px;color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-body-small)}\n"] }]
|
|
34823
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".configuration-source{padding:var(--p-space-4, 16px)}.configuration-source mat-form-field{width:100%}.resource-quick-connect-host{padding:0 var(--p-space-4, 16px) var(--p-space-3, 12px)}.form-widget-schema-warning{margin:0 16px 8px;color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-body-small)}.widget-save-hint{margin:12px 20px;color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-body-small)}\n"] }]
|
|
34040
34824
|
}], propDecorators: { inputs: [{
|
|
34041
34825
|
type: Input
|
|
34042
34826
|
}], widgetKey: [{
|
|
@@ -34371,6 +35155,21 @@ const PRAXIS_DYNAMIC_FORM_COMPONENT_METADATA = {
|
|
|
34371
35155
|
context: {
|
|
34372
35156
|
effectiveConfig: materializedInputs?.['config'],
|
|
34373
35157
|
layoutPolicy: materializedInputs?.['layoutPolicy'],
|
|
35158
|
+
...(materializedInputs?.['resourcePath'] !== undefined
|
|
35159
|
+
? { resourcePath: materializedInputs['resourcePath'] }
|
|
35160
|
+
: {}),
|
|
35161
|
+
...(materializedInputs?.['apiEndpointKey'] !== undefined
|
|
35162
|
+
? { apiEndpointKey: materializedInputs['apiEndpointKey'] }
|
|
35163
|
+
: {}),
|
|
35164
|
+
...(materializedInputs?.['endpointKey'] !== undefined
|
|
35165
|
+
? { endpointKey: materializedInputs['endpointKey'] }
|
|
35166
|
+
: {}),
|
|
35167
|
+
...(materializedInputs?.['apiUrlEntry'] !== undefined
|
|
35168
|
+
? { apiUrlEntry: materializedInputs['apiUrlEntry'] }
|
|
35169
|
+
: {}),
|
|
35170
|
+
...(materializedInputs?.['schemaSource'] !== undefined
|
|
35171
|
+
? { schemaSource: materializedInputs['schemaSource'] }
|
|
35172
|
+
: {}),
|
|
34374
35173
|
},
|
|
34375
35174
|
}),
|
|
34376
35175
|
title: 'Configurar formulário',
|