@rancher/shell 3.0.0-rc.6 → 3.0.0-rc.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.
Files changed (53) hide show
  1. package/assets/styles/global/_tooltip.scss +1 -12
  2. package/assets/translations/en-us.yaml +13 -1
  3. package/chart/monitoring/alerting/index.vue +4 -20
  4. package/chart/monitoring/grafana/index.vue +3 -3
  5. package/chart/monitoring/prometheus/index.vue +7 -14
  6. package/components/CodeMirror.vue +18 -15
  7. package/components/PromptRemove.vue +2 -2
  8. package/components/Questions/index.vue +2 -2
  9. package/components/ResourceDetail/Masthead.vue +1 -0
  10. package/components/ResourceDetail/index.vue +7 -4
  11. package/components/auth/RoleDetailEdit.vue +1 -6
  12. package/components/auth/__tests__/RoleDetailEdit.test.ts +53 -16
  13. package/components/form/ArrayList.vue +7 -3
  14. package/components/form/PodAffinity.vue +1 -1
  15. package/components/formatter/CloudCredExpired.vue +69 -0
  16. package/components/formatter/Date.vue +1 -1
  17. package/components/nav/Header.vue +9 -5
  18. package/components/nav/TopLevelMenu.vue +115 -51
  19. package/components/nav/__tests__/TopLevelMenu.test.ts +49 -23
  20. package/config/labels-annotations.js +9 -5
  21. package/core/types.ts +2 -2
  22. package/detail/provisioning.cattle.io.cluster.vue +0 -4
  23. package/edit/auth/googleoauth.vue +2 -2
  24. package/edit/auth/ldap/config.vue +2 -2
  25. package/edit/auth/oidc.vue +2 -2
  26. package/edit/autoscaling.horizontalpodautoscaler/metrics-row.vue +4 -5
  27. package/edit/management.cattle.io.project.vue +4 -1
  28. package/edit/monitoring.coreos.com.alertmanagerconfig/auth.vue +1 -5
  29. package/edit/monitoring.coreos.com.alertmanagerconfig/types/slack.vue +1 -5
  30. package/edit/monitoring.coreos.com.receiver/types/slack.vue +1 -5
  31. package/edit/provisioning.cattle.io.cluster/index.vue +7 -2
  32. package/edit/provisioning.cattle.io.cluster/rke2.vue +28 -5
  33. package/edit/service.vue +6 -15
  34. package/list/provisioning.cattle.io.cluster.vue +57 -10
  35. package/machine-config/vmwarevsphere.vue +133 -95
  36. package/mixins/create-edit-view/impl.js +2 -0
  37. package/mixins/labeled-form-element.ts +2 -0
  38. package/models/catalog.cattle.io.app.js +4 -3
  39. package/models/cloudcredential.js +158 -2
  40. package/models/management.cattle.io.globalrole.js +6 -0
  41. package/models/management.cattle.io.roletemplate.js +6 -0
  42. package/models/nodedriver.js +5 -0
  43. package/models/provisioning.cattle.io.cluster.js +35 -1
  44. package/package.json +1 -1
  45. package/pages/c/_cluster/apps/charts/index.vue +0 -6
  46. package/pages/c/_cluster/manager/cloudCredential/index.vue +68 -4
  47. package/pages/home.vue +1 -0
  48. package/plugins/dashboard-store/mutations.js +24 -3
  49. package/plugins/dashboard-store/resource-class.js +6 -0
  50. package/store/type-map.js +4 -2
  51. package/types/shell/index.d.ts +17 -3
  52. package/utils/v-sphere.ts +17 -3
  53. package/vue.config.js +2 -0
@@ -76,58 +76,102 @@ export default {
76
76
  return this.clusters.length > this.maxClustersToShow;
77
77
  },
78
78
 
