@rancher/shell 0.3.0 → 0.3.2

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 (342) hide show
  1. package/assets/styles/global/_button.scss +5 -1
  2. package/assets/styles/global/_columns.scss +4 -0
  3. package/assets/styles/global/_gauges.scss +1 -1
  4. package/assets/styles/global/_layout.scss +5 -2
  5. package/assets/styles/global/_select.scss +1 -4
  6. package/assets/styles/themes/_dark.scss +5 -4
  7. package/assets/styles/themes/_light.scss +4 -3
  8. package/assets/styles/themes/_suse.scss +1 -1
  9. package/assets/styles/vendor/vue-select.scss +4 -3
  10. package/assets/translations/en-us.yaml +673 -73
  11. package/assets/translations/zh-hans.yaml +720 -207
  12. package/chart/monitoring/steps/uninstall-v1.vue +2 -2
  13. package/cloud-credential/azure.vue +23 -0
  14. package/cloud-credential/harvester.vue +25 -62
  15. package/cloud-credential/pnap.vue +80 -0
  16. package/components/.DS_Store +0 -0
  17. package/components/ActionMenu.vue +28 -7
  18. package/components/AdvancedSection.vue +9 -2
  19. package/components/Alert.vue +2 -2
  20. package/components/ButtonDropdown.vue +0 -2
  21. package/components/ButtonGroup.vue +1 -0
  22. package/components/CollapsibleCard.vue +0 -1
  23. package/components/CruResource.vue +41 -4
  24. package/components/DetailTop.vue +72 -4
  25. package/components/DisableAuthProviderModal.vue +106 -0
  26. package/{rancher-components/components/Utils/DraggableZone → components}/DraggableZone.vue +0 -0
  27. package/components/ExplorerMembers.vue +253 -30
  28. package/components/ExplorerProjectsNamespaces.vue +77 -33
  29. package/components/ExtensionPanel.vue +42 -0
  30. package/components/GrowlManager.vue +3 -3
  31. package/components/IconOrSvg.vue +178 -0
  32. package/components/LogItem.vue +69 -0
  33. package/components/PodSecurityAdmission.vue +302 -0
  34. package/components/PromptModal.vue +1 -0
  35. package/components/ResourceDetail/Masthead.vue +69 -4
  36. package/components/ResourceDetail/index.vue +12 -5
  37. package/components/ResourceList/Masthead.vue +11 -1
  38. package/components/ResourceList/ResourceLoadingIndicator.vue +12 -2
  39. package/components/ResourceList/index.vue +66 -12
  40. package/components/ResourceList/resource-list.config.js +7 -0
  41. package/components/ResourceTable.vue +33 -6
  42. package/components/SimpleBox.vue +1 -1
  43. package/components/SortableTable/THead.vue +21 -14
  44. package/components/SortableTable/filtering.js +1 -1
  45. package/components/SortableTable/index.vue +21 -10
  46. package/components/SortableTable/selection.js +15 -3
  47. package/components/Tabbed/Tab.vue +1 -1
  48. package/components/Tabbed/index.vue +20 -15
  49. package/components/__tests__/.DS_Store +0 -0
  50. package/components/__tests__/AsyncButton.test.ts +140 -0
  51. package/components/__tests__/BackLink.test.ts +33 -0
  52. package/components/__tests__/ButtonGroup.test.ts +124 -0
  53. package/components/__tests__/ClusterBadge.test.ts +32 -0
  54. package/components/__tests__/CollapsibleCard.test.ts +64 -0
  55. package/components/__tests__/ConsumptionGauge.test.ts +88 -0
  56. package/components/__tests__/CruResource.test.ts +3 -2
  57. package/components/__tests__/FixedBanner.test.ts +129 -0
  58. package/components/__tests__/GrowlManager.test.ts +147 -0
  59. package/components/__tests__/NamespaceFilter.test.ts +33 -25
  60. package/components/__tests__/PercentageBar.test.ts +32 -0
  61. package/components/__tests__/PodSecurityAdmission.test.ts +398 -0
  62. package/components/auth/AuthBanner.vue +20 -10
  63. package/components/auth/RoleDetailEdit.vue +26 -17
  64. package/components/auth/SelectPrincipal.vue +36 -5
  65. package/components/form/ArrayList.vue +3 -35
  66. package/components/form/ArrayListGrouped.vue +13 -4
  67. package/components/form/ArrayListSelect.vue +5 -5
  68. package/components/form/Error.vue +8 -0
  69. package/components/form/KeyValue.vue +39 -7
  70. package/components/form/LabeledSelect.vue +5 -2
  71. package/components/form/Labels.vue +46 -16
  72. package/components/form/Members/ClusterPermissionsEditor.vue +17 -17
  73. package/components/form/Members/MembershipEditor.vue +12 -12
  74. package/components/form/NameNsDescription.vue +1 -1
  75. package/components/form/NodeScheduling.vue +1 -1
  76. package/components/form/Probe.vue +3 -3
  77. package/components/form/ResourceQuota/Project.vue +6 -6
  78. package/components/form/ResourceTabs/index.vue +24 -6
  79. package/components/form/Security.vue +7 -6
  80. package/components/form/Select.vue +3 -2
  81. package/components/form/SelectOrCreateAuthSecret.vue +22 -29
  82. package/components/form/ServicePorts.vue +8 -0
  83. package/components/form/WorkloadPorts.vue +7 -1
  84. package/components/form/__tests__/ArrayList.test.ts +74 -0
  85. package/components/form/__tests__/ArrayListGrouped.test.ts +6 -4
  86. package/components/formatter/Checked.vue +1 -1
  87. package/components/formatter/ClusterLink.vue +5 -0
  88. package/components/formatter/IconIsDefault.vue +2 -2
  89. package/components/formatter/InternalExternalIP.vue +11 -8
  90. package/components/formatter/LiveDuration.vue +78 -0
  91. package/components/formatter/WorkloadHealthScale.vue +5 -3
  92. package/components/nav/Header.vue +74 -7
  93. package/components/nav/NamespaceFilter.vue +146 -63
  94. package/components/nav/TopLevelMenu.vue +22 -19
  95. package/components/nav/WindowManager/ContainerLogs.vue +83 -126
  96. package/components/nav/WindowManager/ContainerShell.vue +9 -7
  97. package/components/nav/WindowManager/Window.vue +2 -0
  98. package/components/nav/WindowManager/index.vue +10 -0
  99. package/config/elemental-types.js +9 -0
  100. package/config/features.js +2 -0
  101. package/config/home-links.js +4 -1
  102. package/config/pod-security-admission.ts +82 -0
  103. package/config/product/apps.js +1 -1
  104. package/config/product/auth.js +6 -5
  105. package/config/product/backup.js +1 -1
  106. package/config/product/explorer.js +6 -6
  107. package/config/product/fleet.js +1 -1
  108. package/config/product/manager.js +6 -2
  109. package/config/query-params.js +1 -0
  110. package/config/secret.js +0 -1
  111. package/config/settings.ts +26 -9
  112. package/config/table-headers.js +22 -11
  113. package/config/types.js +4 -1
  114. package/config/uiplugins.js +3 -3
  115. package/content/docs/zh-hans/getting-started.md +113 -137
  116. package/content/docs/zh-hans/whats-new.md +8 -46
  117. package/core/plugin-helpers.js +171 -0
  118. package/core/plugin.ts +61 -1
  119. package/core/plugins.js +33 -0
  120. package/core/types.ts +128 -2
  121. package/creators/pkg/package-lock.json +37 -0
  122. package/creators/pkg/package.json +1 -1
  123. package/detail/catalog.cattle.io.app.vue +1 -1
  124. package/detail/pod.vue +1 -1
  125. package/detail/provisioning.cattle.io.cluster.vue +35 -9
  126. package/detail/service.vue +2 -9
  127. package/detail/workload/index.vue +0 -1
  128. package/dialog/AddClusterMemberDialog.vue +22 -28
  129. package/dialog/AddProjectMemberDialog.vue +53 -9
  130. package/dialog/DiagnosticTimingsDialog.vue +8 -7
  131. package/dialog/DrainNode.vue +44 -48
  132. package/dialog/ForceMachineRemoveDialog.vue +5 -7
  133. package/dialog/GenericPrompt.vue +15 -20
  134. package/dialog/RollbackWorkloadDialog.vue +15 -46
  135. package/dialog/RotateCertificatesDialog.vue +5 -7
  136. package/dialog/RotateEncryptionKeyDialog.vue +5 -9
  137. package/dialog/SaveAsRKETemplateDialog.vue +5 -13
  138. package/dialog/ScaleMachineDownDialog.vue +1 -1
  139. package/dialog/ScalePoolDownDialog.vue +121 -0
  140. package/edit/__tests__/management.cattle.io.setting.test.ts +3 -3
  141. package/edit/auth/azuread.vue +16 -16
  142. package/edit/auth/github.vue +8 -0
  143. package/edit/auth/googleoauth.vue +10 -1
  144. package/edit/auth/ldap/index.vue +10 -0
  145. package/edit/auth/oidc.vue +10 -0
  146. package/edit/auth/saml.vue +10 -0
  147. package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -1
  148. package/edit/catalog.cattle.io.clusterrepo.vue +3 -0
  149. package/edit/cloudcredential.vue +3 -7
  150. package/edit/logging-flow/Match.vue +39 -8
  151. package/edit/logging-flow/index.vue +27 -4
  152. package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +107 -0
  153. package/edit/management.cattle.io.project.vue +8 -1
  154. package/edit/management.cattle.io.setting.vue +5 -2
  155. package/edit/management.cattle.io.user.vue +7 -1
  156. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +36 -8
  157. package/edit/monitoring.coreos.com.alertmanagerconfig/types/email.vue +2 -2
  158. package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +14 -6
  159. package/edit/namespace.vue +18 -4
  160. package/edit/networking.k8s.io.ingress/Certificate.vue +1 -0
  161. package/edit/networking.k8s.io.ingress/IngressClass.vue +8 -6
  162. package/edit/networking.k8s.io.ingress/RulePath.vue +12 -6
  163. package/edit/networking.k8s.io.ingress/index.vue +8 -6
  164. package/edit/persistentvolume/index.vue +30 -27
  165. package/edit/persistentvolume/plugins/cephfs.vue +29 -29
  166. package/edit/persistentvolume/plugins/csi.vue +102 -62
  167. package/edit/persistentvolume/plugins/fc.vue +19 -19
  168. package/edit/persistentvolume/plugins/iscsi.vue +45 -45
  169. package/edit/persistentvolume/plugins/rbd.vue +39 -39
  170. package/edit/persistentvolumeclaim.vue +78 -75
  171. package/edit/provisioning.cattle.io.cluster/MachinePool.vue +11 -7
  172. package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +10 -1
  173. package/edit/provisioning.cattle.io.cluster/RegistryMirrors.vue +87 -27
  174. package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +3 -6
  175. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +96 -0
  176. package/edit/provisioning.cattle.io.cluster/import.vue +1 -1
  177. package/edit/provisioning.cattle.io.cluster/index.vue +29 -6
  178. package/edit/provisioning.cattle.io.cluster/rke2.vue +445 -154
  179. package/edit/secret/index.vue +3 -7
  180. package/edit/service.vue +3 -1
  181. package/edit/storage.k8s.io.storageclass/index.vue +100 -16
  182. package/edit/storage.k8s.io.storageclass/provisioners/driver.harvesterhci.io.vue +114 -0
  183. package/edit/workload/__tests__/index.test.ts +98 -0
  184. package/edit/workload/index.vue +58 -8
  185. package/edit/workload/mixins/workload.js +107 -70
  186. package/edit/workload/storage/ContainerMountPaths.vue +0 -10
  187. package/edit/workload/storage/emptyDir.vue +88 -0
  188. package/edit/workload/storage/ephemeralVolume/index.vue +1 -1
  189. package/edit/workload/storage/index.vue +8 -0
  190. package/edit/workload/storage/persistentVolumeClaim/index.vue +1 -1
  191. package/layouts/default.vue +57 -44
  192. package/list/__tests__/workload.test.ts +5 -2
  193. package/list/catalog.cattle.io.app.vue +1 -0
  194. package/list/cis.cattle.io.clusterscan.vue +1 -0
  195. package/list/fleet.cattle.io.bundle.vue +5 -6
  196. package/list/fleet.cattle.io.cluster.vue +6 -3
  197. package/list/fleet.cattle.io.clusterregistrationtoken.vue +5 -6
  198. package/list/fleet.cattle.io.gitrepo.vue +4 -9
  199. package/list/helm.cattle.io.projecthelmchart.vue +1 -5
  200. package/list/logging.banzaicloud.io.clusterflow.vue +4 -1
  201. package/list/logging.banzaicloud.io.flow.vue +6 -5
  202. package/list/management.cattle.io.cluster.vue +1 -0
  203. package/list/management.cattle.io.feature.vue +3 -4
  204. package/list/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +47 -0
  205. package/list/management.cattle.io.setting.vue +2 -2
  206. package/list/management.cattle.io.user.vue +4 -10
  207. package/list/monitoring.coreos.com.alertmanagerconfig.vue +2 -7
  208. package/list/node.vue +8 -5
  209. package/list/persistentvolume.vue +3 -3
  210. package/list/persistentvolumeclaim.vue +3 -4
  211. package/list/provisioning.cattle.io.cluster.vue +18 -19
  212. package/list/service.vue +6 -14
  213. package/list/workload.vue +43 -38
  214. package/machine-config/azure.vue +429 -60
  215. package/machine-config/pnap.vue +288 -0
  216. package/mixins/auth-config.js +1 -3
  217. package/mixins/browser-tab-visibility.js +8 -14
  218. package/mixins/chart.js +1 -1
  219. package/mixins/create-edit-view/impl.js +4 -0
  220. package/mixins/create-edit-view/index.js +4 -2
  221. package/mixins/resource-fetch-namespaced.js +98 -0
  222. package/mixins/resource-fetch.js +79 -45
  223. package/mixins/resource-manager.js +1 -23
  224. package/models/apps.controllerrevision.js +7 -0
  225. package/models/apps.daemonset.js +18 -0
  226. package/models/apps.deployment.js +44 -0
  227. package/models/apps.replicaset.js +7 -0
  228. package/models/apps.statefulset.js +18 -0
  229. package/models/batch.job.js +7 -14
  230. package/models/cluster/node.js +10 -2
  231. package/models/cluster.x-k8s.io.machine.js +26 -4
  232. package/models/cluster.x-k8s.io.machinedeployment.js +12 -2
  233. package/models/event.js +7 -0
  234. package/models/logging.banzaicloud.io.flow.js +4 -0
  235. package/models/management.cattle.io.cluster.js +1 -1
  236. package/models/management.cattle.io.clusterroletemplatebinding.js +1 -1
  237. package/models/management.cattle.io.globalrole.js +2 -2
  238. package/models/management.cattle.io.node.js +37 -2
  239. package/models/management.cattle.io.podsecurityadmissionconfigurationtemplate.ts +4 -0
  240. package/models/management.cattle.io.project.js +30 -11
  241. package/models/management.cattle.io.setting.js +1 -1
  242. package/models/management.cattle.io.user.js +37 -1
  243. package/models/namespace.js +42 -5
  244. package/models/persistentvolume.js +14 -2
  245. package/models/pod.js +15 -0
  246. package/models/projectroletemplatebinding.js +7 -0
  247. package/models/provisioning.cattle.io.cluster.js +61 -10
  248. package/models/rke-machine.cattle.io.pnapmachinetemplate.js +15 -0
  249. package/models/service.js +14 -13
  250. package/models/storage.k8s.io.storageclass.js +33 -18
  251. package/models/workload.js +38 -7
  252. package/nuxt.config.js +27 -17
  253. package/package.json +7 -7
  254. package/pages/about.vue +14 -2
  255. package/pages/c/_cluster/apps/charts/index.vue +21 -3
  256. package/pages/c/_cluster/apps/charts/install.vue +59 -22
  257. package/pages/c/_cluster/auth/config/_id.vue +6 -0
  258. package/pages/c/_cluster/auth/config/index.vue +8 -6
  259. package/pages/c/_cluster/auth/group.principal/assign-edit.vue +1 -1
  260. package/pages/c/_cluster/auth/roles/index.vue +1 -1
  261. package/pages/c/_cluster/explorer/index.vue +51 -6
  262. package/pages/c/_cluster/longhorn/index.vue +1 -1
  263. package/pages/c/_cluster/monitoring/alertmanagerconfig/_alertmanagerconfigid/receiver.vue +15 -4
  264. package/pages/c/_cluster/monitoring/index.vue +1 -1
  265. package/pages/c/_cluster/neuvector/index.vue +1 -1
  266. package/pages/c/_cluster/settings/performance.vue +48 -2
  267. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +2 -0
  268. package/pages/c/_cluster/uiplugins/InstallDialog.vue +3 -0
  269. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +42 -2
  270. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +2 -0
  271. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +1 -0
  272. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +2 -0
  273. package/pages/c/_cluster/uiplugins/index.vue +42 -3
  274. package/pages/diagnostic.vue +5 -4
  275. package/pages/home.vue +105 -30
  276. package/pages/prefs.vue +23 -12
  277. package/pages/rio/mesh.vue +1 -1
  278. package/pkg/dynamic-importer.lib.js +8 -0
  279. package/pkg/vue.config.js +4 -0
  280. package/plugins/dashboard-store/__tests__/mutations.spec.js +406 -0
  281. package/plugins/dashboard-store/actions.js +32 -25
  282. package/plugins/dashboard-store/getters.js +50 -33
  283. package/plugins/dashboard-store/mutations.js +134 -28
  284. package/plugins/dashboard-store/resource-class.js +37 -42
  285. package/plugins/steve/actions.js +30 -0
  286. package/plugins/steve/caches/resourceCache.js +60 -0
  287. package/plugins/steve/getters.js +44 -1
  288. package/plugins/steve/mutations.js +97 -36
  289. package/plugins/steve/resourceWatcher.js +277 -0
  290. package/plugins/steve/schema.utils.js +25 -0
  291. package/plugins/steve/subscribe.js +288 -115
  292. package/plugins/steve/worker/index.js +17 -0
  293. package/plugins/steve/worker/web-worker.advanced.js +302 -0
  294. package/plugins/steve/{web-worker.steve-sub-worker.js → worker/web-worker.basic.js} +3 -44
  295. package/rancher-components/Card/Card.vue +3 -3
  296. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +1 -0
  297. package/rancher-components/StringList/StringList.test.ts +45 -420
  298. package/rancher-components/StringList/StringList.vue +1 -10
  299. package/rancher-components/components/Banner/Banner.test.ts +44 -0
  300. package/rancher-components/components/Banner/Banner.vue +130 -61
  301. package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +13 -22
  302. package/rancher-components/components/Form/Checkbox/Checkbox.vue +8 -6
  303. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +9 -9
  304. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +0 -1
  305. package/rancher-components/components/StringList/StringList.test.ts +7 -7
  306. package/rancher-components/components/StringList/StringList.vue +21 -15
  307. package/scripts/test-plugins-build.sh +8 -0
  308. package/static/loading-indicator.html +1 -1
  309. package/store/action-menu.js +4 -3
  310. package/store/index.js +54 -3
  311. package/store/plugins.js +0 -17
  312. package/store/pnap.js +128 -0
  313. package/store/prefs.js +4 -2
  314. package/store/type-map.js +81 -13
  315. package/types/pod-security-admission.ts +36 -0
  316. package/types/shell/index.d.ts +497 -396
  317. package/utils/__tests__/object.test.ts +17 -1
  318. package/utils/__tests__/pod-security-admission.test.ts +61 -0
  319. package/utils/async.ts +36 -0
  320. package/utils/color.js +45 -0
  321. package/utils/crypto/browserHashUtils.js +18 -0
  322. package/utils/dynamic-importer.js +8 -0
  323. package/utils/install-redirect.js +1 -1
  324. package/utils/object.js +24 -0
  325. package/utils/pod-security-admission.ts +39 -0
  326. package/utils/socket.js +61 -24
  327. package/utils/string.js +2 -0
  328. package/utils/svg-filter.js +301 -0
  329. package/utils/time.js +49 -0
  330. package/utils/validators/cidr.js +4 -0
  331. package/utils/validators/formRules/__tests__/index.test.ts +23 -3
  332. package/utils/validators/formRules/index.ts +14 -0
  333. package/config/product/harvester-manager.js +0 -162
  334. package/edit/harvesterhci.io.management.cluster.vue +0 -153
  335. package/list/harvesterhci.io.management.cluster.vue +0 -241
  336. package/machine-config/harvester.vue +0 -693
  337. package/models/harvesterhci.io.management.cluster.js +0 -228
  338. package/pages/c/_cluster/harvesterManager/index.vue +0 -24
  339. package/rancher-components/Card/Card.test.ts +0 -39
  340. package/rancher-components/Utils/DraggableZone/DraggableZone.vue +0 -181
  341. package/rancher-components/Utils/DraggableZone/index.ts +0 -1
  342. package/rancher-components/components/Utils/DraggableZone/index.ts +0 -1
