@rancher/shell 0.3.23 → 0.3.24

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 (57) hide show
  1. package/assets/styles/base/_variables.scss +1 -0
  2. package/assets/styles/themes/_dark.scss +1 -0
  3. package/assets/styles/themes/_light.scss +6 -5
  4. package/assets/translations/en-us.yaml +15 -10
  5. package/assets/translations/zh-hans.yaml +1 -1
  6. package/components/ClusterProviderIconMenu.vue +161 -0
  7. package/components/Loading.vue +1 -1
  8. package/components/SideNav.vue +1 -1
  9. package/components/form/SelectOrCreateAuthSecret.vue +7 -0
  10. package/components/nav/Group.vue +54 -24
  11. package/components/nav/Header.vue +1 -1
  12. package/components/nav/TopLevelMenu.vue +469 -294
  13. package/components/nav/Type.vue +31 -5
  14. package/creators/pkg/init +2 -2
  15. package/edit/fleet.cattle.io.gitrepo.vue +43 -15
  16. package/edit/logging.banzaicloud.io.output/index.vue +7 -0
  17. package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +3 -8
  18. package/edit/provisioning.cattle.io.cluster/rke2.vue +108 -33
  19. package/edit/workload/storage/ContainerMountPaths.vue +7 -5
  20. package/initialize/App.js +2 -0
  21. package/initialize/client.js +63 -51
  22. package/initialize/index.js +2 -0
  23. package/layouts/default.vue +8 -0
  24. package/machine-config/amazonec2.vue +1 -0
  25. package/mixins/fetch.client.js +3 -3
  26. package/package.json +1 -1
  27. package/pages/__tests__/prefs.test.ts +1 -1
  28. package/pages/c/_cluster/explorer/ConfigBadge.vue +1 -0
  29. package/pages/prefs.vue +3 -13
  30. package/plugins/dashboard-store/resource-class.js +1 -1
  31. package/public/index.html +4 -2
  32. package/rancher-components/BadgeState/BadgeState.vue +5 -1
  33. package/rancher-components/Banner/Banner.test.ts +51 -1
  34. package/rancher-components/Banner/Banner.vue +134 -53
  35. package/rancher-components/Card/Card.test.ts +37 -0
  36. package/rancher-components/Card/Card.vue +24 -7
  37. package/rancher-components/Form/Checkbox/Checkbox.test.ts +20 -29
  38. package/rancher-components/Form/Checkbox/Checkbox.vue +45 -20
  39. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +2 -8
  40. package/rancher-components/Form/LabeledInput/LabeledInput.vue +30 -10
  41. package/rancher-components/Form/Radio/RadioButton.test.ts +35 -0
  42. package/rancher-components/Form/Radio/RadioButton.vue +30 -13
  43. package/rancher-components/Form/Radio/RadioGroup.vue +26 -7
  44. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +7 -6
  45. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +25 -38
  46. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +23 -11
  47. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +19 -5
  48. package/rancher-components/StringList/StringList.test.ts +453 -49
  49. package/rancher-components/StringList/StringList.vue +92 -58
  50. package/scripts/extension/parse-tag-name +0 -0
  51. package/store/prefs.js +3 -4
  52. package/store/type-map.js +2 -16
  53. package/types/shell/index.d.ts +13 -10
  54. package/utils/__tests__/sort.test.ts +61 -0
  55. package/utils/string.js +12 -0
  56. package/vue.config.js +1 -4
  57. package/yarn-error.log +200 -0
@@ -2,6 +2,7 @@ $header-font: 'Poppins', sans-serif;
2
2
  $body-font: 'Lato', arial, helvetica, sans-serif;
3
3
  $mono-font: 'Roboto Mono', monospace;
4
4
 
5
+ $app-bar-collapsed-width: 70px;
5
6
  $max-width: 1440px !default;
6
7
  $min-width: 75% !default;
7
8
  $input-height: 61px;
