@rancher/shell 3.0.5-rc.7 → 3.0.5-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 (177) hide show
  1. package/assets/brand/classic/metadata.json +3 -0
  2. package/assets/styles/app.scss +1 -0
  3. package/assets/styles/base/_color.scss +16 -0
  4. package/assets/styles/base/_helpers.scss +10 -0
  5. package/assets/styles/base/_variables.scss +1 -1
  6. package/assets/styles/fonts/_icons.scss +1 -32
  7. package/assets/styles/global/_layout.scss +1 -1
  8. package/assets/styles/themes/_dark.scss +262 -260
  9. package/assets/styles/themes/_light.scss +538 -515
  10. package/assets/styles/themes/_modern.scss +914 -0
  11. package/assets/translations/en-us.yaml +84 -25
  12. package/chart/__tests__/S3.test.ts +2 -1
  13. package/cloud-credential/generic.vue +18 -10
  14. package/cloud-credential/harvester.vue +1 -9
  15. package/components/AdvancedSection.vue +8 -0
  16. package/components/ChartReadme.vue +17 -7
  17. package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +1 -26
  18. package/components/Drawer/ResourceDetailDrawer/composables.ts +0 -23
  19. package/components/Drawer/ResourceDetailDrawer/index.vue +17 -4
  20. package/components/InstallHelmCharts.vue +656 -0
  21. package/components/LazyImage.vue +60 -4
  22. package/components/LocaleSelector.vue +7 -2
  23. package/components/Markdown.vue +4 -0
  24. package/components/Resource/Detail/Masthead/composable.ts +16 -0
  25. package/components/Resource/Detail/Masthead/index.vue +37 -0
  26. package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +5 -5
  27. package/components/Resource/Detail/Metadata/__tests__/composables.test.ts +10 -17
  28. package/components/Resource/Detail/Metadata/composables.ts +9 -7
  29. package/components/Resource/Detail/Metadata/index.vue +17 -2
  30. package/components/Resource/Detail/Page.vue +35 -21
  31. package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +8 -9
  32. package/components/Resource/Detail/TitleBar/composables.ts +2 -3
  33. package/components/Resource/Detail/TitleBar/index.vue +10 -1
  34. package/components/ResourceDetail/index.vue +569 -74
  35. package/components/SlideInPanelManager.vue +10 -3
  36. package/components/SortableTable/index.vue +4 -4
  37. package/components/Tabbed/index.vue +29 -3
  38. package/components/__tests__/LazyImage.spec.ts +121 -0
  39. package/components/fleet/FleetStatus.vue +4 -0
  40. package/components/form/ClusterAppearance.vue +5 -0
  41. package/components/form/Members/ClusterPermissionsEditor.vue +1 -1
  42. package/components/form/ProjectMemberEditor.vue +1 -1
  43. package/components/form/ResourceLabeledSelect.vue +19 -6
  44. package/components/form/ResourceTabs/index.vue +20 -0
  45. package/components/form/SecretSelector.vue +9 -0
  46. package/components/form/labeled-select-utils/labeled-select-pagination.ts +3 -38
  47. package/components/formatter/FleetApplicationSource.vue +25 -17
  48. package/components/nav/Favorite.vue +4 -0
  49. package/components/nav/NotificationCenter/Notification.vue +1 -27
  50. package/components/nav/WindowManager/index.vue +3 -3
  51. package/config/labels-annotations.js +1 -2
  52. package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +11 -0
  53. package/detail/__tests__/workload.test.ts +164 -0
  54. package/detail/configmap.vue +33 -75
  55. package/detail/projectsecret.vue +11 -0
  56. package/detail/provisioning.cattle.io.cluster.vue +350 -324
  57. package/detail/secret.vue +49 -308
  58. package/detail/workload/index.vue +38 -21
  59. package/dialog/InstallExtensionDialog.vue +8 -5
  60. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +224 -0
  61. package/edit/fleet.cattle.io.gitrepo.vue +5 -6
  62. package/edit/fleet.cattle.io.helmop.vue +78 -56
  63. package/edit/logging.banzaicloud.io.output/index.vue +1 -1
  64. package/edit/logging.banzaicloud.io.output/providers/awsElasticsearch.vue +5 -6
  65. package/edit/networking.k8s.io.ingress/Certificate.vue +9 -11
  66. package/edit/networking.k8s.io.ingress/DefaultBackend.vue +8 -3
  67. package/edit/networking.k8s.io.ingress/Rule.vue +2 -5
  68. package/edit/networking.k8s.io.ingress/RulePath.vue +17 -11
  69. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +11 -10
  70. package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +1 -3
  71. package/edit/networking.k8s.io.networkpolicy/index.vue +17 -17
  72. package/edit/provisioning.cattle.io.cluster/rke2.vue +21 -13
  73. package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +9 -7
  74. package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +10 -12
  75. package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +39 -38
  76. package/edit/provisioning.cattle.io.cluster/tabs/etcd/S3Config.vue +41 -19
  77. package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +16 -3
  78. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +30 -31
  79. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryMirrors.vue +9 -10
  80. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +1 -3
  81. package/edit/provisioning.cattle.io.cluster/tabs/upgrade/DrainOptions.vue +16 -9
  82. package/edit/workload/index.vue +5 -14
  83. package/list/provisioning.cattle.io.cluster.vue +1 -69
  84. package/machine-config/__tests__/vmwarevsphere.test.ts +5 -7
  85. package/machine-config/google.vue +9 -1
  86. package/machine-config/vmwarevsphere.vue +7 -17
  87. package/mixins/chart.js +0 -2
  88. package/mixins/resource-fetch-api-pagination.js +3 -4
  89. package/models/__tests__/chart.test.ts +111 -80
  90. package/models/__tests__/fleet.cattle.io.helmop.test.ts +224 -0
  91. package/models/__tests__/node.test.ts +7 -63
  92. package/models/catalog.cattle.io.app.js +1 -1
  93. package/models/catalog.cattle.io.operation.js +1 -1
  94. package/models/chart.js +36 -20
  95. package/models/cloudcredential.js +2 -163
  96. package/models/cluster/node.js +7 -7
  97. package/models/cluster.x-k8s.io.machine.js +3 -3
  98. package/models/compliance.cattle.io.clusterscan.js +2 -2
  99. package/models/configmap.js +4 -0
  100. package/models/constraints.gatekeeper.sh.constraint.js +1 -1
  101. package/models/fleet-application.js +0 -17
  102. package/models/fleet.cattle.io.gitrepo.js +15 -1
  103. package/models/fleet.cattle.io.helmop.js +26 -22
  104. package/models/management.cattle.io.setting.js +4 -0
  105. package/models/persistentvolumeclaim.js +1 -1
  106. package/models/pod.js +2 -2
  107. package/models/provisioning.cattle.io.cluster.js +16 -40
  108. package/models/rke.cattle.io.etcdsnapshot.js +1 -1
  109. package/models/secret.js +4 -0
  110. package/models/storage.k8s.io.storageclass.js +2 -2
  111. package/models/workload.js +3 -3
  112. package/package.json +11 -10
  113. package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +1 -0
  114. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +4 -1
  115. package/pages/c/_cluster/apps/charts/__tests__/AppChartCardFooter.spec.js +41 -0
  116. package/pages/c/_cluster/apps/charts/chart.vue +422 -174
  117. package/pages/c/_cluster/apps/charts/install.vue +1 -1
  118. package/pages/c/_cluster/explorer/projectsecret.vue +3 -13
  119. package/pages/c/_cluster/fleet/__tests__/index.test.ts +608 -314
  120. package/pages/c/_cluster/fleet/index.vue +103 -44
  121. package/pages/c/_cluster/manager/cloudCredential/index.vue +2 -59
  122. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +10 -3
  123. package/pages/c/_cluster/uiplugins/index.vue +36 -25
  124. package/plugins/dashboard-store/actions.js +42 -22
  125. package/plugins/dashboard-store/resource-class.js +31 -0
  126. package/plugins/steve/__tests__/getters.test.ts +1 -1
  127. package/plugins/steve/__tests__/subscribe.spec.ts +259 -1
  128. package/plugins/steve/getters.js +8 -2
  129. package/plugins/steve/resourceWatcher.js +10 -3
  130. package/plugins/steve/subscribe.js +192 -19
  131. package/plugins/steve/worker/web-worker.advanced.js +2 -0
  132. package/rancher-components/Card/Card.vue +0 -18
  133. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.test.ts +15 -0
  134. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +65 -0
  135. package/rancher-components/Pill/RcStatusBadge/index.ts +2 -0
  136. package/rancher-components/Pill/RcStatusBadge/types.ts +5 -0
  137. package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.test.ts +33 -0
  138. package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +75 -0
  139. package/rancher-components/Pill/RcStatusIndicator/index.ts +2 -0
  140. package/rancher-components/Pill/RcStatusIndicator/types.ts +7 -0
  141. package/rancher-components/Pill/types.ts +2 -0
  142. package/rancher-components/RcButton/RcButton.vue +1 -1
  143. package/rancher-components/RcDropdown/RcDropdown.test.ts +98 -0
  144. package/rancher-components/RcDropdown/RcDropdown.vue +5 -0
  145. package/rancher-components/RcDropdown/RcDropdownItem.vue +7 -1
  146. package/rancher-components/RcDropdown/RcDropdownItemCheckbox.vue +2 -1
  147. package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +2 -1
  148. package/rancher-components/RcDropdown/useDropdownContext.ts +21 -0
  149. package/rancher-components/RcDropdown/useDropdownItem.ts +30 -1
  150. package/rancher-components/RcItemCard/RcItemCard.test.ts +20 -0
  151. package/rancher-components/RcItemCard/RcItemCard.vue +40 -6
  152. package/store/__tests__/catalog.test.ts +93 -1
  153. package/store/aws.js +19 -8
  154. package/store/catalog.js +8 -3
  155. package/types/resources/settings.d.ts +1 -1
  156. package/types/shell/index.d.ts +28 -28
  157. package/types/uiplugins.ts +73 -0
  158. package/utils/__tests__/back-off.test.ts +354 -0
  159. package/utils/__tests__/kontainer.test.ts +19 -0
  160. package/utils/__tests__/uiplugins.test.ts +84 -0
  161. package/utils/back-off.ts +176 -0
  162. package/utils/dynamic-importer.js +8 -0
  163. package/utils/kontainer.ts +3 -5
  164. package/utils/style.ts +3 -0
  165. package/utils/uiplugins.ts +29 -2
  166. package/utils/validators/__tests__/setting.test.js +92 -0
  167. package/utils/validators/formRules/__tests__/index.test.ts +88 -7
  168. package/utils/validators/formRules/index.ts +83 -8
  169. package/utils/validators/setting.js +17 -0
  170. package/cloud-credential/__tests__/harvester.test.ts +0 -18
  171. package/components/ResourceDetail/__tests__/index.test.ts +0 -135
  172. package/components/ResourceDetail/legacy.vue +0 -562
  173. package/components/formatter/CloudCredExpired.vue +0 -69
  174. package/pages/explorer/resource/detail/configmap.vue +0 -42
  175. package/pages/explorer/resource/detail/projectsecret.vue +0 -9
  176. package/pages/explorer/resource/detail/secret.vue +0 -63
  177. package/utils/aws.js +0 -0
