@platform-mesh/portal-ui-lib 0.65.6 → 0.65.8

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.
@@ -5,7 +5,7 @@ import '@ui5/webcomponents/dist/Breadcrumbs.js';
5
5
  import '@ui5/webcomponents/dist/BreadcrumbsItem.js';
6
6
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
7
7
  import { ALL_NAMESPACE, kcpRootOrgsPath } from '@platform-mesh/portal-ui-lib/models';
8
- import { ResourceService, GatewayService, AccountInfoService, InstancePermissionsService, OrganizationReadyService, ErrorHandlerService } from '@platform-mesh/portal-ui-lib/services';
8
+ import { ResourceService, GatewayService, AccountInfoService, InstancePermissionsService, OrganizationReadyService, ErrorHandlerService, NamespaceService } from '@platform-mesh/portal-ui-lib/services';
9
9
  import { isNamespacedResource, generateGraphQLFields, mergeListWithSubscriptionResult, permissionKey } from '@platform-mesh/portal-ui-lib/utils';
10
10
  import '@ui5/webcomponents/dist/ComboBox.js';
11
11
  import { Subject, defer, of, firstValueFrom } from 'rxjs';
@@ -1089,13 +1089,89 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImpor
1089
1089
  args: [{ providedIn: 'root' }]
1090
1090
  }] });
1091
1091
 