79
+ /**
80
+ * Filter mgmt clusters by
81
+ * 1. Harvester type 1 (filterOnlyKubernetesClusters)
82
+ * 2. Harvester type 2 (filterHiddenLocalCluster)
83
+ * 3. There's a matching prov cluster
84
+ *
85
+ * Convert remaining clusters to special format
86
+ */
79
87
  clusters() {
80
- const all = this.$store.getters['management/all'](MANAGEMENT.CLUSTER);
81
- let kubeClusters = filterHiddenLocalCluster(filterOnlyKubernetesClusters(all, this.$store), this.$store);
82
- let pClusters = null;
88
+ if (!this.hasProvCluster) {
89
+ // We're filtering out mgmt clusters without prov clusters, so if the user can't see any prov clusters at all
90
+ // exit early
91
+ return [];
92
+ }
83
93
 
84
- if (this.hasProvCluster) {
85
- pClusters = this.$store.getters['management/all'](CAPI.RANCHER_CLUSTER);
86
- const available = pClusters.reduce((p, c) => {
87
- p[c.mgmt] = true;
94
+ const all = this.$store.getters['management/all'](MANAGEMENT.CLUSTER);
95
+ const mgmtClusters = filterHiddenLocalCluster(filterOnlyKubernetesClusters(all, this.$store), this.$store);
96
+ const provClusters = this.$store.getters['management/all'](CAPI.RANCHER_CLUSTER);
97
+ const provClustersByMgmtId = provClusters.reduce((res, provCluster) => {
98
+ if (provCluster.mgmt?.id) {
99
+ res[provCluster.mgmt.id] = provCluster;
100
+ }
88
101
 
89
- return p;
90
- }, {});
102
+ return res;
103
+ }, {});
91
104
 
105
+ return (mgmtClusters || []).reduce((res, mgmtCluster) => {
92
106
  // Filter to only show mgmt clusters that exist for the available provisioning clusters
93
107
  // Addresses issue where a mgmt cluster can take some time to get cleaned up after the corresponding
94
108
  // provisioning cluster has been deleted
95
- kubeClusters = kubeClusters.filter((c) => !!available[c]);
96
- }
109
+ if (!provClustersByMgmtId[mgmtCluster.id]) {
110
+ return res;
111
+ }
97
112
 
98
- return kubeClusters?.map((x) => {
99
- const pCluster = pClusters?.find((c) => c.mgmt?.id === x.id);
113
+ const pCluster = provClustersByMgmtId[mgmtCluster.id];
114
+
115
+ res.push({
116
+ id: mgmtCluster.id,
117
+ label: mgmtCluster.nameDisplay,
118
+ ready: mgmtCluster.isReady && !pCluster?.hasError,
119
+ osLogo: mgmtCluster.providerOsLogo,
120
+ providerNavLogo: mgmtCluster.providerMenuLogo,
121
+ badge: mgmtCluster.badge,
122
+ isLocal: mgmtCluster.isLocal,
123
+ isHarvester: mgmtCluster.isHarvester,
124
+ pinned: mgmtCluster.pinned,
125
+ description: pCluster?.description || mgmtCluster.description,
126
+ pin: () => mgmtCluster.pin(),
127
+ unpin: () => mgmtCluster.unpin(),
128
+ clusterRoute: { name: 'c-cluster-explorer', params: { cluster: mgmtCluster.id } }
129
+ });
100
130
 
101
- return {
102
- id: x.id,
103
- label: x.nameDisplay,
104
- ready: x.isReady && !pCluster?.hasError,
105
- osLogo: x.providerOsLogo,
106
- providerNavLogo: x.providerMenuLogo,
107
- badge: x.badge,
108
- isLocal: x.isLocal,
109
- isHarvester: x.isHarvester,
110
- pinned: x.pinned,
111
- description: pCluster?.description || x.description,
112
- pin: () => x.pin(),
113
- unpin: () => x.unpin(),
114
- clusterRoute: { name: 'c-cluster-explorer', params: { cluster: x.id } }
115
- };
116
- }) || [];
131
+ return res;
132
+ }, []);
117
133
  },
118
134
 