package/detail/secret.vue CHANGED
@@ -1,313 +1,54 @@
1
- <script>
2
- import { SECRET_TYPES as TYPES } from '@shell/config/secret';
3
- import { base64Decode } from '@shell/utils/crypto';
4
- import CreateEditView from '@shell/mixins/create-edit-view';
5
- import ResourceTabs from '@shell/components/form/ResourceTabs';
6
- import DetailText from '@shell/components/DetailText';
7
- import Tab from '@shell/components/Tabbed/Tab';
1
+ <script setup lang="ts">
2
+ import DetailPage from '@shell/components/Resource/Detail/Page.vue';
3
+ import { MANAGEMENT, SECRET } from '@shell/config/types';
4
+ import ResourceTabs from '@shell/components/form/ResourceTabs/index.vue';
5
+ import SecretDataTab from '@shell/components/Resource/Detail/ResourceTabs/SecretDataTab/index.vue';
6
+ import KnownHostsTab from '@shell/components/Resource/Detail/ResourceTabs/KnownHostsTab/index.vue';
7
+ import { useGetKnownHostsTabProps } from '@shell/components/Resource/Detail/ResourceTabs/KnownHostsTab/composables';
8
+ import { useSecretDataTabDefaultProps } from '@shell/components/Resource/Detail/ResourceTabs/SecretDataTab/composeables';
9
+ import { useStore } from 'vuex';
10
+ import { computed } from 'vue';
11
+ import Masthead from '@shell/components/Resource/Detail/Masthead/index.vue';
12
+ import { useDefaultMastheadProps } from '@shell/components/Resource/Detail/Masthead/composable';
13
+
14
+ const store = useStore();
15
+
16
+ export interface Props {
17
+ value: any;
18
+ }
19
+ const props = defineProps<Props>();
20
+ const schema = computed(() => store.getters['cluster/schemaFor'](SECRET));
21
+ const secret = props.value;
22
+
23
+ if (secret.isProjectScoped) {
24
+ store.dispatch('management/find', { id: secret.projectId, type: MANAGEMENT.PROJECT });
25
+ }
26
+
27
+ const defaultMastheadProps = useDefaultMastheadProps(secret);
28
+ const knownHostsTabProps = useGetKnownHostsTabProps(secret);
29
+ const secretDataTabProps = useSecretDataTabDefaultProps(secret);
8
30
 