@@ -0,0 +1,178 @@
1
+ <script>
2
+
3
+ /**
4
+ * This component renders the icon in the top level menu.
5
+ * Icon can either be via a font via the 'icon' property or an svg via the 'src' property
6
+ *
7
+ * The trickiness here is that we want the icon to be the correct color - both normally and when hovered
8
+ * For a font icon, this is easy, since we just set the color css property
9
+ * For an svg icon included with the <img> tag this is harder - there is no way to apply css to
10
+ * the svg brought in this way - the workaround is to apply a css filter - in order to do this we
11
+ * need to generate the css filter for the required color - the code for that is in the 'svg-filter' utility
12
+ *
13
+ * We cache filters and css for given colors, so we only generate them once.
14
+ *
15
+ * This makes the code here look complex - but we are essentially generating the css filters
16
+ * and then injecting custom css into the document so that any icons included via svg will
17
+ * show with the desired colors for the theme.
18
+ */
19
+ import Vue from 'vue';
20
+ import { Solver } from '@shell/utils/svg-filter';
21
+ import { colorToRgb, mapStandardColors } from '@shell/utils/color';
22
+
23
+ const filterCache = {};
24
+ const cssCache = {};
25
+
26
+ const colors = {
27
+ header: {
28
+ color: '--header-btn-text',
29
+ hover: '--header-btn-text-hover'
30
+ },
31
+ primary: {
32
+ color: '--link',
33
+ hover: '--primary-hover-text'
34
+ }
35
+ };
36
+
37
+ export default {
38
+ name: 'IconOrSvg',
39
+ props: {
40
+ src: {
41
+ type: String,
42
+ default: () => undefined,
43
+ },
44
+ icon: {
45
+ type: String,
46
+ default: () => undefined,
47
+ },
48
+ color: {
49
+ type: String,
50
+ default: () => 'primary',
51
+ }
52
+ },
53
+
54
+ data() {
55
+ return { className: '' };
56
+ },
57
+
58
+ created() {
59
+ if (this.src) {
60
+ this.setColor();
61
+ }
62
+ },
63
+
64
+ methods: {
65
+ setColor() {
66
+ const currTheme = this.$store.getters['prefs/theme'];
67
+ let uiColor, hoverColor;
68
+
69
+ // grab css vars values based on the actual stylesheets, depending on the theme applied
70
+ // use for loops to minimize computation
71
+ for (let i = 0; i < Object.keys(document.styleSheets).length; i++) {
72
+ let found = false;
73
+ const stylesheet = document.styleSheets[i];
74
+
75
+ if (stylesheet && stylesheet.cssRules) {
76
+ for (let x = 0; x < Object.keys(stylesheet.cssRules).length; x++) {
77
+ const cssRules = stylesheet.cssRules[x];
78
+ const selectorText = currTheme === 'light' ? 'body, .theme-light' : '.theme-dark';
79
+
80
+ if (cssRules.selectorText && cssRules.selectorText === selectorText) {
81
+ uiColor = mapStandardColors(cssRules.style.getPropertyValue(colors[this.color].color).trim());
82
+ hoverColor = mapStandardColors(cssRules.style.getPropertyValue(colors[this.color].hover).trim());
83
+ found = true;
84
+ break;
85
+ }
86
+ }
87
+ }
88
+ if (found) {
89
+ break;
90
+ } else {
91
+ continue;
92
+ }
93
+ }
94
+
95
+ const uiColorRGB = colorToRgb(uiColor);
96
+ const hoverColorRGB = colorToRgb(hoverColor);
97
+ const uiColorStr = `${ uiColorRGB.r }-${ uiColorRGB.g }-${ uiColorRGB.b }`;
98
+ const hoverColorStr = `${ hoverColorRGB.r }-${ hoverColorRGB.g }-${ hoverColorRGB.b }`;
99
+
100
+ const className = `svg-icon-${ uiColorStr }-${ hoverColorStr }`;
101
+
102
+ if (!cssCache[className]) {
103
+ let hoverFilter = filterCache[hoverColor];
104
+
105
+ if (!hoverFilter) {
106
+ const solver = new Solver(hoverColorRGB);
107
+ const res = solver.solve();
108
+
109
+ hoverFilter = res?.filter;
110
+ filterCache[hoverColor] = hoverFilter;
111
+ }
112
+
113
+ let mainFilter = filterCache[uiColor];
114
+
115
+ if (!mainFilter) {
116
+ const solver = new Solver(uiColorRGB);
117
+ const res = solver.solve();
118
+
119
+ mainFilter = res?.filter;
120
+ filterCache[uiColor] = mainFilter;
121
+ }
122
+
123
+ // Add stylesheet (added as global styles)
124
+ const styles = `
125
+ img.${ className } {
126
+ ${ mainFilter };
127
+ }
128
+ img.${ className }:hover {
129
+ ${ hoverFilter };
130
+ }
131
+ button:hover > img.${ className } {
132
+ ${ hoverFilter };
133
+ }
134
+ li:hover > img.${ className } {
135
+ ${ hoverFilter };
136
+ }
137
+ a.option:hover > img.${ className } {
138
+ ${ hoverFilter };
139
+ } `;
140
+
141
+ const styleSheet = document.createElement('style');
142
+
143
+ styleSheet.innerText = styles;
144
+ document.head.appendChild(styleSheet);
145
+
146
+ cssCache[className] = true;
147
+ }
148
+
149
+ Vue.set(this, 'className', className);
150
+ }
151
+ }
152
+ };
153
+ </script>
154
+
155
+ <template>
156
+ <img
157
+ v-if="src"
158
+ :src="src"
159
+ class="svg-icon"
160
+ :class="className"
161
+ >
162
+ <i
163
+ v-else-if="icon"
164
+ class="icon group-icon"
165
+ :class="icon"
166
+ />
167
+ <i
168
+ v-else
169
+ class="icon icon-extension"
170
+ />
171
+ </template>
172
+
173
+ <style lang="scss" scoped>
174
+ .svg-icon {
175
+ height: 24px;
176
+ width: 24px;
177
+ }
178
+ </style>
@@ -0,0 +1,69 @@
1
+ <script>
2
+ import day from 'dayjs';
3
+ import { DATE_FORMAT, TIME_FORMAT } from '@shell/store/prefs';
4
+ import { escapeHtml } from '@shell/utils/string';
5
+
6
+ export default {
7
+ props: {
8
+ source: {
9
+ type: Object,
10
+ default: () => {}
11
+ }
12
+ },
13
+
14
+ computed: {
15
+ timeFormatStr() {
16
+ const dateFormat = escapeHtml( this.$store.getters['prefs/get'](DATE_FORMAT));
17
+ const timeFormat = escapeHtml( this.$store.getters['prefs/get'](TIME_FORMAT));
18
+
19
+ return `${ dateFormat } ${ timeFormat }`;
20
+ },
21
+ },
22
+
23
+ methods: {
24
+ format(time) {
25
+ if ( !time ) {
26
+ return '';
27
+ }
28
+
29
+ return day(time).format(this.timeFormatStr);
30
+ }
31
+ }
32
+ };
33
+ </script>
34
+
35
+ <template>
36
+ <div class="line">
37
+ <span class="time">{{ format(source.time) }}</span>
38
+ <span
39
+ class="msg"
40
+ v-html="source.msg"
41
+ />
42
+ </div>
43
+ </template>
44
+
45
+ <style lang='scss' scoped>
46
+ .line {
47
+ font-family: Menlo,Consolas,monospace;
48
+ color: var(--logs-text);
49
+ display:flex;
50
+ }
51
+
52
+ .time {
53
+ white-space: nowrap;
54
+ display: none;
55
+ width: 0;
56
+ padding-right: 15px;
57
+ user-select: none;
58
+ }
59
+
60
+ .msg {
61
+ white-space: pre;
62
+
63
+ .highlight {
64
+ color: var(--logs-highlight);
65
+ background-color: var(--logs-highlight-bg);
66
+ }
67
+ }
68
+
69
+ </style>
@@ -0,0 +1,302 @@
1
+ <script lang="ts">
2
+ import Vue from 'vue';
3
+ import { _VIEW, _CREATE } from '@shell/config/query-params';
4
+ import LabeledSelect from '@shell/components/form/LabeledSelect.vue';
5
+ import Checkbox from '@components/Form/Checkbox/Checkbox.vue';
6
+ import LabeledInput from '@components/Form/LabeledInput/LabeledInput.vue';
7
+ import { PSADimension, PSAMode } from '@shell/types/pod-security-admission';
8
+ import {
9
+ PSADefaultLevel,
10
+ PSADefaultVersion, PSADimensions, PSALevels, PSAModes
11
+ } from '@shell/config/pod-security-admission';
12
+ import { pickBy, toDictionary } from '@shell/utils/object';
13
+
14
+ interface PSAControl { active: boolean, level: string, version: string }
15
+ const getPsaControl = (): PSAControl => ({
16
+ active: false,
17
+ level: PSADefaultLevel,
18
+ version: ''
19
+ });
20
+
21
+ // Type and function for exemptions form builder
22
+ interface PSAExemptionControl { active: boolean, value: string }
23
+ const getExemptionControl = (): PSAExemptionControl => ({
24
+ active: false,
25
+ value: ''
26
+ });
27
+
28
+ export default Vue.extend({
29
+ components: {
30
+ Checkbox, LabeledSelect, LabeledInput
31
+ },
32
+ props: {
33
+ /**
34
+ * List of labels used for the resource
35
+ * Note: PSA labels are always paired
36
+ */
37
+ labels: {
38
+ type: Object as () => Record<string, string>,
39
+ default: () => ({})
40
+ },
41
+
42
+ labelsAlwaysActive: {
43
+ type: Boolean,
44
+ default: false
45
+ },
46
+
47
+ /**
48
+ * Map editing capabilities to the component
49
+ */
50
+ mode: {
51
+ type: String,
52
+ required: true
53
+ },
54
+
55
+ /**
56
+ * List of exemptions used for the resource
57
+ */
58
+ exemptions: {
59
+ type: Object as () => Record<PSADimension, string[]>,
60
+ default: () => ({} as Record<PSADimension, string[]>)
61
+ },
62
+
63
+ /**
64
+ * Prefix used for setting labels
65
+ */
66
+ labelsPrefix: {
67
+ type: String,
68
+ default: ''
69
+ },
70
+
71
+ /**
72
+ * Inherited global identifier prefix for tests
73
+ * Define a term based on the parent component to avoid conflicts on multiple components
74
+ */
75
+ componentTestid: {
76
+ type: String,
77
+ default: 'pod-security-admission'
78
+ }
79
+ },
80
+
81
+ data() {
82
+ return {
83
+ // Generate PSA form controls
84
+ psaControls: toDictionary(PSAModes, getPsaControl) as Record<PSAMode, PSAControl>,
85
+ psaExemptionsControls: toDictionary(PSADimensions, getExemptionControl) as Record<PSADimension, PSAExemptionControl>,
86
+ options: PSALevels.map(level => ({
87
+ value: level,
88
+ label: this.t(`podSecurityAdmission.labels.${ level }`)
89
+ })),
90
+ };
91
+ },
92
+
93
+ watch: {},
94
+
95
+ computed: {
96
+ isView(): boolean {
97
+ return this.mode === _VIEW;
98
+ },
99
+
100
+ /**
101
+ * Enable exemption form if any
102
+ */
103
+ hasExemptions(): boolean {
104
+ return Object.keys(this.exemptions).length > 0;
105
+ },
106
+ },
107
+
108
+ created() {
109
+ // Assign values to the form, overriding existing values
110
+ this.psaControls = {
111
+ ...this.psaControls,
112
+ ...this.getPsaControls()
113
+ };
114
+
115
+ this.psaExemptionsControls = this.getPsaExemptions();
116
+
117
+ // Emit initial value on creation if labels always active, as default predefined values are required
118
+ if (this.mode === _CREATE && this.labelsAlwaysActive) {
119
+ this.updateLabels();
120
+ this.updateExemptions();
121
+ }
122
+ },
123
+
124
+ methods: {
125
+ /**
126
+ * Filter out existing PSA labels and emit existing labels with new PSA ones
127
+ */
128
+ updateLabels(): void {
129
+ const nonPSALabels = pickBy(this.labels, (_, key) => !key.includes(this.labelsPrefix));
130
+ const labels = PSAModes.reduce((acc, mode) => {
131
+ return this.psaControls[mode].active || this.labelsAlwaysActive ? {
132
+ ...acc,
133
+ // Set default level if none
134
+ [`${ this.labelsPrefix }${ mode }`]: this.psaControls[mode].level || PSADefaultLevel,
135
+ // Set default version if none
136
+ [`${ this.labelsPrefix }${ mode }-version`]: this.psaControls[mode].version || PSADefaultVersion
137
+ } : acc;
138
+ }, nonPSALabels);
139
+
140
+ this.$emit('updateLabels', labels);
141
+ },
142
+
143
+ /**
144
+ * Emit active exemptions in required format
145
+ */
146
+ updateExemptions(): void {
147
+ const exemptions = PSADimensions.reduce((acc, dimension) => {
148
+ const value = this.psaExemptionsControls[dimension].value.split(',').map(value => value.trim());
149
+ const active = this.psaExemptionsControls[dimension].active;
150
+
151
+ return {
152
+ ...acc,
153
+ [dimension]: active && value ? value : []
154
+ };
155
+ }, {});
156
+
157
+ this.$emit('updateExemptions', exemptions);
158
+ },
159
+
160
+ /**
161
+ * Generate form controls based on PSA labels in the provided dictionary
162
+ */
163
+ getPsaControls(): Record<PSAMode, PSAControl> {
164
+ return PSAModes.reduce((acc, mode) => {
165
+ const level = this.labels[`${ this.labelsPrefix }${ mode }`];
166
+ // Retrieve version, hiding the value 'latest' from the user
167
+ const version = (this.labels[`${ this.labelsPrefix }${ mode }-version`] || '').replace(PSADefaultVersion, '');
168
+
169
+ return level ? {
170
+ ...acc,
171
+ [mode]: {
172
+ active: true,
173
+ level,
174
+ version
175
+ }
176
+ } : acc;
177
+ }, {} as Record<PSAMode, PSAControl>);
178
+ },
179
+
180
+ /**
181
+ * Generate form exemptions based on PSA exemptions provided dictionary
182
+ */
183
+ getPsaExemptions(): Record<PSADimension, PSAExemptionControl> {
184
+ return PSADimensions.reduce((acc, dimension) => {
185
+ const values = (this.exemptions[dimension] || []).map(value => value.trim()).join(',');
186
+
187
+ return {
188
+ ...acc,
189
+ [dimension]: {
190
+ active: !!values.length,
191
+ value: values
192
+ }
193
+ };
194
+ }, {}) as Record<PSADimension, PSAExemptionControl>;
195
+ },
196
+
197
+ /**
198
+ * Add checks on input for PSA controls to be active or not, allowing white cases
199
+ */
200
+ isPsaControlDisabled(active: boolean): boolean {
201
+ return !this.labelsAlwaysActive && (!active || this.isView);
202
+ }
203
+ }
204
+ });
205
+ </script>
206
+
207
+ <template>
208
+ <div class="psa">
209
+ <!-- PSA -->
210
+ <p class="mb-30">
211
+ <t k="podSecurityAdmission.description" />
212
+ </p>
213
+
214
+ <div
215
+ v-for="(psaControl, level, i) in psaControls"
216
+ :key="'psaControl-' + i"
217
+ class="row row--y-center mb-20"
218
+ >
219
+ <span class="col span-2">
220
+ <Checkbox
221
+ v-if="!labelsAlwaysActive"
222
+ v-model="psaControl.active"
223
+ :data-testid="componentTestid + '--psaControl-' + i + '-active'"
224
+ :label="level"
225
+ :label-key="`podSecurityAdmission.labels.${ level }`"
226
+ :disabled="isView"
227
+ @input="updateLabels()"
228
+ />
229
+ <p v-else>
230
+ <t :k="`podSecurityAdmission.labels.${level}`" />
231
+ </p>
232
+ </span>
233
+
234
+ <span
235
+ class="
236
+ col
237
+ span-4"
238
+ >
239
+ <LabeledSelect
240
+ v-model="psaControl.level"
241
+ :data-testid="componentTestid + '--psaControl-' + i + '-level'"
242
+ :disabled="isPsaControlDisabled(psaControl.active)"
243
+ :options="options"
244
+ :mode="mode"
245
+ @input="updateLabels()"
246
+ />
247
+ </span>
248
+
249
+ <span class="col span-4">
250
+ <LabeledInput
251
+ v-model="psaControl.version"
252
+ :data-testid="componentTestid + '--psaControl-' + i + '-version'"
253
+ :disabled="isPsaControlDisabled(psaControl.active)"
254
+ :options="options"
255
+ :placeholder="t('podSecurityAdmission.version.placeholder', { psaControl: mode })"
256
+ :mode="mode"
257
+ @input="updateLabels()"
258
+ />
259
+ </span>
260
+ </div>
261
+
262
+ <!-- Exemptions -->
263
+ <template v-if="hasExemptions">
264
+ <slot name="title">
265
+ <h3>
266
+ <t k="podSecurityAdmission.exemptions.title" />
267
+ </h3>
268
+ </slot>
269
+ <p class="mb-30">
270
+ <t k="podSecurityAdmission.exemptions.description" />
271
+ </p>
272
+
273
+ <div
274
+ v-for="(psaExemptionsControl, dimension, i) in psaExemptionsControls"
275
+ :key="'psaExemptionsControl-' + i"
276
+ class="row row--y-center mb-20"
277
+ >
278
+ <span class="col span-2">
279
+ <Checkbox
280
+ v-model="psaExemptionsControl.active"
281
+ :data-testid="componentTestid + '--psaExemptionsControl-' + i + '-active'"
282
+ :label="dimension"
283
+ :label-key="`podSecurityAdmission.labels.${ dimension }`"
284
+ :disabled="isView"
285
+ @input="updateExemptions()"
286
+ />
287
+ </span>
288
+ <span class="col span-8">
289
+ <LabeledInput
290
+ v-model="psaExemptionsControl.value"
291
+ :data-testid="componentTestid + '--psaExemptionsControl-' + i + '-value'"
292
+ :disabled="(isView || !psaExemptionsControl.active)"
293
+ :options="options"
294
+ :placeholder="t('podSecurityAdmission.exemptions.placeholder', { psaExemptionsControl: dimension })"
295
+ :mode="mode"
296
+ @input="updateExemptions()"
297
+ />
298
+ </span>
299
+ </div>
300
+ </template>
301
+ </div>
302
+ </template>
@@ -88,6 +88,7 @@ export default {
88
88
  @closed="close()"
89
89
  >
90
90
  <component
91
+ v-bind="modalData.componentProps || {}"
91
92
  :is="component"
92
93
  v-if="opened && component"
93
94
  :resources="resources"