@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
@@ -1,7 +1,7 @@
1
1
  <script>
2
2
 
3
3
  import SortableTable from '@shell/components/SortableTable';
4
- import { REASON } from '@shell/config/table-headers';
4
+ import { MESSAGE, NAME, OBJECT, REASON } from '@shell/config/table-headers';
5
5
  import { EVENT } from '@shell/config/types';
6
6
  import { fetchClusterResources } from './explorer-utils';
7
7
 
@@ -21,14 +21,9 @@ export default {
21
21
 
22
22
  const eventHeaders = [
23
23
  reason,
24
- {
25
- name: 'resource',
26
- label: 'Resource',
27
- labelKey: 'clusterIndexPage.sections.events.resource.label',
28
- value: 'displayInvolvedObject',
29
- sort: ['involvedObject.kind', 'involvedObject.name'],
30
- canBeVariable: true,
31
- },
24
+ OBJECT,
25
+ MESSAGE,
26
+ NAME,
32
27
  {
33
28
  name: 'date',
34
29
  label: 'Date',
@@ -61,14 +56,5 @@ export default {
61
56
  :paging="true"
62
57
  :rows-per-page="10"
63
58
  default-sort-by="date"
64
- >
65
- <template #cell:resource="{row, value}">
66
- <n-link :to="row.detailLocation">
67
- {{ value }}
68
- </n-link>
69
- <div v-if="row.message">
70
- {{ row.displayMessage }}
71
- </div>
72
- </template>
73
- </SortableTable>
59
+ />
74
60
  </template>
@@ -82,27 +82,29 @@ export default {
82
82
  fetch() {
83
83
  fetchClusterResources(this.$store, NODE);
84
84
 
85
- setPromiseResult(
86
- allDashboardsExist(this.$store, this.currentCluster.id, [CLUSTER_METRICS_DETAIL_URL, CLUSTER_METRICS_SUMMARY_URL]),
87
- this,
88
- 'showClusterMetrics',
89
- `Determine cluster metrics`
90
- );
91
- setPromiseResult(
92
- allDashboardsExist(this.$store, this.currentCluster.id, [K8S_METRICS_DETAIL_URL, K8S_METRICS_SUMMARY_URL]),
93
- this,
94
- 'showK8sMetrics',
95
- `Determine k8s metrics`
96
- );
97
- setPromiseResult(
98
- allDashboardsExist(this.$store, this.currentCluster.id, [ETCD_METRICS_DETAIL_URL, ETCD_METRICS_SUMMARY_URL]),
99
- this,
100
- 'showEtcdMetrics',
101
- `Determine etcd metrics`
102
- );
103
-
104
- if (this.currentCluster.isLocal) {
105
- this.$store.dispatch('management/findAll', { type: MANAGEMENT.NODE });
85
+ if (this.currentCluster) {
86
+ setPromiseResult(
87
+ allDashboardsExist(this.$store, this.currentCluster.id, [CLUSTER_METRICS_DETAIL_URL, CLUSTER_METRICS_SUMMARY_URL]),
88
+ this,
89
+ 'showClusterMetrics',
90
+ `Determine cluster metrics`
91
+ );
92
+ setPromiseResult(
93
+ allDashboardsExist(this.$store, this.currentCluster.id, [K8S_METRICS_DETAIL_URL, K8S_METRICS_SUMMARY_URL]),
94
+ this,
95
+ 'showK8sMetrics',
96
+ `Determine k8s metrics`
97
+ );
98
+ setPromiseResult(
99
+ allDashboardsExist(this.$store, this.currentCluster.id, [ETCD_METRICS_DETAIL_URL, ETCD_METRICS_SUMMARY_URL]),
100
+ this,
101
+ 'showEtcdMetrics',
102
+ `Determine etcd metrics`
103
+ );
104
+
105
+ if (this.currentCluster.isLocal) {
106
+ this.$store.dispatch('management/findAll', { type: MANAGEMENT.NODE });
107
+ }
106
108
  }
107
109
  },
108
110
 
@@ -184,7 +186,7 @@ export default {
184
186
  displayProvider() {
185
187
  const other = 'other';
186
188
 
187
- let provider = this.currentCluster.status.provider || other;
189
+ let provider = this.currentCluster?.status?.provider || other;
188
190
 
189
191
  if (provider === 'rke.windows') {
190
192
  provider = 'rkeWindows';
@@ -444,11 +446,11 @@ export default {
444
446
  </div>
445
447
  <div>
446
448
  <label>{{ t('glance.version') }}: </label>
449
+ <span>{{ currentCluster.kubernetesVersionBase }}</span>
447
450
  <span
448
451
  v-if="currentCluster.kubernetesVersionExtension"
449
- style="font-size: 0.5em"
452
+ style="font-size: 0.75em"
450
453
  >{{ currentCluster.kubernetesVersionExtension }}</span>
451
- <span>{{ currentCluster.kubernetesVersionBase }}</span>
452
454
  </div>
453
455
  <div>
454
456
  <label>{{ t('glance.created') }}: </label>
@@ -602,6 +604,8 @@ export default {
602
604
  </div>
603
605
  <Tabbed
604
606
  v-if="hasMetricsTabs"
607
+ default-tab="cluster-metrics"
608
+ :use-hash="false"
605
609
  class="mt-30"
606
610
  >
607
611
  <Tab
@@ -705,7 +709,7 @@ export default {
705
709
  }
706
710
 
707
711
  .etcd-metrics ::v-deep .external-link {
708
- top: -102px;
712
+ top: -107px;
709
713
  }
710
714
 
711
715
  .cluster-tools-tip {
@@ -416,7 +416,7 @@ export default {
416
416
  <template>
417
417
  <Loading v-if="$fetchState.pending" />
418
418
  <div v-else-if="options.length">
419
- <h1 v-html="t('catalog.tools.header')" />
419
+ <h1 v-clean-html="t('catalog.tools.header')" />
420
420
  <TypeDescription
421
421
  v-if="!legacyEnabled"
422
422
  resource="chart"
@@ -466,8 +466,8 @@ export default {
466
466
  </div>
467
467
  <div class="description">
468
468
  <div
469
+ v-clean-html="opt.chart.chartDescription"
469
470
  class="description-content"
470
- v-html="opt.chart.chartDescription"
471
471
  />
472
472
  </div>
473
473
  <div
@@ -483,16 +483,16 @@ export default {
483
483
  <div class="action">
484
484
  <template v-if="opt.blocked">
485
485
  <button
486
+ v-clean-html="t('catalog.tools.action.install')"
486
487
  disabled="true"
487
488
  class="btn btn-sm role-primary"
488
- v-html="t('catalog.tools.action.install')"
489
489
  />
490
490
  </template>
491
491
  <template v-else-if="opt.app && opt.chart.legacy">
492
492
  <button
493
+ v-clean-html="t('catalog.tools.action.manage')"
493
494
  class="btn btn-sm role-secondary"
494
495
  @click="openV1Tool(opt.chart.legacyPage)"
495
- v-html="t('catalog.tools.action.manage')"
496
496
  />
497
497
  </template>
498
498
  <template v-else-if="opt.app && opt.upgradeAvailable && !opt.chart.legacy">
@@ -503,9 +503,9 @@ export default {
503
503
  <i class="icon icon-delete icon-lg" />
504
504
  </button>
505
505
  <button
506
+ v-clean-html="t('catalog.tools.action.upgrade')"
506
507
  class="btn btn-sm role-secondary"
507
508
  @click="edit(opt.app, opt.app.upgradeAvailable)"
508
- v-html="t('catalog.tools.action.upgrade')"
509
509
  />
510
510
  </template>
511
511
  <template v-else-if="opt.app">
@@ -516,23 +516,23 @@ export default {
516
516
  <i class="icon icon-delete icon-lg" />
517
517
  </button>
518
518
  <button
519
+ v-clean-html="t('catalog.tools.action.edit')"
519
520
  class="btn btn-sm role-secondary"
520
521
  @click="edit(opt.app)"
521
- v-html="t('catalog.tools.action.edit')"
522
522
  />
523
523
  </template>
524
524
  <template v-else-if="opt.chart.legacy">
525
525
  <button
526
+ v-clean-html="t('catalog.tools.action.install')"
526
527
  class="btn btn-sm role-primary"
527
528
  @click="openV1Tool(opt.chart.legacyPage)"
528
- v-html="t('catalog.tools.action.install')"
529
529
  />
530
530
  </template>
531
531
  <template v-else>
532
532
  <button
533
+ v-clean-html="t('catalog.tools.action.install')"
533
534
  class="btn btn-sm role-primary"
534
535
  @click="install(opt.chart)"
535
- v-html="t('catalog.tools.action.install')"
536
536
  />
537
537
  </template>
538
538
  </div>
@@ -3,11 +3,15 @@ import { mapState } from 'vuex';
3
3
  import { FLEET } from '@shell/config/types';
4
4
  import { WORKSPACE } from '@shell/store/prefs';
5
5
  import { STATES_ENUM, STATES, getStateLabel } from '@shell/plugins/dashboard-store/resource-class';
6
- import { allHash } from '@shell/utils/promise';
7
6
  import Loading from '@shell/components/Loading';
8
7
  import CollapsibleCard from '@shell/components/CollapsibleCard.vue';
9
8
  import ResourceTable from '@shell/components/ResourceTable';
10
9
  import CompoundStatusBadge from '@shell/components/CompoundStatusBadge';
10
+ import { checkPermissions, checkSchemasForFindAllHash } from '@shell/utils/auth';
11
+ import { WORKSPACE_ANNOTATION } from '@shell/config/labels-annotations';
12
+ import { filterBy } from '@shell/utils/array';
13
+ import FleetNoWorkspaces from '@shell/components/fleet/FleetNoWorkspaces.vue';
14
+ import { NAME } from '@shell/config/product/fleet';
11
15
 
12
16
  export default {
13
17
  name: 'ListGitRepo',
@@ -15,27 +19,38 @@ export default {
15
19
  Loading,
16
20
  ResourceTable,
17
21
  CollapsibleCard,
18
- CompoundStatusBadge
22
+ CompoundStatusBadge,
23
+ FleetNoWorkspaces
19
24
  },
20
25
 
21
26
  async fetch() {
22
- const hash = await allHash({
23
- allBundles: this.$store.dispatch('management/findAll', { type: FLEET.BUNDLE }),
24
- gitRepos: this.$store.dispatch('management/findAll', { type: FLEET.GIT_REPO }),
25
- fleetWorkspaces: this.$store.dispatch('management/findAll', { type: FLEET.WORKSPACE }),
26
- });
27
+ const hash = await checkSchemasForFindAllHash({
28
+ fleetWorkspaces: {
29
+ inStoreType: 'management',
30
+ type: FLEET.WORKSPACE,
31
+ schemaValidator: (schema) => {
32
+ return !!schema?.links?.collection;
33
+ }
34
+ },
35
+ allBundles: {
36
+ inStoreType: 'management',
37
+ type: FLEET.BUNDLE,
38
+ },
39
+ gitRepos: {
40
+ inStoreType: 'management',
41
+ type: FLEET.GIT_REPO,
42
+ }
43
+ }, this.$store);
27
44
 
28
- this.allBundles = hash.allBundles;
29
45
  this.gitRepos = hash.gitRepos;
30
- this.fleetWorkspaces = hash.fleetWorkspaces;
46
+ this.fleetWorkspacesData = hash.fleetWorkspaces || [];
31
47
 
32
- // init cards collapse flags
33
- const workspaces = this.fleetWorkspaces.filter(ws => ws.repos.length);
48
+ try {
49
+ const permissions = await checkPermissions({ workspaces: { type: FLEET.WORKSPACE }, gitRepos: { type: FLEET.GIT_REPO, schemaValidator: schema => schema.resourceMethods.includes('PUT') } }, this.$store.getters);
34
50
 
35
- if (workspaces.length) {
36
- workspaces.forEach((ws) => {
37
- this.$set(this.isCollapsed, ws.id, false);
38
- });
51
+ this.permissions = permissions;
52
+ } catch (e) {
53
+ console.error(e); // eslint-disable-line no-console
39
54
  }
40
55
  },
41
56
 
@@ -71,24 +86,49 @@ export default {
71
86
  sort: 'status.resourceCounts.ready',
72
87
  }
73
88
  ],
74
- schema: {},
75
- allBundles: null,
76
- gitRepos: null,
77
- fleetWorkspaces: null,
78
- isCollapsed: {},
79
- getStartedLink: {
89
+ schema: {},
90
+ allBundles: [],
91
+ gitRepos: [],
92
+ fleetWorkspacesData: [],
93
+ isCollapsed: {},
94
+ permissions: {},
95
+ getStartedLink: {
80
96
  name: 'c-cluster-product-resource-create',
81
97
  params: {
82
- product: 'fleet',
98
+ product: NAME,
83
99
  resource: FLEET.GIT_REPO
84
100
  },
85
101
  }
86
102
  };
87
103
  },
88
104
  computed: {
89
- ...mapState(['workspace']),
105
+ ...mapState(['workspace', 'allNamespaces']),
106
+ fleetWorkspaces() {
107
+ if (this.fleetWorkspacesData?.length) {
108
+ return this.fleetWorkspacesData;
109
+ }
110
+
111
+ // When user doesn't have access to the workspaces fall back to namespaces
112
+
113
+ return this.allNamespaces.filter((item) => {
114
+ return item.metadata.annotations[WORKSPACE_ANNOTATION] === WORKSPACE;
115
+ }).map(( obj ) => {
116
+ const repos = filterBy(this.gitRepos, 'metadata.namespace', obj.id);
117
+
118
+ return {
119
+ ...obj,
120
+ counts: {
121
+ clusters: '-',
122
+ clusterGroups: '-',
123
+ gitRepos: repos.length
124
+ },
125
+ repos,
126
+ nameDisplay: obj.id
127
+ };
128
+ });
129
+ },
90
130
  workspacesData() {
91
- return this.fleetWorkspaces.filter(ws => ws.repos.length);
131
+ return this.fleetWorkspaces.filter(ws => ws.repos && ws.repos.length);
92
132
  },
93
133
  emptyWorkspaces() {
94
134
  return this.fleetWorkspaces.filter(ws => !ws.repos || !ws.repos.length);
@@ -105,7 +145,7 @@ export default {
105
145
  this.$router.push({
106
146
  name: 'c-cluster-product-resource',
107
147
  params: {
108
- product: 'fleet',
148
+ product: NAME,
109
149
  resource: FLEET.GIT_REPO
110
150
  },
111
151
  });
@@ -247,6 +287,14 @@ export default {
247
287
  });
248
288
  }
249
289
  },
290
+
291
+ watch: {
292
+ fleetWorkspaces(value) {
293
+ value?.filter(ws => ws.repos?.length).forEach((ws) => {
294
+ this.$set(this.isCollapsed, ws.id, false);
295
+ });
296
+ }
297
+ }
250
298
  };
251
299
  </script>
252
300
 
@@ -254,6 +302,10 @@ export default {
254
302
  <div class="fleet-dashboard">
255
303
  <Loading v-if="$fetchState.pending" />
256
304
  <!-- no git repos -->
305
+ <FleetNoWorkspaces
306
+ v-else-if="!fleetWorkspacesData.length"
307
+ :can-view="permissions.workspaces"
308
+ />
257
309
  <div
258
310
  v-else-if="!gitRepos.length"
259
311
  class="fleet-empty-dashboard"
@@ -270,15 +322,17 @@ export default {
270
322
  {{ t('fleet.dashboard.learnMore') }} <i class="icon icon-external-link" />
271
323
  </a>
272
324
  </p>
273
- <h3 class="mb-30">
274
- {{ t('fleet.dashboard.noRepo', null, true) }}
275
- </h3>
276
- <n-link
277
- :to="getStartedLink"
278
- class="btn role-secondary"
279
- >
280
- {{ t('fleet.dashboard.getStarted') }}
281
- </n-link>
325
+ <template v-if="permissions.gitRepos">
326
+ <h3 class="mb-30">
327
+ {{ t('fleet.dashboard.noRepo', null, true) }}
328
+ </h3>
329
+ <n-link
330
+ :to="getStartedLink"
331
+ class="btn role-secondary"
332
+ >
333
+ {{ t('fleet.dashboard.getStarted') }}
334
+ </n-link>
335
+ </template>
282
336
  </div>
283
337
  <!-- fleet dashboard with repos -->
284
338
  <div
@@ -354,7 +408,9 @@ export default {
354
408
  v-on="$listeners"
355
409
  >
356
410
  <template #cell:clustersReady="{row}">
411
+ <span v-if="ws.type === 'namespace'"> - </span>
357
412
  <CompoundStatusBadge
413
+ v-else
358
414
  :tooltip-text="getTooltipInfo('clusters', row)"
359
415
  :badge-class="getStatusInfo('clusters', row).badgeClass"
360
416
  :icon="getStatusInfo('clusters', row).icon"
@@ -362,7 +418,9 @@ export default {
362
418
  />
363
419
  </template>
364
420
  <template #cell:bundlesReady="{row}">
421
+ <span v-if="ws.type === 'namespace'"> - </span>
365
422
  <CompoundStatusBadge
423
+ v-else
366
424
  :tooltip-text="getTooltipInfo('bundles', row)"
367
425
  :badge-class="getStatusInfo('bundles', row).badgeClass"
368
426
  :icon="getStatusInfo('bundles', row).icon"
@@ -389,6 +447,9 @@ export default {
389
447
  </template>
390
448
 
391
449
  <style lang="scss" scoped>
450
+ .fleet-dashboard {
451
+ min-height: 100vh;
452
+ }
392
453
  .fleet-empty-dashboard {
393
454
  flex: 1;
394
455
  display: flex;
@@ -27,7 +27,7 @@ export default {
27
27
  }
28
28
  }
29
29
  },
30
- count: constraint.violations.length
30
+ count: constraint.totalViolations
31
31
  }));
32
32
  },
33
33
  data(ctx) {
@@ -72,7 +72,7 @@ export default {
72
72
  <template>
73
73
  <div>
74
74
  <h1>Overview</h1>
75
- <h4 v-html="t('istio.poweredBy', {}, true)" />
75
+ <h4 v-clean-html="t('istio.poweredBy', {}, true)" />
76
76
  <div class="links">
77
77
  <div
78
78
  :class="{'disabled':!kialiUrl}"
@@ -99,7 +99,7 @@ export default {
99
99
  </a>
100
100
  <hr>
101
101
  <div class="description">
102
- <span v-html="t('istio.links.kiali.description', {link: monitoringUrl}, true)" />
102
+ <span v-clean-html="t('istio.links.kiali.description', {link: monitoringUrl}, true)" />
103
103
  </div>
104
104
  </div>
105
105
  </span>
@@ -107,7 +107,7 @@ export default {
107
107
  v-if="!kialiUrl"
108
108
  class="disabled-msg"
109
109
  >
110
- <span v-html="t('istio.links.disabled', {app: 'Kiali'})" />
110
+ <span v-clean-html="t('istio.links.disabled', {app: 'Kiali'})" />
111
111
  </div>
112
112
  </div>
113
113
  <div
@@ -135,7 +135,7 @@ export default {
135
135
  </a>
136
136
  <hr>
137
137
  <div class="description">
138
- <span v-html="t('istio.links.jaeger.description', true)" />
138
+ <span v-clean-html="t('istio.links.jaeger.description', true)" />
139
139
  </div>
140
140
  </div>
141
141
  </span>
@@ -143,7 +143,7 @@ export default {
143
143
  v-if="!jaegerUrl"
144
144
  class="disabled-msg"
145
145
  >
146
- <span v-html="t('istio.links.disabled', {app: 'Jaeger'})" />
146
+ <span v-clean-html="t('istio.links.disabled', {app: 'Jaeger'})" />
147
147
  </div>
148
148
  </div>
149
149
  </div>
@@ -89,7 +89,7 @@ export default {
89
89
  <template #cell:apikey="{row}">
90
90
  <span
91
91
  v-if="row.publicData"
92
- v-html="row.publicData"
92
+ v-clean-html="row.publicData"
93
93
  />
94
94
  <span
95
95
  v-else
@@ -214,3 +214,10 @@ export default {
214
214
  </div>
215
215
  </section>
216
216
  </template>
217
+
218
+ <style lang="scss" scoped>
219
+ .create-resource-container .subtype-banner {
220
+ min-height: 80px;
221
+ padding: 10px;
222
+ }
223
+ </style>
@@ -36,7 +36,7 @@ export default {
36
36
 
37
37
  computed: {
38
38
  showVersionSelector() {
39
- return this.plugin?.versions.length > 1;
39
+ return this.versionOptions?.length > 1;
40
40
  },
41
41
 
42
42
  versionOptions() {
@@ -44,8 +44,8 @@ export default {
44
44
  return [];
45
45
  }
46
46
 
47
- // Don't allow update/rollback to curent version
48
- const versions = this.plugin.versions.filter((v) => {
47
+ // Don't allow update/rollback to current version
48
+ const versions = this.plugin?.installableVersions?.filter((v) => {
49
49
  if (this.currentVersion) {
50
50
  return v.version !== this.currentVersion;
51
51
  }
@@ -78,12 +78,12 @@ export default {
78
78
  this.currentVersion = plugin.displayVersion;
79
79
 
80
80
  // Update to latest version, so take the first version
81
- if (plugin.versions.length > 0) {
82
- this.version = plugin.versions[0].version;
81
+ if (plugin.installableVersions?.length > 0) {
82
+ this.version = plugin.installableVersions?.[0]?.version;
83
83
  }
84
84
  } else if (mode === 'rollback') {
85
85
  // Find the newest version once we remove the current version
86
- const versionNames = plugin.versions.filter(v => v.version !== plugin.displayVersion);
86
+ const versionNames = plugin.installableVersions.filter(v => v.version !== plugin.displayVersion);
87
87
 
88
88
  this.currentVersion = plugin.displayVersion;
89
89
 
@@ -93,10 +93,10 @@ export default {
93
93
  }
94
94
 
95
95
  // Make sure we have the version available
96
- const versionChart = plugin.versions?.find(v => v.version === this.version);
96
+ const versionChart = plugin.installableVersions?.find(v => v.version === this.version);
97
97
 
98
98
  if (!versionChart) {
99
- this.version = plugin.versions[0].version;
99
+ this.version = plugin.installableVersions?.[0]?.version;
100
100
  }
101
101
 
102
102
  this.busy = false;
@@ -63,17 +63,19 @@ export default {
63
63
  },
64
64
 
65
65
  async loadPluginVersionInfo(version) {
66
- this.versionError = false;
67
- this.versionInfo = undefined;
68
-
69
66
  const versionName = version || this.info.displayVersion;
70
67
 
71
- this.infoVersion = versionName;
68
+ const isVersionNotCompatibleWithUi = this.info.versions?.find(v => v.version === versionName && !v.isCompatibleWithUi);
72
69
 
73
- if (!this.info.chart) {
70
+ if (!this.info.chart || isVersionNotCompatibleWithUi) {
74
71
  return;
75
72
  }
76
73
 
74
+ this.infoVersion = versionName;
75
+
76
+ this.versionError = false;
77
+ this.versionInfo = undefined;
78
+
77
79
  try {
78
80
  this.versionInfo = await this.$store.dispatch('catalog/getVersionInfo', {
79
81
  repoType: this.info.chart.repoType,
@@ -204,8 +206,9 @@ export default {
204
206
  :key="v.version"
205
207
  >
206
208
  <a
209
+ v-tooltip="v.requiredUiVersion ? t('plugins.info.requiresVersion', { version: v.requiredUiVersion }) : ''"
207
210
  class="version-link"
208
- :class="{'version-active': v.version === infoVersion}"
211
+ :class="{'version-active': v.version === infoVersion, 'disabled': !v.isCompatibleWithUi}"
209
212
  @click="loadPluginVersionInfo(v.version)"
210
213
  >
211
214
  {{ v.version }}
@@ -337,6 +340,7 @@ export default {
337
340
 
338
341
  .plugin-versions {
339
342
  display: flex;
343
+ flex-wrap: wrap;
340
344
  }
341
345
 
342
346
  .plugin-description {
@@ -349,13 +353,22 @@ export default {
349
353
  padding: 2px 8px;
350
354
  border-radius: 5px;
351
355
  user-select: none;
352
- margin-right: 5px;
356
+ margin: 0 5px 5px 0;
357
+ display: block;
353
358
 
354
359
  &.version-active {
355
360
  color: var(--link-text);
356
361
  background: var(--link);
357
362
  }
358
363
 
364
+ &.disabled {
365
+ cursor: not-allowed;
366
+ color: var(--disabled-text) !important;
367
+ background-color: var(--disabled-bg) !important;
368
+ border-color: var(--disabled-bg) !important;
369
+ text-decoration: none !important;
370
+ }
371
+
359
372
  &.version-builtin {
360
373
  display: inline-block;
361
374
  }