@praxisui/crud 9.0.0-beta.71 → 9.0.0-beta.72
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 +28 -0
- package/ai/component-registry.json +303 -54
- package/fesm2022/praxisui-crud.mjs +190 -6
- package/package.json +7 -7
- package/types/praxisui-crud.d.ts +12 -1
|
@@ -6,7 +6,7 @@ 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, fillUndefined, SETTINGS_PANEL_DATA, PraxisI18nService, PraxisIconDirective, providePraxisI18nConfig, createDefaultTableConfig, GLOBAL_SURFACE_SERVICE, SurfaceOutletRegistryService, ComponentKeyService, ResourceDiscoveryService, ResourceActionOpenAdapterService, ResourceSurfaceOpenAdapterService, translateUnavailableWorkflowMessage, EmptyStateCardComponent, RESOURCE_DISCOVERY_I18N_CONFIG, GenericCrudService, ComponentMetadataRegistry } from '@praxisui/core';
|
|
9
|
+
import { ASYNC_CONFIG_STORAGE, GlobalConfigService, CrudOperationResolutionService, fillUndefined, SETTINGS_PANEL_DATA, PraxisI18nService, PraxisIconDirective, providePraxisI18nConfig, createDefaultTableConfig, EnterpriseRuntimeContextService, GLOBAL_SURFACE_SERVICE, SurfaceOutletRegistryService, ComponentKeyService, ResourceDiscoveryService, ResourceActionOpenAdapterService, ResourceSurfaceOpenAdapterService, translateUnavailableWorkflowMessage, EmptyStateCardComponent, RESOURCE_DISCOVERY_I18N_CONFIG, 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';
|
|
@@ -874,6 +874,11 @@ const PRAXIS_CRUD_RUNTIME_I18N_CONFIG = {
|
|
|
874
874
|
'crud.emptyState.title': 'Conecte o CRUD a um recurso',
|
|
875
875
|
'crud.emptyState.description': 'Informe os metadados (resourcePath / schema) ou forneça metadata.data para habilitar a tabela e as ações.',
|
|
876
876
|
'crud.emptyState.primaryAction': 'Configurar metadados',
|
|
877
|
+
'crud.table.emptyState.initial.title': 'Sem registros em {label}',
|
|
878
|
+
'crud.table.emptyState.initial.titleFallback': 'Nenhum registro disponível.',
|
|
879
|
+
'crud.table.emptyState.initial.descriptionWithAction': 'Use a ação principal para adicionar o primeiro registro quando houver informações para cadastrar.',
|
|
880
|
+
'crud.table.emptyState.filtered.title': 'Nenhum resultado encontrado.',
|
|
881
|
+
'crud.table.emptyState.filtered.description': 'Revise os filtros ou ajuste o termo de busca.',
|
|
877
882
|
'crud.preferences.resetSuccess': 'Overrides de CRUD redefinidos',
|
|
878
883
|
'crud.actions.create': 'Adicionar',
|
|
879
884
|
'crud.actions.view': 'Ver',
|
|
@@ -886,6 +891,11 @@ const PRAXIS_CRUD_RUNTIME_I18N_CONFIG = {
|
|
|
886
891
|
'crud.emptyState.title': 'Connect CRUD to a resource',
|
|
887
892
|
'crud.emptyState.description': 'Provide metadata (resourcePath / schema) or metadata.data to enable the table and actions.',
|
|
888
893
|
'crud.emptyState.primaryAction': 'Configure metadata',
|
|
894
|
+
'crud.table.emptyState.initial.title': 'No records in {label}',
|
|
895
|
+
'crud.table.emptyState.initial.titleFallback': 'No records available.',
|
|
896
|
+
'crud.table.emptyState.initial.descriptionWithAction': 'Use the primary action to add the first record when there is information to register.',
|
|
897
|
+
'crud.table.emptyState.filtered.title': 'No results found.',
|
|
898
|
+
'crud.table.emptyState.filtered.description': 'Review the filters or adjust the search term.',
|
|
889
899
|
'crud.preferences.resetSuccess': 'CRUD overrides reset',
|
|
890
900
|
'crud.actions.create': 'Add',
|
|
891
901
|
'crud.actions.view': 'View',
|
|
@@ -3620,6 +3630,8 @@ class PraxisCrudComponent {
|
|
|
3620
3630
|
componentInstanceId;
|
|
3621
3631
|
context;
|
|
3622
3632
|
enableCustomization = false;
|
|
3633
|
+
/** Capability publica exigida para authoring governado do CRUD e da tabela interna. */
|
|
3634
|
+
authoringCapability = null;
|
|
3623
3635
|
configureRequested = new EventEmitter();
|
|
3624
3636
|
afterOpen = new EventEmitter();
|
|
3625
3637
|
afterClose = new EventEmitter();
|
|
@@ -3644,6 +3656,7 @@ class PraxisCrudComponent {
|
|
|
3644
3656
|
table;
|
|
3645
3657
|
storage = inject(ASYNC_CONFIG_STORAGE);
|
|
3646
3658
|
settingsPanel = inject(SettingsPanelService);
|
|
3659
|
+
enterpriseRuntimeContext = inject(EnterpriseRuntimeContextService, { optional: true });
|
|
3647
3660
|
snack = inject(MatSnackBar);
|
|
3648
3661
|
dialog = inject(DialogService);
|
|
3649
3662
|
i18n = inject(PraxisI18nService);
|
|
@@ -3678,6 +3691,18 @@ class PraxisCrudComponent {
|
|
|
3678
3691
|
lastAppliedResourceIdentity = null;
|
|
3679
3692
|
tableCollectionLinks = null;
|
|
3680
3693
|
collectionCapabilities = null;
|
|
3694
|
+
activeAuthoringPanelRef;
|
|
3695
|
+
constructor() {
|
|
3696
|
+
this.enterpriseRuntimeContext?.contextChanges$
|
|
3697
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
3698
|
+
.subscribe(() => {
|
|
3699
|
+
if (!this.isCustomizationAvailable()) {
|
|
3700
|
+
this.activeAuthoringPanelRef?.close();
|
|
3701
|
+
this.activeAuthoringPanelRef = undefined;
|
|
3702
|
+
}
|
|
3703
|
+
this.cdr.markForCheck();
|
|
3704
|
+
});
|
|
3705
|
+
}
|
|
3681
3706
|
collectionCapabilitiesRequestHref = null;
|
|
3682
3707
|
collectionCapabilitiesResolvedHref = null;
|
|
3683
3708
|
collectionCapabilitiesRequestSeq = 0;
|
|
@@ -3792,6 +3817,10 @@ class PraxisCrudComponent {
|
|
|
3792
3817
|
...(actionMeta || { action: normalizedAction }),
|
|
3793
3818
|
action: this.normalizeCrudActionName(actionMeta?.action ?? normalizedAction),
|
|
3794
3819
|
};
|
|
3820
|
+
const handledByDuplicateDraft = await this.tryHandleCanonicalDuplicateDraftAction(effectiveAction, contextualRow);
|
|
3821
|
+
if (handledByDuplicateDraft) {
|
|
3822
|
+
return;
|
|
3823
|
+
}
|
|
3795
3824
|
if (!this.hasExplicitOpenBinding(effectiveAction)) {
|
|
3796
3825
|
const openedByDiscovery = await this.tryOpenDiscoveredCrudSurface(effectiveAction.action, contextualRow, runtimeEvent);
|
|
3797
3826
|
if (openedByDiscovery) {
|
|
@@ -3975,6 +4004,9 @@ class PraxisCrudComponent {
|
|
|
3975
4004
|
return this.tx('crud.emptyState.primaryAction', 'Configure metadata');
|
|
3976
4005
|
}
|
|
3977
4006
|
onConfigureRequested() {
|
|
4007
|
+
if (!this.isCustomizationAvailable()) {
|
|
4008
|
+
return;
|
|
4009
|
+
}
|
|
3978
4010
|
this.configureRequested.emit();
|
|
3979
4011
|
this.openCrudAuthoringFromTable();
|
|
3980
4012
|
}
|
|
@@ -4025,6 +4057,68 @@ class PraxisCrudComponent {
|
|
|
4025
4057
|
this.refreshTable();
|
|
4026
4058
|
return true;
|
|
4027
4059
|
}
|
|
4060
|
+
async tryHandleCanonicalDuplicateDraftAction(action, row) {
|
|
4061
|
+
const normalizedAction = this.normalizeCrudActionName(action.action);
|
|
4062
|
+
if (normalizedAction !== 'duplicate-draft' || !row) {
|
|
4063
|
+
return false;
|
|
4064
|
+
}
|
|
4065
|
+
const duplicateDraftUrl = this.getResourceDiscovery().resolveLinkHref(row['_links'], 'duplicate-draft', this.buildDiscoveryOptions());
|
|
4066
|
+
if (!duplicateDraftUrl) {
|
|
4067
|
+
return false;
|
|
4068
|
+
}
|
|
4069
|
+
const response = await firstValueFrom(this.http.post(duplicateDraftUrl, {}));
|
|
4070
|
+
const draft = this.unwrapRestData(response);
|
|
4071
|
+
if (!this.isRecord(draft)) {
|
|
4072
|
+
throw new Error('Duplicate draft action returned an invalid create draft.');
|
|
4073
|
+
}
|
|
4074
|
+
const configuredCreateAction = this.resolvedMetadata.actions?.find((candidate) => this.normalizeCrudActionName(candidate.action) === 'create') ?? { action: 'create' };
|
|
4075
|
+
const createAction = {
|
|
4076
|
+
...configuredCreateAction,
|
|
4077
|
+
action: 'create',
|
|
4078
|
+
openMode: configuredCreateAction.openMode ??
|
|
4079
|
+
action.openMode ??
|
|
4080
|
+
this.resolvedMetadata.defaults?.openMode ??
|
|
4081
|
+
'drawer',
|
|
4082
|
+
form: {
|
|
4083
|
+
...(configuredCreateAction.form ?? {}),
|
|
4084
|
+
initialValue: { ...draft },
|
|
4085
|
+
},
|
|
4086
|
+
};
|
|
4087
|
+
let drawerCloseEmitted = false;
|
|
4088
|
+
const emitDrawerClose = () => {
|
|
4089
|
+
if (drawerCloseEmitted)
|
|
4090
|
+
return;
|
|
4091
|
+
drawerCloseEmitted = true;
|
|
4092
|
+
this.afterClose.emit();
|
|
4093
|
+
};
|
|
4094
|
+
const handleResult = (result) => {
|
|
4095
|
+
if (result?.type !== 'save') {
|
|
4096
|
+
return;
|
|
4097
|
+
}
|
|
4098
|
+
const data = this.isRecord(result.data) ? result.data : {};
|
|
4099
|
+
const id = data[this.getIdField()];
|
|
4100
|
+
this.afterSave.emit({ id, data });
|
|
4101
|
+
this.refreshTable();
|
|
4102
|
+
};
|
|
4103
|
+
const { mode, ref } = await this.launcher.launch(createAction, undefined, this.resolvedMetadata, this.componentKeyId(), {
|
|
4104
|
+
onClose: () => emitDrawerClose(),
|
|
4105
|
+
onResult: (result) => handleResult(result),
|
|
4106
|
+
}, {
|
|
4107
|
+
capabilities: this.collectionCapabilities,
|
|
4108
|
+
links: this.tableCollectionLinks,
|
|
4109
|
+
});
|
|
4110
|
+
this.afterOpen.emit({ mode, action: normalizedAction });
|
|
4111
|
+
if (mode !== 'drawer' && ref) {
|
|
4112
|
+
ref
|
|
4113
|
+
.afterClosed()
|
|
4114
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
4115
|
+
.subscribe((result) => {
|
|
4116
|
+
this.afterClose.emit();
|
|
4117
|
+
handleResult(result);
|
|
4118
|
+
});
|
|
4119
|
+
}
|
|
4120
|
+
return true;
|
|
4121
|
+
}
|
|
4028
4122
|
refreshTable() {
|
|
4029
4123
|
if (this.tryRefreshMaterializedLocalData()) {
|
|
4030
4124
|
return;
|
|
@@ -4544,6 +4638,7 @@ class PraxisCrudComponent {
|
|
|
4544
4638
|
});
|
|
4545
4639
|
}
|
|
4546
4640
|
changed = true;
|
|
4641
|
+
changed = this.ensureCanonicalCollectionEmptyState(cfg, meta, addAction) || changed;
|
|
4547
4642
|
}
|
|
4548
4643
|
const discoveredToolbarActions = this.resolveCollectionWorkflowToolbarActions(capabilities);
|
|
4549
4644
|
if (discoveredToolbarActions.length) {
|
|
@@ -4704,6 +4799,9 @@ class PraxisCrudComponent {
|
|
|
4704
4799
|
};
|
|
4705
4800
|
}
|
|
4706
4801
|
openCrudAuthoringFromTable = () => {
|
|
4802
|
+
if (!this.isCustomizationAvailable()) {
|
|
4803
|
+
return;
|
|
4804
|
+
}
|
|
4707
4805
|
const seed = this.currentAuthoringDocument
|
|
4708
4806
|
|| createCrudAuthoringDocument({ metadata: this.resolvedMetadata });
|
|
4709
4807
|
const ref = openCrudMetadataEditor(this.settingsPanel, {
|
|
@@ -4712,13 +4810,33 @@ class PraxisCrudComponent {
|
|
|
4712
4810
|
title: this.tx('crud.authoring.title', 'Configurações do CRUD'),
|
|
4713
4811
|
titleIcon: 'table_chart',
|
|
4714
4812
|
});
|
|
4813
|
+
this.activeAuthoringPanelRef = ref;
|
|
4715
4814
|
ref.applied$
|
|
4716
4815
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
4717
4816
|
.subscribe((payload) => this.applyCrudAuthoringPayload(payload, 'applied'));
|
|
4718
4817
|
ref.saved$
|
|
4719
4818
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
4720
4819
|
.subscribe((payload) => this.applyCrudAuthoringPayload(payload, 'saved'));
|
|
4820
|
+
ref.closed$
|
|
4821
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
4822
|
+
.subscribe(() => {
|
|
4823
|
+
if (this.activeAuthoringPanelRef === ref) {
|
|
4824
|
+
this.activeAuthoringPanelRef = undefined;
|
|
4825
|
+
}
|
|
4826
|
+
});
|
|
4721
4827
|
};
|
|
4828
|
+
isCustomizationAvailable() {
|
|
4829
|
+
if (!this.enableCustomization) {
|
|
4830
|
+
return false;
|
|
4831
|
+
}
|
|
4832
|
+
const requiredCapability = String(this.authoringCapability || '').trim();
|
|
4833
|
+
if (!requiredCapability) {
|
|
4834
|
+
return true;
|
|
4835
|
+
}
|
|
4836
|
+
const capabilities = this.enterpriseRuntimeContext?.snapshot?.capabilities;
|
|
4837
|
+
return Array.isArray(capabilities)
|
|
4838
|
+
&& capabilities.some((capability) => capability === requiredCapability);
|
|
4839
|
+
}
|
|
4722
4840
|
applyCrudAuthoringPayload(payload, eventName) {
|
|
4723
4841
|
const next = parseLegacyOrCrudDocument(payload);
|
|
4724
4842
|
this.currentAuthoringDocument = next;
|
|
@@ -4935,6 +5053,48 @@ class PraxisCrudComponent {
|
|
|
4935
5053
|
return action;
|
|
4936
5054
|
}
|
|
4937
5055
|
}
|
|
5056
|
+
ensureCanonicalCollectionEmptyState(config, metadata, createAction) {
|
|
5057
|
+
const behavior = config.behavior || {};
|
|
5058
|
+
if (behavior.emptyState) {
|
|
5059
|
+
return false;
|
|
5060
|
+
}
|
|
5061
|
+
const resourceLabel = String(metadata.resource?.label
|
|
5062
|
+
|| metadata.resource?.title
|
|
5063
|
+
|| metadata.resource?.path
|
|
5064
|
+
|| '').trim();
|
|
5065
|
+
const title = resourceLabel
|
|
5066
|
+
? this.txWithParams('crud.table.emptyState.initial.title', 'Sem registros em {label}', { label: resourceLabel })
|
|
5067
|
+
: this.tx('crud.table.emptyState.initial.titleFallback', 'Nenhum registro disponível.');
|
|
5068
|
+
const actionId = String(createAction.action || createAction.id || 'create').trim() || 'create';
|
|
5069
|
+
const actionLabel = String(createAction.label || this.getCrudActionLabel('create')).trim();
|
|
5070
|
+
const actionIcon = String(createAction.icon || 'add').trim();
|
|
5071
|
+
config.behavior = {
|
|
5072
|
+
...behavior,
|
|
5073
|
+
emptyState: {
|
|
5074
|
+
message: '',
|
|
5075
|
+
contexts: {
|
|
5076
|
+
initial: {
|
|
5077
|
+
title,
|
|
5078
|
+
description: this.tx('crud.table.emptyState.initial.descriptionWithAction', 'Use a ação principal para adicionar o primeiro registro quando houver informações para cadastrar.'),
|
|
5079
|
+
actions: [
|
|
5080
|
+
{
|
|
5081
|
+
label: actionLabel,
|
|
5082
|
+
action: actionId,
|
|
5083
|
+
icon: actionIcon,
|
|
5084
|
+
primary: true,
|
|
5085
|
+
},
|
|
5086
|
+
],
|
|
5087
|
+
},
|
|
5088
|
+
filtered: {
|
|
5089
|
+
title: this.tx('crud.table.emptyState.filtered.title', 'Nenhum resultado encontrado.'),
|
|
5090
|
+
description: this.tx('crud.table.emptyState.filtered.description', 'Revise os filtros ou ajuste o termo de busca.'),
|
|
5091
|
+
actions: [],
|
|
5092
|
+
},
|
|
5093
|
+
},
|
|
5094
|
+
},
|
|
5095
|
+
};
|
|
5096
|
+
return true;
|
|
5097
|
+
}
|
|
4938
5098
|
tx(key, fallback) {
|
|
4939
5099
|
try {
|
|
4940
5100
|
return translateCrudRuntimeText(this.i18n, key, fallback);
|
|
@@ -4943,8 +5103,19 @@ class PraxisCrudComponent {
|
|
|
4943
5103
|
return fallback;
|
|
4944
5104
|
}
|
|
4945
5105
|
}
|
|
5106
|
+
txWithParams(key, fallback, params) {
|
|
5107
|
+
try {
|
|
5108
|
+
return this.interpolateTranslationParams(translateCrudRuntimeText(this.i18n, key, fallback, params), params);
|
|
5109
|
+
}
|
|
5110
|
+
catch {
|
|
5111
|
+
return this.interpolateTranslationParams(fallback, params);
|
|
5112
|
+
}
|
|
5113
|
+
}
|
|
5114
|
+
interpolateTranslationParams(text, params) {
|
|
5115
|
+
return Object.entries(params).reduce((current, [name, value]) => current.replaceAll(`{${name}}`, value), text);
|
|
5116
|
+
}
|
|
4946
5117
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisCrudComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4947
|
-
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", context: "context", enableCustomization: "enableCustomization" }, outputs: { configureRequested: "configureRequested", afterOpen: "afterOpen", afterClose: "afterClose", afterSave: "afterSave", afterDelete: "afterDelete", error: "error", rowClick: "rowClick", selectionChange: "selectionChange", tableRuntimeConfigChange: "tableRuntimeConfigChange", crudAuthoringDocumentApplied: "crudAuthoringDocumentApplied", crudAuthoringDocumentSaved: "crudAuthoringDocumentSaved" }, providers: [
|
|
5118
|
+
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", context: "context", enableCustomization: "enableCustomization", authoringCapability: "authoringCapability" }, outputs: { configureRequested: "configureRequested", afterOpen: "afterOpen", afterClose: "afterClose", afterSave: "afterSave", afterDelete: "afterDelete", error: "error", rowClick: "rowClick", selectionChange: "selectionChange", tableRuntimeConfigChange: "tableRuntimeConfigChange", crudAuthoringDocumentApplied: "crudAuthoringDocumentApplied", crudAuthoringDocumentSaved: "crudAuthoringDocumentSaved" }, providers: [
|
|
4948
5119
|
providePraxisI18nConfig(RESOURCE_DISCOVERY_I18N_CONFIG),
|
|
4949
5120
|
providePraxisI18nConfig(PRAXIS_CRUD_RUNTIME_I18N_CONFIG),
|
|
4950
5121
|
], viewQueries: [{ propertyName: "table", first: true, predicate: PraxisTable, descendants: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
@@ -4958,6 +5129,7 @@ class PraxisCrudComponent {
|
|
|
4958
5129
|
[tableId]="crudId || 'default'"
|
|
4959
5130
|
[crudContext]="tableCrudContext"
|
|
4960
5131
|
[enableCustomization]="enableCustomization"
|
|
5132
|
+
[authoringCapability]="authoringCapability"
|
|
4961
5133
|
(rowClick)="onTableRowClick($event)"
|
|
4962
5134
|
(selectionChange)="onTableSelectionChange($event)"
|
|
4963
5135
|
(rowAction)="onAction($event.action, $event.row, $event)"
|
|
@@ -4969,7 +5141,7 @@ class PraxisCrudComponent {
|
|
|
4969
5141
|
(loadingStateChange)="onTableLoadingStateChange($event)"
|
|
4970
5142
|
></praxis-table>
|
|
4971
5143
|
} @else {
|
|
4972
|
-
@if (
|
|
5144
|
+
@if (isCustomizationAvailable()) {
|
|
4973
5145
|
<praxis-empty-state-card
|
|
4974
5146
|
icon="table_rows"
|
|
4975
5147
|
[title]="getEmptyStateTitle()"
|
|
@@ -4978,7 +5150,7 @@ class PraxisCrudComponent {
|
|
|
4978
5150
|
/>
|
|
4979
5151
|
}
|
|
4980
5152
|
}
|
|
4981
|
-
`, isInline: true, styles: [":host{display:block;width:100%;min-width:0;max-width:100%}\n"], dependencies: [{ kind: "component", type: PraxisTable, selector: "praxis-table", inputs: ["config", "resourcePath", "data", "tableId", "componentInstanceId", "configPersistenceStrategy", "title", "subtitle", "icon", "autoDelete", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "crudContext", "filterCriteria", "queryContext", "aiContext", "aiAssistantVoiceInputMode", "aiAssistantVoiceLanguage", "horizontalScroll", "enableCustomization", "dense"], outputs: ["rowClick", "widgetEvent", "resourceEvent", "rowDoubleClick", "rowExpansionChange", "rowAction", "toolbarAction", "bulkAction", "exportAction", "columnReorder", "columnReorderAttempt", "columnResize", "beforeDelete", "afterDelete", "deleteError", "beforeBulkDelete", "afterBulkDelete", "bulkDeleteError", "schemaStatusChange", "configChange", "metadataChange", "loadingStateChange", "collectionLinksChange", "selectionChange"] }, { kind: "component", type: EmptyStateCardComponent, selector: "praxis-empty-state-card", inputs: ["icon", "title", "description", "primaryAction", "secondaryActions", "inline", "tone", "variant", "alignment", "density", "iconContainer"] }] });
|
|
5153
|
+
`, isInline: true, styles: [":host{display:block;width:100%;min-width:0;max-width:100%}\n"], dependencies: [{ kind: "component", type: PraxisTable, selector: "praxis-table", inputs: ["config", "resourcePath", "data", "tableId", "componentInstanceId", "configPersistenceStrategy", "title", "subtitle", "icon", "autoDelete", "notifyIfOutdated", "snoozeMs", "autoOpenSettingsOnOutdated", "crudContext", "filterCriteria", "queryContext", "aiContext", "aiAssistantVoiceInputMode", "aiAssistantVoiceLanguage", "horizontalScroll", "enableCustomization", "authoringCapability", "dense"], outputs: ["rowClick", "widgetEvent", "resourceEvent", "rowDoubleClick", "rowExpansionChange", "rowAction", "toolbarAction", "bulkAction", "exportAction", "columnReorder", "columnReorderAttempt", "columnResize", "beforeDelete", "afterDelete", "deleteError", "beforeBulkDelete", "afterBulkDelete", "bulkDeleteError", "schemaStatusChange", "configChange", "metadataChange", "loadingStateChange", "collectionLinksChange", "selectionChange"] }, { kind: "component", type: EmptyStateCardComponent, selector: "praxis-empty-state-card", inputs: ["icon", "title", "description", "primaryAction", "secondaryActions", "inline", "tone", "variant", "alignment", "density", "iconContainer"] }] });
|
|
4982
5154
|
}
|
|
4983
5155
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisCrudComponent, decorators: [{
|
|
4984
5156
|
type: Component,
|
|
@@ -4996,6 +5168,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
4996
5168
|
[tableId]="crudId || 'default'"
|
|
4997
5169
|
[crudContext]="tableCrudContext"
|
|
4998
5170
|
[enableCustomization]="enableCustomization"
|
|
5171
|
+
[authoringCapability]="authoringCapability"
|
|
4999
5172
|
(rowClick)="onTableRowClick($event)"
|
|
5000
5173
|
(selectionChange)="onTableSelectionChange($event)"
|
|
5001
5174
|
(rowAction)="onAction($event.action, $event.row, $event)"
|
|
@@ -5007,7 +5180,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
5007
5180
|
(loadingStateChange)="onTableLoadingStateChange($event)"
|
|
5008
5181
|
></praxis-table>
|
|
5009
5182
|
} @else {
|
|
5010
|
-
@if (
|
|
5183
|
+
@if (isCustomizationAvailable()) {
|
|
5011
5184
|
<praxis-empty-state-card
|
|
5012
5185
|
icon="table_rows"
|
|
5013
5186
|
[title]="getEmptyStateTitle()"
|
|
@@ -5017,7 +5190,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
5017
5190
|
}
|
|
5018
5191
|
}
|
|
5019
5192
|
`, styles: [":host{display:block;width:100%;min-width:0;max-width:100%}\n"] }]
|
|
5020
|
-
}], propDecorators: { metadata: [{
|
|
5193
|
+
}], ctorParameters: () => [], propDecorators: { metadata: [{
|
|
5021
5194
|
type: Input,
|
|
5022
5195
|
args: [{ required: true }]
|
|
5023
5196
|
}], crudId: [{
|
|
@@ -5029,6 +5202,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
5029
5202
|
type: Input
|
|
5030
5203
|
}], enableCustomization: [{
|
|
5031
5204
|
type: Input
|
|
5205
|
+
}], authoringCapability: [{
|
|
5206
|
+
type: Input
|
|
5032
5207
|
}], configureRequested: [{
|
|
5033
5208
|
type: Output
|
|
5034
5209
|
}], afterOpen: [{
|
|
@@ -5703,6 +5878,7 @@ class PraxisCrudWidgetConfigEditor {
|
|
|
5703
5878
|
componentInstanceId: this.inputs?.componentInstanceId ?? this.widgetKey,
|
|
5704
5879
|
context: this.inputs?.context,
|
|
5705
5880
|
enableCustomization: this.inputs?.enableCustomization ?? false,
|
|
5881
|
+
authoringCapability: this.inputs?.authoringCapability ?? null,
|
|
5706
5882
|
};
|
|
5707
5883
|
return {
|
|
5708
5884
|
inputs,
|
|
@@ -5835,6 +6011,12 @@ const PRAXIS_CRUD_COMPONENT_METADATA = {
|
|
|
5835
6011
|
default: false,
|
|
5836
6012
|
description: 'Habilita modo de customização do layout.',
|
|
5837
6013
|
},
|
|
6014
|
+
{
|
|
6015
|
+
name: 'authoringCapability',
|
|
6016
|
+
type: 'string | null',
|
|
6017
|
+
default: null,
|
|
6018
|
+
description: 'Capability publica do contexto corporativo exigida para disponibilizar authoring governado no CRUD e na tabela interna.',
|
|
6019
|
+
},
|
|
5838
6020
|
],
|
|
5839
6021
|
outputs: [
|
|
5840
6022
|
{
|
|
@@ -6345,6 +6527,8 @@ const PRAXIS_CRUD_AUTHORING_MANIFEST = {
|
|
|
6345
6527
|
{ name: 'crudId', type: 'string', description: 'Stable CRUD instance id used for table/form identity and persistence.' },
|
|
6346
6528
|
{ name: 'componentInstanceId', type: 'string', description: 'Optional stable host instance id for multiple CRUD widgets on the same route.' },
|
|
6347
6529
|
{ name: 'context', type: 'Record<string, unknown>', description: 'Opaque host context used for authoring seeds and launcher inputs.' },
|
|
6530
|
+
{ name: 'enableCustomization', type: 'boolean', description: 'Explicit host opt-in for CRUD authoring surfaces.' },
|
|
6531
|
+
{ name: 'authoringCapability', type: 'string | null', description: 'Public runtime capability required before CRUD and delegated table authoring can open.' },
|
|
6348
6532
|
{ name: 'afterOpen', type: '{ mode: FormOpenMode; action: string }', description: 'Emitted after a CRUD action opens.' },
|
|
6349
6533
|
{ name: 'afterSave', type: '{ id: string | number; data: unknown }', description: 'Emitted after save; CRUD refetches the list.' },
|
|
6350
6534
|
{ name: 'afterDelete', type: '{ id: string | number }', description: 'Emitted after delete; CRUD refetches the list.' },
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisui/crud",
|
|
3
|
-
"version": "9.0.0-beta.
|
|
3
|
+
"version": "9.0.0-beta.72",
|
|
4
4
|
"description": "CRUD building blocks for Praxis UI: integrates dynamic forms and tables with unified configuration and services.",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"@angular/common": "^21.0.0",
|
|
7
7
|
"@angular/core": "^21.0.0",
|
|
8
|
-
"@praxisui/dynamic-form": "^9.0.0-beta.
|
|
9
|
-
"@praxisui/table": "^9.0.0-beta.
|
|
10
|
-
"@praxisui/core": "^9.0.0-beta.
|
|
11
|
-
"@praxisui/dynamic-fields": "^9.0.0-beta.
|
|
12
|
-
"@praxisui/settings-panel": "^9.0.0-beta.
|
|
8
|
+
"@praxisui/dynamic-form": "^9.0.0-beta.72",
|
|
9
|
+
"@praxisui/table": "^9.0.0-beta.72",
|
|
10
|
+
"@praxisui/core": "^9.0.0-beta.72",
|
|
11
|
+
"@praxisui/dynamic-fields": "^9.0.0-beta.72",
|
|
12
|
+
"@praxisui/settings-panel": "^9.0.0-beta.72",
|
|
13
13
|
"@angular/cdk": "^21.0.0",
|
|
14
14
|
"@angular/forms": "^21.0.0",
|
|
15
15
|
"@angular/material": "^21.0.0",
|
|
16
16
|
"@angular/router": "^21.0.0",
|
|
17
|
-
"@praxisui/ai": "^9.0.0-beta.
|
|
17
|
+
"@praxisui/ai": "^9.0.0-beta.72",
|
|
18
18
|
"rxjs": "~7.8.0"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
package/types/praxisui-crud.d.ts
CHANGED
|
@@ -157,6 +157,8 @@ declare class PraxisCrudComponent implements OnChanges {
|
|
|
157
157
|
componentInstanceId?: string;
|
|
158
158
|
context?: Record<string, unknown>;
|
|
159
159
|
enableCustomization: boolean;
|
|
160
|
+
/** Capability publica exigida para authoring governado do CRUD e da tabela interna. */
|
|
161
|
+
authoringCapability: string | null;
|
|
160
162
|
configureRequested: EventEmitter<void>;
|
|
161
163
|
afterOpen: EventEmitter<{
|
|
162
164
|
mode: FormOpenMode;
|
|
@@ -189,6 +191,7 @@ declare class PraxisCrudComponent implements OnChanges {
|
|
|
189
191
|
private table;
|
|
190
192
|
private readonly storage;
|
|
191
193
|
private readonly settingsPanel;
|
|
194
|
+
private readonly enterpriseRuntimeContext;
|
|
192
195
|
private readonly snack;
|
|
193
196
|
private readonly dialog;
|
|
194
197
|
private readonly i18n;
|
|
@@ -209,6 +212,8 @@ declare class PraxisCrudComponent implements OnChanges {
|
|
|
209
212
|
private lastAppliedResourceIdentity;
|
|
210
213
|
private tableCollectionLinks;
|
|
211
214
|
private collectionCapabilities;
|
|
215
|
+
private activeAuthoringPanelRef;
|
|
216
|
+
constructor();
|
|
212
217
|
private collectionCapabilitiesRequestHref;
|
|
213
218
|
private collectionCapabilitiesResolvedHref;
|
|
214
219
|
private collectionCapabilitiesRequestSeq;
|
|
@@ -237,6 +242,7 @@ declare class PraxisCrudComponent implements OnChanges {
|
|
|
237
242
|
getEmptyStatePrimaryAction(): string;
|
|
238
243
|
onConfigureRequested(): void;
|
|
239
244
|
private tryHandleCanonicalDeleteAction;
|
|
245
|
+
private tryHandleCanonicalDuplicateDraftAction;
|
|
240
246
|
private refreshTable;
|
|
241
247
|
private tryRefreshMaterializedLocalData;
|
|
242
248
|
private isCurrentMaterializedRefresh;
|
|
@@ -277,6 +283,7 @@ declare class PraxisCrudComponent implements OnChanges {
|
|
|
277
283
|
private isCreateActionAliasName;
|
|
278
284
|
private buildTableCrudContext;
|
|
279
285
|
private readonly openCrudAuthoringFromTable;
|
|
286
|
+
isCustomizationAvailable(): boolean;
|
|
280
287
|
private applyCrudAuthoringPayload;
|
|
281
288
|
private buildWidgetPersistencePayload;
|
|
282
289
|
private resolveCreateToolbarAction;
|
|
@@ -298,9 +305,12 @@ declare class PraxisCrudComponent implements OnChanges {
|
|
|
298
305
|
private componentKeyId;
|
|
299
306
|
private warnMissingId;
|
|
300
307
|
private getCrudActionLabel;
|
|
308
|
+
private ensureCanonicalCollectionEmptyState;
|
|
301
309
|
private tx;
|
|
310
|
+
private txWithParams;
|
|
311
|
+
private interpolateTranslationParams;
|
|
302
312
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<PraxisCrudComponent, never>;
|
|
303
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<PraxisCrudComponent, "praxis-crud", never, { "metadata": { "alias": "metadata"; "required": true; }; "crudId": { "alias": "crudId"; "required": true; }; "componentInstanceId": { "alias": "componentInstanceId"; "required": false; }; "context": { "alias": "context"; "required": false; }; "enableCustomization": { "alias": "enableCustomization"; "required": false; }; }, { "configureRequested": "configureRequested"; "afterOpen": "afterOpen"; "afterClose": "afterClose"; "afterSave": "afterSave"; "afterDelete": "afterDelete"; "error": "error"; "rowClick": "rowClick"; "selectionChange": "selectionChange"; "tableRuntimeConfigChange": "tableRuntimeConfigChange"; "crudAuthoringDocumentApplied": "crudAuthoringDocumentApplied"; "crudAuthoringDocumentSaved": "crudAuthoringDocumentSaved"; }, never, never, true, never>;
|
|
313
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<PraxisCrudComponent, "praxis-crud", never, { "metadata": { "alias": "metadata"; "required": true; }; "crudId": { "alias": "crudId"; "required": true; }; "componentInstanceId": { "alias": "componentInstanceId"; "required": false; }; "context": { "alias": "context"; "required": false; }; "enableCustomization": { "alias": "enableCustomization"; "required": false; }; "authoringCapability": { "alias": "authoringCapability"; "required": false; }; }, { "configureRequested": "configureRequested"; "afterOpen": "afterOpen"; "afterClose": "afterClose"; "afterSave": "afterSave"; "afterDelete": "afterDelete"; "error": "error"; "rowClick": "rowClick"; "selectionChange": "selectionChange"; "tableRuntimeConfigChange": "tableRuntimeConfigChange"; "crudAuthoringDocumentApplied": "crudAuthoringDocumentApplied"; "crudAuthoringDocumentSaved": "crudAuthoringDocumentSaved"; }, never, never, true, never>;
|
|
304
314
|
}
|
|
305
315
|
|
|
306
316
|
type CrudDrawerResultType = 'save' | 'delete' | 'close';
|
|
@@ -642,6 +652,7 @@ interface PraxisCrudWidgetEditorInputs {
|
|
|
642
652
|
componentInstanceId?: string;
|
|
643
653
|
context?: Record<string, unknown>;
|
|
644
654
|
enableCustomization?: boolean;
|
|
655
|
+
authoringCapability?: string | null;
|
|
645
656
|
[key: string]: unknown;
|
|
646
657
|
}
|
|
647
658
|
interface PraxisCrudWidgetEditorValue {
|