@rancher/shell 0.3.4 → 0.3.6

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 (289) hide show
  1. package/assets/images/providers/outscale.svg +19 -0
  2. package/assets/styles/app.scss +1 -1
  3. package/assets/styles/base/_basic.scss +18 -0
  4. package/assets/styles/base/_mixins.scss +0 -11
  5. package/assets/styles/base/_variables.scss +2 -4
  6. package/assets/styles/fonts/_fontstack.scss +11 -11
  7. package/assets/styles/global/_button.scss +12 -2
  8. package/assets/styles/vendor/vue-js-modal.scss +3 -3
  9. package/assets/translations/en-us.yaml +113 -22
  10. package/assets/translations/zh-hans.yaml +113 -24
  11. package/babel.config.js +13 -0
  12. package/chart/gatekeeper.vue +78 -0
  13. package/chart/istio.vue +135 -112
  14. package/chart/logging/index.vue +13 -4
  15. package/chart/monitoring/index.vue +15 -5
  16. package/chart/monitoring/steps/uninstall-v1.vue +2 -2
  17. package/chart/rancher-backup/index.vue +10 -3
  18. package/cloud-credential/aws.vue +1 -1
  19. package/cloud-credential/digitalocean.vue +1 -1
  20. package/cloud-credential/gcp.vue +1 -1
  21. package/cloud-credential/generic.vue +2 -2
  22. package/cloud-credential/linode.vue +1 -1
  23. package/cloud-credential/pnap.vue +1 -1
  24. package/components/ActionMenu.vue +3 -4
  25. package/components/AssignTo.vue +1 -1
  26. package/components/AsyncButton.vue +1 -1
  27. package/components/BannerGraphic.vue +1 -1
  28. package/components/BrandImage.vue +1 -4
  29. package/components/ButtonDropdown.vue +2 -3
  30. package/components/Carousel.vue +85 -37
  31. package/components/ChartPsp.vue +76 -0
  32. package/components/CruResource.vue +6 -2
  33. package/components/DashboardMetrics.vue +12 -10
  34. package/components/DetailText.vue +1 -1
  35. package/components/DisableAuthProviderModal.vue +1 -1
  36. package/components/EmberPage.vue +1 -1
  37. package/components/EtcdInfoBanner.vue +12 -7
  38. package/components/ExplorerMembers.vue +101 -6
  39. package/components/ExplorerProjectsNamespaces.vue +46 -3
  40. package/components/FileDiff.vue +6 -7
  41. package/components/GrafanaDashboard.vue +27 -23
  42. package/components/LazyImage.vue +10 -12
  43. package/components/LogItem.vue +1 -1
  44. package/components/Markdown.vue +1 -1
  45. package/components/PromptRemove.vue +2 -2
  46. package/components/PromptRestore.vue +1 -1
  47. package/components/ResourceDetail/Masthead.vue +16 -0
  48. package/components/ResourceDetail/index.vue +21 -4
  49. package/components/ResourceList/index.vue +1 -1
  50. package/components/ResourceTable.vue +4 -1
  51. package/components/SingleClusterInfo.vue +2 -2
  52. package/components/SortableTable/THead.vue +1 -1
  53. package/components/SortableTable/index.vue +28 -13
  54. package/components/SortableTable/selection.js +58 -50
  55. package/components/Wizard.vue +4 -2
  56. package/components/__tests__/AsyncButton.test.ts +3 -1
  57. package/components/__tests__/ChartPsp.test.ts +75 -0
  58. package/components/__tests__/CruResource.test.ts +3 -1
  59. package/components/auth/Principal.vue +1 -1
  60. package/components/auth/RoleDetailEdit.vue +2 -2
  61. package/components/fleet/FleetBundles.vue +3 -1
  62. package/components/fleet/FleetClusters.vue +1 -2
  63. package/components/fleet/FleetIntro.vue +9 -1
  64. package/components/fleet/FleetNoWorkspaces.vue +62 -0
  65. package/components/fleet/FleetSummary.vue +7 -1
  66. package/components/form/HookOption.vue +14 -10
  67. package/components/form/LabeledSelect.vue +14 -11
  68. package/components/form/Labels.vue +32 -27
  69. package/components/form/MatchExpressions.vue +19 -4
  70. package/components/form/Members/ClusterPermissionsEditor.vue +32 -7
  71. package/components/form/NameNsDescription.vue +32 -46
  72. package/components/form/ProjectMemberEditor.vue +46 -21
  73. package/components/form/ResourceSelector.vue +1 -1
  74. package/components/form/SecretSelector.vue +5 -1
  75. package/components/form/ServiceNameSelect.vue +1 -1
  76. package/components/form/SimpleSecretSelector.vue +9 -9
  77. package/components/form/Tolerations.vue +4 -1
  78. package/components/form/ValueFromResource.vue +14 -9
  79. package/components/form/WorkloadPorts.vue +2 -2
  80. package/components/form/__tests__/LabeledSelect.test.ts +138 -0
  81. package/components/form/__tests__/NameNsDescription.ts +59 -0
  82. package/components/formatter/InternalExternalIP.vue +6 -0
  83. package/components/formatter/InvolvedObjectLink.vue +54 -0
  84. package/components/formatter/Link.vue +20 -4
  85. package/components/formatter/LinkName.vue +6 -1
  86. package/components/formatter/ServiceTargets.vue +1 -1
  87. package/components/formatter/WorkloadHealthScale.vue +8 -2
  88. package/components/nav/Group.vue +2 -2
  89. package/components/nav/NamespaceFilter.vue +23 -11
  90. package/components/nav/TopLevelMenu.vue +2 -4
  91. package/components/nav/Type.vue +1 -1
  92. package/components/nav/WorkspaceSwitcher.vue +46 -5
  93. package/components/nuxt/nuxt-build-indicator.vue +143 -0
  94. package/components/nuxt/nuxt-child.js +122 -0
  95. package/components/nuxt/nuxt-error.vue +98 -0
  96. package/components/nuxt/nuxt-link.client.js +98 -0
  97. package/components/nuxt/nuxt-link.server.js +16 -0
  98. package/components/nuxt/nuxt-loading.vue +154 -0
  99. package/components/nuxt/nuxt.js +101 -0
  100. package/config/labels-annotations.js +17 -0
  101. package/config/middleware.js +12 -0
  102. package/config/product/auth.js +3 -2
  103. package/config/product/explorer.js +34 -6
  104. package/config/product/fleet.js +2 -0
  105. package/config/query-params.js +1 -0
  106. package/config/router.js +414 -0
  107. package/config/store.js +181 -0
  108. package/config/table-headers.js +54 -12
  109. package/config/types.js +18 -8
  110. package/config/uiplugins.js +30 -0
  111. package/content/docs/en-us/whats-new.md +10 -0
  112. package/content/docs/zh-hans/whats-new.md +11 -1
  113. package/core/plugin-routes.ts +23 -0
  114. package/core/plugin.ts +4 -2
  115. package/core/types.ts +258 -1
  116. package/creators/app/app.package.json +2 -1
  117. package/creators/app/files/.eslintrc.js +1 -1
  118. package/creators/app/files/babel.config.js +1 -18
  119. package/creators/app/files/tsconfig.json +0 -1
  120. package/creators/app/files/vue.config.js +6 -0
  121. package/creators/app/init +5 -5
  122. package/creators/pkg/files/.github/workflows/build-extension.yml +110 -0
  123. package/creators/pkg/files/tsconfig.json +0 -1
  124. package/creators/pkg/init +35 -4
  125. package/creators/pkg/pkg.package.json +3 -3
  126. package/creators/update/init +1 -1
  127. package/detail/constraints.gatekeeper.sh.constraint.vue +34 -17
  128. package/detail/fleet.cattle.io.clustergroup.vue +7 -1
  129. package/detail/fleet.cattle.io.gitrepo.vue +19 -11
  130. package/detail/harvesterhci.io.management.cluster.vue +3 -3
  131. package/detail/provisioning.cattle.io.cluster.vue +54 -12
  132. package/detail/workload/index.vue +3 -3
  133. package/dialog/AddClusterMemberDialog.vue +1 -1
  134. package/dialog/AddProjectMemberDialog.vue +2 -2
  135. package/dialog/AddonConfigConfirmationDialog.vue +27 -15
  136. package/dialog/DiagnosticTimingsDialog.vue +1 -1
  137. package/dialog/ForceMachineRemoveDialog.vue +1 -1
  138. package/dialog/GenericPrompt.vue +18 -6
  139. package/dialog/RotateEncryptionKeyDialog.vue +1 -1
  140. package/dialog/SaveAsRKETemplateDialog.vue +1 -1
  141. package/dialog/ScaleMachineDownDialog.vue +1 -1
  142. package/edit/auth/github.vue +8 -8
  143. package/edit/auth/googleoauth.vue +5 -5
  144. package/edit/auth/ldap/index.vue +1 -1
  145. package/edit/auth/oidc.vue +1 -1
  146. package/edit/auth/saml.vue +1 -1
  147. package/edit/cis.cattle.io.clusterscan.vue +1 -1
  148. package/edit/fleet.cattle.io.clustergroup.vue +6 -4
  149. package/edit/fleet.cattle.io.gitrepo.vue +32 -4
  150. package/edit/helm.cattle.io.projecthelmchart.vue +5 -1
  151. package/edit/logging.banzaicloud.io.output/index.vue +18 -5
  152. package/edit/logging.banzaicloud.io.output/providers/loki.vue +1 -0
  153. package/edit/management.cattle.io.fleetworkspace.vue +141 -6
  154. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +4 -1
  155. package/edit/management.cattle.io.setting.vue +1 -1
  156. package/edit/monitoring.coreos.com.alertmanagerconfig/types/webhook.vue +2 -2
  157. package/edit/monitoring.coreos.com.receiver/tls.vue +18 -18
  158. package/edit/monitoring.coreos.com.receiver/types/webhook.banner.vue +4 -4
  159. package/edit/monitoring.coreos.com.receiver/types/webhook.vue +1 -1
  160. package/edit/namespace.vue +14 -10
  161. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +126 -45
  162. package/edit/networking.k8s.io.networkpolicy/index.vue +1 -1
  163. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +21 -4
  164. package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +1 -0
  165. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +202 -2
  166. package/edit/provisioning.cattle.io.cluster/import.vue +23 -25
  167. package/edit/provisioning.cattle.io.cluster/rke2.vue +344 -102
  168. package/edit/resources.cattle.io.backup.vue +1 -1
  169. package/edit/service.vue +1 -1
  170. package/edit/storage.k8s.io.storageclass/provisioners/driver.harvesterhci.io.vue +2 -2
  171. package/edit/workload/__tests__/Job.test.ts +3 -1
  172. package/edit/workload/index.vue +8 -3
  173. package/edit/workload/mixins/workload.js +22 -7
  174. package/edit/workload/storage/Mount.vue +3 -3
  175. package/initialize/App.js +206 -0
  176. package/initialize/client.js +863 -0
  177. package/initialize/index.js +364 -0
  178. package/layouts/default.vue +7 -3
  179. package/layouts/standalone.vue +13 -0
  180. package/list/catalog.cattle.io.clusterrepo.vue +1 -0
  181. package/list/fleet.cattle.io.bundle.vue +6 -3
  182. package/list/fleet.cattle.io.clusterregistrationtoken.vue +3 -1
  183. package/list/fleet.cattle.io.gitrepo.vue +44 -5
  184. package/list/management.cattle.io.fleetworkspace.vue +45 -0
  185. package/list/node.vue +69 -16
  186. package/list/provisioning.cattle.io.cluster.vue +30 -1
  187. package/list/rbac.authorization.k8s.io.clusterrolebinding.vue +48 -0
  188. package/list/workload.vue +6 -4
  189. package/machine-config/azure.vue +97 -38
  190. package/middleware/authenticated.js +34 -0
  191. package/mixins/chart.js +101 -2
  192. package/mixins/fetch.client.js +95 -0
  193. package/mixins/fetch.server.js +73 -0
  194. package/mixins/labeled-form-element.ts +2 -2
  195. package/mixins/resource-fetch.js +2 -2
  196. package/models/apps.statefulset.js +28 -0
  197. package/models/cluster/node.js +23 -2
  198. package/models/cluster.x-k8s.io.machine.js +4 -2
  199. package/models/clusterroletemplatebinding.js +7 -0
  200. package/models/constraints.gatekeeper.sh.constraint.js +46 -0
  201. package/models/fleet.cattle.io.cluster.js +19 -10
  202. package/models/fleet.cattle.io.gitrepo.js +7 -2
  203. package/models/management.cattle.io.cluster.js +1 -1
  204. package/models/management.cattle.io.fleetworkspace.js +12 -0
  205. package/models/management.cattle.io.gitreporestriction.js +5 -0
  206. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.js +3 -0
  207. package/models/pod.js +4 -0
  208. package/models/provisioning.cattle.io.cluster.js +7 -5
  209. package/models/rbac.authorization.k8s.io.clusterrolebinding.js +16 -0
  210. package/models/rbac.authorization.k8s.io.rolebinding.js +16 -0
  211. package/package.json +13 -21
  212. package/pages/auth/setup.vue +2 -2
  213. package/pages/c/_cluster/apps/charts/__tests__/install.helper.test.ts +33 -0
  214. package/pages/c/_cluster/apps/charts/chart.vue +4 -4
  215. package/pages/c/_cluster/apps/charts/install.helpers.js +26 -0
  216. package/pages/c/_cluster/apps/charts/install.vue +98 -102
  217. package/pages/c/_cluster/explorer/EventsTable.vue +5 -19
  218. package/pages/c/_cluster/explorer/index.vue +29 -25
  219. package/pages/c/_cluster/explorer/tools/index.vue +8 -8
  220. package/pages/c/_cluster/fleet/index.vue +95 -34
  221. package/pages/c/_cluster/gatekeeper/index.vue +1 -1
  222. package/pages/c/_cluster/istio/index.vue +5 -5
  223. package/pages/c/_cluster/manager/cloudCredential/index.vue +1 -1
  224. package/pages/c/_cluster/monitoring/index.vue +7 -0
  225. package/pages/c/_cluster/uiplugins/InstallDialog.vue +8 -8
  226. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +20 -7
  227. package/pages/c/_cluster/uiplugins/index.vue +49 -17
  228. package/pages/diagnostic.vue +32 -25
  229. package/pages/home.vue +9 -4
  230. package/pages/index.vue +10 -1
  231. package/pages/rio/mesh.vue +1 -2
  232. package/pkg/tsconfig.json +0 -1
  233. package/plugins/clean-html-directive.js +34 -0
  234. package/plugins/dashboard-store/actions.js +32 -9
  235. package/plugins/dashboard-store/index.js +1 -1
  236. package/plugins/dashboard-store/mutations.js +5 -2
  237. package/plugins/dashboard-store/resource-class.js +8 -1
  238. package/plugins/plugin.js +0 -14
  239. package/plugins/portal-vue.js +4 -0
  240. package/plugins/steve/mutations.js +3 -2
  241. package/plugins/steve/steve-description-class.js +5 -1
  242. package/plugins/steve/subscribe.js +63 -54
  243. package/plugins/steve-create-worker.js +14 -0
  244. package/promptRemove/management.cattle.io.globalrole.vue +2 -2
  245. package/promptRemove/management.cattle.io.project.vue +2 -2
  246. package/promptRemove/management.cattle.io.roletemplate.vue +2 -2
  247. package/promptRemove/pod.vue +1 -1
  248. package/public/index.html +65 -0
  249. package/rancher-components/components/Banner/Banner.test.ts +7 -1
  250. package/rancher-components/components/Banner/Banner.vue +2 -1
  251. package/rancher-components/components/Form/Checkbox/Checkbox.vue +2 -0
  252. package/rancher-components/components/Form/Radio/RadioButton.test.ts +31 -0
  253. package/rancher-components/components/Form/Radio/RadioButton.vue +14 -3
  254. package/scripts/build-pkg.sh +1 -0
  255. package/scripts/clean +6 -0
  256. package/scripts/extension/bundle +58 -0
  257. package/scripts/extension/helmpatch +89 -0
  258. package/scripts/extension/publish +333 -0
  259. package/scripts/serve-pkgs +6 -2
  260. package/scripts/test-plugins-build.sh +4 -0
  261. package/store/__tests__/index.test.ts +110 -0
  262. package/store/index.js +145 -58
  263. package/store/type-map.js +6 -2
  264. package/tsconfig.default.json +36 -0
  265. package/tsconfig.json +23 -0
  266. package/types/rancher/index.d.ts +2 -0
  267. package/types/shell/index.d.ts +466 -320
  268. package/utils/__tests__/grafana.test.ts +44 -0
  269. package/utils/__tests__/string.test.ts +12 -0
  270. package/utils/auth.js +65 -0
  271. package/utils/axios.js +190 -0
  272. package/utils/cookie-universal-nuxt.js +10 -0
  273. package/utils/dom.js +15 -0
  274. package/utils/grafana.js +35 -16
  275. package/utils/monitoring.js +2 -1
  276. package/utils/nuxt.js +659 -0
  277. package/utils/position.js +5 -8
  278. package/utils/router.scrollBehavior.js +80 -0
  279. package/utils/select.js +1 -3
  280. package/utils/socket.js +1 -0
  281. package/utils/string.js +13 -0
  282. package/utils/time.js +9 -0
  283. package/vue.config.js +690 -0
  284. package/chart/rancher-alerting-drivers.vue +0 -53
  285. package/chart/rancher-gatekeeper.vue +0 -37
  286. package/creators/app/files/nuxt.config.js +0 -6
  287. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.ts +0 -4
  288. package/nuxt.config.js +0 -798
  289. package/plugins/dashboard-store/extensions.js +0 -22