9
- const types = [
10
- TYPES.OPAQUE,
11
- TYPES.DOCKER_JSON,
12
- TYPES.TLS,
13
- TYPES.SSH,
14
- TYPES.BASIC,
15
- ];
16
- const registryAddresses = [
17
- 'DockerHub', 'Quay.io', 'Artifactory', 'Custom'
18
- ];
19
-
20
- export default {
21
- emits: ['input'],
22
-
23
- components: {
24
- ResourceTabs,
25
- DetailText,
26
- Tab,
27
- },
28
-
29
- mixins: [CreateEditView],
30
-
31
- props: {
32
- value: {
33
- type: Object,
34
- default: () => {
35
- return {};
36
- }
37
- }
38
- },
39
-
40
- data() {
41
- let username;
42
- let password;
43
- let registryUrl;
44
- let registryProvider = 'Custom';
45
- let key;
46
- let crt;
47
-
48
- if (this.value._type === TYPES.DOCKER_JSON) {
49
- const json = base64Decode(this.value.data['.dockerconfigjson']);
50
-
51
- const { auths } = JSON.parse(json);
52
-
53
- registryUrl = Object.keys(auths)[0];
54
-
55
- if (registryUrl === 'index.docker.io/v1/') {
56
- registryProvider = 'DockerHub';
57
- } else if (registryUrl === 'quay.io') {
58
- registryProvider = 'Quay.io';
59
- } else if (registryUrl.includes('artifactory')) {
60
- registryProvider = 'Artifactory';
61
- }
62
-
63
- username = auths[registryUrl].username;
64
- password = auths[registryUrl].password;
65
- }
66
-
67
- const data = this.value?.data || {};
68
-
69
- if (this.value._type === TYPES.TLS) {
70
- // do not show existing key when editing
71
- key = this.mode === 'edit' ? '' : base64Decode(data['tls.key']);
72
-
73
- crt = base64Decode(data['tls.crt']);
74
- }
75
-
76
- if (this.value._type === TYPES.SERVICE_ACCT) {
77
- key = base64Decode(data['token']);
78
- crt = base64Decode(data['ca.crt']);
79
- }
80
-
81
- if ( this.value._type === TYPES.BASIC ) {
82
- username = base64Decode(data.username || '');
83
- password = base64Decode(data.password || '');
84
- }
85
-
86
- if ( this.value._type === TYPES.SSH ) {
87
- username = base64Decode(data['ssh-publickey'] || '');
88
- password = base64Decode(data['ssh-privatekey'] || '');
89
- }
90
-
91
- if (!this.value._type) {
92
- this.value['_type'] = TYPES.OPAQUE;
93
- }
94
-
95
- return {
96
- types,
97
- registryAddresses,
98
- registryProvider,
99
- username,
100
- password,
101
- registryUrl,
102
- key,
103
- crt,
104
- relatedServices: [],
105
- };
106
- },
107
-
108
- computed: {
109
- isCertificate() {
110
- return this.value._type === TYPES.TLS;
111
- },
112
-
113
- isSvcAcctToken() {
114
- return this.value._type === TYPES.SERVICE_ACCT;
115
- },
116
-
117
- isRegistry() {
118
- return this.value._type === TYPES.DOCKER_JSON;
119
- },
120
-
121
- isSsh() {
122
- return this.value._type === TYPES.SSH;
123
- },
124
-
125
- showKnownHosts() {
126
- return this.isSsh && this.value.supportsSshKnownHosts;
127
- },
128
-
129
- isBasicAuth() {
130
- return this.value._type === TYPES.BASIC;
131
- },
132
-
133
- parsedRows() {
134
- const rows = [];
135
- const { data = {} } = this.value;
136
-
137
- Object.keys(data).forEach((key) => {
138
- const value = base64Decode(data[key]);
139
-
140
- rows.push({
141
- key,
142
- value
143
- });
144
- });
145
-
146
- return rows;
147
- },
148
-
149
- knownHosts() {
150
- const { data = {} } = this.value;
151
-
152
- return data.known_hosts ? base64Decode(data.known_hosts) : '';
153
- },
154
-
155
- dataLabel() {
156
- switch (this.value._type) {
157
- case TYPES.TLS:
158
- return this.t('secret.certificate.certificate');
159
- case TYPES.SSH:
160
- return this.t('secret.ssh.keys');
161
- case TYPES.BASIC:
162
- return this.t('secret.authentication');
163
- default:
164
- return this.t('secret.data');
165
- }
166
- }
167
- },
168
- };
169
31
  </script>