@@ -65,6 +65,7 @@
65
65
  --nav-border : #{$medium};
66
66
  --nav-hover : var(--primary);
67
67
  --nav-expander-hover : var(--primary-banner-bg);
68
+ --nav-icon-badge-bg : #{$dark};
68
69
 
69
70
  --disabled-bg : #{darken($disabled, 10%)};
70
71
  --disabled-text : #{$secondary};
@@ -11,7 +11,7 @@ $dark : #B6B6C2;
11
11
  //light border and buttons
12
12
  $medium : #DCDEE7;
13
13
 
14
- //light inputs
14
+ //light inputs
15
15
  $light : #EEEFF4;
16
16
 
17
17
  //light sidebar and box
@@ -84,9 +84,9 @@ BODY, .theme-light {
84
84
  --link-border : #{$link};
85
85
  --link-banner-bg : #{rgba($link, 0.15)};
86
86
  --link-light-bg : #{rgba($link, 0.05)};
87
-
88
87
 
89
-
88
+
89
+
90
90
  .text-link {
91
91
  color: var(--link) !important;
92
92
  }
@@ -301,7 +301,7 @@ BODY, .theme-light {
301
301
  background: var(--error-active-bg);
302
302
  }
303
303
  }
304
-
304
+
305
305
 
306
306
  --body-bg : #{$lightest};
307
307
  --body-text : #{$darkest};