135
+ /**
136
+ * Filter clusters by
137
+ * 1. Not pinned
138
+ * 2. Includes search term
139
+ *
140
+ * Sort remaining clusters
141
+ *
142
+ * Reduce number of clusters if too many too show
143
+ *
144
+ * Important! This is used to show unpinned clusters OR results of search
145
+ */
119
146
  clustersFiltered() {
120
147
  const search = (this.clusterFilter || '').toLowerCase();
121
- const out = search ? this.clusters.filter((item) => item.label?.toLowerCase().includes(search)) : this.clusters;
122
- const sorted = sortBy(out, ['ready:desc', 'label']);
148
+ let localCluster = null;
123
149
 
124
- // put local cluster on top of list always
125
- // https://github.com/rancher/dashboard/issues/10975
126
- if (sorted.findIndex((c) => c.id === 'local') > 0) {
127
- const localCluster = sorted.find((c) => c.id === 'local');
128
- const localIndex = sorted.findIndex((c) => c.id === 'local');
150
+ const filtered = this.clusters.filter((c) => {
151
+ // If we're searching we don't care if pinned or not
152
+ if (search) {
153
+ if (!c.label?.toLowerCase().includes(search)) {
154
+ return false;
155
+ }
156
+ } else if (c.pinned) {
157
+ // Not searching, not pinned, don't care
158
+ return false;
159
+ }
160
+
161
+ if (!localCluster && c.id === 'local') {
162
+ // Local cluster is a special case, we're inserting it at top so don't include in the middle
163
+ localCluster = c;
164
+
165
+ return false;
166
+ }
129
167
 
130
- sorted.splice(localIndex, 1);
168
+ return true;
169
+ });
170
+
171
+ const sorted = sortBy(filtered, ['ready:desc', 'label']);
172
+
173
+ // put local cluster on top of list always - https://github.com/rancher/dashboard/issues/10975
174
+ if (localCluster) {
131
175
  sorted.unshift(localCluster);
132
176
  }
133
177
 
@@ -141,25 +185,45 @@ export default {
141
185
  this.searchActive = false;
142
186
 
143
187
  if (sorted.length >= this.maxClustersToShow) {
144
- const sortedPinOut = sorted.filter((item) => !item.pinned).slice(0, this.maxClustersToShow);
145
-
146
- return sortedPinOut;
147
- } else {
148
- return sorted.filter((item) => !item.pinned);
188
+ return sorted.slice(0, this.maxClustersToShow);
149
189
  }
190
+
191
+ return sorted;
150
192
  },
151
193
 
194
+ /**
195
+ * Filter clusters by
196
+ * 1. Not pinned
197
+ * 2. Includes search term
198
+ *
199
+ * Sort remaining clusters
200
+ *
201
+ * Reduce number of clusters if too many too show
202
+ *
203
+ * Important! This is hidden if there's a filter (user searching)
204
+ */
152
205
  pinFiltered() {
153
- const out = this.clusters.filter((item) => item.pinned);
154
- const sorted = sortBy(out, ['ready:desc', 'label']);
206
+ let localCluster = null;
207
+ const filtered = this.clusters.filter((c) => {
208
+ if (!c.pinned) {
209
+ // We only care about pinned clusters
210
+ return false;
211
+ }
212
+
213
+ if (c.id === 'local') {
214
+ // Special case, we're going to add this at the start so filter out
215
+ localCluster = c;
216
+
217
+ return false;
218
+ }
219
+
220
+ return true;
221
+ });
155
222
 
156
- // put local cluster on top of list always
157
- // https://github.com/rancher/dashboard/issues/10975
158
- if (sorted.findIndex((c) => c.id === 'local') > 0) {
159
- const localCluster = sorted.find((c) => c.id === 'local');
160
- const localIndex = sorted.findIndex((c) => c.id === 'local');
223
+ const sorted = sortBy(filtered, ['ready:desc', 'label']);
161
224
 
162
- sorted.splice(localIndex, 1);
225
+ // put local cluster on top of list always - https://github.com/rancher/dashboard/issues/10975
226
+ if (localCluster) {
163
227
  sorted.unshift(localCluster);
164
228
  }
165
229
 
@@ -167,7 +231,7 @@ export default {
167
231
  },
168
232
 
169
233
  pinnedClustersHeight() {
170
- const pinCount = this.clusters.filter((item) => item.pinned).length;
234
+ const pinCount = this.pinFiltered.length;
171
235
  const height = pinCount > 2 ? (pinCount * 43) : 90;
172
236
 
173
237
  return `min-height: ${ height }px`;
@@ -5,7 +5,7 @@ import { mount, Wrapper } from '@vue/test-utils';
5
5
  // DISCLAIMER: This should not be added here, although we have several store requests which are irrelevant
6
6
  const defaultStore = {
7
7
  'management/byId': jest.fn(),
8
- 'management/schemaFor': jest.fn(),
8
+ 'management/schemaFor': () => ({}),
9
9
  'i18n/t': jest.fn(),
10
10
  'features/get': jest.fn(),
11
11
  'prefs/theme': jest.fn(),
@@ -21,7 +21,11 @@ describe('topLevelMenu', () => {
21
21
  mocks: {
22
22
  $store: {
23
23
  getters: {
24
- 'management/all': () => [{ name: 'whatever' }],
24
+ 'management/all': () => [{
25
+ name: 'whatever',
26
+ id: 'an-id1',
27
+ mgmt: { id: 'an-id1' },
28
+ }],
25
29
  ...defaultStore
26
30
  },
27
31
  },
@@ -53,21 +57,21 @@ describe('topLevelMenu', () => {
53
57
  'management/all': () => [
54
58
  {
55
59
  name: 'x32-cwf5-name',
56
- id: 'x32-cwf5-id',
60
+ id: 'an-id1',
57
61
  mgmt: { id: 'an-id1' },
58
62
  nameDisplay: 'c-cluster',
59
63
  isReady: true
60
64
  },
61
65
  {
62
66
  name: 'x33-cwf5-name',
63
- id: 'x33-cwf5-id',
67
+ id: 'an-id2',
64
68
  mgmt: { id: 'an-id2' },
65
69
  nameDisplay: 'a-cluster',
66
70
  isReady: true
67
71
  },
68
72
  {
69
73
  name: 'x34-cwf5-name',
70
- id: 'x34-cwf5-id',
74
+ id: 'an-id3',
71
75
  mgmt: { id: 'an-id3' },
72
76
  nameDisplay: 'b-cluster',
73
77
  isReady: true
@@ -75,7 +79,7 @@ describe('topLevelMenu', () => {
75
79
  {
76
80
  name: 'local-name',
77
81
  id: 'local',
78
- mgmt: { id: 'an-id4' },
82
+ mgmt: { id: 'local' },
79
83
  nameDisplay: 'local',
80
84
  isReady: true
81
85
  },
@@ -112,21 +116,21 @@ describe('topLevelMenu', () => {
112
116
  'management/all': () => [
113
117
  {
114
118
  name: 'x32-cwf5-name',
115
- id: 'x32-cwf5-id',
119
+ id: 'an-id1',
116
120
  mgmt: { id: 'an-id1' },
117
121
  nameDisplay: 'c-cluster',
118
122
  isReady: true
119
123
  },
120
124
  {
121
125
  name: 'x33-cwf5-name',
122
- id: 'x33-cwf5-id',
126
+ id: 'an-id2',
123
127
  mgmt: { id: 'an-id2' },
124
128
  nameDisplay: 'a-cluster',
125
129
  isReady: false
126
130
  },
127
131
  {
128
132
  name: 'x34-cwf5-name',
129
- id: 'x34-cwf5-id',
133
+ id: 'an-id3',
130
134
  mgmt: { id: 'an-id3' },
131
135
  nameDisplay: 'b-cluster',
132
136
  isReady: true
@@ -134,7 +138,7 @@ describe('topLevelMenu', () => {
134
138
  {
135
139
  name: 'local-name',
136
140
  id: 'local',
137
- mgmt: { id: 'an-id4' },
141
+ mgmt: { id: 'local' },
138
142
  nameDisplay: 'local',
139
143
  isReady: true
140
144
  },
@@ -171,7 +175,7 @@ describe('topLevelMenu', () => {
171
175
  'management/all': () => [
172
176
  {
173
177
  name: 'x32-cwf5-name',
174
- id: 'x32-cwf5-id',
178
+ id: 'an-id1',
175
179
  mgmt: { id: 'an-id1' },
176
180
  nameDisplay: 'c-cluster',
177
181
  isReady: true,
@@ -179,7 +183,7 @@ describe('topLevelMenu', () => {
179
183
  },
180
184
  {
181
185
  name: 'x33-cwf5-name',
182
- id: 'x33-cwf5-id',
186
+ id: 'an-id2',
183
187
  mgmt: { id: 'an-id2' },
184
188
  nameDisplay: 'a-cluster',
185
189
  isReady: true,
@@ -187,7 +191,7 @@ describe('topLevelMenu', () => {
187
191
  },
188
192
  {
189
193
  name: 'x34-cwf5-name',
190
- id: 'x34-cwf5-id',
194
+ id: 'an-id3',
191
195
  mgmt: { id: 'an-id3' },
192
196
  nameDisplay: 'b-cluster',
193
197
  isReady: true,
@@ -196,7 +200,7 @@ describe('topLevelMenu', () => {
196
200
  {
197
201
  name: 'local-name',
198
202
  id: 'local',
199
- mgmt: { id: 'an-id4' },
203
+ mgmt: { id: 'local' },
200
204
  nameDisplay: 'local',
201
205
  isReady: true,
202
206
  pinned: true
@@ -234,7 +238,7 @@ describe('topLevelMenu', () => {
234
238
  'management/all': () => [
235
239
  {
236
240
  name: 'x32-cwf5-name',
237
- id: 'x32-cwf5-id',
241
+ id: 'an-id1',
238
242
  mgmt: { id: 'an-id1' },
239
243
  nameDisplay: 'c-cluster',
240
244
  isReady: true,
@@ -242,7 +246,7 @@ describe('topLevelMenu', () => {
242
246
  },
243
247
  {
244
248
  name: 'x33-cwf5-name',
245
- id: 'x33-cwf5-id',
249
+ id: 'an-id2',
246
250
  mgmt: { id: 'an-id2' },
247
251
  nameDisplay: 'a-cluster',
248
252
  isReady: true,
@@ -250,7 +254,7 @@ describe('topLevelMenu', () => {
250
254
  },
251
255
  {
252
256
  name: 'x34-cwf5-name',
253
- id: 'x34-cwf5-id',
257
+ id: 'an-id3',
254
258
  mgmt: { id: 'an-id3' },
255
259
  nameDisplay: 'b-cluster',
256
260
  isReady: false,
@@ -259,7 +263,7 @@ describe('topLevelMenu', () => {
259
263
  {
260
264
  name: 'local-name',
261
265
  id: 'local',
262
- mgmt: { id: 'an-id4' },
266
+ mgmt: { id: 'local' },
263
267
  nameDisplay: 'local',
264
268
  isReady: true,
265
269
  pinned: true
@@ -356,7 +360,7 @@ describe('topLevelMenu', () => {
356
360
  it('should show description if it is available on the mgmt cluster (relevant for RKE1/ember world)', async() => {
357
361
  const wrapper: Wrapper<InstanceType<typeof TopLevelMenu>> = mount(TopLevelMenu, {
358
362
  data: () => {
359
- return { hasProvCluster: false, showPinClusters: true };
363
+ return { hasProvCluster: true, showPinClusters: true };
360
364
  },
361
365
 
362
366
  global: {
@@ -372,6 +376,7 @@ describe('topLevelMenu', () => {
372
376
  {
373
377
  name: 'whatever',
374
378
  id: 'an-id1',
379
+ mgmt: { id: 'an-id1' },
375
380
  description: 'some-description1',
376
381
  nameDisplay: 'some-label',
377
382
  isReady: true,
@@ -381,6 +386,7 @@ describe('topLevelMenu', () => {
381
386
  {
382
387
  name: 'whatever',
383
388
  id: 'an-id2',
389
+ mgmt: { id: 'an-id2' },
384
390
  description: 'some-description2',
385
391
  nameDisplay: 'some-label',
386
392
  pinned: true
@@ -389,6 +395,7 @@ describe('topLevelMenu', () => {
389
395
  {
390
396
  name: 'whatever',
391
397
  id: 'an-id3',
398
+ mgmt: { id: 'an-id3' },
392
399
  description: 'some-description3',
393
400
  nameDisplay: 'some-label',
394
401
  isReady: true
@@ -397,6 +404,7 @@ describe('topLevelMenu', () => {
397
404
  {
398
405
  name: 'whatever',
399
406
  id: 'an-id4',
407
+ mgmt: { id: 'an-id4' },
400
408
  description: 'some-description4',
401
409
  nameDisplay: 'some-label'
402
410
  },
@@ -466,7 +474,11 @@ describe('topLevelMenu', () => {
466
474
  mocks: {
467
475
  $store: {
468
476
  getters: {
469
- 'management/all': () => [{ nameDisplay: 'something else' }],
477
+ 'management/all': () => [{
478
+ id: 'an-id1',
479
+ mgmt: { id: 'an-id1' },
480
+ nameDisplay: 'something else'
481
+ }],
470
482
  ...defaultStore
471
483
  },
472
484
  },
@@ -489,7 +501,12 @@ describe('topLevelMenu', () => {
489
501
  mocks: {
490
502
  $store: {
491
503
  getters: {
492
- 'management/all': () => [{ nameDisplay: 'something else', pinned: true }],
504
+ 'management/all': () => [{
505
+ id: 'an-id1',
506
+ mgmt: { id: 'an-id1' },
507
+ nameDisplay: 'something else',
508
+ pinned: true
509
+ }],
493
510
  ...defaultStore
494
511
  },
495
512
  },
@@ -515,7 +532,11 @@ describe('topLevelMenu', () => {
515
532
  mocks: {
516
533
  $store: {
517
534
  getters: {
518
- 'management/all': () => [{ nameDisplay: search }],
535
+ 'management/all': () => [{
536
+ id: 'an-id1',
537
+ mgmt: { id: 'an-id1' },
538
+ nameDisplay: search
539
+ }],
519
540
  ...defaultStore
520
541
  },
521
542
  },
@@ -540,7 +561,12 @@ describe('topLevelMenu', () => {
540
561
  mocks: {
541
562
  $store: {
542
563
  getters: {
543
- 'management/all': () => [{ nameDisplay: search, pinned: true }],
564
+ 'management/all': () => [{
565
+ nameDisplay: search,
566
+ pinned: true,
567
+ id: 'an-id1',
568
+ mgmt: { id: 'an-id1' },
569
+ }],
544
570
  ...defaultStore
545
571
  },
546
572
  },
@@ -11,6 +11,7 @@ export const CATTLE_PUBLIC_ENDPOINTS = 'field.cattle.io/publicEndpoints';
11
11
  export const TARGET_WORKLOADS = 'field.cattle.io/targetWorkloadIds';
12
12
  export const UI_MANAGED = 'management.cattle.io/ui-managed';
13
13
  export const CREATOR_ID = 'field.cattle.io/creatorId';
14
+ export const CREATOR_PRINCIPAL_ID = 'field.cattle.io/creator-principal-name';
14
15
  export const RESOURCE_QUOTA = 'field.cattle.io/resourceQuota';
15
16
  export const AZURE_MIGRATED = 'auth.cattle.io/azuread-endpoint-migrated';
16
17
  export const WORKSPACE_ANNOTATION = 'objectset.rio.cattle.io/id';
@@ -90,11 +91,12 @@ export const CATALOG = {
90
91
  _CLUSTER_TPL: 'cluster-template',
91
92
  _CLUSTER_TOOL: 'cluster-tool',
92
93
 
93
- COMPONENT: 'catalog.cattle.io/ui-component',
94
- SOURCE_REPO_TYPE: 'catalog.cattle.io/ui-source-repo-type',
95
- SOURCE_REPO_NAME: 'catalog.cattle.io/ui-source-repo',
96
- COLOR: 'catalog.cattle.io/ui-color',
97
- DISPLAY_NAME: 'catalog.cattle.io/display-name',
94
+ COMPONENT: 'catalog.cattle.io/ui-component',
95
+ SOURCE_REPO_TYPE: 'catalog.cattle.io/ui-source-repo-type',
96
+ SOURCE_REPO_NAME: 'catalog.cattle.io/ui-source-repo',
97
+ COLOR: 'catalog.cattle.io/ui-color',
98
+ DISPLAY_NAME: 'catalog.cattle.io/display-name',
99
+ CLUSTER_REPO_NAME: 'catalog.cattle.io/cluster-repo-name',
98
100
 
99
101
  SUPPORTED_OS: 'catalog.cattle.io/os',
100
102
  PERMITTED_OS: 'catalog.cattle.io/permits-os',
@@ -172,3 +174,5 @@ export const SYSTEM_LABELS = [
172
174
  'node.kubernetes.io',
173
175
  'egress.rke2.io'
174
176
  ];
177
+
178
+ export const CLOUD_CREDENTIALS = { EXPIRATION: 'rancher.io/expiration-timestamp' };
package/core/types.ts CHANGED
@@ -26,7 +26,7 @@ export type CoreStoreInit = (store: any, ctx: any) => void;
26
26
  export type RegisterStore = () => (store: any) => void
27
27
  export type UnregisterStore = (store: any) => void
28
28
 
29
- export type PluginRouteRecordRaw = {parent?: string, route: RouteRecordRaw}
29
+ export type PluginRouteRecordRaw = { [key: string]: any }
30
30
 
31
31
  export type OnEnterLeavePackageConfig = {
32
32
  clusterId: string,
@@ -235,7 +235,7 @@ export interface ProductOptions {
235
235
  /**
236
236
  * The route that the product will lead to if click on in navigation.
237
237
  */
238
- to?: Location;
238
+ to?: PluginRouteRecordRaw;
239
239
 
240
240
  /**
241
241
  * Leaving these here for completeness but I don't think these should be advertised as useable to plugin creators.
@@ -573,10 +573,6 @@ export default {
573
573
  }
574
574
  },
575
575
 
576
- mounted() {
577
- window.c = this;
578
- },
579
-
580
576
  methods: {
581
577
  toggleScaleDownModal( event, resources ) {
582
578
  // Check if the user held alt key when an action is clicked.
@@ -196,7 +196,7 @@ export default {
196
196
  class="role-tertiary add mt-5"
197
197
  :label="t('generic.readFromFile')"
198
198
  :mode="mode"
199
- @selected="$set(model, 'oauthCredential', $event)"
199
+ @selected="model.oauthCredential = $event"
200
200
  />
201
201
  </div>
202
202
  </div>
@@ -231,7 +231,7 @@ export default {
231
231
  class="role-tertiary add mt-5"
232
232
  :label="t('generic.readFromFile')"
233
233
  :mode="mode"
234
- @selected="$set(model, 'serviceAccountCredential', $event)"
234
+ @selected="model.serviceAccountCredential = $event"
235
235
  />
236
236
  </div>
237
237
  </div>
@@ -120,7 +120,7 @@ export default {
120
120
  :step="1"
121
121
  :mode="mode"
122
122
  :label="t('authConfig.ldap.port')"
123
- @update:value="e=>$set(model, 'port', e.replace(/[^0-9]*/g, ''))"
123
+ @update:value="e=> model.port = e.replace(/[^0-9]*/g, '')"
124
124
  />
125
125
  </div>
126
126
 
@@ -158,7 +158,7 @@ export default {
158
158
  class="role-tertiary add mt-5"
159
159
  :label="t('generic.readFromFile')"
160
160
  :mode="mode"
161
- @selected="$set(model, 'certificate', $event)"
161
+ @selected="model.certificate = $event"
162
162
  />
163
163
  </div>
164
164
  </div>
@@ -233,7 +233,7 @@ export default {
233
233
  class="role-tertiary add mt-5"
234
234
  :label="t('generic.readFromFile')"
235
235
  :mode="mode"
236
- @selected="$set(model, 'privateKey', $event)"
236
+ @selected="model.privateKey = $event"
237
237
  />
238
238
  </div>
239
239
  <div class="col span-6">
@@ -248,7 +248,7 @@ export default {
248
248
  class="role-tertiary add mt-5"
249
249
  :label="t('generic.readFromFile')"
250
250
  :mode="mode"
251
- @selected="$set(model, 'certificate', $event)"
251
+ @selected="model.certificate = $event"
252
252
  />
253
253
  </div>
254
254
  </div>
@@ -84,29 +84,28 @@ export default {
84
84
 
85
85
  watch: {
86
86
  'value.type'(neuType, oldType) {
87
- const { $set } = this;
88
87
  let resourceSpec, podSpec, objectSpec, externalSpec;
89
88
 
90
89
  switch (neuType) {
91
90
  case 'External':
92
91
  externalSpec = this.initExternalSpec();
93
92
 
94
- $set(this.value, 'external', externalSpec);
93
+ this.value.external = externalSpec;
95
94
  break;
96
95
  case 'Object':
97
96
  objectSpec = this.initObjectSpec();
98
97
 
99
- $set(this.value, 'object', objectSpec);
98
+ this.value.object = objectSpec;
100
99
  break;
101
100
  case 'Pods':
102
101
  podSpec = this.initPodsSpec();
103
102
 
104
- $set(this.value, 'pods', podSpec);
103
+ this.value.pods = podSpec;
105
104
  break;
106
105
  case 'Resource':
107
106
  resourceSpec = this.initResourceSpec();
108
107
 
109
- $set(this.value, 'resource', resourceSpec.resource);
108
+ this.value.resource = resourceSpec.resource;
110
109
  break;
111
110
  default:
112
111
  break;
@@ -14,7 +14,7 @@ import { MANAGEMENT } from '@shell/config/types';
14
14
  import { NAME } from '@shell/config/product/explorer';
15
15
  import { PROJECT_ID, _VIEW, _CREATE, _EDIT } from '@shell/config/query-params';
16
16
  import ProjectMembershipEditor, { canViewProjectMembershipEditor } from '@shell/components/form/Members/ProjectMembershipEditor';
17
-
17
+ import { CREATOR_PRINCIPAL_ID } from '@shell/config/labels-annotations';
18
18
  import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
19
19
  import { Banner } from '@components/Banner';
20
20
 
@@ -103,6 +103,9 @@ export default {
103
103
  this.value.metadata['namespace'] = this.$store.getters['currentCluster'].id;
104
104
  this.value['spec'] = this.value.spec || {};
105
105
  this.value.spec['containerDefaultResourceLimit'] = this.value.spec.containerDefaultResourceLimit || {};
106
+ if (!this.$store.getters['auth/principalId'].includes('local://')) {
107
+ this.value.metadata.annotations[CREATOR_PRINCIPAL_ID] = this.$store.getters['auth/principalId'];
108
+ }
106
109
  },
107
110
  methods: {
108
111
  async save(saveCb) {
@@ -64,11 +64,7 @@ export default {
64
64
  initializeType(authOptions, type) {
65
65
  authOptions.forEach((authOption) => {
66
66
  if (authOption.value === type && type !== 'none') {
67
- this.$set(
68
- this.value,
69
- authOption.value,
70
- this.value[authOption.value] || authOption.default
71
- );
67
+ this.value.authOption.value = this.value[authOption.value] || authOption.default;
72
68
  } else if (typeof this.value[authOption.value] !== 'undefined') {
73
69
  delete this.value[authOption.value];
74
70
  }
@@ -28,11 +28,7 @@ export default {
28
28
  this.value['sendResolved'] = this.value.sendResolved || false;
29
29
 
30
30
  if (this.mode === _CREATE) {
31
- this.$set(
32
- this.value,
33
- 'text',
34
- this.value.text || '{{ template "slack.rancher.text" . }}'
35
- );
31
+ this.value.text = this.value.text || '{{ template "slack.rancher.text" . }}';
36
32
  }
37
33
 
38
34
  return {