170
-
171
32
  <template>
172
- <ResourceTabs
173
- :value="value"
174
- :mode="mode"
175
- @update:value="$emit('input', $event)"
176
- >
177
- <Tab
178
- name="data"
179
- :label="dataLabel"
180
- >
181
- <template v-if="isRegistry || isBasicAuth">
182
- <div
183
- v-if="isRegistry"
184
- class="row"
185
- >
186
- <div class="col span-12">
187
- <DetailText
188
- :value="registryUrl"
189
- label-key="secret.registry.domainName"
190
- />
191
- </div>
192
- </div>
193
- <div class="row mt-20">
194
- <div class="col span-6">
195
- <DetailText
196
- :value="username"
197
- label-key="secret.registry.username"
198
- />
199
- </div>
200
- <div class="col span-6">
201
- <DetailText
202
- :value="password"
203
- label-key="secret.registry.password"
204
- :conceal="true"
205
- />
206
- </div>
207
- </div>
208
- </template>
209
-
210
- <div
211
- v-else-if="isCertificate"
212
- class="row"
213
- >
214
- <div class="col span-6">
215
- <DetailText
216
- :value="key"
217
- label-key="secret.certificate.privateKey"
218
- :conceal="true"
219
- />
220
- </div>
221
- <div class="col span-6">
222
- <DetailText
223
- :value="crt"
224
- label-key="secret.certificate.certificate"
225
- />
226
- </div>
227
- </div>
228
-
229
- <div
230
- v-else-if="isSvcAcctToken"
231
- class="row"
33
+ <DetailPage>
34
+ <template #top-area>
35
+ <Masthead v-bind="defaultMastheadProps" />
36
+ </template>
37
+ <template #bottom-area>
38
+ <ResourceTabs
39
+ :value="secret"
40
+ :schema="schema"
232
41
  >