@@ -4,7 +4,7 @@ import ResourceTable from '@shell/components/ResourceTable';
4
4
  import { STATE, AGE, NAME } from '@shell/config/table-headers';
5
5
  import { uniq } from '@shell/utils/array';
6
6
  import { MANAGEMENT, NAMESPACE, VIRTUAL_TYPES } from '@shell/config/types';
7
- import { PROJECT_ID } from '@shell/config/query-params';
7
+ import { PROJECT_ID, FLAT_VIEW } from '@shell/config/query-params';
8
8
  import Masthead from '@shell/components/ResourceList/Masthead';
9
9
  import { mapPref, GROUP_RESOURCES, ALL_NAMESPACES } from '@shell/store/prefs';
10
10
  import MoveModal from '@shell/components/MoveModal';
@@ -112,6 +112,10 @@ export default {
112
112
  // is updated if a new project is created or removed.
113
113
  const projectsInAllClusters = this.$store.getters['management/all'](MANAGEMENT.PROJECT);
114
114
 
115
+ if (this.currentProduct?.customNamespaceFilter && this.currentProduct?.inStore && this.$store.getters[`${ this.currentProduct.inStore }/filterProject`]) {
116
+ return this.$store.getters[`${ this.currentProduct.inStore }/filterProject`];
117
+ }
118
+
115
119
  const clustersInProjects = projectsInAllClusters.filter(project => project.spec.clusterName === clusterId);
116
120
 
117
121
  return clustersInProjects;
@@ -232,6 +236,9 @@ export default {
232
236
 
233
237
  notInProjectKey() {
234
238
  return this.$store.getters['i18n/t']('resourceTable.groupLabel.notInAProject');
239
+ },
240
+ showCreateNsButton() {
241
+ return this.groupPreference !== 'namespace';
235
242
  }
236
243
  },
237
244
  methods: {
@@ -280,6 +287,21 @@ export default {
280
287
 
281
288
  return location;
282
289
  },
290
+
291
+ createNamespaceLocationFlatList() {
292
+ const location = this.createNamespaceLocationOverride ? { ...this.createNamespaceLocationOverride } : {
293
+ name: 'c-cluster-product-resource-create',
294
+ params: {
295
+ product: this.$store.getters['currentProduct']?.name,
296
+ resource: NAMESPACE
297
+ },
298
+ };
299
+
300
+ location.query = { [FLAT_VIEW]: true };
301
+
302
+ return location;
303
+ },
304
+
283
305
  showProjectAction(event, group) {
284
306
  const project = group.rows[0].project;
285
307
 
@@ -339,7 +361,19 @@ export default {
339
361
  :show-incremental-loading-indicator="showIncrementalLoadingIndicator"
340
362
  :load-resources="loadResources"
341
363
  :load-indeterminate="loadIndeterminate"
342
- />
364
+ >
365
+ <template
366
+ v-if="showCreateNsButton"
367
+ slot="extraActions"
368
+ >
369
+ <n-link
370
+ :to="createNamespaceLocationFlatList()"
371
+ class="btn role-primary mr-10"
372
+ >
373
+ {{ t('projectNamespaces.createNamespace') }}
374
+ </n-link>
375
+ </template>
376
+ </Masthead>
343
377
  <ResourceTable
344
378
  ref="table"
345
379
  class="table"
@@ -364,8 +398,8 @@ export default {
364
398
  class="group-tab"
365
399
  >
366
400
  <div
401
+ v-clean-html="projectLabel(group.group)"
367
402
  class="project-name"
368
- v-html="projectLabel(group.group)"
369
403
  />
370
404
  <div
371
405
  v-if="projectDescription(group.group)"
@@ -411,6 +445,11 @@ export default {
411
445
  <span v-else>
412
446
  {{ row.name }}
413
447
  </span>
448
+ <i
449
+ v-if="row.injectionEnabled"
450
+ v-tooltip="t('projectNamespaces.isIstioInjectionEnabled')"
451
+ class="icon icon-istio ml-5"
452
+ />
414
453
  <i
415
454
  v-if="row.hasSystemLabels"
416
455
  v-tooltip="getPsaTooltip(row)"
@@ -483,6 +522,10 @@ export default {
483
522
  .namespace-name {
484
523
  display: flex;
485
524
  align-items: center;
525
+
526
+ .icon-istio {
527
+ color: var(--primary);
528
+ }
486
529
  }
487
530
  }
488
531
  }
@@ -1,7 +1,6 @@
1
1
  <script>
2
2
  import { Diff2Html } from 'diff2html';
3
3
  import { createPatch } from 'diff';
4
- import $ from 'jquery';
5
4
 
6
5
  export default {
7
6
  props: {
@@ -74,21 +73,21 @@ export default {
74
73
  return;
75
74
  }
76
75
 
77
- const container = $(this.$refs.root);
76
+ const container = this.$refs.root;
78
77
 
79
- if ( !container || !container.length ) {
78
+ if ( !container ) {
80
79
  return;
81
80
  }
82
81
 
83
- const offset = container.offset();
82
+ const offset = container.getBoundingClientRect();
84
83
 
85
84
  if ( !offset ) {
86
85
  return;
87
86
  }
88
87
 
89
- const desired = $(window).innerHeight() - offset.top - this.footerSpace;
88
+ const desired = window.innerHeight - offset.top - this.footerSpace;
90
89
 
91
- container.css('height', `${ Math.max(0, desired) }px`);
90
+ container.style.height = `${ Math.max(0, desired) }px`;
92
91
  },
93
92
  },
94
93
  };
@@ -99,8 +98,8 @@ export default {
99
98
  <resize-observer @notify="fit" />
100
99
  <div
101
100
  ref="root"
101
+ v-clean-html="html"
102
102
  class="root"
103
- v-html="html"
104
103
  />
105
104
  </div>
106
105
  </template>
@@ -2,6 +2,7 @@
2
2
  import Loading from '@shell/components/Loading';
3
3
  import { Banner } from '@components/Banner';
4
4
  import { computeDashboardUrl } from '@shell/utils/grafana';
5
+ import { CATALOG } from '@shell/config/types';
5
6
 
6
7
  export default {
7
8
  components: { Banner, Loading },
@@ -31,9 +32,15 @@ export default {
31
32
  default: 'dark'
32
33
  }
33
34
  },
35
+ async fetch() {
36
+ const inStore = this.$store.getters['currentProduct'].inStore;
37
+ const res = await this.$store.dispatch(`${ inStore }/find`, { type: CATALOG.APP, id: 'cattle-monitoring-system/rancher-monitoring' });
38
+
39
+ this.monitoringVersion = res?.currentVersion;
40
+ },
34
41
  data() {
35
42
  return {
36
- loading: false, error: false, interval: null, initialUrl: this.computeUrl(), errorTimer: null
43
+ loading: false, error: false, interval: null, initialUrl: this.computeUrl(), errorTimer: null, monitoringVersion: null
37
44
  };
38
45
  },
39
46
  computed: {
@@ -54,14 +61,11 @@ export default {
54
61
  }
55
62
  },
56
63
  watch: {
57
- currentUrl() {
64
+ currentUrl(neu) {
65
+ // Should consider changing `this.graphWindow?.angular` to something like `!loaded && !error`
66
+ // https://github.com/rancher/dashboard/pull/5802
58
67
  if (this.graphHistory && this.graphWindow?.angular) {
59
- const angularElement = this.graphWindow.angular.element(this.graphDocument.querySelector('.grafana-app'));
60
- const injector = angularElement.injector();
61
-
62
- this.graphHistory.pushState({}, '', this.currentUrl);
63
- injector.get('$route').updateParams(this.computeParams());
64
- injector.get('$route').reload();
68
+ this.graphWindow.location.replace(neu);
65
69
  }
66
70
  },
67
71
 
@@ -134,7 +138,7 @@ export default {
134
138
  const clusterId = this.$store.getters['currentCluster'].id;
135
139
  const params = this.computeParams();
136
140
 
137
- return computeDashboardUrl(embedUrl, clusterId, params);
141
+ return computeDashboardUrl(this.monitoringVersion, embedUrl, clusterId, params);
138
142
  },
139
143
  computeParams() {
140
144
  const params = {};
@@ -222,15 +226,15 @@ export default {
222
226
 
223
227
  <template>
224
228
  <div class="grafana-graph">
225
- <Banner
226
- v-if="error"
227
- color="error"
228
- style="z-index: 1000"
229
+ <Banner
230
+ v-if="error"
231
+ color="error"
232
+ style="z-index: 1000"
229
233
  >
230
234
  <div class="text-center">
231
- {{ t('grafanaDashboard.failedToLoad') }} <a
232
- href="#"
233
- @click="reload"
235
+ {{ t('grafanaDashboard.failedToLoad') }} <a
236
+ href="#"
237
+ @click="reload"
234
238
  >{{ t('grafanaDashboard.reload') }}</a>
235
239
  </div>
236
240
  </Banner>
@@ -245,14 +249,14 @@ export default {
245
249
  <div v-if="loading">
246
250
  <Loading />
247
251
  </div>
248
- <div
249
- v-if="!loading && !error"
250
- class="external-link"
252
+ <div
253
+ v-if="!loading && !error"
254
+ class="external-link"
251
255
  >
252
- <a
253
- :href="grafanaUrl"
254
- target="_blank"
255
- rel="noopener noreferrer nofollow"
256
+ <a
257
+ :href="grafanaUrl"
258
+ target="_blank"
259
+ rel="noopener noreferrer nofollow"
256
260
  >{{ t('grafanaDashboard.grafana') }} <i class="icon icon-external-link" /></a>
257
261
  </div>
258
262
  </div>
@@ -1,6 +1,4 @@
1
1
  <script>
2
- import $ from 'jquery';
3
-
4
2
  export default {
5
3
  props: {
6
4
  initialSrc: {
@@ -32,31 +30,31 @@ export default {
32
30
  },
33
31
 
34
32
  beforeDestroy() {
35
- const $img = $(this.$refs.img);
33
+ const img = this.$refs.img;
36
34
 
37
- if ( $img?.length ) {
38
- $img.off('error', this.boundError);
35
+ if (img) {
36
+ img.removeEventListener('error', this.boundError);
39
37
  }
40
38
  },
41
39
 
42
40
  methods: {
43
41
  // Ensure we load the image when the source changes
44
42
  loadImage() {
45
- const $img = $(this.$refs.img);
43
+ const img = this.$refs.img;
46
44
 
47
- if ( this.src ) {
48
- $img.attr('src', this.src);
45
+ if (this.src) {
46
+ img.setAttribute('src', this.src);
49
47
  this.boundError = this.onError.bind(this);
50
48
 
51
- $img.on('error', this.boundError);
49
+ img.addEventListener('error', this.boundError);
52
50
  }
53
51
  },
54
52
 
55
53
  onError() {
56
- const $img = $(this.$refs.img);
54
+ const img = this.$refs.img;
57
55
 
58
- if ( $img?.length ) {
59
- $img.attr('src', this.errorSrc);
56
+ if (img) {
57
+ img.setAttribute('src', this.errorSrc);
60
58
  }
61
59
  }
62
60
  }
@@ -36,8 +36,8 @@ export default {
36
36
  <div class="line">
37
37
  <span class="time">{{ format(source.time) }}</span>
38
38
  <span
39
+ v-clean-html="source.msg"
39
40
  class="msg"
40
- v-html="source.msg"
41
41
  />
42
42
  </div>
43
43
  </template>
@@ -77,8 +77,8 @@ export default {
77
77
  <template>
78
78
  <div
79
79
  v-if="loaded"
80
+ v-clean-html="sanitized"
80
81
  class="markdown"
81
- v-html="sanitized"
82
82
  />
83
83
  <Loading v-else />
84
84
  </template>
@@ -343,7 +343,7 @@ export default {
343
343
  <div class="mb-10">
344
344
  <template v-if="!hasCustomRemove">
345
345
  {{ t('promptRemove.attemptingToRemove', { type }) }} <span
346
- v-html="resourceNames(names, plusMore, t)"
346
+ v-clean-html="resourceNames(names, plusMore, t)"
347
347
  />
348
348
  </template>
349
349
 
@@ -367,7 +367,7 @@ export default {
367
367
  class="mt-10"
368
368
  >
369
369
  <span
370
- v-html="t('promptRemove.confirmName', { nameToMatch: escapeHtml(nameToMatch) }, true)"
370
+ v-clean-html="t('promptRemove.confirmName', { nameToMatch: escapeHtml(nameToMatch) }, true)"
371
371
  />
372
372
  </div>
373
373
  </template>
@@ -218,8 +218,8 @@ export default {
218
218
  >
219
219
  <h4
220
220
  slot="title"
221
+ v-clean-html="t('promptRestore.title', null, true)"
221
222
  class="text-default-text"
222
- v-html="t('promptRestore.title', null, true)"
223
223
  />
224
224
 
225
225
  <div
@@ -429,6 +429,15 @@ export default {
429
429
  class="masthead-state"
430
430
  :value="value"
431
431
  />
432
+ <span
433
+ v-if="!isCreate && value.injectionEnabled"
434
+ class="masthead-istio"
435
+ >
436
+ <i
437
+ v-tooltip="t('projectNamespaces.isIstioInjectionEnabled')"
438
+ class="icon icon-sm icon-istio"
439
+ />
440
+ </span>
432
441
  </h1>
433
442
  </div>
434
443
  <div
@@ -568,6 +577,13 @@ export default {
568
577
  top: -2px;
569
578
  }
570
579
 
580
+ .masthead-istio {
581
+ .icon {
582
+ vertical-align: middle;
583
+ color: var(--primary);
584
+ }
585
+ }
586
+
571
587
  .left-right-split {
572
588
  display: grid;
573
589
  align-items: center;
@@ -13,6 +13,7 @@ import DetailTop from '@shell/components/DetailTop';
13
13
  import { clone, diff } from '@shell/utils/object';
14
14
  import IconMessage from '@shell/components/IconMessage';
15
15
  import ForceDirectedTreeChart from '@shell/components/fleet/ForceDirectedTreeChart';
16
+ import { checkSchemasForFindAllHash } from '@shell/utils/auth';
16
17
 
17
18
  function modeFor(route) {
18
19
  if ( route.query?.mode === _IMPORT ) {
@@ -159,9 +160,24 @@ export default {
159
160
  }
160
161
  } else {
161
162
  if ( as === _GRAPH ) {
162
- await store.dispatch('management/findAll', { type: FLEET.CLUSTER });
163
- await store.dispatch('management/findAll', { type: FLEET.BUNDLE });
164
- await store.dispatch('management/findAll', { type: FLEET.BUNDLE_DEPLOYMENT });
163
+ const graphSchema = await checkSchemasForFindAllHash({
164
+ cluster: {
165
+ inStoreType: 'management',
166
+ type: FLEET.CLUSTER
167
+ },
168
+ bundle: {
169
+ inStoreType: 'management',
170
+ type: FLEET.BUNDLE
171
+ },
172
+
173
+ bundleDeployment: {
174
+ inStoreType: 'management',
175
+ type: FLEET.BUNDLE_DEPLOYMENT
176
+ }
177
+
178
+ }, this.$store);
179
+
180
+ this.canViewChart = graphSchema.cluster && graphSchema.bundle && graphSchema.bundleDeployment;
165
181
  }
166
182
 
167
183
  let fqid = id;
@@ -249,6 +265,7 @@ export default {
249
265
  value: null,
250
266
  model: null,
251
267
  notFound: null,
268
+ canViewChart: true,
252
269
  };
253
270
  },
254
271
 
@@ -385,7 +402,7 @@ export default {
385
402
  </Masthead>
386
403
 
387
404
  <ForceDirectedTreeChart
388
- v-if="isGraph"
405
+ v-if="isGraph && canViewChart"
389
406
  :data="chartData"
390
407
  :fdc-config="getGraphConfig"
391
408
  />
@@ -177,8 +177,8 @@ export default {
177
177
  >
178
178
  <template #message>
179
179
  <span
180
+ v-clean-html="t('resourceList.nsFiltering', { resource: $store.getters['type-map/labelFor'](schema, 2) || customTypeDisplay }, true)"
180
181
  class="filter"
181
- v-html="t('resourceList.nsFiltering', { resource: $store.getters['type-map/labelFor'](schema, 2) || customTypeDisplay }, true)"
182
182
  />
183
183
  </template>
184
184
  </IconMessage>
@@ -30,6 +30,9 @@ export const defaultTableSortGenerationFn = (schema, $store) => {
30
30
  if ( nsFilterKey ) {
31
31
  return `${ sortKey }/${ nsFilterKey }`;
32
32
  }
33
+
34
+ // covers case where we have no current cluster's ns cache
35
+ return sortKey;
33
36
  };
34
37
 
35
38
  export default {
@@ -462,8 +465,8 @@ export default {
462
465
 
463
466
  <template #group-by="{group: thisGroup}">
464
467
  <div
468
+ v-clean-html="thisGroup.ref"
465
469
  class="group-tab"
466
- v-html="thisGroup.ref"
467
470
  />
468
471
  </template>
469
472
 
@@ -118,11 +118,11 @@ export default {
118
118
  class="glance-item"
119
119
  >
120
120
  <label>{{ t('glance.version') }}: </label>
121
+ <span>{{ clusterDetail.kubernetesVersionBase }}</span>
121
122
  <span
122
123
  v-if="clusterDetail.kubernetesVersionExtension"
123
- style="font-size: 0.5em"
124
+ style="font-size: 0.75em"
124
125
  >{{ clusterDetail.kubernetesVersionExtension }}</span>
125
- <span>{{ clusterDetail.kubernetesVersionBase }}</span>
126
126
  </div>
127
127
  <div class="glance-item">
128
128
  <label>{{ t('glance.created') }}: </label>
@@ -242,7 +242,7 @@ export default {
242
242
  v-if="col.sort"
243
243
  v-tooltip="tooltip(col)"
244
244
  >
245
- <span v-html="labelFor(col)" />
245
+ <span v-clean-html="labelFor(col)" />
246
246
  <i
247
247
  v-show="hasAdvancedFiltering && !col.isFilter"
248
248
  v-tooltip="t('sortableTable.tableHeader.noFilter')"
@@ -7,7 +7,6 @@ import { removeObject } from '@shell/utils/array';
7
7
  import { Checkbox } from '@components/Form/Checkbox';
8
8
  import AsyncButton, { ASYNC_BUTTON_STATES } from '@shell/components/AsyncButton';
9
9
  import ActionDropdown from '@shell/components/ActionDropdown';
10
- import $ from 'jquery';
11
10
  import throttle from 'lodash/throttle';
12
11
  import debounce from 'lodash/debounce';
13
12
  import THead from './THead';
@@ -19,6 +18,8 @@ import grouping from './grouping';
19
18
  import actions from './actions';
20
19
  import AdvancedFiltering from './advanced-filtering';
21
20
  import LabeledSelect from '@shell/components/form/LabeledSelect';
21
+ import { getParent } from '@shell/utils/dom';
22
+
22
23
  // Uncomment for table performance debugging
23
24
  // import tableDebug from './debug';
24
25
 
@@ -340,10 +341,10 @@ export default {
340
341
  }, 200);
341
342
 
342
343
  // Add scroll listener to the main element
343
- const $main = $('main');
344
+ const $main = document.querySelector('main');
344
345
 
345
346
  this._onScroll = this.onScroll.bind(this);
346
- $main.on('scroll', this._onScroll);
347
+ $main?.addEventListener('scroll', this._onScroll);
347
348
  },
348
349
 
349
350
  beforeDestroy() {
@@ -354,9 +355,9 @@ export default {
354
355
  clearTimeout(this._delayedColumnsTimer);
355
356
  clearTimeout(this.manualRefreshTimer);
356
357
 
357
- const $main = $('main');
358
+ const $main = document.querySelector('main');
358
359
 
359
- $main.off('scroll', this._onScroll);
360
+ $main?.removeEventListener('scroll', this._onScroll);
360
361
  },
361
362
 
362
363
  watch: {
@@ -817,13 +818,12 @@ export default {
817
818
  },
818
819
 
819
820
  nearestCheckbox() {
820
- const $cur = $(document.activeElement).closest('tr.main-row').find('.checkbox-custom');
821
-
822
- return $cur[0];
821
+ return document.activeElement.closest('tr.main-row')?.querySelector('.checkbox-custom');
823
822
  },
824
823
 
825
824
  focusAdjacent(next = true) {
826
- const all = $('.checkbox-custom', this.$el).toArray();
825
+ const all = Array.from(this.$el.querySelectorAll('.checkbox-custom'));
826
+
827
827
  const cur = this.nearestCheckbox();
828
828
  let idx = -1;
829
829
 
@@ -837,10 +837,14 @@ export default {
837
837
 
838
838
  if ( idx < 1 ) { // Don't go up to the check all button
839
839
  idx = 1;
840
+
841
+ return null;
840
842
  }
841
843
 
842
844
  if ( idx >= all.length ) {
843
845
  idx = all.length - 1;
846
+
847
+ return null;
844
848
  }
845
849
 
846
850
  if ( all[idx] ) {
@@ -852,14 +856,22 @@ export default {
852
856
 
853
857
  focusNext: throttle(function(event, more = false) {
854
858
  const elem = this.focusAdjacent(true);
855
- const row = $(elem).parents('tr');
859
+ const row = getParent(elem, 'tr');
860
+
861
+ if (row?.classList.contains('row-selected')) {
862
+ return;
863
+ }
856
864
 
857
865
  this.keySelectRow(row, more);
858
866
  }, 50),
859
867
 
860
868
  focusPrevious: throttle(function(event, more = false) {
861
869
  const elem = this.focusAdjacent(false);
862
- const row = $(elem).parents('tr');
870
+ const row = getParent(elem, 'tr');
871
+
872
+ if (row?.classList.contains('row-selected')) {
873
+ return;
874
+ }
863
875
 
864
876
  this.keySelectRow(row, more);
865
877
  }, 50),
@@ -926,7 +938,7 @@ export default {
926
938
  v-if="act.icon"
927
939
  :class="act.icon"
928
940
  />
929
- <span v-html="act.label" />
941
+ <span v-clean-html="act.label" />
930
942
  </button>
931
943
  <ActionDropdown
932
944
  :class="bulkActionsDropdownClass"
@@ -964,7 +976,7 @@ export default {
964
976
  v-if="act.icon"
965
977
  :class="act.icon"
966
978
  />
967
- <span v-html="act.label" />
979
+ <span v-clean-html="act.label" />
968
980
  </li>
969
981
  </ul>
970
982
  </template>
@@ -1325,6 +1337,9 @@ export default {
1325
1337
  :full-colspan="fullColspan"
1326
1338
  :row="row.row"
1327
1339
  :sub-matches="subMatches"
1340
+ :keyField="keyField"
1341
+ :componentTestid="componentTestid"
1342
+ :i="i"
1328
1343
  :onRowMouseEnter="onRowMouseEnter"
1329
1344
  :onRowMouseLeave="onRowMouseLeave"
1330
1345
  >