@praxisui/crud 9.0.5-rc.9 → 9.0.6
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 +27 -3
- package/ai/component-registry.json +65 -12
- package/fesm2022/praxisui-crud.mjs +339 -64
- package/package.json +7 -7
- package/types/praxisui-crud-drawer-adapter.d.ts +32 -1
- package/types/praxisui-crud.d.ts +87 -6
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, InjectionToken, inject, input, signal, computed, effect, ChangeDetectionStrategy, Component, EventEmitter, DestroyRef, ChangeDetectorRef, Injector, ViewChild, Output, Input, Optional, Inject, ViewEncapsulation, ENVIRONMENT_INITIALIZER } from '@angular/core';
|
|
2
|
+
import { Injectable, InjectionToken, inject, input, signal, computed, effect, ChangeDetectionStrategy, Component, EventEmitter, output, DestroyRef, ChangeDetectorRef, Injector, ViewChild, Output, Input, Optional, Inject, ViewEncapsulation, ENVIRONMENT_INITIALIZER } from '@angular/core';
|
|
3
3
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
4
|
import { HttpClient } from '@angular/common/http';
|
|
5
5
|
import { Router, ActivatedRoute, RouterLink } from '@angular/router';
|
|
6
6
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
|
7
7
|
import { firstValueFrom, BehaviorSubject, Subscription } from 'rxjs';
|
|
8
8
|
import * as i2$1 from '@praxisui/core';
|
|
9
|
-
import { ASYNC_CONFIG_STORAGE, GlobalConfigService, CrudOperationResolutionService, LoggerService, SurfaceNavigationError, fillUndefined, SETTINGS_PANEL_DATA, PraxisI18nService, PraxisIconDirective, providePraxisI18nConfig, createDefaultTableConfig, EnterpriseRuntimeContextService, GLOBAL_SURFACE_SERVICE, SurfaceOutletRegistryService, ComponentKeyService, ResourceDiscoveryService, ResourceActionOpenAdapterService, ResourceSurfaceOpenAdapterService, normalizeSurfaceOperationContext, translateUnavailableWorkflowMessage, isSurfaceNavigationError, translateSurfaceNavigationRejected, EmptyStateCardComponent, RESOURCE_DISCOVERY_I18N_CONFIG, SURFACE_DRAWER_REF, SURFACE_DRAWER_CONTENT_DATA, PraxisIconButtonComponent, PraxisResourceIdentityComponent, GenericCrudService, ComponentMetadataRegistry } from '@praxisui/core';
|
|
9
|
+
import { ASYNC_CONFIG_STORAGE, GlobalConfigService, CrudOperationResolutionService, LoggerService, SurfaceNavigationError, fillUndefined, SETTINGS_PANEL_DATA, PraxisI18nService, PraxisIconDirective, providePraxisI18nConfig, createDefaultTableConfig, EnterpriseRuntimeContextService, GLOBAL_SURFACE_SERVICE, SurfaceOutletRegistryService, ComponentKeyService, ResourceDiscoveryService, ResourceActionOpenAdapterService, ResourceSurfaceOpenAdapterService, normalizeSurfaceOperationContext, translateUnavailableWorkflowMessage, isSurfaceNavigationError, translateSurfaceNavigationRejected, normalizeUnknownError, EmptyStateCardComponent, RESOURCE_DISCOVERY_I18N_CONFIG, SURFACE_DRAWER_REF, SURFACE_DRAWER_CONTENT_DATA, PraxisIconButtonComponent, PraxisResourceIdentityComponent, GenericCrudService, ComponentMetadataRegistry } from '@praxisui/core';
|
|
10
10
|
import { SettingsPanelService } from '@praxisui/settings-panel';
|
|
11
11
|
import { PraxisTableInlineAuthoringEditorComponent, PraxisTable } from '@praxisui/table';
|
|
12
12
|
import { ConfirmDialogComponent } from '@praxisui/dynamic-fields';
|
|
@@ -193,6 +193,12 @@ class CrudLauncherService {
|
|
|
193
193
|
presentation: mode === 'drawer' ? 'drawer' : 'modal',
|
|
194
194
|
resourceIdentity,
|
|
195
195
|
contextIdentity,
|
|
196
|
+
showResourceIdentityKey: runtime?.showResourceIdentityKey !== false,
|
|
197
|
+
reactiveDeterminationCallbacks: {
|
|
198
|
+
onEvent: drawerCallbacks?.onReactiveDetermination,
|
|
199
|
+
onPendingChange: drawerCallbacks?.onReactiveDeterminationPendingChange,
|
|
200
|
+
onStabilityChange: drawerCallbacks?.onReactiveDeterminationStabilityChange,
|
|
201
|
+
},
|
|
196
202
|
};
|
|
197
203
|
const modalCfg = { ...(merged.metadata.defaults?.modal || {}) };
|
|
198
204
|
const restoreFocus = resolveCrudRestoreFocus(modalCfg.restoreFocus, actionFocusOrigin);
|
|
@@ -240,9 +246,13 @@ class CrudLauncherService {
|
|
|
240
246
|
inputs,
|
|
241
247
|
resourceIdentity,
|
|
242
248
|
contextIdentity,
|
|
249
|
+
showResourceIdentityKey: runtime?.showResourceIdentityKey !== false,
|
|
243
250
|
restoreFocus,
|
|
244
251
|
onClose: drawerCallbacks?.onClose,
|
|
245
252
|
onResult: drawerCallbacks?.onResult,
|
|
253
|
+
onReactiveDetermination: drawerCallbacks?.onReactiveDetermination,
|
|
254
|
+
onReactiveDeterminationPendingChange: drawerCallbacks?.onReactiveDeterminationPendingChange,
|
|
255
|
+
onReactiveDeterminationStabilityChange: drawerCallbacks?.onReactiveDeterminationStabilityChange,
|
|
246
256
|
}));
|
|
247
257
|
return { mode };
|
|
248
258
|
}
|
|
@@ -760,6 +770,9 @@ function validateCrudAuthoringDocument(doc, context) {
|
|
|
760
770
|
if (!trimString(metadata.resource?.path) && !Array.isArray(metadata.data)) {
|
|
761
771
|
diagnostics.push(warnDiagnostic('crud.metadata.resource-or-data.missing', 'Provide metadata.resource.path or metadata.data so the CRUD can resolve its source', 'metadata.resource.path'));
|
|
762
772
|
}
|
|
773
|
+
if (trimString(metadata.resource?.path) && Array.isArray(metadata.data)) {
|
|
774
|
+
diagnostics.push(warnDiagnostic('crud.metadata.data.ignored-by-resource', 'metadata.data is ignored because metadata.resource.path activates remote table mode', 'metadata.data'));
|
|
775
|
+
}
|
|
763
776
|
if (context?.requireCanonicalActions) {
|
|
764
777
|
for (const actionName of CANONICAL_ACTIONS) {
|
|
765
778
|
if (!findCrudAction(metadata.actions, actionName)) {
|
|
@@ -1121,6 +1134,7 @@ const PRAXIS_CRUD_AUTHORING_I18N_CONFIG = {
|
|
|
1121
1134
|
'crud.authoring.section.connection': 'Conexão',
|
|
1122
1135
|
'crud.authoring.section.actions': 'Ações',
|
|
1123
1136
|
'crud.authoring.section.defaults': 'Abertura e cabeçalho',
|
|
1137
|
+
'crud.authoring.tab.defaults': 'Abertura',
|
|
1124
1138
|
'crud.authoring.section.table': 'Tabela',
|
|
1125
1139
|
'crud.authoring.section.json': 'JSON',
|
|
1126
1140
|
'crud.authoring.overview.connection': 'Conexão',
|
|
@@ -1131,6 +1145,9 @@ const PRAXIS_CRUD_AUTHORING_I18N_CONFIG = {
|
|
|
1131
1145
|
'crud.authoring.overview.connectionIdField': 'ID: {value}',
|
|
1132
1146
|
'crud.authoring.overview.connectionEndpoint': 'API: {value}',
|
|
1133
1147
|
'crud.authoring.overview.connectionDetailsPending': 'Identificador e endpoint ainda são opcionais aqui.',
|
|
1148
|
+
'crud.authoring.overview.sourceRemote': 'Fonte remota',
|
|
1149
|
+
'crud.authoring.overview.sourceRemoteLocalIgnored': 'Fonte remota · {count} registros locais ignorados',
|
|
1150
|
+
'crud.authoring.overview.sourceLocal': 'Fonte local · {count} registros',
|
|
1134
1151
|
'crud.authoring.overview.backVisible': 'Voltar visível',
|
|
1135
1152
|
'crud.authoring.overview.backHidden': 'Voltar oculto',
|
|
1136
1153
|
'crud.authoring.overview.modalDensity': 'Modal: {value}',
|
|
@@ -1181,6 +1198,7 @@ const PRAXIS_CRUD_AUTHORING_I18N_CONFIG = {
|
|
|
1181
1198
|
'crud.authoring.diagnostics.warnings': 'Alertas',
|
|
1182
1199
|
'crud.authoring.diagnostics.errorSummary': '{count} diagnósticos bloqueantes nesta seção.',
|
|
1183
1200
|
'crud.authoring.diagnostics.warningSummary': '{count} diagnósticos que valem revisão nesta seção.',
|
|
1201
|
+
'crud.authoring.diagnostics.warningSummarySingle': '1 diagnóstico que vale revisão nesta seção.',
|
|
1184
1202
|
'crud.authoring.connection.resourcePath': 'Recurso',
|
|
1185
1203
|
'crud.authoring.connection.resourcePath.placeholder': 'ex.: api/human-resources/cargos',
|
|
1186
1204
|
'crud.authoring.connection.idField': 'Campo identificador',
|
|
@@ -1304,6 +1322,7 @@ const PRAXIS_CRUD_AUTHORING_I18N_CONFIG = {
|
|
|
1304
1322
|
'crud.authoring.action.create': 'Criar',
|
|
1305
1323
|
'crud.authoring.action.view': 'Visualizar',
|
|
1306
1324
|
'crud.authoring.action.edit': 'Editar',
|
|
1325
|
+
'crud.authoring.action.delete': 'Excluir',
|
|
1307
1326
|
'crud.authoring.table.summary': 'A configuração detalhada da tabela continua sendo tratada pela superfície canônica de TableConfig. Nesta fase, o editor de CRUD preserva o snapshot atual da tabela sem duplicar o editor completo.',
|
|
1308
1327
|
'crud.authoring.json.hint': 'O JSON abaixo representa o documento canônico de authoring do CRUD.',
|
|
1309
1328
|
'crud.authoring.table.structureSummary': '{count} colunas | {density}',
|
|
@@ -1323,6 +1342,13 @@ const PRAXIS_CRUD_AUTHORING_I18N_CONFIG = {
|
|
|
1323
1342
|
'crud.authoring.json.summaryWarnings': 'O documento canônico possui diagnósticos que valem revisão.',
|
|
1324
1343
|
'crud.authoring.json.summaryClean': 'O documento canônico está estruturalmente consistente.',
|
|
1325
1344
|
'crud.authoring.validation.routeRequired': 'Informe uma rota quando o modo efetivo for route.',
|
|
1345
|
+
'crud.authoring.validation.componentInvalid': 'O componente deve ser praxis-crud.',
|
|
1346
|
+
'crud.authoring.validation.tableRequired': 'Informe a configuração canônica da tabela.',
|
|
1347
|
+
'crud.authoring.validation.resourcePathRequired': 'Informe o caminho do recurso configurado.',
|
|
1348
|
+
'crud.authoring.validation.sourceMissing': 'Informe um recurso remoto ou dados locais para o CRUD.',
|
|
1349
|
+
'crud.authoring.validation.dataIgnoredByResource': 'Os registros locais são ignorados porque o recurso remoto está ativo.',
|
|
1350
|
+
'crud.authoring.validation.openModeInvalid': 'Use route, modal ou drawer como modo de abertura.',
|
|
1351
|
+
'crud.authoring.validation.canonicalActionMissing': 'A ação CRUD canônica “{action}” ainda não foi declarada.',
|
|
1326
1352
|
'crud.authoring.validation.formIdRequired': 'Informe um formId quando o modo efetivo for modal ou drawer.',
|
|
1327
1353
|
'crud.authoring.validation.submitContract': 'submitUrl e submitMethod devem ser informados juntos.',
|
|
1328
1354
|
'crud.authoring.overview.actionsNextCompact': 'Próxima: {action}. {summary}',
|
|
@@ -1341,6 +1367,7 @@ const PRAXIS_CRUD_AUTHORING_I18N_CONFIG = {
|
|
|
1341
1367
|
'crud.authoring.section.connection': 'Connection',
|
|
1342
1368
|
'crud.authoring.section.actions': 'Actions',
|
|
1343
1369
|
'crud.authoring.section.defaults': 'Open mode and header',
|
|
1370
|
+
'crud.authoring.tab.defaults': 'Opening',
|
|
1344
1371
|
'crud.authoring.section.table': 'Table',
|
|
1345
1372
|
'crud.authoring.section.json': 'JSON',
|
|
1346
1373
|
'crud.authoring.overview.connection': 'Connection',
|
|
@@ -1351,6 +1378,9 @@ const PRAXIS_CRUD_AUTHORING_I18N_CONFIG = {
|
|
|
1351
1378
|
'crud.authoring.overview.connectionIdField': 'ID: {value}',
|
|
1352
1379
|
'crud.authoring.overview.connectionEndpoint': 'API: {value}',
|
|
1353
1380
|
'crud.authoring.overview.connectionDetailsPending': 'Identifier and endpoint details are still optional here.',
|
|
1381
|
+
'crud.authoring.overview.sourceRemote': 'Remote source',
|
|
1382
|
+
'crud.authoring.overview.sourceRemoteLocalIgnored': 'Remote source · {count} local rows ignored',
|
|
1383
|
+
'crud.authoring.overview.sourceLocal': 'Local source · {count} rows',
|
|
1354
1384
|
'crud.authoring.overview.backVisible': 'Back visible',
|
|
1355
1385
|
'crud.authoring.overview.backHidden': 'Back hidden',
|
|
1356
1386
|
'crud.authoring.overview.modalDensity': 'Modal: {value}',
|
|
@@ -1401,6 +1431,7 @@ const PRAXIS_CRUD_AUTHORING_I18N_CONFIG = {
|
|
|
1401
1431
|
'crud.authoring.diagnostics.warnings': 'Warnings',
|
|
1402
1432
|
'crud.authoring.diagnostics.errorSummary': '{count} blocking diagnostics in this section.',
|
|
1403
1433
|
'crud.authoring.diagnostics.warningSummary': '{count} diagnostics worth reviewing in this section.',
|
|
1434
|
+
'crud.authoring.diagnostics.warningSummarySingle': '1 diagnostic worth reviewing in this section.',
|
|
1404
1435
|
'crud.authoring.connection.resourcePath': 'Resource',
|
|
1405
1436
|
'crud.authoring.connection.resourcePath.placeholder': 'e.g. api/human-resources/cargos',
|
|
1406
1437
|
'crud.authoring.connection.idField': 'Identifier field',
|
|
@@ -1524,6 +1555,7 @@ const PRAXIS_CRUD_AUTHORING_I18N_CONFIG = {
|
|
|
1524
1555
|
'crud.authoring.action.create': 'Create',
|
|
1525
1556
|
'crud.authoring.action.view': 'View',
|
|
1526
1557
|
'crud.authoring.action.edit': 'Edit',
|
|
1558
|
+
'crud.authoring.action.delete': 'Delete',
|
|
1527
1559
|
'crud.authoring.table.summary': 'Detailed table configuration remains owned by the canonical TableConfig surface. In this phase, the CRUD editor preserves the current table snapshot without duplicating the full table editor.',
|
|
1528
1560
|
'crud.authoring.table.structureSummary': '{count} columns | {density}',
|
|
1529
1561
|
'crud.authoring.table.paginationSummary': 'Page size {value}',
|
|
@@ -1543,6 +1575,13 @@ const PRAXIS_CRUD_AUTHORING_I18N_CONFIG = {
|
|
|
1543
1575
|
'crud.authoring.json.summaryWarnings': 'The canonical document has diagnostics worth reviewing.',
|
|
1544
1576
|
'crud.authoring.json.summaryClean': 'The canonical document is structurally consistent.',
|
|
1545
1577
|
'crud.authoring.validation.routeRequired': 'Provide a route when the effective mode is route.',
|
|
1578
|
+
'crud.authoring.validation.componentInvalid': 'The component must be praxis-crud.',
|
|
1579
|
+
'crud.authoring.validation.tableRequired': 'Provide the canonical table configuration.',
|
|
1580
|
+
'crud.authoring.validation.resourcePathRequired': 'Provide the configured resource path.',
|
|
1581
|
+
'crud.authoring.validation.sourceMissing': 'Provide a remote resource or local data for the CRUD.',
|
|
1582
|
+
'crud.authoring.validation.dataIgnoredByResource': 'Local rows are ignored because the remote resource is active.',
|
|
1583
|
+
'crud.authoring.validation.openModeInvalid': 'Use route, modal, or drawer as the open mode.',
|
|
1584
|
+
'crud.authoring.validation.canonicalActionMissing': 'Canonical CRUD action “{action}” is not declared yet.',
|
|
1546
1585
|
'crud.authoring.validation.formIdRequired': 'Provide a formId when the effective mode is modal or drawer.',
|
|
1547
1586
|
'crud.authoring.validation.submitContract': 'submitUrl and submitMethod must be provided together.',
|
|
1548
1587
|
'crud.authoring.overview.actionsNextCompact': 'Next: {action}. {summary}',
|
|
@@ -1701,6 +1740,10 @@ class CrudMetadataEditorComponent {
|
|
|
1701
1740
|
actionLabel(actionName) {
|
|
1702
1741
|
return this.tx(`crud.authoring.action.${actionName}`, actionName);
|
|
1703
1742
|
}
|
|
1743
|
+
actionUsesRoute(actionName) {
|
|
1744
|
+
const action = this.actionValue(actionName);
|
|
1745
|
+
return (action.openMode || this.defaultsOpenMode()) === 'route';
|
|
1746
|
+
}
|
|
1704
1747
|
actionSummary(actionName) {
|
|
1705
1748
|
const action = this.actionValue(actionName);
|
|
1706
1749
|
const mode = (action.openMode || this.defaultsOpenMode());
|
|
@@ -1799,7 +1842,8 @@ class CrudMetadataEditorComponent {
|
|
|
1799
1842
|
const apiStatus = this.actionGroupStatus(actionName, 'api');
|
|
1800
1843
|
const inputsSummary = this.actionInputsSummaryBadge(actionName);
|
|
1801
1844
|
if (submitStatus === 'ready' && apiStatus === 'ready') {
|
|
1802
|
-
|
|
1845
|
+
const summary = this.tx('crud.authoring.action.advancedReady', 'Advanced ready');
|
|
1846
|
+
return inputsSummary ? `${summary} · ${inputsSummary}` : summary;
|
|
1803
1847
|
}
|
|
1804
1848
|
const pending = [];
|
|
1805
1849
|
if (submitStatus !== 'ready') {
|
|
@@ -1907,20 +1951,16 @@ class CrudMetadataEditorComponent {
|
|
|
1907
1951
|
return hasBinding ? 'ready' : 'pending';
|
|
1908
1952
|
}
|
|
1909
1953
|
if (group === 'schema') {
|
|
1910
|
-
return
|
|
1954
|
+
return 'ready';
|
|
1911
1955
|
}
|
|
1912
1956
|
if (group === 'submit') {
|
|
1913
1957
|
const hasSubmitError = actionDiagnostics.some((issue) => issue.code === 'crud.metadata.actions.form.submit-contract.invalid');
|
|
1914
1958
|
if (hasSubmitError) {
|
|
1915
1959
|
return 'invalid';
|
|
1916
1960
|
}
|
|
1917
|
-
|
|
1918
|
-
&& !!String(action.form?.submitMethod || '').trim();
|
|
1919
|
-
return hasSubmitPair ? 'ready' : 'pending';
|
|
1961
|
+
return 'ready';
|
|
1920
1962
|
}
|
|
1921
|
-
|
|
1922
|
-
const hasApiEntry = !!String(this.actionApiUrlEntryDraft(actionName) || '').trim();
|
|
1923
|
-
return hasApiEndpoint || hasApiEntry ? 'ready' : 'pending';
|
|
1963
|
+
return 'ready';
|
|
1924
1964
|
}
|
|
1925
1965
|
actionGroupStatusLabel(actionName, group) {
|
|
1926
1966
|
return {
|
|
@@ -1980,13 +2020,7 @@ class CrudMetadataEditorComponent {
|
|
|
1980
2020
|
const hasBinding = effectiveMode === 'route'
|
|
1981
2021
|
? !!String(action.route || '').trim()
|
|
1982
2022
|
: !!String(action.formId || '').trim();
|
|
1983
|
-
|
|
1984
|
-
&& !!String(action.form?.submitMethod || '').trim();
|
|
1985
|
-
const hasSchema = !!String(action.form?.schemaUrl || '').trim();
|
|
1986
|
-
if (hasBinding && (hasSubmitPair || hasSchema)) {
|
|
1987
|
-
return 'ready';
|
|
1988
|
-
}
|
|
1989
|
-
return 'pending';
|
|
2023
|
+
return hasBinding ? 'ready' : 'pending';
|
|
1990
2024
|
}
|
|
1991
2025
|
actionStatusLabel(actionName) {
|
|
1992
2026
|
return {
|
|
@@ -2015,6 +2049,16 @@ class CrudMetadataEditorComponent {
|
|
|
2015
2049
|
if (endpointKey) {
|
|
2016
2050
|
parts.push(this.tx('crud.authoring.overview.connectionEndpoint', 'API: {value}').replace('{value}', endpointKey));
|
|
2017
2051
|
}
|
|
2052
|
+
const localRows = this.currentDocument().metadata.data;
|
|
2053
|
+
if (this.resourcePath().trim()) {
|
|
2054
|
+
parts.push(Array.isArray(localRows)
|
|
2055
|
+
? this.tx('crud.authoring.overview.sourceRemoteLocalIgnored', 'Fonte remota · {count} registros locais ignorados').replace('{count}', String(localRows.length))
|
|
2056
|
+
: this.tx('crud.authoring.overview.sourceRemote', 'Fonte remota'));
|
|
2057
|
+
}
|
|
2058
|
+
else if (Array.isArray(localRows)) {
|
|
2059
|
+
parts.push(this.tx('crud.authoring.overview.sourceLocal', 'Fonte local · {count} registros')
|
|
2060
|
+
.replace('{count}', String(localRows.length)));
|
|
2061
|
+
}
|
|
2018
2062
|
if (!parts.length) {
|
|
2019
2063
|
return this.tx('crud.authoring.overview.connectionDetailsPending', 'Identifier and endpoint details are still optional here.');
|
|
2020
2064
|
}
|
|
@@ -2210,9 +2254,13 @@ class CrudMetadataEditorComponent {
|
|
|
2210
2254
|
return this.tx('crud.authoring.json.summaryClean', 'The canonical document is structurally consistent.');
|
|
2211
2255
|
}
|
|
2212
2256
|
sectionStatus(section) {
|
|
2213
|
-
|
|
2257
|
+
const diagnostics = this.sectionDiagnostics(section);
|
|
2258
|
+
if (diagnostics.some((issue) => issue.level === 'error')) {
|
|
2214
2259
|
return 'invalid';
|
|
2215
2260
|
}
|
|
2261
|
+
if (diagnostics.some((issue) => issue.level === 'warning')) {
|
|
2262
|
+
return 'pending';
|
|
2263
|
+
}
|
|
2216
2264
|
if (section === 'connection') {
|
|
2217
2265
|
return this.resourcePath().trim() ? 'ready' : 'pending';
|
|
2218
2266
|
}
|
|
@@ -2347,7 +2395,12 @@ class CrudMetadataEditorComponent {
|
|
|
2347
2395
|
return this.tx('crud.authoring.diagnostics.errorSummary', '{count} blocking diagnostics in this section.')
|
|
2348
2396
|
.replace('{count}', String(errorCount));
|
|
2349
2397
|
}
|
|
2350
|
-
|
|
2398
|
+
const key = warningCount === 1
|
|
2399
|
+
? 'crud.authoring.diagnostics.warningSummarySingle'
|
|
2400
|
+
: 'crud.authoring.diagnostics.warningSummary';
|
|
2401
|
+
return this.tx(key, warningCount === 1
|
|
2402
|
+
? '1 diagnostic worth reviewing in this section.'
|
|
2403
|
+
: '{count} diagnostics worth reviewing in this section.')
|
|
2351
2404
|
.replace('{count}', String(warningCount));
|
|
2352
2405
|
}
|
|
2353
2406
|
modeLabel(mode) {
|
|
@@ -2380,11 +2433,25 @@ class CrudMetadataEditorComponent {
|
|
|
2380
2433
|
}
|
|
2381
2434
|
diagnosticMessage(code, fallback) {
|
|
2382
2435
|
const key = {
|
|
2436
|
+
'crud.metadata.component.invalid': 'crud.authoring.validation.componentInvalid',
|
|
2437
|
+
'crud.metadata.table.required': 'crud.authoring.validation.tableRequired',
|
|
2438
|
+
'crud.metadata.resource.path.required': 'crud.authoring.validation.resourcePathRequired',
|
|
2439
|
+
'crud.metadata.resource-or-data.missing': 'crud.authoring.validation.sourceMissing',
|
|
2440
|
+
'crud.metadata.data.ignored-by-resource': 'crud.authoring.validation.dataIgnoredByResource',
|
|
2441
|
+
'crud.metadata.actions.openMode.invalid': 'crud.authoring.validation.openModeInvalid',
|
|
2383
2442
|
'crud.metadata.actions.route.required': 'crud.authoring.validation.routeRequired',
|
|
2384
2443
|
'crud.metadata.actions.formId.required': 'crud.authoring.validation.formIdRequired',
|
|
2385
2444
|
'crud.metadata.actions.form.submit-contract.invalid': 'crud.authoring.validation.submitContract',
|
|
2386
2445
|
}[code];
|
|
2387
|
-
|
|
2446
|
+
if (key) {
|
|
2447
|
+
return this.tx(key, fallback);
|
|
2448
|
+
}
|
|
2449
|
+
const canonicalActionMatch = code.match(/^crud\.metadata\.actions\.(create|view|edit|delete)\.missing$/);
|
|
2450
|
+
if (canonicalActionMatch) {
|
|
2451
|
+
return this.tx('crud.authoring.validation.canonicalActionMissing', 'Canonical CRUD action {action} is not declared yet')
|
|
2452
|
+
.replace('{action}', this.actionLabel(canonicalActionMatch[1]));
|
|
2453
|
+
}
|
|
2454
|
+
return fallback;
|
|
2388
2455
|
}
|
|
2389
2456
|
setResourceField(field, value) {
|
|
2390
2457
|
this.updateMetadata((metadata) => ({
|
|
@@ -2615,13 +2682,13 @@ class CrudMetadataEditorComponent {
|
|
|
2615
2682
|
.some((section) => this.sectionStatus(section) === bucket);
|
|
2616
2683
|
}
|
|
2617
2684
|
sectionDiagnostics(section) {
|
|
2618
|
-
const
|
|
2619
|
-
connection: 'metadata.resource',
|
|
2620
|
-
defaults: 'metadata.defaults',
|
|
2621
|
-
actions: 'metadata.actions',
|
|
2622
|
-
table: 'metadata.table',
|
|
2685
|
+
const prefixes = {
|
|
2686
|
+
connection: ['metadata.component', 'metadata.resource', 'metadata.data'],
|
|
2687
|
+
defaults: ['metadata.defaults'],
|
|
2688
|
+
actions: ['metadata.actions'],
|
|
2689
|
+
table: ['metadata.table'],
|
|
2623
2690
|
}[section];
|
|
2624
|
-
return this.diagnostics().filter((issue) => String(issue.path || '').includes(prefix));
|
|
2691
|
+
return this.diagnostics().filter((issue) => prefixes.some((prefix) => String(issue.path || '').includes(prefix)));
|
|
2625
2692
|
}
|
|
2626
2693
|
actionDiagnostics(actionName) {
|
|
2627
2694
|
return this.diagnostics()
|
|
@@ -2727,7 +2794,7 @@ class CrudMetadataEditorComponent {
|
|
|
2727
2794
|
</div>
|
|
2728
2795
|
</section>
|
|
2729
2796
|
|
|
2730
|
-
<mat-tab-group class="editor-tabs" data-testid="crud-editor-tabs" dynamicHeight>
|
|
2797
|
+
<mat-tab-group class="editor-tabs" data-testid="crud-editor-tabs" dynamicHeight animationDuration="0ms">
|
|
2731
2798
|
<mat-tab>
|
|
2732
2799
|
<ng-template mat-tab-label>
|
|
2733
2800
|
<mat-icon [praxisIcon]="'link'"></mat-icon>
|
|
@@ -2771,7 +2838,7 @@ class CrudMetadataEditorComponent {
|
|
|
2771
2838
|
<mat-tab>
|
|
2772
2839
|
<ng-template mat-tab-label>
|
|
2773
2840
|
<mat-icon [praxisIcon]="'tune'"></mat-icon>
|
|
2774
|
-
<span data-testid="crud-editor-tab-defaults">{{ tx('crud.authoring.
|
|
2841
|
+
<span data-testid="crud-editor-tab-defaults">{{ tx('crud.authoring.tab.defaults', 'Opening') }}</span>
|
|
2775
2842
|
<span
|
|
2776
2843
|
class="tab-status-dot"
|
|
2777
2844
|
[class.tab-status-dot--warn]="sectionStatus('defaults') === 'pending'"
|
|
@@ -2956,16 +3023,20 @@ class CrudMetadataEditorComponent {
|
|
|
2956
3023
|
}
|
|
2957
3024
|
</mat-select>
|
|
2958
3025
|
</mat-form-field>
|
|
2959
|
-
|
|
2960
|
-
<mat-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
<
|
|
2966
|
-
|
|
3026
|
+
@if (actionUsesRoute(actionName)) {
|
|
3027
|
+
<mat-form-field appearance="outline">
|
|
3028
|
+
<mat-label>{{ tx('crud.authoring.action.route', 'Route') }}</mat-label>
|
|
3029
|
+
<input matInput [attr.data-testid]="'crud-editor-action-' + actionName + '-route'" [ngModel]="actionValue(actionName).route || ''" (ngModelChange)="setActionField(actionName, 'route', $event)" [disabled]="isReadonly()" />
|
|
3030
|
+
</mat-form-field>
|
|
3031
|
+
} @else {
|
|
3032
|
+
<mat-form-field appearance="outline">
|
|
3033
|
+
<mat-label>{{ tx('crud.authoring.action.formId', 'formId') }}</mat-label>
|
|
3034
|
+
<input matInput [attr.data-testid]="'crud-editor-action-' + actionName + '-formId'" [ngModel]="actionValue(actionName).formId || ''" (ngModelChange)="setActionField(actionName, 'formId', $event)" [disabled]="isReadonly()" />
|
|
3035
|
+
</mat-form-field>
|
|
3036
|
+
}
|
|
2967
3037
|
</div>
|
|
2968
3038
|
</section>
|
|
3039
|
+
@if (!actionUsesRoute(actionName)) {
|
|
2969
3040
|
<section class="action-group" [attr.data-testid]="'crud-editor-action-' + actionName + '-schema-group'">
|
|
2970
3041
|
<div class="action-group__header">
|
|
2971
3042
|
<div>
|
|
@@ -3118,6 +3189,7 @@ class CrudMetadataEditorComponent {
|
|
|
3118
3189
|
</div>
|
|
3119
3190
|
</section>
|
|
3120
3191
|
</mat-expansion-panel>
|
|
3192
|
+
}
|
|
3121
3193
|
</mat-expansion-panel>
|
|
3122
3194
|
}
|
|
3123
3195
|
</div>
|
|
@@ -3206,7 +3278,7 @@ class CrudMetadataEditorComponent {
|
|
|
3206
3278
|
</mat-tab>
|
|
3207
3279
|
</mat-tab-group>
|
|
3208
3280
|
</section>
|
|
3209
|
-
`, isInline: true, styles: [":host{display:block;min-width:0;color:var(--md-sys-color-on-surface,#1a1b20)}.editor-shell{display:grid;gap:16px}.editor-header{display:flex;justify-content:space-between;gap:16px;align-items:start}.editor-overview,.editor-health-map{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.editor-health-card{display:grid;gap:4px;padding:14px;border-radius:18px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.editor-health-card--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.editor-health-card--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.editor-focus{display:flex;gap:12px;align-items:start;padding:14px 16px;border-radius:18px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.editor-focus--success{background:color-mix(in srgb,var(--md-sys-color-secondary-container,#d7e3ff) 70%,transparent)}.editor-focus-chip{padding:6px 10px;border-radius:999px;font-size:12px;background:color-mix(in srgb,var(--md-sys-color-secondary-container,#d7e3ff) 70%,transparent);white-space:nowrap}.editor-focus-chip--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.editor-focus-chip--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.editor-focus-copy{display:grid;gap:4px}.editor-focus-copy p{margin:0;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-tabs{display:flex;flex-direction:column;min-width:0}.editor-tabs .mat-mdc-tab{min-width:118px}.editor-tabs ::ng-deep .mdc-tab__content{gap:8px}.editor-tabs ::ng-deep .mat-mdc-tab-body-wrapper,.editor-tabs ::ng-deep .mat-mdc-tab-group-container{flex:1 1 auto;min-height:0}.editor-tabs ::ng-deep .mat-mdc-tab-body-content{overflow:visible}.tab-status-dot{width:8px;height:8px;border-radius:999px;background:var(--md-sys-color-primary,#1263b4);flex:0 0 auto}.tab-status-dot--warn{background:var(--md-sys-color-tertiary,#7d5700)}.tab-status-dot--error{background:var(--md-sys-color-error,#b3261e)}.tab-content{display:grid;gap:14px;min-width:0;padding:12px 2px 4px;box-sizing:border-box}.editor-overview-card{display:grid;gap:4px;padding:14px;border-radius:18px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.editor-overview-card--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.editor-overview-card--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.editor-overview-label{font-size:12px;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-overview-value{line-height:1.3;overflow-wrap:anywhere}.editor-overview-note{margin:0;font-size:12px;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-header h2,.editor-card h3{margin:0}.editor-header p{margin:6px 0 0;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-chip{padding:6px 10px;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary,#1263b4) 12%,transparent);font-size:12px}.editor-card{display:grid;gap:14px;padding:16px;border-radius:20px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline,#c5c7ce) 70%,transparent)}.editor-section-header{display:flex;justify-content:space-between;gap:12px;align-items:start}.editor-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.editor-grid--compact{grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}.editor-toggles{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.editor-actions,.action-grid{display:grid;gap:14px}.action-summary-strip{display:flex;flex-wrap:wrap;gap:8px}.action-summary-chip{padding:6px 10px;border-radius:999px;font-size:12px;background:color-mix(in srgb,var(--md-sys-color-secondary-container,#d7e3ff) 70%,transparent)}.action-summary-chip--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.action-summary-chip--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.action-group{display:grid;gap:10px;padding:12px;border-radius:16px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 88%,transparent)}.action-group--advanced{background:color-mix(in srgb,var(--md-sys-color-surface-container,#f5f7fb) 90%,transparent)}.action-group__header{display:grid;gap:4px}.action-subgroup{display:grid;gap:10px;padding:10px;border-radius:14px;background:color-mix(in srgb,var(--md-sys-color-surface-container-low,#fafbfd) 92%,transparent)}.action-subgroup__header{display:grid;gap:4px}.action-param-list{display:grid;gap:12px}.action-param-row{display:grid;gap:8px}.action-advanced-panel{border:1px solid color-mix(in srgb,var(--md-sys-color-outline,#c5c7ce) 65%,transparent);border-radius:16px}.editor-section-note{margin:0;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.diagnostics-groups{display:grid;gap:12px}.diagnostics-group{display:grid;gap:10px;padding:12px;border-radius:16px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.diagnostics{display:grid;gap:8px;margin:0;padding-left:18px}.diagnostics .error{color:var(--md-sys-color-error,#b3261e)}pre{margin:0;overflow:auto;max-height:320px;padding:12px;border-radius:14px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}\n"], dependencies: [{ 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: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i3.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i4.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i4.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i4.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i4.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i8.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: i8.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i9.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i10.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i10.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i10.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: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisTableInlineAuthoringEditorComponent, selector: "praxis-table-inline-authoring-editor", inputs: ["config", "readonly"], outputs: ["configChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3281
|
+
`, isInline: true, styles: [":host{display:block;min-width:0;color:var(--md-sys-color-on-surface,#1a1b20)}.editor-shell{display:grid;gap:16px}.editor-header{display:flex;justify-content:space-between;gap:16px;align-items:start}.editor-overview,.editor-health-map{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.editor-health-card{display:grid;gap:4px;padding:14px;border-radius:18px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.editor-health-card--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.editor-health-card--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.editor-focus{display:flex;gap:12px;align-items:start;padding:14px 16px;border-radius:18px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.editor-focus--success{background:color-mix(in srgb,var(--md-sys-color-secondary-container,#d7e3ff) 70%,transparent)}.editor-focus-chip{padding:6px 10px;border-radius:999px;font-size:12px;background:color-mix(in srgb,var(--md-sys-color-secondary-container,#d7e3ff) 70%,transparent);white-space:nowrap}.editor-focus-chip--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.editor-focus-chip--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.editor-focus-copy{display:grid;gap:4px}.editor-focus-copy p{margin:0;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-tabs{display:flex;flex-direction:column;min-width:0}.editor-tabs .mat-mdc-tab{min-width:118px}.editor-tabs ::ng-deep .mdc-tab__content{gap:8px}.editor-tabs ::ng-deep .mat-mdc-tab-body-wrapper,.editor-tabs ::ng-deep .mat-mdc-tab-group-container{flex:1 1 auto;min-height:0}.editor-tabs ::ng-deep .mat-mdc-tab-body-content{overflow:hidden}.tab-status-dot{width:8px;height:8px;border-radius:999px;background:var(--md-sys-color-primary,#1263b4);flex:0 0 auto}.tab-status-dot--warn{background:var(--md-sys-color-tertiary,#7d5700)}.tab-status-dot--error{background:var(--md-sys-color-error,#b3261e)}.tab-content{display:grid;gap:14px;min-width:0;padding:12px 2px 4px;box-sizing:border-box}.editor-overview-card{display:grid;gap:4px;padding:14px;border-radius:18px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.editor-overview-card--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.editor-overview-card--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.editor-overview-label{font-size:12px;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-overview-value{line-height:1.3;overflow-wrap:anywhere}.editor-overview-note{margin:0;font-size:12px;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-header h2,.editor-card h3{margin:0}.editor-header p{margin:6px 0 0;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-chip{padding:6px 10px;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary,#1263b4) 12%,transparent);font-size:12px}.editor-card{display:grid;gap:14px;padding:16px;border-radius:20px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline,#c5c7ce) 70%,transparent)}.editor-section-header{display:flex;justify-content:space-between;gap:12px;align-items:start}.editor-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.editor-grid--compact{grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}.editor-toggles{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.editor-actions,.action-grid{display:grid;gap:14px}.action-summary-strip{display:flex;flex-wrap:wrap;gap:8px}.action-summary-chip{padding:6px 10px;border-radius:999px;font-size:12px;background:color-mix(in srgb,var(--md-sys-color-secondary-container,#d7e3ff) 70%,transparent)}.action-summary-chip--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.action-summary-chip--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.action-group{display:grid;gap:10px;padding:12px;border-radius:16px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 88%,transparent)}.action-group--advanced{background:color-mix(in srgb,var(--md-sys-color-surface-container,#f5f7fb) 90%,transparent)}.action-group__header{display:grid;gap:4px}.action-subgroup{display:grid;gap:10px;padding:10px;border-radius:14px;background:color-mix(in srgb,var(--md-sys-color-surface-container-low,#fafbfd) 92%,transparent)}.action-subgroup__header{display:grid;gap:4px}.action-param-list{display:grid;gap:12px}.action-param-row{display:grid;gap:8px}.action-advanced-panel{border:1px solid color-mix(in srgb,var(--md-sys-color-outline,#c5c7ce) 65%,transparent);border-radius:16px}.editor-section-note{margin:0;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.diagnostics-groups{display:grid;gap:12px}.diagnostics-group{display:grid;gap:10px;padding:12px;border-radius:16px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.diagnostics{display:grid;gap:8px;margin:0;padding-left:18px}.diagnostics .error{color:var(--md-sys-color-error,#b3261e)}pre{margin:0;overflow:auto;max-height:320px;padding:12px;border-radius:14px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}\n"], dependencies: [{ 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: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i3.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "component", type: i4.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i4.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i4.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i4.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i8.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: i8.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i9.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i10.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i10.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i10.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: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisTableInlineAuthoringEditorComponent, selector: "praxis-table-inline-authoring-editor", inputs: ["config", "readonly"], outputs: ["configChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3210
3282
|
}
|
|
3211
3283
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: CrudMetadataEditorComponent, decorators: [{
|
|
3212
3284
|
type: Component,
|
|
@@ -3291,7 +3363,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
3291
3363
|
</div>
|
|
3292
3364
|
</section>
|
|
3293
3365
|
|
|
3294
|
-
<mat-tab-group class="editor-tabs" data-testid="crud-editor-tabs" dynamicHeight>
|
|
3366
|
+
<mat-tab-group class="editor-tabs" data-testid="crud-editor-tabs" dynamicHeight animationDuration="0ms">
|
|
3295
3367
|
<mat-tab>
|
|
3296
3368
|
<ng-template mat-tab-label>
|
|
3297
3369
|
<mat-icon [praxisIcon]="'link'"></mat-icon>
|
|
@@ -3335,7 +3407,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
3335
3407
|
<mat-tab>
|
|
3336
3408
|
<ng-template mat-tab-label>
|
|
3337
3409
|
<mat-icon [praxisIcon]="'tune'"></mat-icon>
|
|
3338
|
-
<span data-testid="crud-editor-tab-defaults">{{ tx('crud.authoring.
|
|
3410
|
+
<span data-testid="crud-editor-tab-defaults">{{ tx('crud.authoring.tab.defaults', 'Opening') }}</span>
|
|
3339
3411
|
<span
|
|
3340
3412
|
class="tab-status-dot"
|
|
3341
3413
|
[class.tab-status-dot--warn]="sectionStatus('defaults') === 'pending'"
|
|
@@ -3520,16 +3592,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
3520
3592
|
}
|
|
3521
3593
|
</mat-select>
|
|
3522
3594
|
</mat-form-field>
|
|
3523
|
-
|
|
3524
|
-
<mat-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
<
|
|
3530
|
-
|
|
3595
|
+
@if (actionUsesRoute(actionName)) {
|
|
3596
|
+
<mat-form-field appearance="outline">
|
|
3597
|
+
<mat-label>{{ tx('crud.authoring.action.route', 'Route') }}</mat-label>
|
|
3598
|
+
<input matInput [attr.data-testid]="'crud-editor-action-' + actionName + '-route'" [ngModel]="actionValue(actionName).route || ''" (ngModelChange)="setActionField(actionName, 'route', $event)" [disabled]="isReadonly()" />
|
|
3599
|
+
</mat-form-field>
|
|
3600
|
+
} @else {
|
|
3601
|
+
<mat-form-field appearance="outline">
|
|
3602
|
+
<mat-label>{{ tx('crud.authoring.action.formId', 'formId') }}</mat-label>
|
|
3603
|
+
<input matInput [attr.data-testid]="'crud-editor-action-' + actionName + '-formId'" [ngModel]="actionValue(actionName).formId || ''" (ngModelChange)="setActionField(actionName, 'formId', $event)" [disabled]="isReadonly()" />
|
|
3604
|
+
</mat-form-field>
|
|
3605
|
+
}
|
|
3531
3606
|
</div>
|
|
3532
3607
|
</section>
|
|
3608
|
+
@if (!actionUsesRoute(actionName)) {
|
|
3533
3609
|
<section class="action-group" [attr.data-testid]="'crud-editor-action-' + actionName + '-schema-group'">
|
|
3534
3610
|
<div class="action-group__header">
|
|
3535
3611
|
<div>
|
|
@@ -3682,6 +3758,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
3682
3758
|
</div>
|
|
3683
3759
|
</section>
|
|
3684
3760
|
</mat-expansion-panel>
|
|
3761
|
+
}
|
|
3685
3762
|
</mat-expansion-panel>
|
|
3686
3763
|
}
|
|
3687
3764
|
</div>
|
|
@@ -3770,7 +3847,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
3770
3847
|
</mat-tab>
|
|
3771
3848
|
</mat-tab-group>
|
|
3772
3849
|
</section>
|
|
3773
|
-
`, styles: [":host{display:block;min-width:0;color:var(--md-sys-color-on-surface,#1a1b20)}.editor-shell{display:grid;gap:16px}.editor-header{display:flex;justify-content:space-between;gap:16px;align-items:start}.editor-overview,.editor-health-map{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.editor-health-card{display:grid;gap:4px;padding:14px;border-radius:18px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.editor-health-card--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.editor-health-card--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.editor-focus{display:flex;gap:12px;align-items:start;padding:14px 16px;border-radius:18px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.editor-focus--success{background:color-mix(in srgb,var(--md-sys-color-secondary-container,#d7e3ff) 70%,transparent)}.editor-focus-chip{padding:6px 10px;border-radius:999px;font-size:12px;background:color-mix(in srgb,var(--md-sys-color-secondary-container,#d7e3ff) 70%,transparent);white-space:nowrap}.editor-focus-chip--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.editor-focus-chip--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.editor-focus-copy{display:grid;gap:4px}.editor-focus-copy p{margin:0;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-tabs{display:flex;flex-direction:column;min-width:0}.editor-tabs .mat-mdc-tab{min-width:118px}.editor-tabs ::ng-deep .mdc-tab__content{gap:8px}.editor-tabs ::ng-deep .mat-mdc-tab-body-wrapper,.editor-tabs ::ng-deep .mat-mdc-tab-group-container{flex:1 1 auto;min-height:0}.editor-tabs ::ng-deep .mat-mdc-tab-body-content{overflow:
|
|
3850
|
+
`, styles: [":host{display:block;min-width:0;color:var(--md-sys-color-on-surface,#1a1b20)}.editor-shell{display:grid;gap:16px}.editor-header{display:flex;justify-content:space-between;gap:16px;align-items:start}.editor-overview,.editor-health-map{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}.editor-health-card{display:grid;gap:4px;padding:14px;border-radius:18px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.editor-health-card--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.editor-health-card--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.editor-focus{display:flex;gap:12px;align-items:start;padding:14px 16px;border-radius:18px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.editor-focus--success{background:color-mix(in srgb,var(--md-sys-color-secondary-container,#d7e3ff) 70%,transparent)}.editor-focus-chip{padding:6px 10px;border-radius:999px;font-size:12px;background:color-mix(in srgb,var(--md-sys-color-secondary-container,#d7e3ff) 70%,transparent);white-space:nowrap}.editor-focus-chip--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.editor-focus-chip--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.editor-focus-copy{display:grid;gap:4px}.editor-focus-copy p{margin:0;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-tabs{display:flex;flex-direction:column;min-width:0}.editor-tabs .mat-mdc-tab{min-width:118px}.editor-tabs ::ng-deep .mdc-tab__content{gap:8px}.editor-tabs ::ng-deep .mat-mdc-tab-body-wrapper,.editor-tabs ::ng-deep .mat-mdc-tab-group-container{flex:1 1 auto;min-height:0}.editor-tabs ::ng-deep .mat-mdc-tab-body-content{overflow:hidden}.tab-status-dot{width:8px;height:8px;border-radius:999px;background:var(--md-sys-color-primary,#1263b4);flex:0 0 auto}.tab-status-dot--warn{background:var(--md-sys-color-tertiary,#7d5700)}.tab-status-dot--error{background:var(--md-sys-color-error,#b3261e)}.tab-content{display:grid;gap:14px;min-width:0;padding:12px 2px 4px;box-sizing:border-box}.editor-overview-card{display:grid;gap:4px;padding:14px;border-radius:18px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.editor-overview-card--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.editor-overview-card--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.editor-overview-label{font-size:12px;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-overview-value{line-height:1.3;overflow-wrap:anywhere}.editor-overview-note{margin:0;font-size:12px;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-header h2,.editor-card h3{margin:0}.editor-header p{margin:6px 0 0;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.editor-chip{padding:6px 10px;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary,#1263b4) 12%,transparent);font-size:12px}.editor-card{display:grid;gap:14px;padding:16px;border-radius:20px;border:1px solid color-mix(in srgb,var(--md-sys-color-outline,#c5c7ce) 70%,transparent)}.editor-section-header{display:flex;justify-content:space-between;gap:12px;align-items:start}.editor-grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.editor-grid--compact{grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}.editor-toggles{display:grid;gap:10px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.editor-actions,.action-grid{display:grid;gap:14px}.action-summary-strip{display:flex;flex-wrap:wrap;gap:8px}.action-summary-chip{padding:6px 10px;border-radius:999px;font-size:12px;background:color-mix(in srgb,var(--md-sys-color-secondary-container,#d7e3ff) 70%,transparent)}.action-summary-chip--warn{background:color-mix(in srgb,var(--md-sys-color-tertiary-container,#f8e08e) 78%,transparent)}.action-summary-chip--error{background:color-mix(in srgb,var(--md-sys-color-error-container,#f9dedc) 82%,transparent);color:var(--md-sys-color-on-error-container,#410e0b)}.action-group{display:grid;gap:10px;padding:12px;border-radius:16px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 88%,transparent)}.action-group--advanced{background:color-mix(in srgb,var(--md-sys-color-surface-container,#f5f7fb) 90%,transparent)}.action-group__header{display:grid;gap:4px}.action-subgroup{display:grid;gap:10px;padding:10px;border-radius:14px;background:color-mix(in srgb,var(--md-sys-color-surface-container-low,#fafbfd) 92%,transparent)}.action-subgroup__header{display:grid;gap:4px}.action-param-list{display:grid;gap:12px}.action-param-row{display:grid;gap:8px}.action-advanced-panel{border:1px solid color-mix(in srgb,var(--md-sys-color-outline,#c5c7ce) 65%,transparent);border-radius:16px}.editor-section-note{margin:0;color:var(--md-sys-color-on-surface-variant,#5a5d67)}.diagnostics-groups{display:grid;gap:12px}.diagnostics-group{display:grid;gap:10px;padding:12px;border-radius:16px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}.diagnostics{display:grid;gap:8px;margin:0;padding-left:18px}.diagnostics .error{color:var(--md-sys-color-error,#b3261e)}pre{margin:0;overflow:auto;max-height:320px;padding:12px;border-radius:14px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high,#eef1f6) 92%,transparent)}\n"] }]
|
|
3774
3851
|
}], ctorParameters: () => [], propDecorators: { documentInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "document", required: false }] }], metadataInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "metadata", required: false }] }], crudIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "crudId", required: false }] }], readonlyInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }] } });
|
|
3775
3852
|
function cloneTableConfig(config) {
|
|
3776
3853
|
return JSON.parse(JSON.stringify(config || { columns: [] }));
|
|
@@ -3801,6 +3878,8 @@ class PraxisCrudComponent {
|
|
|
3801
3878
|
tableConfigPersistenceStrategy = 'local-first';
|
|
3802
3879
|
context;
|
|
3803
3880
|
enableCustomization = false;
|
|
3881
|
+
/** Controls whether existing-record hosts expose the canonical identity key. */
|
|
3882
|
+
showResourceIdentityKey = true;
|
|
3804
3883
|
/** Capability publica exigida para authoring governado do CRUD e da tabela interna. */
|
|
3805
3884
|
authoringCapability = null;
|
|
3806
3885
|
configureRequested = new EventEmitter();
|
|
@@ -3808,11 +3887,17 @@ class PraxisCrudComponent {
|
|
|
3808
3887
|
afterClose = new EventEmitter();
|
|
3809
3888
|
afterSave = new EventEmitter();
|
|
3810
3889
|
afterDelete = new EventEmitter();
|
|
3890
|
+
/** Metadata-only Reactive Determination evidence from an open form host. */
|
|
3891
|
+
reactiveDeterminationExecuted = new EventEmitter();
|
|
3892
|
+
reactiveDeterminationPendingChange = new EventEmitter();
|
|
3893
|
+
reactiveDeterminationStabilityChange = new EventEmitter();
|
|
3811
3894
|
error = new EventEmitter();
|
|
3812
3895
|
rowClick = new EventEmitter();
|
|
3813
3896
|
/** Emits the canonical table row-action envelope before the CRUD handles its surface/action. */
|
|
3814
3897
|
rowAction = new EventEmitter();
|
|
3815
3898
|
selectionChange = new EventEmitter();
|
|
3899
|
+
/** Forwards the canonical resource interaction envelope emitted by the internal table. */
|
|
3900
|
+
resourceEvent = output();
|
|
3816
3901
|
tableRuntimeConfigChange = new EventEmitter();
|
|
3817
3902
|
crudAuthoringDocumentApplied = new EventEmitter();
|
|
3818
3903
|
crudAuthoringDocumentSaved = new EventEmitter();
|
|
@@ -3834,11 +3919,13 @@ class PraxisCrudComponent {
|
|
|
3834
3919
|
snack = inject(MatSnackBar);
|
|
3835
3920
|
dialog = inject(DialogService);
|
|
3836
3921
|
i18n = inject(PraxisI18nService);
|
|
3922
|
+
logger = inject(LoggerService, { optional: true });
|
|
3837
3923
|
injector = inject(Injector);
|
|
3838
3924
|
resourceDiscoveryInstance;
|
|
3839
3925
|
actionOpenAdapterInstance;
|
|
3840
3926
|
surfaceOpenAdapterInstance;
|
|
3841
3927
|
materializedRefreshSequence = 0;
|
|
3928
|
+
surfaceOpenAttemptSequence = 0;
|
|
3842
3929
|
global = (() => {
|
|
3843
3930
|
try {
|
|
3844
3931
|
return inject(GlobalConfigService);
|
|
@@ -3860,6 +3947,7 @@ class PraxisCrudComponent {
|
|
|
3860
3947
|
})();
|
|
3861
3948
|
warnedMissingId = false;
|
|
3862
3949
|
lastEmittedTableRuntimeConfigJson = '';
|
|
3950
|
+
lastTableRuntimeConfigSnapshot = null;
|
|
3863
3951
|
lastAssignedTableConfigJson = '';
|
|
3864
3952
|
lastAssignedTableCrudContextJson = '';
|
|
3865
3953
|
lastAppliedResourceIdentity = null;
|
|
@@ -3922,6 +4010,9 @@ class PraxisCrudComponent {
|
|
|
3922
4010
|
this.selectedRow = this.extractSelectedRowFromEvent(event);
|
|
3923
4011
|
this.selectionChange.emit(event);
|
|
3924
4012
|
}
|
|
4013
|
+
onTableResourceEvent(event) {
|
|
4014
|
+
this.resourceEvent.emit(event);
|
|
4015
|
+
}
|
|
3925
4016
|
async onBulkAction(event) {
|
|
3926
4017
|
const action = String(event?.action || '').trim();
|
|
3927
4018
|
if (!action) {
|
|
@@ -3947,6 +4038,8 @@ class PraxisCrudComponent {
|
|
|
3947
4038
|
return;
|
|
3948
4039
|
}
|
|
3949
4040
|
this.materializedRefreshSequence += 1;
|
|
4041
|
+
this.lastTableRuntimeConfigSnapshot = null;
|
|
4042
|
+
this.lastEmittedTableRuntimeConfigJson = '';
|
|
3950
4043
|
try {
|
|
3951
4044
|
const parsed = typeof this.metadata === 'string'
|
|
3952
4045
|
? JSON.parse(this.metadata)
|
|
@@ -4051,6 +4144,18 @@ class PraxisCrudComponent {
|
|
|
4051
4144
|
this.refreshTable();
|
|
4052
4145
|
}
|
|
4053
4146
|
},
|
|
4147
|
+
onReactiveDetermination: (event) => this.reactiveDeterminationExecuted.emit({
|
|
4148
|
+
action: effectiveAction.action,
|
|
4149
|
+
event,
|
|
4150
|
+
}),
|
|
4151
|
+
onReactiveDeterminationPendingChange: (pending) => this.reactiveDeterminationPendingChange.emit({
|
|
4152
|
+
action: effectiveAction.action,
|
|
4153
|
+
pending,
|
|
4154
|
+
}),
|
|
4155
|
+
onReactiveDeterminationStabilityChange: (stability) => this.reactiveDeterminationStabilityChange.emit({
|
|
4156
|
+
action: effectiveAction.action,
|
|
4157
|
+
...stability,
|
|
4158
|
+
}),
|
|
4054
4159
|
}, {
|
|
4055
4160
|
capabilities: effectiveAction.action === 'create'
|
|
4056
4161
|
? this.collectionCapabilities
|
|
@@ -4058,6 +4163,7 @@ class PraxisCrudComponent {
|
|
|
4058
4163
|
links: this.resolveCrudRuntimeLinks(effectiveAction.action, contextualRow),
|
|
4059
4164
|
resourceIdentity,
|
|
4060
4165
|
contextIdentity,
|
|
4166
|
+
showResourceIdentityKey: this.showResourceIdentityKey,
|
|
4061
4167
|
focusOrigin: runtimeEvent?.focusOrigin ?? null,
|
|
4062
4168
|
surfaceRuntime: this.resolveSurfaceRuntime(),
|
|
4063
4169
|
});
|
|
@@ -4141,6 +4247,10 @@ class PraxisCrudComponent {
|
|
|
4141
4247
|
return current;
|
|
4142
4248
|
}
|
|
4143
4249
|
}
|
|
4250
|
+
onTableConfigChange(config) {
|
|
4251
|
+
this.lastTableRuntimeConfigSnapshot = this.cloneTableConfigSnapshot(config);
|
|
4252
|
+
this.emitTableRuntimeConfigSnapshot(this.lastTableRuntimeConfigSnapshot);
|
|
4253
|
+
}
|
|
4144
4254
|
onTableMetadataChange() {
|
|
4145
4255
|
this.emitTableRuntimeConfigSnapshot();
|
|
4146
4256
|
}
|
|
@@ -4324,9 +4434,16 @@ class PraxisCrudComponent {
|
|
|
4324
4434
|
const { mode, ref } = await this.launcher.launch(createAction, undefined, this.resolvedMetadata, this.componentKeyId(), {
|
|
4325
4435
|
onClose: () => emitDrawerClose(),
|
|
4326
4436
|
onResult: (result) => handleResult(result),
|
|
4437
|
+
onReactiveDetermination: (event) => this.reactiveDeterminationExecuted.emit({ action: normalizedAction, event }),
|
|
4438
|
+
onReactiveDeterminationPendingChange: (pending) => this.reactiveDeterminationPendingChange.emit({ action: normalizedAction, pending }),
|
|
4439
|
+
onReactiveDeterminationStabilityChange: (stability) => this.reactiveDeterminationStabilityChange.emit({
|
|
4440
|
+
action: normalizedAction,
|
|
4441
|
+
...stability,
|
|
4442
|
+
}),
|
|
4327
4443
|
}, {
|
|
4328
4444
|
capabilities: this.collectionCapabilities,
|
|
4329
4445
|
links: this.tableCollectionLinks,
|
|
4446
|
+
showResourceIdentityKey: this.showResourceIdentityKey,
|
|
4330
4447
|
surfaceRuntime: this.resolveSurfaceRuntime(),
|
|
4331
4448
|
});
|
|
4332
4449
|
this.afterOpen.emit({ mode, action: normalizedAction });
|
|
@@ -4421,10 +4538,11 @@ class PraxisCrudComponent {
|
|
|
4421
4538
|
}
|
|
4422
4539
|
return null;
|
|
4423
4540
|
}
|
|
4424
|
-
emitTableRuntimeConfigSnapshot() {
|
|
4425
|
-
const snapshot = this.getCurrentTableConfigSnapshot();
|
|
4541
|
+
emitTableRuntimeConfigSnapshot(preferredSnapshot) {
|
|
4542
|
+
const snapshot = preferredSnapshot || this.getCurrentTableConfigSnapshot();
|
|
4426
4543
|
if (!snapshot)
|
|
4427
4544
|
return;
|
|
4545
|
+
this.lastTableRuntimeConfigSnapshot = this.cloneTableConfigSnapshot(snapshot);
|
|
4428
4546
|
try {
|
|
4429
4547
|
const nextJson = JSON.stringify(snapshot);
|
|
4430
4548
|
if (nextJson === this.lastEmittedTableRuntimeConfigJson)
|
|
@@ -4434,6 +4552,14 @@ class PraxisCrudComponent {
|
|
|
4434
4552
|
catch { }
|
|
4435
4553
|
this.tableRuntimeConfigChange.emit(snapshot);
|
|
4436
4554
|
}
|
|
4555
|
+
cloneTableConfigSnapshot(config) {
|
|
4556
|
+
try {
|
|
4557
|
+
return JSON.parse(JSON.stringify(config));
|
|
4558
|
+
}
|
|
4559
|
+
catch {
|
|
4560
|
+
return config;
|
|
4561
|
+
}
|
|
4562
|
+
}
|
|
4437
4563
|
applyResolvedCrudState(meta) {
|
|
4438
4564
|
this.effectiveTableConfig = this.buildEffectiveTableConfig(meta, this.collectionCapabilities);
|
|
4439
4565
|
const nextTableConfig = this.effectiveTableConfig ||
|
|
@@ -4582,6 +4708,12 @@ class PraxisCrudComponent {
|
|
|
4582
4708
|
return true;
|
|
4583
4709
|
}
|
|
4584
4710
|
const focusOrigin = this.resolveRuntimeFocusOrigin(runtimeEvent);
|
|
4711
|
+
const correlationId = [
|
|
4712
|
+
this.componentKeyId() || this.crudId || 'praxis-crud',
|
|
4713
|
+
'surface.open',
|
|
4714
|
+
surface.id,
|
|
4715
|
+
++this.surfaceOpenAttemptSequence,
|
|
4716
|
+
].join(':');
|
|
4585
4717
|
let openPromise;
|
|
4586
4718
|
try {
|
|
4587
4719
|
const surfaceContext = {
|
|
@@ -4592,6 +4724,7 @@ class PraxisCrudComponent {
|
|
|
4592
4724
|
resourcePath,
|
|
4593
4725
|
surfaceId: surface.id,
|
|
4594
4726
|
operationId: surface.operationId,
|
|
4727
|
+
correlationId,
|
|
4595
4728
|
},
|
|
4596
4729
|
runtime: {
|
|
4597
4730
|
row: row ?? null,
|
|
@@ -4607,11 +4740,8 @@ class PraxisCrudComponent {
|
|
|
4607
4740
|
openPromise = handledInline ? Promise.resolve(undefined) : Promise.resolve(this.surfaceService.open(payload, surfaceContext));
|
|
4608
4741
|
}
|
|
4609
4742
|
catch (error) {
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
return true;
|
|
4613
|
-
}
|
|
4614
|
-
return false;
|
|
4743
|
+
this.reportDiscoveredSurfaceOpenFailure(error, normalizedAction, surface, resourcePath, correlationId);
|
|
4744
|
+
return true;
|
|
4615
4745
|
}
|
|
4616
4746
|
try {
|
|
4617
4747
|
this.bindDiscoveredSurfaceLifecycle(await openPromise);
|
|
@@ -4621,8 +4751,7 @@ class PraxisCrudComponent {
|
|
|
4621
4751
|
});
|
|
4622
4752
|
}
|
|
4623
4753
|
catch (err) {
|
|
4624
|
-
this.
|
|
4625
|
-
this.notifySurfaceNavigationFailure(err);
|
|
4754
|
+
this.reportDiscoveredSurfaceOpenFailure(err, normalizedAction, surface, resourcePath, correlationId);
|
|
4626
4755
|
}
|
|
4627
4756
|
return true;
|
|
4628
4757
|
}
|
|
@@ -4742,6 +4871,31 @@ class PraxisCrudComponent {
|
|
|
4742
4871
|
this.snack.open(translateSurfaceNavigationRejected(this.i18n), undefined, { duration: 4500 });
|
|
4743
4872
|
return true;
|
|
4744
4873
|
}
|
|
4874
|
+
reportDiscoveredSurfaceOpenFailure(error, action, surface, resourcePath, correlationId) {
|
|
4875
|
+
const normalizedCause = normalizeUnknownError(error);
|
|
4876
|
+
this.error.emit(error);
|
|
4877
|
+
this.notifySurfaceNavigationFailure(error);
|
|
4878
|
+
this.logger?.warn('Discovered CRUD surface failed to open.', {
|
|
4879
|
+
context: {
|
|
4880
|
+
lib: '@praxisui/crud',
|
|
4881
|
+
component: 'PraxisCrudComponent',
|
|
4882
|
+
actionId: action,
|
|
4883
|
+
correlationId,
|
|
4884
|
+
},
|
|
4885
|
+
data: {
|
|
4886
|
+
surfaceId: surface.id,
|
|
4887
|
+
mode: 'drawer',
|
|
4888
|
+
resourcePath,
|
|
4889
|
+
selectedPath: 'surface.open',
|
|
4890
|
+
fallback: 'none',
|
|
4891
|
+
cause: {
|
|
4892
|
+
name: normalizedCause.name,
|
|
4893
|
+
message: normalizedCause.message,
|
|
4894
|
+
},
|
|
4895
|
+
},
|
|
4896
|
+
throttleKey: `crud:surface.open:${action}:${surface.id}`,
|
|
4897
|
+
});
|
|
4898
|
+
}
|
|
4745
4899
|
async resolveDiscoveredActionCatalog(row) {
|
|
4746
4900
|
try {
|
|
4747
4901
|
if (row) {
|
|
@@ -5139,8 +5293,18 @@ class PraxisCrudComponent {
|
|
|
5139
5293
|
if (!this.isCustomizationAvailable()) {
|
|
5140
5294
|
return;
|
|
5141
5295
|
}
|
|
5142
|
-
const
|
|
5296
|
+
const canonicalSeed = this.currentAuthoringDocument
|
|
5143
5297
|
|| createCrudAuthoringDocument({ metadata: this.resolvedMetadata });
|
|
5298
|
+
const liveTableConfig = this.lastTableRuntimeConfigSnapshot
|
|
5299
|
+
|| this.getCurrentTableConfigSnapshot();
|
|
5300
|
+
const seed = liveTableConfig
|
|
5301
|
+
? createCrudAuthoringDocument({
|
|
5302
|
+
metadata: {
|
|
5303
|
+
...canonicalSeed.metadata,
|
|
5304
|
+
table: this.cloneTableConfigSnapshot(liveTableConfig),
|
|
5305
|
+
},
|
|
5306
|
+
})
|
|
5307
|
+
: canonicalSeed;
|
|
5144
5308
|
const ref = openCrudMetadataEditor(this.settingsPanel, {
|
|
5145
5309
|
crudId: this.crudId,
|
|
5146
5310
|
document: seed,
|
|
@@ -5178,6 +5342,9 @@ class PraxisCrudComponent {
|
|
|
5178
5342
|
const next = parseLegacyOrCrudDocument(payload);
|
|
5179
5343
|
this.currentAuthoringDocument = next;
|
|
5180
5344
|
this.resolvedMetadata = next.metadata;
|
|
5345
|
+
this.lastTableRuntimeConfigSnapshot = next.metadata.table
|
|
5346
|
+
? this.cloneTableConfigSnapshot(next.metadata.table)
|
|
5347
|
+
: null;
|
|
5181
5348
|
this.tableQueryContext = this.resolveQueryContext(this.resolvedMetadata);
|
|
5182
5349
|
this.tableFilterCriteria = this.resolveFilterCriteria(this.resolvedMetadata);
|
|
5183
5350
|
this.applyResolvedCrudState(this.resolvedMetadata);
|
|
@@ -5467,7 +5634,7 @@ class PraxisCrudComponent {
|
|
|
5467
5634
|
return Object.entries(params).reduce((current, [name, value]) => current.split(`{${name}}`).join(value), text);
|
|
5468
5635
|
}
|
|
5469
5636
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisCrudComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5470
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisCrudComponent, isStandalone: true, selector: "praxis-crud", inputs: { metadata: "metadata", crudId: "crudId", componentInstanceId: "componentInstanceId", tableConfigPersistenceStrategy: "tableConfigPersistenceStrategy", context: "context", enableCustomization: "enableCustomization", authoringCapability: "authoringCapability" }, outputs: { configureRequested: "configureRequested", afterOpen: "afterOpen", afterClose: "afterClose", afterSave: "afterSave", afterDelete: "afterDelete", error: "error", rowClick: "rowClick", rowAction: "rowAction", selectionChange: "selectionChange", tableRuntimeConfigChange: "tableRuntimeConfigChange", crudAuthoringDocumentApplied: "crudAuthoringDocumentApplied", crudAuthoringDocumentSaved: "crudAuthoringDocumentSaved" }, providers: [
|
|
5637
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisCrudComponent, isStandalone: true, selector: "praxis-crud", inputs: { metadata: "metadata", crudId: "crudId", componentInstanceId: "componentInstanceId", tableConfigPersistenceStrategy: "tableConfigPersistenceStrategy", context: "context", enableCustomization: "enableCustomization", showResourceIdentityKey: "showResourceIdentityKey", authoringCapability: "authoringCapability" }, outputs: { configureRequested: "configureRequested", afterOpen: "afterOpen", afterClose: "afterClose", afterSave: "afterSave", afterDelete: "afterDelete", reactiveDeterminationExecuted: "reactiveDeterminationExecuted", reactiveDeterminationPendingChange: "reactiveDeterminationPendingChange", reactiveDeterminationStabilityChange: "reactiveDeterminationStabilityChange", error: "error", rowClick: "rowClick", rowAction: "rowAction", selectionChange: "selectionChange", resourceEvent: "resourceEvent", tableRuntimeConfigChange: "tableRuntimeConfigChange", crudAuthoringDocumentApplied: "crudAuthoringDocumentApplied", crudAuthoringDocumentSaved: "crudAuthoringDocumentSaved" }, providers: [
|
|
5471
5638
|
providePraxisI18nConfig(RESOURCE_DISCOVERY_I18N_CONFIG),
|
|
5472
5639
|
providePraxisI18nConfig(PRAXIS_CRUD_RUNTIME_I18N_CONFIG),
|
|
5473
5640
|
], viewQueries: [{ propertyName: "table", first: true, predicate: PraxisTable, descendants: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
@@ -5492,11 +5659,13 @@ class PraxisCrudComponent {
|
|
|
5492
5659
|
[authoringCapability]="authoringCapability"
|
|
5493
5660
|
(rowClick)="onTableRowClick($event)"
|
|
5494
5661
|
(selectionChange)="onTableSelectionChange($event)"
|
|
5662
|
+
(resourceEvent)="onTableResourceEvent($event)"
|
|
5495
5663
|
(rowAction)="onTableRowAction($event)"
|
|
5496
5664
|
(toolbarAction)="onToolbarAction($event)"
|
|
5497
5665
|
(bulkAction)="onBulkAction($event)"
|
|
5498
5666
|
(collectionLinksChange)="onCollectionLinksChange($event)"
|
|
5499
5667
|
(reset)="onResetPreferences()"
|
|
5668
|
+
(configChange)="onTableConfigChange($event)"
|
|
5500
5669
|
(metadataChange)="onTableMetadataChange()"
|
|
5501
5670
|
(loadingStateChange)="onTableLoadingStateChange($event)"
|
|
5502
5671
|
></praxis-table>
|
|
@@ -5540,11 +5709,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
5540
5709
|
[authoringCapability]="authoringCapability"
|
|
5541
5710
|
(rowClick)="onTableRowClick($event)"
|
|
5542
5711
|
(selectionChange)="onTableSelectionChange($event)"
|
|
5712
|
+
(resourceEvent)="onTableResourceEvent($event)"
|
|
5543
5713
|
(rowAction)="onTableRowAction($event)"
|
|
5544
5714
|
(toolbarAction)="onToolbarAction($event)"
|
|
5545
5715
|
(bulkAction)="onBulkAction($event)"
|
|
5546
5716
|
(collectionLinksChange)="onCollectionLinksChange($event)"
|
|
5547
5717
|
(reset)="onResetPreferences()"
|
|
5718
|
+
(configChange)="onTableConfigChange($event)"
|
|
5548
5719
|
(metadataChange)="onTableMetadataChange()"
|
|
5549
5720
|
(loadingStateChange)="onTableLoadingStateChange($event)"
|
|
5550
5721
|
></praxis-table>
|
|
@@ -5574,6 +5745,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
5574
5745
|
type: Input
|
|
5575
5746
|
}], enableCustomization: [{
|
|
5576
5747
|
type: Input
|
|
5748
|
+
}], showResourceIdentityKey: [{
|
|
5749
|
+
type: Input
|
|
5577
5750
|
}], authoringCapability: [{
|
|
5578
5751
|
type: Input
|
|
5579
5752
|
}], configureRequested: [{
|
|
@@ -5586,6 +5759,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
5586
5759
|
type: Output
|
|
5587
5760
|
}], afterDelete: [{
|
|
5588
5761
|
type: Output
|
|
5762
|
+
}], reactiveDeterminationExecuted: [{
|
|
5763
|
+
type: Output
|
|
5764
|
+
}], reactiveDeterminationPendingChange: [{
|
|
5765
|
+
type: Output
|
|
5766
|
+
}], reactiveDeterminationStabilityChange: [{
|
|
5767
|
+
type: Output
|
|
5589
5768
|
}], error: [{
|
|
5590
5769
|
type: Output
|
|
5591
5770
|
}], rowClick: [{
|
|
@@ -5594,7 +5773,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
5594
5773
|
type: Output
|
|
5595
5774
|
}], selectionChange: [{
|
|
5596
5775
|
type: Output
|
|
5597
|
-
}], tableRuntimeConfigChange: [{
|
|
5776
|
+
}], resourceEvent: [{ type: i0.Output, args: ["resourceEvent"] }], tableRuntimeConfigChange: [{
|
|
5598
5777
|
type: Output
|
|
5599
5778
|
}], crudAuthoringDocumentApplied: [{
|
|
5600
5779
|
type: Output
|
|
@@ -5633,6 +5812,9 @@ class DynamicFormDialogHostComponent {
|
|
|
5633
5812
|
configStorage;
|
|
5634
5813
|
surfaceRef;
|
|
5635
5814
|
formComp;
|
|
5815
|
+
reactiveDeterminationExecuted = new EventEmitter();
|
|
5816
|
+
reactiveDeterminationPendingChange = new EventEmitter();
|
|
5817
|
+
reactiveDeterminationStabilityChange = new EventEmitter();
|
|
5636
5818
|
modal = {};
|
|
5637
5819
|
presentation = 'modal';
|
|
5638
5820
|
maximized = false;
|
|
@@ -5644,11 +5826,13 @@ class DynamicFormDialogHostComponent {
|
|
|
5644
5826
|
terminalClose = false;
|
|
5645
5827
|
destroyRef = inject(DestroyRef);
|
|
5646
5828
|
i18n = inject(PraxisI18nService);
|
|
5829
|
+
reactiveDeterminationStabilitySignature = '';
|
|
5647
5830
|
resourcePath;
|
|
5648
5831
|
resourceId;
|
|
5649
5832
|
initialValue;
|
|
5650
5833
|
resourceIdentity = null;
|
|
5651
5834
|
contextIdentity = null;
|
|
5835
|
+
showResourceIdentityKey = true;
|
|
5652
5836
|
schemaUrl;
|
|
5653
5837
|
submitUrl;
|
|
5654
5838
|
submitMethod;
|
|
@@ -5737,6 +5921,7 @@ class DynamicFormDialogHostComponent {
|
|
|
5737
5921
|
this.resourceIdentity = this.mode !== 'create' && this.data.resourceIdentity
|
|
5738
5922
|
? this.data.resourceIdentity
|
|
5739
5923
|
: null;
|
|
5924
|
+
this.showResourceIdentityKey = this.data.showResourceIdentityKey !== false;
|
|
5740
5925
|
this.contextIdentity = this.data.contextIdentity
|
|
5741
5926
|
? this.data.contextIdentity
|
|
5742
5927
|
: null;
|
|
@@ -5967,6 +6152,9 @@ class DynamicFormDialogHostComponent {
|
|
|
5967
6152
|
if (stage === 'before' || stage === 'error') {
|
|
5968
6153
|
return;
|
|
5969
6154
|
}
|
|
6155
|
+
if (this.formComp?.hasPendingReactiveDeterminations?.()
|
|
6156
|
+
|| this.formComp?.hasUnsatisfiedReactiveDeterminations?.())
|
|
6157
|
+
return;
|
|
5970
6158
|
if (this.modal.closeOnSave === false) {
|
|
5971
6159
|
this.saveState();
|
|
5972
6160
|
return;
|
|
@@ -5982,6 +6170,47 @@ class DynamicFormDialogHostComponent {
|
|
|
5982
6170
|
}
|
|
5983
6171
|
}
|
|
5984
6172
|
onCancel() {
|
|
6173
|
+
if (this.formComp?.hasPendingReactiveDeterminations?.()
|
|
6174
|
+
|| this.formComp?.hasUnsatisfiedReactiveDeterminations?.()) {
|
|
6175
|
+
void this.formComp.waitForReactiveDeterminations().then((stable) => {
|
|
6176
|
+
if (stable)
|
|
6177
|
+
this.continueCancel();
|
|
6178
|
+
});
|
|
6179
|
+
return;
|
|
6180
|
+
}
|
|
6181
|
+
this.continueCancel();
|
|
6182
|
+
}
|
|
6183
|
+
onReactiveDeterminationExecuted(event) {
|
|
6184
|
+
this.reactiveDeterminationExecuted.emit(event);
|
|
6185
|
+
this.data.reactiveDeterminationCallbacks?.onEvent?.(event);
|
|
6186
|
+
this.emitReactiveDeterminationStability();
|
|
6187
|
+
}
|
|
6188
|
+
onReactiveDeterminationPendingChange(pending) {
|
|
6189
|
+
this.reactiveDeterminationPendingChange.emit(pending);
|
|
6190
|
+
this.data.reactiveDeterminationCallbacks?.onPendingChange?.(pending);
|
|
6191
|
+
this.emitReactiveDeterminationStability();
|
|
6192
|
+
}
|
|
6193
|
+
emitReactiveDeterminationStability() {
|
|
6194
|
+
const pending = this.formComp?.hasPendingReactiveDeterminations?.() === true;
|
|
6195
|
+
const unsatisfied = this.formComp?.hasUnsatisfiedReactiveDeterminations?.() === true;
|
|
6196
|
+
const status = pending
|
|
6197
|
+
? 'pending'
|
|
6198
|
+
: unsatisfied
|
|
6199
|
+
? 'settled-unsatisfied'
|
|
6200
|
+
: 'settled-satisfied';
|
|
6201
|
+
const signature = `${status}:${pending}:${unsatisfied}`;
|
|
6202
|
+
if (signature === this.reactiveDeterminationStabilitySignature)
|
|
6203
|
+
return;
|
|
6204
|
+
this.reactiveDeterminationStabilitySignature = signature;
|
|
6205
|
+
const stability = {
|
|
6206
|
+
status,
|
|
6207
|
+
pending,
|
|
6208
|
+
unsatisfied,
|
|
6209
|
+
};
|
|
6210
|
+
this.reactiveDeterminationStabilityChange.emit(stability);
|
|
6211
|
+
this.data.reactiveDeterminationCallbacks?.onStabilityChange?.(stability);
|
|
6212
|
+
}
|
|
6213
|
+
continueCancel() {
|
|
5985
6214
|
if (this.surfaceRef) {
|
|
5986
6215
|
void this.canLeaveSurfaceFrame().then((allowed) => {
|
|
5987
6216
|
if (!allowed)
|
|
@@ -6018,6 +6247,12 @@ class DynamicFormDialogHostComponent {
|
|
|
6018
6247
|
}
|
|
6019
6248
|
}
|
|
6020
6249
|
async canLeaveSurfaceFrame() {
|
|
6250
|
+
if (this.formComp?.hasPendingReactiveDeterminations?.()
|
|
6251
|
+
|| this.formComp?.hasUnsatisfiedReactiveDeterminations?.()) {
|
|
6252
|
+
const stable = await this.formComp.waitForReactiveDeterminations();
|
|
6253
|
+
if (!stable)
|
|
6254
|
+
return false;
|
|
6255
|
+
}
|
|
6021
6256
|
if (this.terminalClose || !this.formComp?.form.dirty) {
|
|
6022
6257
|
return true;
|
|
6023
6258
|
}
|
|
@@ -6157,7 +6392,7 @@ class DynamicFormDialogHostComponent {
|
|
|
6157
6392
|
return { ...horizontal, ...vertical };
|
|
6158
6393
|
}
|
|
6159
6394
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DynamicFormDialogHostComponent, deps: [{ token: MatDialogRef, optional: true }, { token: MAT_DIALOG_DATA, optional: true }, { token: DialogService }, { token: i2$1.GenericCrudService }, { token: ASYNC_CONFIG_STORAGE }, { token: SURFACE_DRAWER_REF, optional: true }, { token: SURFACE_DRAWER_CONTENT_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
6160
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: DynamicFormDialogHostComponent, isStandalone: true, selector: "praxis-dynamic-form-dialog-host", host: { properties: { "attr.data-density": "modal.density || \"default\"", "attr.data-presentation": "presentation", "class.praxis-drawer": "presentation === \"drawer\"", "class.praxis-surface-frame": "isSurfaceFrame" }, classAttribute: "praxis-dialog" }, providers: [
|
|
6395
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: DynamicFormDialogHostComponent, isStandalone: true, selector: "praxis-dynamic-form-dialog-host", outputs: { reactiveDeterminationExecuted: "reactiveDeterminationExecuted", reactiveDeterminationPendingChange: "reactiveDeterminationPendingChange", reactiveDeterminationStabilityChange: "reactiveDeterminationStabilityChange" }, host: { properties: { "attr.data-density": "modal.density || \"default\"", "attr.data-presentation": "presentation", "class.praxis-drawer": "presentation === \"drawer\"", "class.praxis-surface-frame": "isSurfaceFrame" }, classAttribute: "praxis-dialog" }, providers: [
|
|
6161
6396
|
GenericCrudService,
|
|
6162
6397
|
providePraxisI18nConfig(PRAXIS_CRUD_RUNTIME_I18N_CONFIG),
|
|
6163
6398
|
], viewQueries: [{ propertyName: "formComp", first: true, predicate: PraxisDynamicForm, descendants: true }], ngImport: i0, template: `
|
|
@@ -6229,7 +6464,8 @@ class DynamicFormDialogHostComponent {
|
|
|
6229
6464
|
<praxis-resource-identity
|
|
6230
6465
|
[identity]="resourceIdentity"
|
|
6231
6466
|
density="compact"
|
|
6232
|
-
[
|
|
6467
|
+
[showKey]="showResourceIdentityKey"
|
|
6468
|
+
[showKeyLabel]="showResourceIdentityKey"
|
|
6233
6469
|
[ariaLabel]="resourceIdentityLabel"
|
|
6234
6470
|
></praxis-resource-identity>
|
|
6235
6471
|
</div>
|
|
@@ -6256,9 +6492,11 @@ class DynamicFormDialogHostComponent {
|
|
|
6256
6492
|
[actions]="formActions"
|
|
6257
6493
|
(formSubmit)="onSave($event)"
|
|
6258
6494
|
(formCancel)="onCancel()"
|
|
6495
|
+
(reactiveDeterminationExecuted)="onReactiveDeterminationExecuted($event)"
|
|
6496
|
+
(reactiveDeterminationPendingChange)="onReactiveDeterminationPendingChange($event)"
|
|
6259
6497
|
></praxis-dynamic-form>
|
|
6260
6498
|
</mat-dialog-content>
|
|
6261
|
-
`, isInline: true, styles: ["praxis-dynamic-form-dialog-host{--dlg-header-h: 56px;--dlg-footer-h: 56px;--dlg-pad: 16px;display:flex;flex-direction:column;height:100%;overflow:hidden}praxis-dynamic-form-dialog-host[data-density=compact]{--dlg-header-h: 44px;--dlg-footer-h: 44px;--dlg-pad: 12px}praxis-dynamic-form-dialog-host .dialog-header{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:var(--dlg-pad);min-height:var(--dlg-header-h);padding:10px var(--dlg-pad);margin:0;background:var(--md-sys-color-surface-container-high);border-bottom:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-title{margin:0;font:inherit;font-weight:600;color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-heading{display:grid;min-width:0;gap:2px}praxis-dynamic-form-dialog-host .dialog-title-icon{display:inline-grid;flex:0 0 auto;width:36px;height:36px;place-items:center;border-radius:10px;color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}praxis-dynamic-form-dialog-host .dialog-title-icon mat-icon{width:22px;height:22px;font-size:22px}praxis-dynamic-form-dialog-host .dialog-subtitle{display:-webkit-box;overflow:hidden;color:var(--md-sys-color-on-surface-variant);font-size:.82rem;font-weight:400;line-height:1.35;-webkit-box-orient:vertical;-webkit-line-clamp:2}praxis-dynamic-form-dialog-host .spacer{flex:1}praxis-dynamic-form-dialog-host .dialog-content{flex:1 1 auto;overflow:auto;padding:var(--dlg-pad);max-height:calc(100svh - var(--dlg-header-h) - 32px)}praxis-dynamic-form-dialog-host .crud-operation-context{position:sticky;top:0;z-index:1;display:grid;gap:.75rem;margin-block-end:var(--dlg-pad);padding-block:.5rem .75rem;background:var(--pfx-form-surface, var(--md-sys-color-surface));border-bottom:1px solid var(--md-sys-color-outline-variant)}praxis-dynamic-form-dialog-host .crud-resource-identity{display:grid;gap:.25rem;min-width:0}praxis-dynamic-form-dialog-host .crud-resource-identity__label{color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-label-medium, 500 .75rem/1rem inherit)}praxis-dynamic-form-dialog-host.praxis-drawer{--dlg-header-h: 72px;width:100%;min-width:0;max-width:100vw;height:100dvh;background:var(--pfx-form-surface, var(--md-sys-color-surface));color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-header{background:color-mix(in srgb,var(--md-sys-color-surface-container-high, var(--md-sys-color-surface)),transparent 4%)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content{display:flex;flex-direction:column;max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form{display:block;flex:1 1 auto;min-height:0}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form>.praxis-dynamic-form{min-height:100%}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form>.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections]{margin-top:auto;padding-top:var(--pfx-actions-gap-top, var(--pfx-section-gap, 20px))}praxis-dynamic-form-dialog-host.praxis-surface-frame .dialog-content{max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button{color:var(--md-sys-color-on-surface-variant)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button:hover{color:var(--md-sys-color-primary)}praxis-dynamic-form-dialog-host .dialog-footer{position:sticky;bottom:0;z-index:1;padding:var(--dlg-pad)}.pfx-blur-backdrop{background-color:var(--pfx-backdrop, rgba(15, 23, 42, .42))!important;backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%);-webkit-backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%)}.pfx-transparent-backdrop{background-color:transparent!important}.cdk-overlay-pane.pfx-dialog-pane{overflow:hidden;transition:width .2s ease,height .2s ease,margin .2s ease}.cdk-overlay-pane.pfx-dialog-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane .mdc-dialog__surface{display:flex;flex-direction:column;width:100%;min-width:0;height:100%;max-height:inherit;overflow:hidden;background:var(--pfx-form-surface, var(--md-sys-color-surface))!important;border:1px solid var(--pfx-form-stroke, var(--md-sys-color-outline-variant))!important}.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mdc-dialog__surface{backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.cdk-overlay-pane.pfx-drawer-pane{margin:0!important;border-radius:0!important;box-shadow:var(--md-sys-elevation-level3, 0 24px 80px rgba(15, 23, 42, .28)),0 0 0 1px color-mix(in srgb,var(--md-sys-color-outline, #64748b) 24%,transparent)}.cdk-overlay-pane.pfx-drawer-pane.pfx-drawer-maximized{margin:var(--pfx-drawer-edge-gap, 8px)!important}.cdk-overlay-pane.pfx-drawer-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-drawer-pane .mdc-dialog__surface{min-width:0!important;border-radius:0!important}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisResourceIdentityComponent, selector: "praxis-resource-identity", inputs: ["identity", "emptyTitle", "density", "showMetadataLabels", "showKeyLabel", "ariaLabel"] }, { kind: "component", type: PraxisDynamicForm, selector: "praxis-dynamic-form", inputs: ["resourcePath", "resourceId", "initialValue", "editorialContext", "mode", "config", "actions", "schemaSource", "schemaUrl", "readUrl", "submitUrl", "submitMethod", "submitIdempotencyKey", "submitCorrelationId", "submitResourceVersion", "responseSchemaUrl", "apiEndpointKey", "apiUrlEntry", "enableCustomization", "showAiAssistant", "formId", "componentInstanceId", "configPersistenceStrategy", "layout", "generatedLayoutPreset", "layoutPolicy", "backConfig", "hooks", "removeEmptyContainersOnSave", "reactiveValidation", "reactiveValidationDebounceMs", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "readonlyModeGlobal", "disabledModeGlobal", "presentationModeGlobal", "visibleGlobal", "fieldIconPolicy", "domainRules", "customEndpoints"], outputs: ["formSubmit", "formCancel", "formReset", "configChange", "configPatchChange", "formReady", "valueChange", "syncCompleted", "initializationError", "loadingStateChange", "enableCustomizationChange", "customAction", "actionConfirmation", "schemaStatusChange", "fieldRenderError", "ruleDiagnosticsChange"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
6499
|
+
`, isInline: true, styles: ["praxis-dynamic-form-dialog-host{--dlg-header-h: 56px;--dlg-footer-h: 56px;--dlg-pad: 16px;display:flex;flex-direction:column;height:100%;overflow:hidden}praxis-dynamic-form-dialog-host[data-density=compact]{--dlg-header-h: 44px;--dlg-footer-h: 44px;--dlg-pad: 12px}praxis-dynamic-form-dialog-host .dialog-header{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:var(--dlg-pad);min-height:var(--dlg-header-h);padding:10px var(--dlg-pad);margin:0;background:var(--md-sys-color-surface-container-high);border-bottom:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-title{margin:0;font:inherit;font-weight:600;color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-heading{display:grid;min-width:0;gap:2px}praxis-dynamic-form-dialog-host .dialog-title-icon{display:inline-grid;flex:0 0 auto;width:36px;height:36px;place-items:center;border-radius:10px;color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}praxis-dynamic-form-dialog-host .dialog-title-icon mat-icon{width:22px;height:22px;font-size:22px}praxis-dynamic-form-dialog-host .dialog-subtitle{display:-webkit-box;overflow:hidden;color:var(--md-sys-color-on-surface-variant);font-size:.82rem;font-weight:400;line-height:1.35;-webkit-box-orient:vertical;-webkit-line-clamp:2}praxis-dynamic-form-dialog-host .spacer{flex:1}praxis-dynamic-form-dialog-host .dialog-content{flex:1 1 auto;overflow:auto;padding:var(--dlg-pad);max-height:calc(100svh - var(--dlg-header-h) - 32px)}praxis-dynamic-form-dialog-host .crud-operation-context{position:sticky;top:0;z-index:1;display:grid;gap:.75rem;margin-block-end:var(--dlg-pad);padding-block:.5rem .75rem;background:var(--pfx-form-surface, var(--md-sys-color-surface));border-bottom:1px solid var(--md-sys-color-outline-variant)}praxis-dynamic-form-dialog-host .crud-resource-identity{display:grid;gap:.25rem;min-width:0}praxis-dynamic-form-dialog-host .crud-resource-identity__label{color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-label-medium, 500 .75rem/1rem inherit)}praxis-dynamic-form-dialog-host.praxis-drawer{--dlg-header-h: 72px;width:100%;min-width:0;max-width:100vw;height:100dvh;background:var(--pfx-form-surface, var(--md-sys-color-surface));color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-header{background:color-mix(in srgb,var(--md-sys-color-surface-container-high, var(--md-sys-color-surface)),transparent 4%)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content{display:flex;flex-direction:column;max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form{display:block;flex:1 1 auto;min-height:0}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form>.praxis-dynamic-form{min-height:100%}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form>.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections]{margin-top:auto;padding-top:var(--pfx-actions-gap-top, var(--pfx-section-gap, 20px))}praxis-dynamic-form-dialog-host.praxis-surface-frame .dialog-content{max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button{color:var(--md-sys-color-on-surface-variant)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button:hover{color:var(--md-sys-color-primary)}praxis-dynamic-form-dialog-host .dialog-footer{position:sticky;bottom:0;z-index:1;padding:var(--dlg-pad)}.pfx-blur-backdrop{background-color:var(--pfx-backdrop, rgba(15, 23, 42, .42))!important;backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%);-webkit-backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%)}.pfx-transparent-backdrop{background-color:transparent!important}.cdk-overlay-pane.pfx-dialog-pane{overflow:hidden;transition:width .2s ease,height .2s ease,margin .2s ease}.cdk-overlay-pane.pfx-dialog-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane .mdc-dialog__surface{display:flex;flex-direction:column;width:100%;min-width:0;height:100%;max-height:inherit;overflow:hidden;background:var(--pfx-form-surface, var(--md-sys-color-surface))!important;border:1px solid var(--pfx-form-stroke, var(--md-sys-color-outline-variant))!important}.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mdc-dialog__surface{backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.cdk-overlay-pane.pfx-drawer-pane{margin:0!important;border-radius:0!important;box-shadow:var(--md-sys-elevation-level3, 0 24px 80px rgba(15, 23, 42, .28)),0 0 0 1px color-mix(in srgb,var(--md-sys-color-outline, #64748b) 24%,transparent)}.cdk-overlay-pane.pfx-drawer-pane.pfx-drawer-maximized{margin:var(--pfx-drawer-edge-gap, 8px)!important}.cdk-overlay-pane.pfx-drawer-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-drawer-pane .mdc-dialog__surface{min-width:0!important;border-radius:0!important}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisResourceIdentityComponent, selector: "praxis-resource-identity", inputs: ["identity", "emptyTitle", "density", "showMetadataLabels", "showKey", "showKeyLabel", "ariaLabel"] }, { kind: "component", type: PraxisDynamicForm, selector: "praxis-dynamic-form", inputs: ["resourcePath", "resourceId", "initialValue", "editorialContext", "mode", "config", "actions", "schemaSource", "schemaUrl", "readUrl", "submitUrl", "submitMethod", "submitIdempotencyKey", "submitCorrelationId", "submitResourceVersion", "submitResourceVersionTargetResourceKey", "submitResourceVersionTargetIdField", "responseSchemaUrl", "apiEndpointKey", "apiUrlEntry", "enableCustomization", "showAiAssistant", "formId", "componentInstanceId", "configPersistenceStrategy", "layout", "generatedLayoutPreset", "layoutPolicy", "backConfig", "hooks", "removeEmptyContainersOnSave", "reactiveValidation", "reactiveValidationDebounceMs", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "readonlyModeGlobal", "disabledModeGlobal", "presentationModeGlobal", "visibleGlobal", "fieldIconPolicy", "domainRules", "customEndpoints"], outputs: ["formSubmit", "formCancel", "formReset", "configChange", "configPatchChange", "formReady", "valueChange", "syncCompleted", "initializationError", "loadingStateChange", "enableCustomizationChange", "customAction", "actionConfirmation", "schemaStatusChange", "fieldRenderError", "ruleDiagnosticsChange", "reactiveDeterminationExecuted", "reactiveDeterminationPendingChange"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
6262
6500
|
}
|
|
6263
6501
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: DynamicFormDialogHostComponent, decorators: [{
|
|
6264
6502
|
type: Component,
|
|
@@ -6347,7 +6585,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
6347
6585
|
<praxis-resource-identity
|
|
6348
6586
|
[identity]="resourceIdentity"
|
|
6349
6587
|
density="compact"
|
|
6350
|
-
[
|
|
6588
|
+
[showKey]="showResourceIdentityKey"
|
|
6589
|
+
[showKeyLabel]="showResourceIdentityKey"
|
|
6351
6590
|
[ariaLabel]="resourceIdentityLabel"
|
|
6352
6591
|
></praxis-resource-identity>
|
|
6353
6592
|
</div>
|
|
@@ -6374,6 +6613,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
6374
6613
|
[actions]="formActions"
|
|
6375
6614
|
(formSubmit)="onSave($event)"
|
|
6376
6615
|
(formCancel)="onCancel()"
|
|
6616
|
+
(reactiveDeterminationExecuted)="onReactiveDeterminationExecuted($event)"
|
|
6617
|
+
(reactiveDeterminationPendingChange)="onReactiveDeterminationPendingChange($event)"
|
|
6377
6618
|
></praxis-dynamic-form>
|
|
6378
6619
|
</mat-dialog-content>
|
|
6379
6620
|
`, styles: ["praxis-dynamic-form-dialog-host{--dlg-header-h: 56px;--dlg-footer-h: 56px;--dlg-pad: 16px;display:flex;flex-direction:column;height:100%;overflow:hidden}praxis-dynamic-form-dialog-host[data-density=compact]{--dlg-header-h: 44px;--dlg-footer-h: 44px;--dlg-pad: 12px}praxis-dynamic-form-dialog-host .dialog-header{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:var(--dlg-pad);min-height:var(--dlg-header-h);padding:10px var(--dlg-pad);margin:0;background:var(--md-sys-color-surface-container-high);border-bottom:1px solid var(--md-sys-color-outline-variant);color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-title{margin:0;font:inherit;font-weight:600;color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host .dialog-heading{display:grid;min-width:0;gap:2px}praxis-dynamic-form-dialog-host .dialog-title-icon{display:inline-grid;flex:0 0 auto;width:36px;height:36px;place-items:center;border-radius:10px;color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}praxis-dynamic-form-dialog-host .dialog-title-icon mat-icon{width:22px;height:22px;font-size:22px}praxis-dynamic-form-dialog-host .dialog-subtitle{display:-webkit-box;overflow:hidden;color:var(--md-sys-color-on-surface-variant);font-size:.82rem;font-weight:400;line-height:1.35;-webkit-box-orient:vertical;-webkit-line-clamp:2}praxis-dynamic-form-dialog-host .spacer{flex:1}praxis-dynamic-form-dialog-host .dialog-content{flex:1 1 auto;overflow:auto;padding:var(--dlg-pad);max-height:calc(100svh - var(--dlg-header-h) - 32px)}praxis-dynamic-form-dialog-host .crud-operation-context{position:sticky;top:0;z-index:1;display:grid;gap:.75rem;margin-block-end:var(--dlg-pad);padding-block:.5rem .75rem;background:var(--pfx-form-surface, var(--md-sys-color-surface));border-bottom:1px solid var(--md-sys-color-outline-variant)}praxis-dynamic-form-dialog-host .crud-resource-identity{display:grid;gap:.25rem;min-width:0}praxis-dynamic-form-dialog-host .crud-resource-identity__label{color:var(--md-sys-color-on-surface-variant);font:var(--md-sys-typescale-label-medium, 500 .75rem/1rem inherit)}praxis-dynamic-form-dialog-host.praxis-drawer{--dlg-header-h: 72px;width:100%;min-width:0;max-width:100vw;height:100dvh;background:var(--pfx-form-surface, var(--md-sys-color-surface));color:var(--md-sys-color-on-surface)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-header{background:color-mix(in srgb,var(--md-sys-color-surface-container-high, var(--md-sys-color-surface)),transparent 4%)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content{display:flex;flex-direction:column;max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form{display:block;flex:1 1 auto;min-height:0}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form>.praxis-dynamic-form{min-height:100%}praxis-dynamic-form-dialog-host.praxis-drawer .dialog-content>praxis-dynamic-form>.praxis-dynamic-form>praxis-form-actions[data-actions-placement=afterSections]{margin-top:auto;padding-top:var(--pfx-actions-gap-top, var(--pfx-section-gap, 20px))}praxis-dynamic-form-dialog-host.praxis-surface-frame .dialog-content{max-height:none;min-height:0;padding:clamp(12px,2.4vw,24px)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button{color:var(--md-sys-color-on-surface-variant)}praxis-dynamic-form-dialog-host .dialog-header button.praxis-icon-button:hover{color:var(--md-sys-color-primary)}praxis-dynamic-form-dialog-host .dialog-footer{position:sticky;bottom:0;z-index:1;padding:var(--dlg-pad)}.pfx-blur-backdrop{background-color:var(--pfx-backdrop, rgba(15, 23, 42, .42))!important;backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%);-webkit-backdrop-filter:blur(var(--pfx-backdrop-blur, 10px)) saturate(110%)}.pfx-transparent-backdrop{background-color:transparent!important}.cdk-overlay-pane.pfx-dialog-pane{overflow:hidden;transition:width .2s ease,height .2s ease,margin .2s ease}.cdk-overlay-pane.pfx-dialog-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane .mdc-dialog__surface{display:flex;flex-direction:column;width:100%;min-width:0;height:100%;max-height:inherit;overflow:hidden;background:var(--pfx-form-surface, var(--md-sys-color-surface))!important;border:1px solid var(--pfx-form-stroke, var(--md-sys-color-outline-variant))!important}.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-dialog-pane.pfx-dialog-frosted .mdc-dialog__surface{backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.cdk-overlay-pane.pfx-drawer-pane{margin:0!important;border-radius:0!important;box-shadow:var(--md-sys-elevation-level3, 0 24px 80px rgba(15, 23, 42, .28)),0 0 0 1px color-mix(in srgb,var(--md-sys-color-outline, #64748b) 24%,transparent)}.cdk-overlay-pane.pfx-drawer-pane.pfx-drawer-maximized{margin:var(--pfx-drawer-edge-gap, 8px)!important}.cdk-overlay-pane.pfx-drawer-pane .mat-mdc-dialog-surface,.cdk-overlay-pane.pfx-drawer-pane .mdc-dialog__surface{min-width:0!important;border-radius:0!important}\n"] }]
|
|
@@ -6403,6 +6644,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
6403
6644
|
}] }], propDecorators: { formComp: [{
|
|
6404
6645
|
type: ViewChild,
|
|
6405
6646
|
args: [PraxisDynamicForm]
|
|
6647
|
+
}], reactiveDeterminationExecuted: [{
|
|
6648
|
+
type: Output
|
|
6649
|
+
}], reactiveDeterminationPendingChange: [{
|
|
6650
|
+
type: Output
|
|
6651
|
+
}], reactiveDeterminationStabilityChange: [{
|
|
6652
|
+
type: Output
|
|
6406
6653
|
}] } });
|
|
6407
6654
|
function getFormSubmitStage(result) {
|
|
6408
6655
|
if (!result || typeof result !== 'object' || !('stage' in result)) {
|
|
@@ -6681,6 +6928,12 @@ const PRAXIS_CRUD_COMPONENT_METADATA = {
|
|
|
6681
6928
|
default: false,
|
|
6682
6929
|
description: 'Habilita modo de customização do layout.',
|
|
6683
6930
|
},
|
|
6931
|
+
{
|
|
6932
|
+
name: 'showResourceIdentityKey',
|
|
6933
|
+
type: 'boolean',
|
|
6934
|
+
default: true,
|
|
6935
|
+
description: 'Controla se modal e drawer exibem a chave da identidade canônica do registro. Use false quando a chave pública for opaca ou apenas técnica; o título legível permanece visível.',
|
|
6936
|
+
},
|
|
6684
6937
|
{
|
|
6685
6938
|
name: 'authoringCapability',
|
|
6686
6939
|
type: 'string | null',
|
|
@@ -6709,6 +6962,21 @@ const PRAXIS_CRUD_COMPONENT_METADATA = {
|
|
|
6709
6962
|
type: '{ id: string | number }',
|
|
6710
6963
|
description: 'Emitido ao deletar.',
|
|
6711
6964
|
},
|
|
6965
|
+
{
|
|
6966
|
+
name: 'reactiveDeterminationExecuted',
|
|
6967
|
+
type: '{ action: string; event: ReactiveDeterminationExecutionEvent }',
|
|
6968
|
+
description: 'Evidencia metadata-only encaminhada pelo formulario aberto, com contexto da acao CRUD.',
|
|
6969
|
+
},
|
|
6970
|
+
{
|
|
6971
|
+
name: 'reactiveDeterminationPendingChange',
|
|
6972
|
+
type: '{ action: string; pending: boolean }',
|
|
6973
|
+
description: 'Estado agregado de estabilizacao do formulario aberto, sem valores sensiveis.',
|
|
6974
|
+
},
|
|
6975
|
+
{
|
|
6976
|
+
name: 'reactiveDeterminationStabilityChange',
|
|
6977
|
+
type: 'CrudReactiveDeterminationStabilityChange',
|
|
6978
|
+
description: 'Conclusao agregada do formulario aberto, distinguindo settled-satisfied de settled-unsatisfied e preservando o contexto da acao.',
|
|
6979
|
+
},
|
|
6712
6980
|
{
|
|
6713
6981
|
name: 'rowClick',
|
|
6714
6982
|
type: '{ row: unknown; index: number }',
|
|
@@ -6724,6 +6992,11 @@ const PRAXIS_CRUD_COMPONENT_METADATA = {
|
|
|
6724
6992
|
type: 'unknown',
|
|
6725
6993
|
description: 'Encaminha a mudança de seleção da tabela interna quando o CRUD é usado como widget composto.',
|
|
6726
6994
|
},
|
|
6995
|
+
{
|
|
6996
|
+
name: 'resourceEvent',
|
|
6997
|
+
type: 'PraxisResourceEvent<unknown>',
|
|
6998
|
+
description: 'Encaminha o envelope canônico da tabela interna com kind, resourcePath, resourceId, payload e contexto para composição governada.',
|
|
6999
|
+
},
|
|
6727
7000
|
{
|
|
6728
7001
|
name: 'error',
|
|
6729
7002
|
type: 'unknown',
|
|
@@ -7218,10 +7491,12 @@ const PRAXIS_CRUD_AUTHORING_MANIFEST = {
|
|
|
7218
7491
|
{ name: 'tableConfigPersistenceStrategy', type: "'local-first' | 'input-first' | 'volatile'", description: 'Persistence precedence forwarded to the internal Praxis Table. Governed previews should use input-first or volatile explicitly.' },
|
|
7219
7492
|
{ name: 'context', type: 'Record<string, unknown>', description: 'Opaque host context used for authoring seeds and launcher inputs.' },
|
|
7220
7493
|
{ name: 'enableCustomization', type: 'boolean', description: 'Explicit host opt-in for CRUD authoring surfaces.' },
|
|
7494
|
+
{ name: 'showResourceIdentityKey', type: 'boolean', description: 'Presentation-only control for the canonical key in existing-record modal and drawer headers. Defaults to true; false preserves the readable title while hiding an opaque or technical key.' },
|
|
7221
7495
|
{ name: 'authoringCapability', type: 'string | null', description: 'Public runtime capability required before CRUD and delegated table authoring can open.' },
|
|
7222
7496
|
{ name: 'afterOpen', type: '{ mode: FormOpenMode; action: string }', description: 'Emitted after a CRUD action opens.' },
|
|
7223
7497
|
{ name: 'afterSave', type: '{ id: string | number; data: unknown }', description: 'Emitted after save; CRUD refetches the list.' },
|
|
7224
7498
|
{ name: 'afterDelete', type: '{ id: string | number }', description: 'Emitted after delete; CRUD refetches the list.' },
|
|
7499
|
+
{ name: 'resourceEvent', type: 'PraxisResourceEvent<unknown>', description: 'Canonical resource interaction envelope forwarded from the internal table for governed host composition.' },
|
|
7225
7500
|
],
|
|
7226
7501
|
editableTargets: [
|
|
7227
7502
|
{ kind: 'resourceBinding', resolver: 'crud-resource-by-path-or-key', description: 'Resource path/key, optional schema path template, id field, endpoint key and query context owned by CRUD orchestration.' },
|