@praxisui/core 9.0.0-beta.40 → 9.0.0-beta.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ai/component-registry.json +2 -2
- package/fesm2022/praxisui-core.mjs +222 -9
- package/package.json +1 -1
- package/types/praxisui-core.d.ts +12 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "1.0.0",
|
|
3
|
-
"generatedAt": "2026-07-
|
|
3
|
+
"generatedAt": "2026-07-06T18:00:15.329Z",
|
|
4
4
|
"packageName": "@praxisui/core",
|
|
5
|
-
"packageVersion": "9.0.0-beta.
|
|
5
|
+
"packageVersion": "9.0.0-beta.41",
|
|
6
6
|
"sourceRegistry": "praxis-component-registry-ingestion",
|
|
7
7
|
"sourceRegistryVersion": "1.0.0",
|
|
8
8
|
"componentCount": 4,
|
|
@@ -13960,7 +13960,7 @@ class SurfaceOpenMaterializerService {
|
|
|
13960
13960
|
};
|
|
13961
13961
|
}
|
|
13962
13962
|
const schemaFields = await this.resolveSchemaFields(payload, discoveryOptions);
|
|
13963
|
-
return this.
|
|
13963
|
+
return this.materializeArrayProjection(payload, collectionData, schemaFields, resourceId, readUrl);
|
|
13964
13964
|
}
|
|
13965
13965
|
if (responseCardinality === 'COLLECTION' || responseCardinality === 'PAGE') {
|
|
13966
13966
|
return {
|
|
@@ -14133,6 +14133,86 @@ class SurfaceOpenMaterializerService {
|
|
|
14133
14133
|
return [];
|
|
14134
14134
|
}
|
|
14135
14135
|
}
|
|
14136
|
+
materializeArrayProjection(payload, data, fields, resourceId, readUrl) {
|
|
14137
|
+
if (this.hasRelatedChildWriteOperations(payload)) {
|
|
14138
|
+
return this.materializeArrayAsCrud(payload, data, fields, resourceId, readUrl);
|
|
14139
|
+
}
|
|
14140
|
+
return this.materializeArrayAsTable(payload, data, fields, resourceId, readUrl);
|
|
14141
|
+
}
|
|
14142
|
+
materializeArrayAsCrud(payload, data, fields, resourceId, readUrl) {
|
|
14143
|
+
const previousInputs = payload.widget.inputs || {};
|
|
14144
|
+
const surfaceId = this.stableSurfaceId(payload);
|
|
14145
|
+
const relatedResource = this.resolveRelatedResource(payload);
|
|
14146
|
+
const schemaResourcePath = this.normalizeResourcePath(relatedResource?.childResourcePath || this.resolveSurfacePath(payload));
|
|
14147
|
+
const resourcePath = this.normalizeResourcePath(readUrl);
|
|
14148
|
+
const tableConfig = this.buildLocalTableConfig(fields, data, payload);
|
|
14149
|
+
const operations = this.resolveRelatedChildOperations(payload);
|
|
14150
|
+
const actions = this.buildRelatedCrudActions(payload, operations);
|
|
14151
|
+
return {
|
|
14152
|
+
...payload,
|
|
14153
|
+
widget: {
|
|
14154
|
+
...payload.widget,
|
|
14155
|
+
id: 'praxis-crud',
|
|
14156
|
+
bindingOrder: [
|
|
14157
|
+
'crudId',
|
|
14158
|
+
'componentInstanceId',
|
|
14159
|
+
'metadata',
|
|
14160
|
+
'context',
|
|
14161
|
+
'enableCustomization',
|
|
14162
|
+
],
|
|
14163
|
+
outputs: {
|
|
14164
|
+
afterOpen: 'emit',
|
|
14165
|
+
afterClose: 'emit',
|
|
14166
|
+
afterSave: 'emit',
|
|
14167
|
+
afterDelete: 'emit',
|
|
14168
|
+
rowClick: 'emit',
|
|
14169
|
+
selectionChange: 'emit',
|
|
14170
|
+
error: 'emit',
|
|
14171
|
+
},
|
|
14172
|
+
inputs: {
|
|
14173
|
+
crudId: String(previousInputs['tableId'] || surfaceId),
|
|
14174
|
+
componentInstanceId: `${surfaceId}.${resourceId}`,
|
|
14175
|
+
metadata: {
|
|
14176
|
+
component: 'praxis-crud',
|
|
14177
|
+
resource: {
|
|
14178
|
+
path: resourcePath,
|
|
14179
|
+
schemaPath: schemaResourcePath || null,
|
|
14180
|
+
idField: this.resolveRelatedSelectionKeyField(payload),
|
|
14181
|
+
endpointKey: previousInputs['apiEndpointKey'] ?? undefined,
|
|
14182
|
+
apiUrlEntry: previousInputs['apiUrlEntry'] ?? undefined,
|
|
14183
|
+
},
|
|
14184
|
+
data,
|
|
14185
|
+
table: tableConfig,
|
|
14186
|
+
queryContext: previousInputs['queryContext'] ?? payload.context?.['queryContext'] ?? null,
|
|
14187
|
+
defaults: {
|
|
14188
|
+
openMode: 'drawer',
|
|
14189
|
+
modal: {
|
|
14190
|
+
width: 'min(720px, 100vw)',
|
|
14191
|
+
maxWidth: '100vw',
|
|
14192
|
+
height: '100vh',
|
|
14193
|
+
position: 'end',
|
|
14194
|
+
},
|
|
14195
|
+
},
|
|
14196
|
+
actions,
|
|
14197
|
+
},
|
|
14198
|
+
context: {
|
|
14199
|
+
...(payload.context || {}),
|
|
14200
|
+
materialization: {
|
|
14201
|
+
...payload.context?.['materialization'],
|
|
14202
|
+
relatedResourceCrud: true,
|
|
14203
|
+
},
|
|
14204
|
+
},
|
|
14205
|
+
enableCustomization: previousInputs['enableCustomization'] ?? true,
|
|
14206
|
+
},
|
|
14207
|
+
},
|
|
14208
|
+
context: this.mergeMaterializationContext(payload, {
|
|
14209
|
+
readUrl,
|
|
14210
|
+
dataShape: 'array',
|
|
14211
|
+
recordCount: data.length,
|
|
14212
|
+
presentation: 'materialized-crud',
|
|
14213
|
+
}),
|
|
14214
|
+
};
|
|
14215
|
+
}
|
|
14136
14216
|
materializeArrayAsTable(payload, data, fields, resourceId, readUrl) {
|
|
14137
14217
|
const previousInputs = payload.widget.inputs || {};
|
|
14138
14218
|
const tableInputOverrides = this.projectTableInputs(previousInputs);
|
|
@@ -14169,7 +14249,7 @@ class SurfaceOpenMaterializerService {
|
|
|
14169
14249
|
subtitle: payload.subtitle,
|
|
14170
14250
|
icon: payload.icon,
|
|
14171
14251
|
data,
|
|
14172
|
-
config: this.buildLocalTableConfig(fields, data),
|
|
14252
|
+
config: this.buildLocalTableConfig(fields, data, payload),
|
|
14173
14253
|
enableCustomization: previousInputs['enableCustomization'] ?? true,
|
|
14174
14254
|
},
|
|
14175
14255
|
},
|
|
@@ -14245,7 +14325,7 @@ class SurfaceOpenMaterializerService {
|
|
|
14245
14325
|
]);
|
|
14246
14326
|
return Object.fromEntries(Object.entries(inputs).filter(([key]) => supported.has(key)));
|
|
14247
14327
|
}
|
|
14248
|
-
buildLocalTableConfig(fields, data) {
|
|
14328
|
+
buildLocalTableConfig(fields, data, payload) {
|
|
14249
14329
|
const schemaColumns = fields
|
|
14250
14330
|
.filter((field) => !field.hidden && !field.tableHidden && !!field.name)
|
|
14251
14331
|
.map((field) => ({
|
|
@@ -14258,8 +14338,30 @@ class SurfaceOpenMaterializerService {
|
|
|
14258
14338
|
const fallbackColumns = schemaColumns.length
|
|
14259
14339
|
? []
|
|
14260
14340
|
: this.inferColumnsFromData(data);
|
|
14341
|
+
const childOperations = this.resolveRelatedChildOperations(payload);
|
|
14342
|
+
const relatedActions = this.buildRelatedCrudActions(payload, childOperations);
|
|
14343
|
+
const toolbarActions = relatedActions
|
|
14344
|
+
.filter((action) => action['action'] === 'create')
|
|
14345
|
+
.map((action) => ({ ...action, variant: 'raised' }));
|
|
14346
|
+
const bulkActions = relatedActions
|
|
14347
|
+
.filter((action) => action['action'] === 'edit' || action['action'] === 'delete');
|
|
14261
14348
|
return {
|
|
14262
14349
|
columns: schemaColumns.length ? schemaColumns : fallbackColumns,
|
|
14350
|
+
toolbar: toolbarActions.length
|
|
14351
|
+
? {
|
|
14352
|
+
visible: true,
|
|
14353
|
+
actions: toolbarActions,
|
|
14354
|
+
}
|
|
14355
|
+
: undefined,
|
|
14356
|
+
actions: bulkActions.length
|
|
14357
|
+
? {
|
|
14358
|
+
bulk: {
|
|
14359
|
+
enabled: true,
|
|
14360
|
+
position: 'toolbar',
|
|
14361
|
+
actions: bulkActions,
|
|
14362
|
+
},
|
|
14363
|
+
}
|
|
14364
|
+
: undefined,
|
|
14263
14365
|
behavior: {
|
|
14264
14366
|
localDataMode: { enabled: true },
|
|
14265
14367
|
pagination: { enabled: true, pageSize: 10 },
|
|
@@ -14271,6 +14373,109 @@ class SurfaceOpenMaterializerService {
|
|
|
14271
14373
|
},
|
|
14272
14374
|
};
|
|
14273
14375
|
}
|
|
14376
|
+
buildRelatedCrudActions(payload, operations) {
|
|
14377
|
+
const noun = this.resolveRelatedActionNoun(payload);
|
|
14378
|
+
const actions = [];
|
|
14379
|
+
if (operations.has('CREATE')) {
|
|
14380
|
+
actions.push({
|
|
14381
|
+
id: 'create',
|
|
14382
|
+
action: 'create',
|
|
14383
|
+
label: `Novo ${noun}`,
|
|
14384
|
+
icon: 'add',
|
|
14385
|
+
color: 'primary',
|
|
14386
|
+
type: 'button',
|
|
14387
|
+
openMode: 'drawer',
|
|
14388
|
+
});
|
|
14389
|
+
}
|
|
14390
|
+
if (operations.has('UPDATE')) {
|
|
14391
|
+
actions.push({
|
|
14392
|
+
id: 'edit',
|
|
14393
|
+
action: 'edit',
|
|
14394
|
+
label: `Editar ${noun}`,
|
|
14395
|
+
icon: 'edit',
|
|
14396
|
+
color: 'primary',
|
|
14397
|
+
type: 'button',
|
|
14398
|
+
openMode: 'drawer',
|
|
14399
|
+
});
|
|
14400
|
+
}
|
|
14401
|
+
if (operations.has('DELETE')) {
|
|
14402
|
+
actions.push({
|
|
14403
|
+
id: 'delete',
|
|
14404
|
+
action: 'delete',
|
|
14405
|
+
label: `Apagar ${noun}`,
|
|
14406
|
+
icon: 'delete',
|
|
14407
|
+
color: 'warn',
|
|
14408
|
+
type: 'button',
|
|
14409
|
+
openMode: 'drawer',
|
|
14410
|
+
requiresConfirmation: true,
|
|
14411
|
+
});
|
|
14412
|
+
}
|
|
14413
|
+
return actions;
|
|
14414
|
+
}
|
|
14415
|
+
hasRelatedChildWriteOperations(payload) {
|
|
14416
|
+
const operations = this.resolveRelatedChildOperations(payload);
|
|
14417
|
+
return operations.has('CREATE') || operations.has('UPDATE') || operations.has('DELETE');
|
|
14418
|
+
}
|
|
14419
|
+
resolveRelatedChildOperations(payload) {
|
|
14420
|
+
const relatedResource = this.resolveRelatedResource(payload);
|
|
14421
|
+
const operations = Array.isArray(relatedResource?.childOperations)
|
|
14422
|
+
? relatedResource.childOperations
|
|
14423
|
+
: [];
|
|
14424
|
+
return new Set(operations
|
|
14425
|
+
.map((operation) => String(operation || '').trim().toUpperCase())
|
|
14426
|
+
.filter(Boolean));
|
|
14427
|
+
}
|
|
14428
|
+
resolveRelatedResource(payload) {
|
|
14429
|
+
const relatedResource = payload.context?.['relatedResource'];
|
|
14430
|
+
return relatedResource;
|
|
14431
|
+
}
|
|
14432
|
+
resolveRelatedSelectionKeyField(payload) {
|
|
14433
|
+
const relatedResource = this.resolveRelatedResource(payload);
|
|
14434
|
+
const field = String(relatedResource?.selectionKeyField || '').trim();
|
|
14435
|
+
return field || 'id';
|
|
14436
|
+
}
|
|
14437
|
+
resolveSurfacePath(payload) {
|
|
14438
|
+
const surface = payload.context?.['surface'];
|
|
14439
|
+
return String(surface?.['path'] || '').trim();
|
|
14440
|
+
}
|
|
14441
|
+
normalizeResourcePath(value) {
|
|
14442
|
+
const raw = String(value || '').trim();
|
|
14443
|
+
if (!raw)
|
|
14444
|
+
return '';
|
|
14445
|
+
if (/^https?:\/\//i.test(raw)) {
|
|
14446
|
+
try {
|
|
14447
|
+
return new URL(raw).pathname.replace(/\/+$/, '');
|
|
14448
|
+
}
|
|
14449
|
+
catch {
|
|
14450
|
+
return '';
|
|
14451
|
+
}
|
|
14452
|
+
}
|
|
14453
|
+
return raw.replace(/\/+$/, '');
|
|
14454
|
+
}
|
|
14455
|
+
resolveRelatedActionNoun(payload) {
|
|
14456
|
+
const source = [
|
|
14457
|
+
payload.title,
|
|
14458
|
+
payload.context?.['surface']?.['title'],
|
|
14459
|
+
this.resolveRelatedResource(payload)?.childResourcePath,
|
|
14460
|
+
]
|
|
14461
|
+
.map((value) => String(value || '').trim())
|
|
14462
|
+
.find(Boolean) || '';
|
|
14463
|
+
const normalized = source
|
|
14464
|
+
.normalize('NFD')
|
|
14465
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
14466
|
+
.toLowerCase();
|
|
14467
|
+
if (/\b(documentos?|documents?)\b/.test(normalized)) {
|
|
14468
|
+
return 'documento';
|
|
14469
|
+
}
|
|
14470
|
+
const firstToken = normalized
|
|
14471
|
+
.split(/[^a-z0-9]+/)
|
|
14472
|
+
.filter(Boolean)
|
|
14473
|
+
.find((token) => !['de', 'da', 'do', 'das', 'dos', 'legal', 'legais'].includes(token));
|
|
14474
|
+
if (firstToken && firstToken.length > 3) {
|
|
14475
|
+
return firstToken.endsWith('s') ? firstToken.slice(0, -1) : firstToken;
|
|
14476
|
+
}
|
|
14477
|
+
return 'item';
|
|
14478
|
+
}
|
|
14274
14479
|
inferColumnsFromData(data) {
|
|
14275
14480
|
const first = data.find((item) => item && typeof item === 'object' && !Array.isArray(item));
|
|
14276
14481
|
if (!first || typeof first !== 'object')
|
|
@@ -14359,6 +14564,7 @@ class CrudOperationResolutionService {
|
|
|
14359
14564
|
throw new Error('CrudOperationResolutionService requires resourcePath.');
|
|
14360
14565
|
}
|
|
14361
14566
|
const resourcePath = this.resolveCanonicalResourcePath(request, metadataResourcePath);
|
|
14567
|
+
const schemaResourcePath = this.resolveCanonicalSchemaResourcePath(request, resourcePath);
|
|
14362
14568
|
const diagnostics = [];
|
|
14363
14569
|
const resolutionOptions = this.toDiscoveryOptions(request);
|
|
14364
14570
|
if (this.hasExplicitContract(request)) {
|
|
@@ -14393,9 +14599,9 @@ class CrudOperationResolutionService {
|
|
|
14393
14599
|
visible: this.isAvailable(operationCapability),
|
|
14394
14600
|
enabled: this.isAvailable(operationCapability),
|
|
14395
14601
|
availability: operationCapability?.availability ?? null,
|
|
14396
|
-
schemaUrl: this.resolveCanonicalSchemaUrl(operation,
|
|
14602
|
+
schemaUrl: this.resolveCanonicalSchemaUrl(operation, schemaResourcePath, preferredMethod, resolutionOptions),
|
|
14397
14603
|
responseSchemaUrl: operation === 'view'
|
|
14398
|
-
? this.resolveCanonicalSchemaUrl('view',
|
|
14604
|
+
? this.resolveCanonicalSchemaUrl('view', schemaResourcePath, preferredMethod, resolutionOptions)
|
|
14399
14605
|
: null,
|
|
14400
14606
|
submitUrl: linkResolution.href,
|
|
14401
14607
|
submitMethod: operation === 'view'
|
|
@@ -14407,6 +14613,7 @@ class CrudOperationResolutionService {
|
|
|
14407
14613
|
return this.buildConventionResolution({
|
|
14408
14614
|
operation,
|
|
14409
14615
|
resourcePath,
|
|
14616
|
+
schemaResourcePath,
|
|
14410
14617
|
resourceId: request.resourceId ?? null,
|
|
14411
14618
|
diagnostics,
|
|
14412
14619
|
resolutionOptions,
|
|
@@ -14468,7 +14675,7 @@ class CrudOperationResolutionService {
|
|
|
14468
14675
|
};
|
|
14469
14676
|
}
|
|
14470
14677
|
buildConventionResolution(params) {
|
|
14471
|
-
const { operation, resourcePath, resourceId, diagnostics, resolutionOptions, capability, preferredMethod, scope } = params;
|
|
14678
|
+
const { operation, resourcePath, schemaResourcePath, resourceId, diagnostics, resolutionOptions, capability, preferredMethod, scope } = params;
|
|
14472
14679
|
const submitUrl = this.resolveConventionSubmitUrl(operation, resourcePath, resourceId, diagnostics, resolutionOptions);
|
|
14473
14680
|
return {
|
|
14474
14681
|
operation,
|
|
@@ -14480,9 +14687,9 @@ class CrudOperationResolutionService {
|
|
|
14480
14687
|
visible: this.isAvailable(capability),
|
|
14481
14688
|
enabled: this.isAvailable(capability),
|
|
14482
14689
|
availability: capability?.availability ?? null,
|
|
14483
|
-
schemaUrl: this.resolveCanonicalSchemaUrl(operation,
|
|
14690
|
+
schemaUrl: this.resolveCanonicalSchemaUrl(operation, schemaResourcePath, preferredMethod, resolutionOptions),
|
|
14484
14691
|
responseSchemaUrl: operation === 'view'
|
|
14485
|
-
? this.resolveCanonicalSchemaUrl('view',
|
|
14692
|
+
? this.resolveCanonicalSchemaUrl('view', schemaResourcePath, preferredMethod, resolutionOptions)
|
|
14486
14693
|
: null,
|
|
14487
14694
|
submitUrl,
|
|
14488
14695
|
submitMethod: operation === 'view' ? preferredMethod : preferredMethod?.toLowerCase() ?? null,
|
|
@@ -14656,7 +14863,9 @@ class CrudOperationResolutionService {
|
|
|
14656
14863
|
}
|
|
14657
14864
|
try {
|
|
14658
14865
|
const resolved = this.discovery.resolveHref(normalized, options);
|
|
14659
|
-
const pathname = new URL(resolved).pathname
|
|
14866
|
+
const pathname = decodeURIComponent(new URL(resolved).pathname)
|
|
14867
|
+
.replace(/\/+/g, '/')
|
|
14868
|
+
.replace(/\/+$/, '');
|
|
14660
14869
|
return pathname || (normalized.startsWith('/') ? normalized : `/${normalized}`);
|
|
14661
14870
|
}
|
|
14662
14871
|
catch {
|
|
@@ -14670,6 +14879,10 @@ class CrudOperationResolutionService {
|
|
|
14670
14879
|
}
|
|
14671
14880
|
return fallbackResourcePath;
|
|
14672
14881
|
}
|
|
14882
|
+
resolveCanonicalSchemaResourcePath(request, fallbackResourcePath) {
|
|
14883
|
+
const explicitSchemaPath = this.normalizeResourcePath(request.schemaResourcePath || '');
|
|
14884
|
+
return explicitSchemaPath || fallbackResourcePath;
|
|
14885
|
+
}
|
|
14673
14886
|
toDiscoveryOptions(request) {
|
|
14674
14887
|
if (!request.endpointKey && !request.apiUrlEntry) {
|
|
14675
14888
|
return undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisui/core",
|
|
3
|
-
"version": "9.0.0-beta.
|
|
3
|
+
"version": "9.0.0-beta.41",
|
|
4
4
|
"description": "Core library for Praxis UI Workspace: types, tokens, services and utilities shared across @praxisui/* packages.",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"@angular/common": "^21.0.0",
|
package/types/praxisui-core.d.ts
CHANGED
|
@@ -9759,11 +9759,21 @@ declare class SurfaceOpenMaterializerService {
|
|
|
9759
9759
|
private resolveResourceId;
|
|
9760
9760
|
private resolveItemReadUrl;
|
|
9761
9761
|
private resolveSchemaFields;
|
|
9762
|
+
private materializeArrayProjection;
|
|
9763
|
+
private materializeArrayAsCrud;
|
|
9762
9764
|
private materializeArrayAsTable;
|
|
9763
9765
|
private ensureCollectionTableSelectionContract;
|
|
9764
9766
|
private ensureTableSelectionConfig;
|
|
9765
9767
|
private projectTableInputs;
|
|
9766
9768
|
private buildLocalTableConfig;
|
|
9769
|
+
private buildRelatedCrudActions;
|
|
9770
|
+
private hasRelatedChildWriteOperations;
|
|
9771
|
+
private resolveRelatedChildOperations;
|
|
9772
|
+
private resolveRelatedResource;
|
|
9773
|
+
private resolveRelatedSelectionKeyField;
|
|
9774
|
+
private resolveSurfacePath;
|
|
9775
|
+
private normalizeResourcePath;
|
|
9776
|
+
private resolveRelatedActionNoun;
|
|
9767
9777
|
private inferColumnsFromData;
|
|
9768
9778
|
private extractCollectionData;
|
|
9769
9779
|
private mergeMaterializationContext;
|
|
@@ -9801,6 +9811,7 @@ interface ResolvedCrudOperation {
|
|
|
9801
9811
|
interface ResolveCrudOperationRequest {
|
|
9802
9812
|
operation: ResourceCrudOperationId;
|
|
9803
9813
|
resourcePath: string;
|
|
9814
|
+
schemaResourcePath?: string | null;
|
|
9804
9815
|
resourceId?: string | number | null;
|
|
9805
9816
|
explicit?: ExplicitCrudResolutionContract | null;
|
|
9806
9817
|
}
|
|
@@ -9838,6 +9849,7 @@ declare class CrudOperationResolutionService {
|
|
|
9838
9849
|
private normalizeResourcePath;
|
|
9839
9850
|
private resolveSchemaResourcePath;
|
|
9840
9851
|
private resolveCanonicalResourcePath;
|
|
9852
|
+
private resolveCanonicalSchemaResourcePath;
|
|
9841
9853
|
private toDiscoveryOptions;
|
|
9842
9854
|
static ɵfac: i0.ɵɵFactoryDeclaration<CrudOperationResolutionService, never>;
|
|
9843
9855
|
static ɵprov: i0.ɵɵInjectableDeclaration<CrudOperationResolutionService>;
|