@@ -320,13 +320,14 @@ BODY, .theme-light {
320
320
  --header-height : 55px;
321
321
  --header-border : #{$medium};
322
322
  --header-border-size : 1px;
323
- --nav-width : 230px;
323
+ --nav-width : 300px;
324
324
  --nav-bg : #{$lightest};
325
325
  --nav-active : #{$light};
326
326
  --nav-hover : #{$medium};
327
327
  --nav-expander-hover : #{darken($medium, 10%)};
328
328
  --nav-border : #{$medium};
329
329
  --nav-border-size : 1px;
330
+ --nav-icon-badge-bg : #{$lightest};
330
331
 
331
332
  --footer-bg : transparent;
332
333
  --footer-height : 0px;
@@ -139,6 +139,8 @@ nav:
139
139
  rotateEncryptionKeys: Rotate Encryption Keys
140
140
  saveAsRKETemplate: Save as RKE Template
141
141
  takeSnapshot: Take Snapshot
142
+ seeAllClusters: See all clusters
143
+ seeAllClustersCollapsed: See all
142
144
  group:
143
145
  cluster: Cluster
144
146
  inUse: More Resources
@@ -185,6 +187,7 @@ nav:
185
187
  search:
186
188
  placeholder: Type to search clusters
187
189
  noResults: No matching clusters
190
+ clusters: clusters
188
191
  resourceSearch:
189
192
  label: Resource Search
190
193
  toolTip: Resource Search {key}
@@ -1637,7 +1640,7 @@ cluster:
1637
1640
  advanced: These are advanced configuration options. Generally, they should be left as-is.
1638
1641
  tolerations: Additional Pod Tolerations will be added to the default Tolerations applied by Rancher.
1639
1642
  limits: Pod Requests and Limits do not have a default configuration.
1640
- windowsCompatibility: "We do not recommended removing the Node Affinity rule that prevents the <b>agent</b> from running on Windows nodes as this is not a supported configuration."
1643
+ windowsCompatibility: "We do not recommend removing the Node Affinity rule that prevents the <b>agent</b> from running on Windows nodes as this is not a supported configuration."
1641
1644
  affinity:
1642
1645
  default: Use default affinity rules defined by Rancher
1643
1646
  custom: Use custom affinity rules
@@ -1647,7 +1650,7 @@ cluster:
1647
1650
  machineSelector:
1648
1651
  label: Add Machine Selector
1649
1652
  listLabel: Add Argument
1650
- bannerLabel: 'Note: The last selector that matches wins and only args from it will be used. Args from other matches above will not combined together or merged.'
1653
+ bannerLabel: 'Note: The last selector that matches wins, and only args from it will be used. Args from other matches above will not be combined together or merged.'
1651
1654
  title: 'For machines with labels matching:'
1652
1655
  subTitle: 'Use the Kubelet args:'
1653
1656
  titleAlt: |-
@@ -1661,14 +1664,14 @@ cluster:
1661
1664
  agentArgs:
1662
1665
  label: Raise error if kernel parameters are different than the expected kubelet defaults
1663
1666
  banner:
1664
- warning: 'This cluster contains a machineSelectorConfig which this form does not fully support; use the YAML editor to manage the full configuration.'
1665
- os: 'You are attemping to add a {newOS} worker node to a cluster with one or more {existingOS} worker nodes: some installed apps may need to be upgraded or removed.'
1667
+ warning: 'This cluster contains a machineSelectorConfig, which this form does not fully support; use the YAML editor to manage the full configuration.'
1668
+ os: 'You are attempting to add a {newOS} worker node to a cluster with one or more {existingOS} worker nodes: some installed apps may need to be upgraded or removed.'
1666
1669
  rke2-k3-reprovisioning: 'Making changes to cluster configuration may result in nodes reprovisioning. For more information see the <a target="blank" href="{docsBase}/cluster-provisioning/rke-clusters/behavior-differences-between-rke1-and-rke2/" target="_blank" rel="noopener nofollow">documentation</a>.'
1667
1670
  desiredNodeGroupWarning: There are 0 nodes available to run the cluster agent. The cluster will not become active until at least one node is available.
1668
1671
  invalidPsps: You have one or more PodSecurityPolicy resource(s) in this cluster. Pod Security Policies are not available in Kubernetes v1.25 and will be automatically removed.
1669
- haveArgInfo: Configuration information is not available for the selected Kubernetes version. The options available in this screen will be limited, you may want to use the YAML editor.
1672
+ haveArgInfo: Configuration information is not available for the selected Kubernetes version. The options available on this screen will be limited; you may want to use the YAML editor.
1670
1673
  deprecatedPsp: Pod Security Policies are deprecated as of Kubernetes v1.21, and have been removed in Kubernetes v1.25.
1671
- removedPsp: Pod Security Policies have been removed in Kubernetes v1.25, use Pod Security Admission instead.
1674
+ removedPsp: Pod Security Policies have been removed in Kubernetes v1.25. Use Pod Security Admission instead.
1672
1675
  rkeTemplateUpgrade: Template revision {name} available for upgrade
1673
1676
 
1674
1677
  availabilityWarnings:
@@ -1830,7 +1833,7 @@ cluster:
1830
1833
  modal:
1831
1834
  pspChange:
1832
1835
  title: Pod Security Policy deprecation
1833
- body: Kubernetes has removed support for Pod Security Policies (PSPs) starting with version 1.25. If your cluster has PodSecurityPolicy admission controller enabled via "kube-apiserver-arg.enable-admission-plugins" in Cluster YAML, it has to be <i>manually</i> removed before proceeding with the upgrade. Additionally, any PSPs that may be present in the cluster will no longer be available/enforced. Do you want to proceed?
1836
+ body: <p>Kubernetes has removed support for Pod Security Policies (PSPs) starting with version 1.25. If your cluster has PodSecurityPolicy admission controller enabled via "kube-apiserver-arg.enable-admission-plugins" in Cluster YAML, it has to be <i>manually</i> removed before proceeding with the upgrade. Additionally, any PSPs that may be present in the cluster will no longer be available/enforced. Do you want to proceed?</p>
1834
1837
  snapshots:
1835
1838
  suffix: Snapshots per node
1836
1839
  systemService:
@@ -1846,6 +1849,7 @@ cluster:
1846
1849
  header: Cloud Provider Config
1847
1850
  defaultValue:
1848
1851
  label: Default - RKE2 Embedded
1852
+ unsupported: The current Cloud Provider is not supported by this version of Kubernetes. The Cloud Provider has been changed to External. Please use the Cloud Provider Config to supply an out-of-tree configuration as needed.
1849
1853
  security:
1850
1854
  header: Security
1851
1855
  cis:
@@ -2162,7 +2166,7 @@ fleet:
2162
2166
  keepResources: Always Keep Resources
2163
2167
  keepResourcesBanner: When enabled above, resources will be kept when deleting a GitRepo or Bundle - only Helm release secrets will be deleted.
2164
2168
  correctDrift: Enable Self-Healing
2165
- correctDriftBanner: When enabled, Fleet will ensure that the cluster resources are kept in sync with the git repository. All resource changes made on th ecluster will be lost.
2169
+ correctDriftBanner: When enabled, Fleet will ensure that the cluster resources are kept in sync with the git repository. All resource changes made on the cluster will be lost.
2166
2170
  add:
2167
2171
  steps:
2168
2172
  repoInfo:
@@ -2214,6 +2218,7 @@ fleet:
2214
2218
  workspace:
2215
2219
  label: Workspace
2216
2220
  addWorkspace: Create a workspace
2221
+ helmRepoURLRegex: Helm Repos (URL Regex)
2217
2222
  clusterGroup:
2218
2223
  selector:
2219
2224
  label: Cluster Selectors
@@ -4090,14 +4095,14 @@ plugins:
4090
4095
  subtitle: Catalogs
4091
4096
  imageLoad:
4092
4097
  load: Import Extension Catalog
4093
- prompt: An Extension Catalog contains extension assets bundled into an image, importing will take the image and host a Helm repository to act as a catalog for custom built Extensions.
4098
+ prompt: An Extension Catalog contains extension assets bundled into an image, importing will take the image and host a Helm repository to act as a catalog for custom built Extensions.
4094
4099
  fields:
4095
4100
  image:
4096
4101
  label: Catalog Image Reference
4097
4102
  placeholder: "e.g. hub.docker.io/example-org/my-image:latest"
4098
4103
  secrets:
4099
4104
  banner: "If the registry that hosts the Catalog Image requires Pull Secrets, they must be created in the following namespace:<pre>cattle-ui-plugin-system</pre>"
4100
- banner: This will create an Deployment, Service, and Helm repository to serve the extension charts.
4105
+ banner: This will create an Deployment, Service, and Helm repository to serve the extension charts.
4101
4106
  imageVersion:
4102
4107
  title: Image Version Not Found
4103
4108
  message: Unable to determine image version from {image}, defaulting to latest
@@ -1838,7 +1838,7 @@ cluster:
1838
1838
  modal:
1839
1839
  pspChange:
1840
1840
  title: 弃用 Pod 安全策略
1841
- body: v1.25 版开始,Kubernetes 已经取消了对 Pod 安全策略 (PSP) 的支持。如果你的集群通过集群 YAML 中的 “kube-apiserver-arg.enable-admission-plugins” 启用了 PodSecurityPolicy 准入控制器,你必须在继续升级之前<i>手动</i>删除它。此外,集群中存在的任何 PSP 将不再可用或强制执行。是否继续操作?
1841
+ body: <p>从 v1.25 版开始,Kubernetes 已经取消了对 Pod 安全策略 (PSP) 的支持。如果你的集群通过集群 YAML 中的 “kube-apiserver-arg.enable-admission-plugins” 启用了 PodSecurityPolicy 准入控制器,你必须在继续升级之前<i>手动</i>删除它。此外,集群中存在的任何 PSP 将不再可用或强制执行。是否继续操作?</p>
1842
1842
  snapshots:
1843
1843
  suffix: 每个节点的快照
1844
1844
  systemService:
@@ -0,0 +1,161 @@
1
+ <script>
2
+ export default {
3
+ props: {
4
+ cluster: {
5
+ type: Object,
6
+ required: true,
7
+ },
8
+ },
9
+ computed: {
10
+ isEnabled() {
11
+ return !!this.cluster?.ready;
12
+ },
13
+ },
14
+ methods: {
15
+ /**
16
+ * Shortens an input string based on the number of segments it contains.
17
+ * @param {string} input - The input string to be shortened.
18
+ * @returns {string} - The shortened string.
19
+ * @example smallIdentifier('local') => 'lcl'
20
+ * @example smallIdentifier('word-wide-web') => 'www'
21
+ */
22
+ smallIdentifier(input) {
23
+ if (this.cluster.badge?.iconText) {
24
+ return this.cluster.badge?.iconText;
25
+ }
26
+
27
+ if (!input) {
28
+ return '';
29
+ }
30
+
31
+ if (input.length <= 3) {
32
+ return input;
33
+ }
34
+
35
+ const segments = input.match(/([A-Za-z]+|\d+)/g);
36
+
37
+ if (!segments) return ''; // In case no valid segments are found
38
+
39
+ let result = '';
40
+
41
+ switch (segments.length) {
42
+ case 1:
43
+ // eslint-disable-next-line no-case-declarations
44
+ const word = segments[0];
45
+
46
+ result = `${ word[0] }${ word[Math.floor(word.length / 2)] }${ word[word.length - 1] }`;
47
+ break;
48
+ case 2:
49
+ result = `${ segments[0][0] }${ segments[1][0] }${ segments[1][segments[1].length - 1] }`;
50
+ break;
51
+ default:
52
+ result = segments.slice(0, 3).map((segment) => segment[0]).join('');
53
+ }
54
+
55
+ return result;
56
+ },
57
+
58
+ }
59
+ };
60
+ </script>
61
+
62
+ <template>
63
+ <div
64
+ v-if="cluster"
65
+ class="cluster-icon-menu"
66
+ >
67
+ <div
68
+ class="cluster-badge-logo"
69
+ :class="{ 'disabled': !isEnabled }"
70
+ :style="{borderBottom: cluster.badge?.color ? `4px solid ${cluster.badge?.color}` : ''}"
71
+ >
72
+ <span
73
+ class="cluster-badge-logo-text"
74
+ >
75
+ {{ smallIdentifier(cluster.label) }}
76
+ </span>
77
+ <!-- {{ cluster.badge.iconText }} -->
78
+ </div>
79
+ <!-- eslint-enable -->
80
+ <svg
81
+ v-if="cluster.isLocal && !cluster.isHarvester"
82
+ id="local-cluster-icon-menu"
83
+ class="cluster-os-logo"
84
+ version="1.1"
85
+ xmlns="http://www.w3.org/2000/svg"
86
+ xmlns:xlink="http://www.w3.org/1999/xlink"
87
+ viewBox="0 0 100 100"
88
+ style="enable-background:new 0 0 100 100;"
89
+ >
90
+ <g>
91
+ <g>
92
+ <path
93
+ class="rancher-icon-fill"
94
+ d="M26.0862026,44.4953918H8.6165142c-5.5818157,0-9.3979139-4.6252708-8.4802637-10.1311035l2.858391-17.210701
95
+ C3.912292,11.6477556,6.1382647,7.1128125,7.8419709,7.1128125s3.1788611,4.5368752,3.1788611,10.1186218v4.4837742
96
+ c0,5.5817471,4.4044495,9.5409164,9.9862652,9.5409164h5.0791054V44.4953918z"
97
+ />
98
+ </g>
99
+ <path
100
+ class="rancher-icon-fill"
101
+ d="M63.0214729,92.8871841H37.0862045c-6.0751343,0-11.0000019-4.9248657-11.0000019-11V30.3864384
102
+ c0-6.0751324,4.9248676-11,11.0000019-11h25.9352684c6.0751305,0,11.0000038,4.9248676,11.0000038,11v51.5007477
103
+ C74.0214767,87.9623184,69.0966034,92.8871841,63.0214729,92.8871841z"
104
+ />
105
+ <g>
106
+ <path
107
+ class="rancher-icon-fill"
108
+ d="M73.9137955,44.4953918h17.4696884c5.5818176,0,9.3979187-4.6252708,8.4802628-10.1311035
109
+ l-2.8583908-17.210701c-0.9176483-5.5058317-3.1436234-10.0407753-4.8473282-10.0407753
110
+ s-3.1788635,4.5368752-3.1788635,10.1186218v4.4837742c0,5.5817471-4.4044418,9.5409164-9.9862595,9.5409164h-5.0791092
111
+ V44.4953918z"
112
+ />
113
+ </g>
114
+ </g>
115
+ </svg>
116
+ <img
117
+ v-else
118
+ class="cluster-os-logo"
119
+ :src="cluster.providerNavLogo"
120
+ >
121
+ </div>
122
+ </template>
123
+
124
+ <style lang="scss" scoped>
125
+
126
+ .cluster-icon-menu {
127
+ position: relative;
128
+ align-items: center;
129
+ display: flex;
130
+ height: 28px;
131
+ justify-content: center;
132
+ width: 42px;
133
+ }
134
+ .cluster-os-logo {
135
+ position: absolute;
136
+ top: -6px;
137
+ right: -4px;
138
+ width: 14px;
139
+ }
140
+
141
+ .cluster-badge-logo {
142
+ width: 42px;
143
+ height: 28px;
144
+ display: flex;
145
+ align-items: center;
146
+ justify-content: center;
147
+ color: var(--default-active-text);
148
+ font-weight: bold;
149
+ background: var(--nav-icon-badge-bg);
150
+ border: 1px solid var(--default-border);
151
+ border-radius: 5px;
152
+ padding-top: 2px;
153
+ font-size: 12px;
154
+ text-transform: uppercase;
155
+
156
+ &.disabled {
157
+ filter: grayscale(1);
158
+ color: var(--muted);
159
+ }
160
+ }
161
+ </style>
@@ -75,7 +75,7 @@ export default {
75
75
  }
76
76
 
77
77
  &-content-mode {
78
- left: var(--nav-width);
78
+ left: calc(var(--nav-width));
79
79
  top: var(--header-height);
80
80
  }
81
81
  }