1092
+ class NamespacedResourceSelectionService {
1093
+ constructor() {
1094
+ this.luigiCoreService = inject(LuigiCoreService);
1095
+ }
1096
+ resolveNamespace(entityNode, entityId, kcpPath, ctx) {
1097
+ const searchNamespace = this.getSelectedSearchNamespace();
1098
+ if (!isNamespacedResource(ctx)) {
1099
+ return searchNamespace;
1100
+ }
1101
+ const entityTypeId = entityNode.defineEntity?.id;
1102
+ const namespace = searchNamespace ??
1103
+ this.getSelectedNamespace(entityTypeId, entityId, kcpPath);
1104
+ this.selection =
1105
+ entityTypeId && namespace
1106
+ ? { entityTypeId, entityId, kcpPath, namespace }
1107
+ : undefined;
1108
+ return namespace;
1109
+ }
1110
+ restoreNamespaceSearchParam(nextNode, currentContext) {
1111
+ const selection = this.selection;
1112
+ if (!selection) {
1113
+ return;
1114
+ }
1115
+ if (!this.isWithinSelectedResource(nextNode, currentContext, selection)) {
1116
+ this.selection = undefined;
1117
+ return;
1118
+ }
1119
+ if (this.getSelectedSearchNamespace()) {
1120
+ return;
1121
+ }
1122
+ this.luigiCoreService
1123
+ .routing()
1124
+ .addSearchParams({ namespace: selection.namespace }, false, true);
1125
+ }
1126
+ getSelectedSearchNamespace() {
1127
+ const namespace = this.luigiCoreService.routing().getSearchParams()
1128
+ .namespace;
1129
+ return namespace && namespace !== ALL_NAMESPACE ? namespace : undefined;
1130
+ }
1131
+ getSelectedNamespace(entityTypeId, entityId, kcpPath) {
1132
+ const selection = this.selection;
1133
+ if (!selection ||
1134
+ selection.entityTypeId !== entityTypeId ||
1135
+ selection.entityId !== entityId ||
1136
+ selection.kcpPath !== kcpPath) {
1137
+ return undefined;
1138
+ }
1139
+ return selection.namespace;
1140
+ }
1141
+ isWithinSelectedResource(node, currentContext, selection) {
1142
+ for (let current = node; current; current = current.parent) {
1143
+ if (current.defineEntity?.id === selection.entityTypeId &&
1144
+ this.getEntityId(current, currentContext) === selection.entityId) {
1145
+ return true;
1146
+ }
1147
+ }
1148
+ return false;
1149
+ }
1150
+ getEntityId(entityNode, currentContext) {
1151
+ const contextKey = entityNode.defineEntity?.contextKey;
1152
+ const dynamicEntityId = contextKey
1153
+ ? currentContext[contextKey]
1154
+ : undefined;
1155
+ return (dynamicEntityId ||
1156
+ entityNode.context?.resourceDefinition?.name);
1157
+ }
1158
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NamespacedResourceSelectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1159
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NamespacedResourceSelectionService, providedIn: 'root' }); }
1160
+ }
1161
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NamespacedResourceSelectionService, decorators: [{
1162
+ type: Injectable,
1163
+ args: [{ providedIn: 'root' }]
1164
+ }] });
1165
+
1092
1166
  class NodeChangeHookConfigServiceImpl {
1093
1167
  constructor() {
1094
1168
  this.luigiCoreService = inject(LuigiCoreService);
1095
1169
  this.crdGatewayKcpPatchResolver = inject(CrdGatewayKcpPatchResolver);
1096
1170
  this.persistentPanelService = inject(PersistentPanelService);
1171
+ this.namespacedResourceSelectionService = inject(NamespacedResourceSelectionService);
1097
1172
  }
1098
1173
  async nodeChangeHook(prevNode, nextNode, currentContext) {
1174
+ this.namespacedResourceSelectionService.restoreNamespaceSearchParam(nextNode, currentContext);
1099
1175
  const updatePersistentPanelTarget = this.persistentPanelService.beginTargetUpdate();
1100
1176
  if (nextNode.initialRoute &&
1101
1177
  nextNode.virtualTree &&
@@ -1136,7 +1212,8 @@ class NodeContextProcessingServiceImpl {
1136
1212
  this.instancePermissionsService = inject(InstancePermissionsService);
1137
1213
  this.organizationReadyService = inject(OrganizationReadyService);
1138
1214
  this.errorHandlerService = inject(ErrorHandlerService);
1139
- this.luigiCoreService = inject(LuigiCoreService);
1215
+ this.namespaceService = inject(NamespaceService);
1216
+ this.namespacedResourceSelectionService = inject(NamespacedResourceSelectionService);
1140
1217
  }
1141
1218
  async processNodeContext(dynamicEntityId, entityNode, ctx) {
1142
1219
  const kind = entityNode.defineEntity?.type;
@@ -1145,14 +1222,12 @@ class NodeContextProcessingServiceImpl {
1145
1222
  return;
1146
1223
  }
1147
1224
  const { kcpPath, accountPath } = await this.crdGatewayKcpPatchResolver.resolveCrdGatewayKcpPath(entityNode, entityId, kind);
1148
- const namespace = this.luigiCoreService.routing().getSearchParams().namespace !==
1149
- ALL_NAMESPACE
1150
- ? this.luigiCoreService.routing().getSearchParams().namespace
1151
- : undefined;
1225
+ const namespace = this.namespacedResourceSelectionService.resolveNamespace(entityNode, entityId, kcpPath, ctx);
1152
1226
  // update the current already calculated by Luigi context for a node
1153
1227
  this.addFieldsToContext(ctx, entityId, kcpPath, accountPath, kind, namespace);
1154
1228
  // update the node context of sa node to contain the entity for future context calculations
1155
1229
  this.addFieldsToContext(entityNode.context, entityId, kcpPath, accountPath, kind, namespace);
1230
+ await this.addNamespacesToContext(ctx, namespace);
1156
1231
  this.accamulatePortalPermissions(ctx);
1157
1232
  this.getEntityPermissions(ctx, namespace);
1158
1233
  try {
@@ -1202,6 +1277,17 @@ class NodeContextProcessingServiceImpl {
1202
1277
  ctx.accountPath = accountPath;
1203
1278
  ctx.namespaceId = namespace;
1204
1279
  }
1280
+ async addNamespacesToContext(ctx, namespace) {
1281
+ if (!isNamespacedResource(ctx) || namespace) {
1282
+ return;
1283
+ }
1284
+ try {
1285
+ ctx.namespaces = await firstValueFrom(this.namespaceService.list(ctx));
1286
+ }
1287
+ catch (e) {
1288
+ this.errorHandlerService.showError(e, 'Failed to read namespaces.');
1289
+ }
1290
+ }
1205
1291
  addFieldsToContextFromAccountInfo(ctx, entityId, accountInfo) {
1206
1292
  const accountOriginClusterId = accountInfo.spec.account.originClusterId;
1207
1293
  const organizationOriginClusterId = accountInfo.spec.organization.originClusterId;
@@ -1261,7 +1347,6 @@ class CustomRoutingConfigServiceImpl {
1261
1347
  }
1262
1348
  getRoutingConfig() {
1263
1349
  return {
1264
- preserveQueryParams: true,
1265
1350
  pageNotFoundHandler: () => {
1266
1351
  if (!this.envConfig?.baseDomain) {
1267
1352
  return this.redirectTo('error/404');