233
- <div class="col span-6">
234
- <DetailText
235
- :value="crt"
236
- label-key="secret.serviceAcct.ca"
237
- />
238
- </div>
239
- <div class="col span-6">
240
- <DetailText
241
- :value="key"
242
- label-key="secret.serviceAcct.token"
243
- :conceal="true"
244
- />
245
- </div>
246
- </div>
247
-
248
- <div
249
- v-else-if="isSsh"
250
- class="row"
251
- >
252
- <div class="col span-6">
253
- <DetailText
254
- :value="username"
255
- label-key="secret.ssh.public"
256
- />
257
- </div>
258
- <div class="col span-6">
259
- <DetailText
260
- :value="password"
261
- label-key="secret.ssh.private"
262
- :conceal="true"
263
- />
264
- </div>
265
- </div>
266
-
267
- <div v-else>
268
- <div
269
- v-for="(row,idx) in parsedRows"
270
- :key="idx"
271
- class="entry"
272
- >
273
- <DetailText
274
- :value="row.value"
275
- :label="row.key"
276
- :conceal="true"
277
- />
278
- </div>
279
- <div v-if="!parsedRows.length">
280
- <div
281
- v-t="'sortableTable.noRows'"
282
- class="m-20 text-center"
283
- />
284
- </div>
285
- </div>
286
- </Tab>
287
- <Tab
288
- v-if="showKnownHosts"
289
- name="known_hosts"
290
- label-key="secret.ssh.knownHosts"
291
- >
292
- <div class="row">
293
- <div class="col span-12">
294
- <DetailText
295
- :value="knownHosts"
296
- label-key="secret.ssh.knownHosts"
297
- :conceal="false"
298
- />
299
- </div>
300
- </div>
301
- </Tab>
302
- </ResourceTabs>
42
+ <SecretDataTab
43
+ v-bind="secretDataTabProps"
44
+ :weight="1"
45
+ />
46
+ <KnownHostsTab
47
+ v-if="knownHostsTabProps"
48
+ v-bind="knownHostsTabProps"
49
+ :weight="0"
50
+ />
51
+ </ResourceTabs>
52
+ </template>
53
+ </DetailPage>
303
54
  </template>