@@ -552,7 +552,7 @@ export default {
552
552
  ::v-deep h6 {
553
553
  margin: 0;
554
554
  letter-spacing: normal;
555
- line-height: initial;
555
+ line-height: 15px;
556
556
 
557
557
  A { padding-left: 0; }
558
558
  }
@@ -477,6 +477,7 @@ export default {
477
477
  <div :class="firstCol">
478
478
  <LabeledSelect
479
479
  v-model="selected"
480
+ data-testid="auth-secret-select"
480
481
  :mode="mode"
481
482
  :label-key="labelKey"
482
483
  :loading="$fetchState.pending"
@@ -488,6 +489,7 @@ export default {
488
489
  <div :class="moreCols">
489
490
  <LabeledInput
490
491
  v-model="publicKey"
492
+ data-testid="auth-secret-ssh-public-key"
491
493
  :mode="mode"
492
494
  type="multiline"
493
495
  label-key="selectOrCreateAuthSecret.ssh.publicKey"
@@ -496,6 +498,7 @@ export default {
496
498
  <div :class="moreCols">
497
499
  <LabeledInput
498
500
  v-model="privateKey"
501
+ data-testid="auth-secret-ssh-private-key"
499
502
  :mode="mode"
500
503
  type="multiline"
501
504
  label-key="selectOrCreateAuthSecret.ssh.privateKey"
@@ -506,6 +509,7 @@ export default {
506
509
  <div :class="moreCols">
507
510
  <LabeledInput
508
511
  v-model="publicKey"
512
+ data-testid="auth-secret-basic-public-key"
509
513
  :mode="mode"
510
514
  label-key="selectOrCreateAuthSecret.basic.username"
511
515
  />
@@ -513,6 +517,7 @@ export default {
513
517
  <div :class="moreCols">
514
518
  <LabeledInput
515
519
  v-model="privateKey"
520
+ data-testid="auth-secret-basic-private-key"
516
521
  :mode="mode"
517
522
  type="password"
518
523
  label-key="selectOrCreateAuthSecret.basic.password"
@@ -523,6 +528,7 @@ export default {
523
528
  <div :class="moreCols">
524
529
  <LabeledInput
525
530
  v-model="publicKey"
531
+ data-testid="auth-secret-s3-public-key"
526
532
  :mode="mode"
527
533
  label-key="selectOrCreateAuthSecret.s3.accessKey"
528
534
  />
@@ -530,6 +536,7 @@ export default {
530
536
  <div :class="moreCols">
531
537
  <LabeledInput
532
538
  v-model="privateKey"
539
+ data-testid="auth-secret-s3-private-key"
533
540
  :mode="mode"
534
541
  type="password"
535
542
  label-key="selectOrCreateAuthSecret.s3.secretKey"
@@ -69,7 +69,7 @@ export default {
69
69
  if (overviewRoute && grp.overview) {
70
70
  const route = this.$router.resolve(overviewRoute || {});
71
71
 
72
- return this.$route.fullPath === route?.route?.fullPath;
72
+ return this.$route.fullPath.split('#')[0] === route?.route?.fullPath;
73
73
  }
74
74
  }
75
75
 
@@ -96,8 +96,14 @@ export default {
96
96
  // Don't auto-select first group entry if we're already expanded and contain the currently-selected nav item
97
97
  if (this.hasActiveRoute() && this.isExpanded) {
98
98
  return;
99
- }
99
+ } else {
100
+ // Remove all active class if click on group header and not active route
101
+ const headerEl = document.querySelectorAll('.header');
100
102
 
103
+ headerEl.forEach((el) => {
104
+ el.classList.remove('active');
105
+ });
106
+ }
101
107
  this.expandGroup();
102
108
 
103
109
  const items = this.group[this.childrenKey];
@@ -132,6 +138,11 @@ export default {
132
138
 
133
139
  // User clicked on the expander icon, so toggle the expansion so the user can see inside the group
134
140
  peek($event) {
141
+ // Add active class to the current header if click on chevron icon
142
+ $event.target.parentElement.classList.remove('active');
143
+ if (this.hasActiveRoute()) {
144
+ $event.target.parentElement.classList.add('active');
145
+ }
135
146
  this.isExpanded = !this.isExpanded;
136
147
  $event.stopPropagation();
137
148
  },
@@ -212,7 +223,7 @@ export default {
212
223
  <i
213
224
  v-if="!onlyHasOverview && canCollapse"
214
225
  class="icon toggle"
215
- :class="{'icon-chevron-down': !isExpanded, 'icon-chevron-up': isExpanded}"
226
+ :class="{'icon-chevron-right': !isExpanded, 'icon-chevron-down': isExpanded}"
216
227
  @click="peek($event, true)"
217
228
  />
218
229
  </div>
@@ -267,17 +278,18 @@ export default {
267
278
  position: relative;
268
279
  cursor: pointer;
269
280
  color: var(--body-text);
281
+ height: 33px;
270
282
 
271
- > H6 {
283
+ H6 {
272
284
  color: var(--body-text);
273
285
  user-select: none;
274
286
  text-transform: none;
275
- font-size: 14px;
287
+ font-size: 16px;
276
288
  }
277
289
 
278
290
  > A {
279
291
  display: block;
280
- padding-left: 10px;
292
+ padding-left: 16px;
281
293
  &:hover{
282
294
  text-decoration: none;
283
295
  }
@@ -285,20 +297,14 @@ export default {
285
297
  outline:none;
286
298
  }
287
299
  > H6 {
288
- font-size: 14px;
289
300
  text-transform: none;
290
301
  }
291
302
  }
292
-
293
303
  &.active {
294
304
  background-color: var(--nav-active);
295
305
  }
296
306
  }
297
307
 
298
- .body {
299
- margin-left: 10px;
300
- }
301
-
302
308
  .accordion {
303
309
  .header {
304
310
  &:hover:not(.noHover) {
@@ -323,18 +329,21 @@ export default {
323
329
  }
324
330
 
325
331
  > H6 {
326
- font-size: 14px;
327
332
  text-transform: none;
328
- padding-left: 10px;
333
+ padding-left: 16px;
329
334
  }
330
335
 
331
336
  > I {
332
337
  position: absolute;
333
338
  right: 0;
334
339
  top: 0;
335
- padding: 10px 7px 9px 7px;
340
+ padding: 10px 10px 9px 7px;
336
341
  user-select: none;
337
342
  }
343
+
344
+ &:has(> a.nuxt-link-active) {
345
+ background: var(--nav-active);
346
+ }
338
347
  }
339
348
 
340
349
  > .body {
@@ -344,20 +353,19 @@ export default {
344
353
 
345
354
  &.depth-1 {
346
355
  > .header {
356
+ padding-left: 20px;
347
357
  > H6 {
348
- font-size: 13px;
349
- line-height: 16px;
358
+ line-height: 18px;
350
359
  padding: 8px 0 7px 5px !important;
351
360
  }
352
361
  > I {
353
- padding: 9px 7px 8px 7px !important;
362
+ padding: 10px 7px 9px 7px !important;
354
363
  }
355
364
  }
356
365
  }
357
366
 
358
367
  &:not(.depth-0) {
359
368
  > .header {
360
- padding-left: 10px;
361
369
  > H6 {
362
370
  // Child groups that aren't linked themselves
363
371
  display: inline-block;
@@ -372,18 +380,29 @@ export default {
372
380
  }
373
381
  }
374
382
  }
383
+
384
+ &.expanded:has(> .active),
385
+ &.expanded:has(> ul li.nuxt-link-active) {
386
+ background: var(--nav-active);
387
+ }
388
+
389
+ &.expanded:has(> ul li.root) {
390
+ background: transparent;
391
+ }
375
392
  }
376
393
 
377
- .body ::v-deep > .child.nuxt-link-active,
378
- .header ::v-deep > .child.nuxt-link-exact-active {
394
+ .body ::v-deep > .child.nuxt-link-active,
395
+ .header ::v-deep > .child.nuxt-link-exact-active {
379
396
  padding: 0;
380
397
 
381
398
  A, A I {
382
- color: var(--body-text);
399
+ color: var(--primary-hover-text);
383
400
  }
384
401
 
385
402
  A {
386
- background-color: var(--nav-active);
403
+ color: var(--primary-hover-text);
404
+ background-color: var(--primary-hover-bg);
405
+ font-weight: bold;
387
406
  }
388
407
  }
389
408
 
@@ -391,11 +410,22 @@ export default {
391
410
  A {
392
411
  border-left: solid 5px transparent;
393
412
  line-height: 16px;
394
- font-size: 13px;
413
+ font-size: 14px;
414
+ padding-left: 24px;
415
+ display: flex;
416
+ justify-content: space-between;
395
417
  }
396
418
 
397
419
  A:focus {
398
420
  outline: none;
399
421
  }
422
+
423
+ &.root {
424
+ background: transparent;
425
+ A {
426
+ padding-left: 14px;
427
+ }
428
+ }
400
429
  }
430
+
401
431
  </style>
@@ -715,7 +715,7 @@ export default {
715
715
  }
716
716
 
717
717
  > .menu-spacer {
718
- flex: 0 0 calc(var(--header-height) + 10px);
718
+ flex: 0 0 15px;
719
719
 
720
720
  &.isSingleProduct {
721
721
  display: flex;