@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
@@ -47,11 +47,19 @@ export default {
47
47
  computed: {
48
48
  ...mapGetters(['clusterId']),
49
49
  trackStyle() {
50
- const sliderItem = this.activeItemId * 100 / this.slider.length;
51
- const width = 60 * this.slider.length;
50
+ let sliderItem = ( this.activeItemId + 1) * 100 / (this.slider.length + 2);
51
+ const width = 60 * (this.slider.length + 2);
52
+
53
+ if (this.slider.length === 1) {
54
+ sliderItem = 0;
55
+ }
52
56
 
53
57
  return `transform: translateX(-${ sliderItem }%); width: ${ width }%`;
54
58
  },
59
+
60
+ test() {
61
+ return 'test';
62
+ }
55
63
  },
56
64
 
57
65
  methods: {
@@ -64,26 +72,35 @@ export default {
64
72
  scrollSlide(i) {
65
73
  this.autoScroll = false;
66
74
  this.activeItemId = i;
67
- setTimeout(() => {
68
- this.slidePosition();
69
- }, 400);
70
75
  },
71
76
 
72
- nextPrev(item) {
77
+ nextPrev(direction) {
73
78
  this.autoScroll = false;
74
- if (item === 'next' && this.activeItemId < this.slider.length - 1) {
75
- this.activeItemId++;
76
- }
79
+ const slideTrack = document.getElementById('slide-track');
77
80
 
78
- if (item === 'prev' && this.activeItemId > 0) {
79
- this.activeItemId--;
80
- }
81
+ slideTrack.style.transition = `transform 450ms ease-in-out`;
82
+
83
+ direction !== 'prev' ? (this.activeItemId++) : (this.activeItemId--);
81
84
 
82
- this.slidePosition();
85
+ slideTrack.addEventListener('transitionend', this.slideTransition);
86
+ },
87
+
88
+ slideTransition() {
89
+ const slideTrack = document.getElementById('slide-track');
90
+ const slidesArray = this.slider.length + 2;
91
+
92
+ if (this.activeItemId === -1) {
93
+ slideTrack.style.transition = 'none';
94
+ this.activeItemId = this.slider.length - 1;
95
+ }
96
+ if (this.activeItemId === slidesArray - 2) {
97
+ slideTrack.style.transition = 'none';
98
+ this.activeItemId = 0;
99
+ }
83
100
  },
84
101
 
85
102
  autoScrollSlide() {
86
- if (this.activeItemId < this.slider.length && this.autoScroll ) {
103
+ if (this.activeItemId < (this.slider.length + 1) && this.autoScroll ) {
87
104
  this.activeItemId++;
88
105
  }
89
106
 
@@ -91,18 +108,7 @@ export default {
91
108
  this.autoScroll = false;
92
109
  this.activeItemId = 0;
93
110
  }
94
- this.slidePosition();
95
111
  },
96
-
97
- slidePosition() {
98
- if (this.activeItemId <= 1) {
99
- this.$refs.slide[this.slider.length - 1].style.left = '-93%';
100
- this.$refs.slide[0].style.left = '7%';
101
- } else {
102
- this.$refs.slide[this.slider.length - 1].style.left = '7%';
103
- this.$refs.slide[0].style.left = '107%';
104
- }
105
- }
106
112
  },
107
113
 
108
114
  beforeDestroy() {
@@ -112,14 +118,30 @@ export default {
112
118
  },
113
119
 
114
120
  mounted() {
121
+ const slideTrack = document.getElementById('slide-track');
122
+
123
+ if (this.slider.length === 1) {
124
+ // singleSlide.style = 'width: 100%; max-width: 100%';
125
+ slideTrack.style = 'transform:translateX(0%); width:100%; left:0';
126
+ } else {
127
+ const node = document.getElementById('slide0');
128
+ const clone = node.cloneNode(true);
129
+
130
+ const nodeLast = document.getElementById(`slide${ this.slider.length - 1 }`);
131
+ const cloneLast = nodeLast.cloneNode(true);
132
+
133
+ slideTrack.appendChild(clone);
134
+ slideTrack.insertBefore(cloneLast, slideTrack.children[0]);
135
+ }
136
+
115
137
  const lastSeenCluster = sessionStorage.getItem(carouselSeenStorageKey);
116
138
 
117
139
  if (lastSeenCluster !== this.clusterId) {
118
140
  // Session storage lasts until tab/window closed (retained on refresh)
119
141
  sessionStorage.setItem(carouselSeenStorageKey, this.clusterId);
120
-
121
- this.autoScrollSlideInterval = setInterval(this.autoScrollSlide, 5000);
122
142
  }
143
+
144
+ this.autoScrollSlideInterval = setInterval(this.autoScrollSlide, 5000);
123
145
  },
124
146
 
125
147
  };
@@ -127,7 +149,10 @@ export default {
127
149
  </script>
128
150
 
129
151
  <template>
130
- <div class="slider">
152
+ <div
153
+ class="slider"
154
+ :class="{'disable': sliders.length === 1}"
155
+ >
131
156
  <div
132
157
  id="slide-track"
133
158
  ref="slider"
@@ -141,6 +166,7 @@ export default {
141
166
  ref="slide"
142
167
  :key="get(slide, keyField)"
143
168
  class="slide"
169
+ :class="{'singleSlide': sliders.length === 1}"
144
170
  :href="asLink ? get(slide, linkField) : null"
145
171
  :target="get(slide, targetField)"
146
172
  :rel="rel"
@@ -155,13 +181,16 @@ export default {
155
181
  :label="slide.repoName"
156
182
  color="slider-badge mb-20"
157
183
  />
158
- <h1>{{ slide.chartNameDisplay }}</h1>
184
+ <h1>{{ slide.chartNameDisplay }} {{ i + 1 }}</h1>
159
185
  <p>{{ slide.chartDescription }}</p>
160
186
  </div>
161
187
  </div>
162
188
  </div>
163
189
  </div>
164
- <div class="controls">
190
+ <div
191
+ class="controls"
192
+ :class="{'disable': sliders.length === 1}"
193
+ >
165
194
  <div
166
195
  v-for="(slide, i) in slider"
167
196
  :key="i"
@@ -173,7 +202,7 @@ export default {
173
202
  <div
174
203
  ref="prev"
175
204
  class="prev"
176
- :class="[activeItemId === 0 ? 'disabled' : 'prev']"
205
+ :class="{'disable': sliders.length === 1}"
177
206
  @click="nextPrev('prev')"
178
207
  >
179
208
  <i class="icon icon-chevron-left icon-4x" />
@@ -181,7 +210,7 @@ export default {
181
210
  <div
182
211
  ref="next"
183
212
  class="next"
184
- :class="[activeItemId === slider.length - 1 ? 'disabled' : 'next']"
213
+ :class="{'disable': sliders.length === 1}"
185
214
  @click="nextPrev('next')"
186
215
  >
187
216
  <i class="icon icon-chevron-right icon-4x" />
@@ -197,7 +226,19 @@ export default {
197
226
  place-items: center;
198
227
  overflow: hidden;
199
228
  margin-bottom: 30px;
200
- min-width: 700px;
229
+ // min-width: 700px;
230
+
231
+ &.disable::before,
232
+ &.disable::after {
233
+ display: none;
234
+ }
235
+
236
+ &.disable:hover {
237
+ .prev,
238
+ .next {
239
+ display: none;
240
+ }
241
+ }
201
242
 
202
243
  &:hover {
203
244
  .prev,
@@ -212,6 +253,7 @@ export default {
212
253
  animation: scrolls 10s ;
213
254
  position: relative;
214
255
  transition: 1s ease-in-out;
256
+ left: 21%;
215
257
  }
216
258
 
217
259
  .slider-badge {
@@ -226,13 +268,12 @@ export default {
226
268
  position: relative;
227
269
  border: 1px solid var(--tabbed-border);
228
270
  border-radius: var(--border-radius);
229
- left: 7%;
230
271
  cursor: pointer;
231
272
 
232
- &:last-child {
233
- left: -93%;
273
+ &.singleSlide {
274
+ width: 100%;
275
+ max-width: 100%;
234
276
  }
235
-
236
277
  .slide-header {
237
278
  background: var(--default);
238
279
  width: 100%;
@@ -278,6 +319,9 @@ export default {
278
319
  .slider::before {
279
320
  left: 0;
280
321
  top: 0;
322
+ &.disable {
323
+ display: none;
324
+ }
281
325
  }
282
326
  .slider::after{
283
327
  right: -1px;
@@ -291,6 +335,10 @@ export default {
291
335
  justify-content: center;
292
336
  margin-top: 10px;
293
337
 
338
+ &.disable {
339
+ display: none;
340
+ }
341
+
294
342
  .control-item {
295
343
  width: 10px;
296
344
  height: 10px;
@@ -0,0 +1,76 @@
1
+ <script>
2
+ import { Checkbox } from '@components/Form/Checkbox';
3
+ import { mapGetters } from 'vuex';
4
+
5
+ export default {
6
+ components: { Checkbox },
7
+ props: {
8
+ value: {
9
+ type: Object,
10
+ default: () => {
11
+ return {};
12
+ }
13
+ },
14
+ mode: {
15
+ type: String,
16
+ default: 'edit'
17
+ },
18
+
19
+ /**
20
+ * Optional title section prior checkbox
21
+ */
22
+ title: {
23
+ type: String,
24
+ default: null
25
+ },
26
+
27
+ /**
28
+ * Cluster information
29
+ */
30
+ cluster: {
31
+ type: Object,
32
+ default: null
33
+ }
34
+ },
35
+ created() {
36
+ if (!this.value.global.cattle) {
37
+ this.$set(this.value.global, 'cattle', { psp: { enabled: false } });
38
+ }
39
+ if (!this.value.global.cattle.psp) {
40
+ this.$set(this.value.global.cattle, 'psp', { enabled: false });
41
+ }
42
+ },
43
+ computed: {
44
+ ...mapGetters({ t: 'i18n/t' }),
45
+
46
+ /**
47
+ * Display checkbox only if contains PSP or K8S version is less than 1.25
48
+ */
49
+ hasCheckbox() {
50
+ const clusterVersion = this.cluster?.kubernetesVersion || '';
51
+ const version = clusterVersion.match(/\d+/g);
52
+ const isRequiredVersion = version?.length ? +version[0] === 1 && +version[1] < 25 : false;
53
+
54
+ return isRequiredVersion;
55
+ }
56
+ }
57
+ };
58
+ </script>
59
+
60
+ <template>
61
+ <div
62
+ v-if="hasCheckbox"
63
+ class="mt-10 mb-10"
64
+ >
65
+ <h3 v-if="title">
66
+ {{ title }}
67
+ </h3>
68
+
69
+ <Checkbox
70
+ v-model="value.global.cattle.psp.enabled"
71
+ data-testid="psp-checkbox"
72
+ :mode="mode"
73
+ :label="t('catalog.chart.enablePSP')"
74
+ />
75
+ </div>
76
+ </template>
@@ -358,6 +358,10 @@ export default {
358
358
  const newNamespaceName = get(this.resource, this.namespaceKey);
359
359
  let namespaceAlreadyExists = false;
360
360
 
361
+ if (!this.createNamespace) {
362
+ return;
363
+ }
364
+
361
365
  try {
362
366
  // This is in a try-catch block because the call to fetch
363
367
  // a namespace throws an error if the namespace is not found.
@@ -461,7 +465,7 @@ export default {
461
465
  <h5>
462
466
  <span
463
467
  v-if="$store.getters['i18n/exists'](subtype.label)"
464
- v-html="t(subtype.label)"
468
+ v-clean-html="t(subtype.label)"
465
469
  />
466
470
  <span v-else>{{ subtype.label }}</span>
467
471
  </h5>
@@ -480,7 +484,7 @@ export default {
480
484
  >
481
485
  <span
482
486
  v-if="$store.getters['i18n/exists'](subtype.description)"
483
- v-html="t(subtype.description, {}, true)"
487
+ v-clean-html="t(subtype.description, {}, true)"
484
488
  />
485
489
  <span v-else>{{ subtype.description }}</span>
486
490
  </div>
@@ -47,25 +47,26 @@ export default {
47
47
  </script>
48
48
 
49
49
  <template>
50
- <div
51
- class="dashboard-metrics"
52
- :class="!hasSummaryAndDetail && 'external-link-pull-left'"
50
+ <div
51
+ class="dashboard-metrics"
52
+ :class="!hasSummaryAndDetail && 'external-link-pull-left'"
53
53
  >
54
54
  <div class="graph-options mb-10">
55
- <DashboardOptions
56
- v-model="graphOptions"
57
- :has-summary-and-detail="hasSummaryAndDetail"
55
+ <DashboardOptions
56
+ v-model="graphOptions"
57
+ :has-summary-and-detail="hasSummaryAndDetail"
58
58
  />
59
59
  </div>
60
60
  <div class="info">
61
61
  <slot />
62
62
  </div>
63
- <div
64
- class="graphs"
65
- :style="{height: graphHeight}"
63
+ <div
64
+ class="graphs"
65
+ :style="{height: graphHeight}"
66
66
  >
67
67
  <GrafanaDashboard
68
68
  v-if="graphOptions.type === 'detail'"
69
+ key="'detail'"
69
70
  class="col span-12 detail"
70
71
  :background-color="graphBackgroundColor"
71
72
  :theme="theme"
@@ -76,6 +77,7 @@ export default {
76
77
  />
77
78
  <GrafanaDashboard
78
79
  v-else
80
+ key="'summary'"
79
81
  class="col span-12 summary"
80
82
  :background-color="graphBackgroundColor"
81
83
  :theme="theme"
@@ -108,7 +110,7 @@ export default {
108
110
  .external-link {
109
111
  position: absolute;
110
112
  left: 10px;
111
- top: -45px;
113
+ top: -47px;
112
114
  }
113
115
  }
114
116
  }
@@ -169,8 +169,8 @@ export default {
169
169
 
170
170
  <span
171
171
  v-else
172
+ v-clean-html="bodyHtml"
172
173
  :class="{'conceal': concealed, 'monospace': monospace && !isBinary}"
173
- v-html="bodyHtml"
174
174
  />
175
175
 
176
176
  <template v-if="!isBinary && !jsonStr && isLong && !expanded">
@@ -49,7 +49,7 @@ export default {
49
49
  </h4>
50
50
  <div slot="body">
51
51
  <div class="mb-10">
52
- <p v-html="t('promptRemove.attemptingToRemoveAuthConfig', null, true)" />
52
+ <p v-clean-html="t('promptRemove.attemptingToRemoveAuthConfig', null, true)" />
53
53
  </div>
54
54
  </div>
55
55
  <template #actions>
@@ -522,8 +522,8 @@ export default {
522
522
  />
523
523
  <div
524
524
  v-if="inline && !loaded"
525
+ v-clean-html="t('generic.loading', {}, true)"
525
526
  class="inline-loading"
526
- v-html="t('generic.loading', {}, true)"
527
527
  />
528
528
  <div
529
529
  v-if="error"
@@ -3,15 +3,19 @@ import { Banner } from '@components/Banner';
3
3
  import Loading from '@shell/components/Loading';
4
4
  import { mapGetters } from 'vuex';
5
5
  import { hasLeader, leaderChanges, failedProposals } from '@shell/utils/grafana';
6
+ import { CATALOG } from '@shell/config/types';
6
7
 
7
8
  export default {
8
9
  components: { Banner, Loading },
9
10
  async fetch() {
10
- const leader = await hasLeader(this.$store.dispatch, this.currentCluster.id);
11
+ const inStore = this.$store.getters['currentProduct'].inStore;
12
+ const res = await this.$store.dispatch(`${ inStore }/find`, { type: CATALOG.APP, id: 'cattle-monitoring-system/rancher-monitoring' });
13
+ const monitoringVersion = res?.currentVersion;
14
+ const leader = await hasLeader(monitoringVersion, this.$store.dispatch, this.currentCluster.id);
11
15
 
12
16
  this.hasLeader = leader ? this.t('generic.yes') : this.t('generic.no');
13
- this.leaderChanges = await leaderChanges(this.$store.dispatch, this.currentCluster.id);
14
- this.failedProposals = await failedProposals(this.$store.dispatch, this.currentCluster.id);
17
+ this.leaderChanges = await leaderChanges(monitoringVersion, this.$store.dispatch, this.currentCluster.id);
18
+ this.failedProposals = await failedProposals(monitoringVersion, this.$store.dispatch, this.currentCluster.id);
15
19
  },
16
20
  data() {
17
21
  return {
@@ -26,10 +30,10 @@ export default {
26
30
 
27
31
  <template>
28
32
  <Loading v-if="$fetchState.pending" />
29
- <Banner
30
- v-else
31
- class="banner"
32
- color="info"
33
+ <Banner
34
+ v-else
35
+ class="banner"
36
+ color="info"
33
37
  >
34
38
  <div class="datum">
35
39
  <label>{{ t('etcdInfoBanner.hasLeader') }}</label> {{ hasLeader }}
@@ -51,6 +55,7 @@ export default {
51
55
 
52
56
  .datum {
53
57
  text-align: center;
58
+ margin-right: 5px;
54
59
  }
55
60
 
56
61
  & ::v-deep label {
@@ -114,7 +114,6 @@ export default {
114
114
  labelKey: 'tableHeaders.role',
115
115
  value: 'roleTemplate.nameDisplay'
116
116
  },
117
- { ...AGE, value: 'createdTS' }
118
117
  ],
119
118
  loadingProjectBindings: true,
120
119
  loadingClusterBindings: true
@@ -185,7 +184,25 @@ export default {
185
184
  };
186
185
  });
187
186
 
188
- return [...fakeRows, ...this.filteredProjectRoleTemplateBindings];
187
+ // We need to group each of the TemplateRoleBindings by the user + project
188
+ const userRoles = [...fakeRows, ...this.filteredProjectRoleTemplateBindings].reduce((rows, curr) => {
189
+ const { userId, roleTemplate, projectId } = curr;
190
+
191
+ const userKey = userId + projectId;
192
+
193
+ if (!rows[userKey] && userId ) {
194
+ rows[userKey] = curr;
195
+ rows[userKey].allRoles = [];
196
+ }
197
+
198
+ if (roleTemplate && userId) {
199
+ rows[userKey].allRoles.push(curr.roleTemplate);
200
+ }
201
+
202
+ return rows;
203
+ }, {});
204
+
205
+ return Object.values(userRoles);
189
206
  },
190
207
  canManageMembers() {
191
208
  return canViewClusterPermissionsEditor(this.$store);
@@ -223,6 +240,26 @@ export default {
223
240
  modalSticky: true
224
241
  });
225
242
  },
243
+
244
+ getProjectRoleBinding(row, role) {
245
+ // Each row is a combination of user and project
246
+ // So find the specfic roleBindingTemplate corresponding to the specific role + project
247
+ return this.projectRoleTemplateBindings.find(r => r.roleTemplateId === role.id && r.userId === row.userId);
248
+ },
249
+
250
+ async removeRole(row, role, event) {
251
+ const resource = this.getProjectRoleBinding(row, role);
252
+
253
+ await resource.promptRemove();
254
+ },
255
+
256
+ viewRoleInAPI(row, role) {
257
+ const resource = this.getProjectRoleBinding(row, role);
258
+
259
+ if (resource?.canViewInApi) {
260
+ resource.viewInApi();
261
+ }
262
+ },
226
263
  slotName(project) {
227
264
  return `main-row:${ project.id }`;
228
265
  },
@@ -249,7 +286,7 @@ export default {
249
286
  <Tabbed>
250
287
  <Tab
251
288
  name="cluster-membership"
252
- label="Cluster Membership"
289
+ :label="t('members.clusterMemebership')"
253
290
  >
254
291
  <div
255
292
  v-if="canEditClusterMembers"
@@ -266,7 +303,8 @@ export default {
266
303
  :schema="schema"
267
304
  :headers="headers"
268
305
  :rows="filteredClusterRoleTemplateBindings"
269
- :groupable="false"
306
+ :groupable="true"
307
+ :show-grouping="true"
270
308
  :namespaced="false"
271
309
  :loading="$fetchState.pending || !currentCluster || loadingClusterBindings"
272
310
  sub-search="subSearch"
@@ -276,13 +314,15 @@ export default {
276
314
  <Tab
277
315
  v-if="canManageProjectMembers"
278
316
  name="project-membership"
279
- label="Project Membership"
317
+ :label="t('members.projectMembership')"
280
318
  >
281
319
  <SortableTable
282
320
  group-by="projectId"
283
321
  :loading="$fetchState.pending || !currentCluster || loadingProjectBindings"
284
322
  :rows="rowsWithFakeProjects"
285
323
  :headers="projectRoleTemplateColumns"
324
+ :table-actions="false"
325
+ :row-actions="false"
286
326
  >
287
327
  <template #group-by="group">
288
328
  <div class="group-bar">
@@ -291,8 +331,8 @@ export default {
291
331
  class="group-tab"
292
332
  >
293
333
  <div
334
+ v-clean-html="getProjectLabel(group)"
294
335
  class="project-name"
295
- v-html="getProjectLabel(group)"
296
336
  />
297
337
  </div>
298
338
  <div class="right">
@@ -307,6 +347,31 @@ export default {
307
347
  </div>
308
348
  </div>
309
349
  </template>
350
+ <template
351
+ #cell:role="{row}"
352
+ >
353
+ <span
354
+ v-for="(role, j) in row.allRoles"
355
+ :key="j"
356
+
357
+ ref="value"
358
+ :data-testid="`role-value-${j}`"
359
+ class="role"
360
+ >
361
+ <span
362
+ class="role-value"
363
+ :class="{'text-link-enabled' : row.canViewInApi}"
364
+ @click="viewRoleInAPI(row, role)"
365
+ >
366
+ {{ role.nameDisplay }}
367
+ </span>
368
+ <i
369
+ class="icon icon-close"
370
+ :data-testid="`role-values-close-${j}`"
371
+ @click="removeRole(row, role, $event)"
372
+ />
373
+ </span>
374
+ </template>
310
375
  <template
311
376
  v-for="project in projectsWithoutRoles"
312
377
  v-slot:[slotName(project)]
@@ -330,6 +395,36 @@ export default {
330
395
  </template>
331
396
 
332
397
  <style lang='scss' scoped>
398
+
399
+ .role {
400
+ align-items: center;
401
+ background-color: rgba(0, 0, 0, 0.05);
402
+ border: 1px solid var(--header-border);
403
+ border-radius: 5px;
404
+ color: var(--tag-text);
405
+ line-height: 20px;
406
+ padding: 2px 5px;
407
+ white-space: nowrap;
408
+ display: inline-flex;
409
+ margin-right: 3px;
410
+ }
411
+
412
+ .role-value {
413
+ &.text-link-enabled {
414
+ cursor: pointer;
415
+ &:hover {
416
+ color: var(--primary);
417
+ }
418
+ }
419
+ + .icon-close {
420
+ margin-left: 3px;
421
+ cursor: pointer;
422
+ &:hover {
423
+ color: var(--primary);
424
+ }
425
+ }
426
+ }
427
+
333
428
  .project-members {
334
429
  & ::v-deep .group-bar{
335
430
  display: flex;