304
-
305
- <style lang="scss" scoped>
306
- .entry {
307
- margin-top: 10px;
308
-
309
- &:first-of-type {
310
- margin-top: 0;
311
- }
312
- }
313
- </style>
@@ -164,13 +164,15 @@ export default {
164
164
  },
165
165
 
166
166
  jobHeaders() {
167
- return this.$store.getters['type-map/headersFor'](this.jobSchema);
167
+ return this.$store.getters['type-map/headersFor'](this.jobSchema).filter((h) => !h.name || h.name !== NAMESPACE_COL.name);
168
168
  },
169
+
169
170
  ingressHeaders() {
170
- return this.$store.getters['type-map/headersFor'](this.ingressSchema);
171
+ return this.$store.getters['type-map/headersFor'](this.ingressSchema).filter((h) => !h.name || h.name !== NAMESPACE_COL.name);
171
172
  },
173
+
172
174
  serviceHeaders() {
173
- return this.$store.getters['type-map/headersFor'](this.serviceSchema);
175
+ return this.$store.getters['type-map/headersFor'](this.serviceSchema).filter((h) => !h.name || h.name !== NAMESPACE_COL.name);
174
176
  },
175
177
 
176
178
  totalRuns() {
@@ -278,39 +280,50 @@ export default {
278
280
  // Find Ingresses that forward traffic to Services
279
281
  // that select this workload.
280
282
  const matchingIngresses = this.allIngresses.filter((ingress) => {
281
- const rules = ingress.spec.rules;
283
+ try {
284
+ const rules = ingress.spec.rules;
285
+
286
+ if (!rules || !Array.isArray(rules)) return false;
282
287
 
283
- if (rules) {
284
288
  for (let i = 0; i < rules.length; i++) {
285
- const rule = rules[i];
289
+ const paths = rules[i]?.http?.paths;
286
290
 
287
- const paths = rule.http.paths;
291
+ if (!paths || !Array.isArray(paths)) continue;
292
+ // For each Ingress, check if any Services that match
293
+ // this workload are also target backends for the Ingress.
294
+ for (let j = 0; j < paths.length; j++) {
295
+ const pathData = paths[j];
296
+ const targetServiceName = pathData?.backend?.service?.name;
288
297
 
289
- if (paths) {
290
- // For each Ingress, check if any Services that match
291
- // this workload are also target backends for the Ingress.
292
- for (let j = 0; j < paths.length; j++) {
293
- const pathData = paths[j];
294
- const targetServiceName = pathData.backend.service.name;
298
+ if (!targetServiceName) continue;
295
299
 
296
- for (let k = 0; k < this.matchingServices.length; k++) {
297
- const service = this.matchingServices[k];
298
- const matchingServiceName = service.metadata?.name;
300
+ for (let k = 0; k < this.matchingServices.length; k++) {
301
+ const service = this.matchingServices[k];
302
+ const matchingServiceName = service?.metadata?.name;
299
303
 
300
- if (ingress.metadata?.namespace === this.value.metadata?.namespace && matchingServiceName === targetServiceName) {
301
- return true;
302
- }
304
+ if (ingress.metadata?.namespace === this.value.metadata?.namespace && matchingServiceName === targetServiceName) {
305
+ return true;
303
306
  }
304
307
  }
305
308
  }
306
309
  }
310
+ } catch (err) {
311
+ return false;
307
312
  }
308
-
309
- return false;
310
313
  });
311
314
 
312
315
  this.matchingIngresses = matchingIngresses;
313
316
  }
317
+ },
318
+
319
+ watch: {
320
+ async 'value.jobRelationships.length'(neu, old) {
321
+ // If there are MORE jobs ensure we go out and fetch them (changes and removals are tracked by watches)
322
+ if (neu > old) {
323
+ // We don't need to worry about spam, this won't be called often and it will be infrequent
324
+ await this.value.matchingJobs();
325
+ }
326
+ }
314
327
  }
315
328
  };
316
329
  </script>
@@ -376,6 +389,7 @@ export default {
376
389
  :headers="jobHeaders"
377
390
  key-field="id"
378
391
  :schema="jobSchema"
392
+ :namespaced="false"
379
393
  :groupable="false"
380
394
  :search="false"
381
395
  />
@@ -391,6 +405,7 @@ export default {
391
405
  :headers="podHeaders"
392
406
  key-field="id"
393
407
  :schema="podSchema"
408
+ :namespaced="false"
394
409
  :groupable="false"
395
410
  :search="false"
396
411
  />
@@ -457,6 +472,7 @@ export default {
457
472
  :headers="serviceHeaders"
458
473
  key-field="id"
459
474
  :schema="serviceSchema"
475
+ :namespaced="false"
460
476
  :groupable="false"
461
477
  :search="false"
462
478
  :table-actions="false"
@@ -498,6 +514,7 @@ export default {
498
514
  :headers="ingressHeaders"
499
515
  key-field="id"
500
516
  :schema="ingressSchema"
517
+ :namespaced="false"
501
518
  :groupable="false"
502
519
  :search="false"
503
520
  :table-actions="false"
@@ -6,6 +6,7 @@ import { CATALOG as CATALOG_ANNOTATIONS } from '@shell/config/labels-annotations
6
6
  import { UI_PLUGIN_NAMESPACE } from '@shell/config/uiplugins';
7
7
  import Banner from '@components/Banner/Banner.vue';
8
8
  import { SETTING } from '@shell/config/settings';
9
+ import { getPluginChartVersion, getPluginChartVersionLabel } from '@shell/utils/uiplugins';
9
10
 
10
11
  // Note: This dialog handles installation and update of a plugin
11
12
 
@@ -62,11 +63,13 @@ export default {
62
63
  },
63
64
 
64
65
  async fetch() {
66
+ const chartVersion = getPluginChartVersion(this.plugin);
67
+
65
68
  // Default to latest version on install (this is default on the plugin)
66
- this.version = this.plugin?.displayVersion;
69
+ this.version = chartVersion;
67
70
 
68
71
  if (this.mode === 'update') {
69
- this.currentVersion = this.plugin?.displayVersion;
72
+ this.currentVersion = chartVersion;
70
73
 
71
74
  // Update to latest version, so take the first version
72
75
  if (this.plugin?.installableVersions?.length > 0) {
@@ -74,9 +77,9 @@ export default {
74
77
  }
75
78
  } else if (this.mode === 'rollback') {
76
79
  // Find the newest version once we remove the current version
77
- const versionNames = this.plugin?.installableVersions.filter((v) => v.version !== this.plugin?.displayVersion);
80
+ const versionNames = this.plugin.installableVersions.filter((v) => v.version !== chartVersion);
78
81
 
79
- this.currentVersion = this.plugin?.displayVersion;
82
+ this.currentVersion = chartVersion;
80
83
 
81
84
  if (versionNames.length > 0) {
82
85
  this.version = versionNames[0].version;
@@ -131,7 +134,7 @@ export default {
131
134
 
132
135
  return versions.map((version) => {
133
136
  return {
134
- label: version.version,
137
+ label: getPluginChartVersionLabel(version),
135
138
  value: version.version,
136
139
  };
137
140
  });