@rancher/shell 3.0.5-rc.8 → 3.0.5

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 (199) hide show
  1. package/assets/styles/base/_color.scss +4 -1
  2. package/assets/styles/global/_tooltip.scss +7 -4
  3. package/assets/styles/themes/_dark.scss +11 -0
  4. package/assets/styles/themes/_light.scss +13 -1
  5. package/assets/styles/themes/_modern.scss +22 -0
  6. package/assets/translations/en-us.yaml +147 -19
  7. package/assets/translations/zh-hans.yaml +0 -1
  8. package/chart/monitoring/grafana/index.vue +8 -2
  9. package/components/ActionMenuShell.vue +3 -1
  10. package/components/Cron/CronExpressionEditor.vue +299 -0
  11. package/components/Cron/CronExpressionEditorModal.vue +247 -0
  12. package/components/Cron/CronTooltip.vue +87 -0
  13. package/components/Cron/types.ts +13 -0
  14. package/components/ForceDirectedTreeChart/composable.ts +11 -0
  15. package/components/PodSecurityAdmission.vue +2 -0
  16. package/components/PromptModal.vue +1 -1
  17. package/components/Resource/Detail/Card/__tests__/StateCard.test.ts +1 -0
  18. package/components/Resource/Detail/CopyToClipboard.vue +78 -0
  19. package/components/Resource/Detail/FetchLoader/__tests__/composables.test.ts +69 -0
  20. package/components/Resource/Detail/FetchLoader/composables.ts +27 -0
  21. package/components/Resource/Detail/Metadata/Annotations/__tests__/index.test.ts +1 -1
  22. package/components/Resource/Detail/Metadata/Annotations/index.vue +1 -1
  23. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/identifying-fields.test.ts +13 -61
  24. package/components/Resource/Detail/Metadata/IdentifyingInformation/__tests__/index.test.ts +33 -6
  25. package/components/Resource/Detail/Metadata/IdentifyingInformation/identifying-fields.ts +24 -38
  26. package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +25 -5
  27. package/components/Resource/Detail/Metadata/KeyValue.vue +12 -23
  28. package/components/Resource/Detail/Metadata/KeyValueRow.vue +144 -0
  29. package/components/Resource/Detail/Metadata/Labels/__tests__/index.test.ts +1 -0
  30. package/components/Resource/Detail/Metadata/Labels/index.vue +1 -0
  31. package/components/Resource/Detail/Metadata/__tests__/KeyValue.test.ts +30 -32
  32. package/components/Resource/Detail/Metadata/__tests__/KeyValueRow.test.ts +108 -0
  33. package/components/Resource/Detail/Metadata/__tests__/composables.test.ts +0 -3
  34. package/components/Resource/Detail/Metadata/__tests__/index.test.ts +12 -5
  35. package/components/Resource/Detail/Metadata/composables.ts +1 -4
  36. package/components/Resource/Detail/Metadata/index.vue +1 -0
  37. package/components/Resource/Detail/Preview/Content.vue +63 -0
  38. package/components/Resource/Detail/Preview/Preview.vue +128 -0
  39. package/components/Resource/Detail/Preview/__tests__/Content.spec.ts +71 -0
  40. package/components/Resource/Detail/Preview/__tests__/Preview.spec.ts +121 -0
  41. package/components/Resource/Detail/ResourcePopover/ResourcePopoverCard.vue +141 -0
  42. package/components/Resource/Detail/ResourcePopover/__tests__/ResourcePopoverCard.test.ts +136 -0
  43. package/components/Resource/Detail/ResourcePopover/__tests__/index.test.ts +245 -0
  44. package/components/Resource/Detail/ResourcePopover/index.vue +226 -0
  45. package/components/Resource/Detail/SpacedRow.vue +1 -0
  46. package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +0 -5
  47. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +1 -1
  48. package/components/Resource/Detail/TitleBar/composables.ts +1 -3
  49. package/components/Resource/Detail/TitleBar/index.vue +2 -29
  50. package/components/Resource/Detail/ViewOptions/composable.ts +9 -0
  51. package/components/Resource/Detail/ViewOptions/index.vue +41 -0
  52. package/components/Resource/Detail/__tests__/CopyToClipboard.spec.ts +82 -0
  53. package/components/ResourceDetail/Masthead/legacy.vue +0 -19
  54. package/components/ResourceDetail/index.vue +1 -26
  55. package/components/ResourceTable.vue +24 -0
  56. package/components/SortableTable/index.vue +7 -1
  57. package/components/SortableTable/paging.js +3 -0
  58. package/components/Tabbed/Tab.vue +43 -1
  59. package/components/Tabbed/index.vue +3 -1
  60. package/components/__tests__/Cron/CronExpressionEditor.test.ts +151 -0
  61. package/components/__tests__/Cron/CronExpressionEditorModal.test.ts +81 -0
  62. package/components/auth/login/saml.vue +86 -0
  63. package/components/form/LabeledSelect.vue +8 -8
  64. package/components/form/ProjectMemberEditor.vue +2 -0
  65. package/components/form/ResourceTabs/composable.ts +54 -0
  66. package/components/form/ResourceTabs/index.vue +10 -7
  67. package/components/form/Select.vue +13 -10
  68. package/components/form/__tests__/LabeledSelect.test.ts +133 -0
  69. package/components/form/__tests__/Select.test.ts +134 -0
  70. package/components/nav/Header.vue +6 -5
  71. package/composables/useExtensionManager.ts +17 -0
  72. package/config/home-links.js +12 -0
  73. package/config/labels-annotations.js +0 -1
  74. package/config/page-actions.js +0 -1
  75. package/config/product/explorer.js +3 -1
  76. package/config/product/fleet.js +2 -7
  77. package/config/product/manager.js +0 -5
  78. package/config/query-params.js +1 -0
  79. package/config/router/navigation-guards/clusters.js +2 -1
  80. package/config/router/navigation-guards/products.js +1 -1
  81. package/config/store.js +2 -0
  82. package/core/extension-manager-impl.js +518 -0
  83. package/core/plugins.js +35 -468
  84. package/core/types.ts +8 -2
  85. package/detail/__tests__/autoscaling.horizontalpodautoscaler.test.ts +1 -0
  86. package/detail/catalog.cattle.io.app.vue +7 -4
  87. package/detail/fleet.cattle.io.bundle.vue +1 -5
  88. package/detail/fleet.cattle.io.cluster.vue +3 -2
  89. package/detail/fleet.cattle.io.gitrepo.vue +76 -49
  90. package/detail/fleet.cattle.io.helmop.vue +78 -49
  91. package/dialog/AddonConfigConfirmationDialog.vue +1 -1
  92. package/dialog/GenericPrompt.vue +1 -1
  93. package/dialog/ImportDialog.vue +9 -2
  94. package/dialog/InstallExtensionDialog.vue +18 -10
  95. package/dialog/SloDialog.vue +1 -1
  96. package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +2 -1
  97. package/edit/__tests__/resources.cattle.io.restore.test.ts +106 -0
  98. package/edit/auth/oidc.vue +106 -6
  99. package/edit/auth/saml.vue +5 -5
  100. package/edit/cloudcredential.vue +31 -17
  101. package/edit/constraints.gatekeeper.sh.constraint/index.vue +10 -2
  102. package/edit/fleet.cattle.io.cluster.vue +19 -0
  103. package/edit/fleet.cattle.io.gitrepo.vue +23 -16
  104. package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +12 -11
  105. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +11 -1
  106. package/edit/provisioning.cattle.io.cluster/index.vue +14 -19
  107. package/edit/provisioning.cattle.io.cluster/rke2.vue +11 -3
  108. package/edit/provisioning.cattle.io.cluster/tabs/AddOnAdditionalManifest.vue +1 -0
  109. package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +1 -0
  110. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +1 -0
  111. package/edit/provisioning.cattle.io.cluster/tabs/etcd/S3Config.vue +1 -0
  112. package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +2 -0
  113. package/edit/provisioning.cattle.io.cluster/tabs/upgrade/DrainOptions.vue +6 -0
  114. package/edit/resources.cattle.io.restore.vue +5 -8
  115. package/initialize/install-plugins.js +1 -3
  116. package/list/__tests__/workload.test.ts +1 -0
  117. package/list/workload.vue +8 -1
  118. package/machine-config/components/GCEImage.vue +6 -5
  119. package/machine-config/google.vue +11 -6
  120. package/mixins/__tests__/auth-config.test.ts +4 -6
  121. package/mixins/__tests__/chart.test.ts +139 -1
  122. package/mixins/auth-config.js +33 -10
  123. package/mixins/chart.js +58 -18
  124. package/models/__tests__/namespace.test.ts +69 -0
  125. package/models/apps.statefulset.js +8 -10
  126. package/models/chart.js +5 -1
  127. package/models/fleet-application.js +16 -46
  128. package/models/fleet.cattle.io.bundle.js +1 -38
  129. package/models/fleet.cattle.io.gitrepo.js +4 -0
  130. package/models/fleet.cattle.io.helmop.js +4 -0
  131. package/models/management.cattle.io.cluster.js +1 -1
  132. package/models/management.cattle.io.project.js +12 -0
  133. package/models/namespace.js +30 -0
  134. package/models/workload.js +4 -1
  135. package/package.json +10 -10
  136. package/pages/auth/login.vue +8 -3
  137. package/pages/auth/logout.vue +6 -5
  138. package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +26 -11
  139. package/pages/c/_cluster/apps/charts/chart.vue +29 -20
  140. package/pages/c/_cluster/apps/charts/index.vue +1 -0
  141. package/pages/c/_cluster/apps/charts/install.vue +6 -5
  142. package/pages/c/_cluster/explorer/tools/__tests__/index.test.ts +102 -12
  143. package/pages/c/_cluster/explorer/tools/index.vue +145 -254
  144. package/pages/c/_cluster/manager/cloudCredential/index.vue +18 -1
  145. package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +12 -2
  146. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +1 -1
  147. package/pages/c/_cluster/uiplugins/__tests__/index.spec.ts +318 -0
  148. package/pages/c/_cluster/uiplugins/index.vue +221 -363
  149. package/pages/home.vue +1 -9
  150. package/plugins/axios.js +3 -2
  151. package/plugins/dashboard-store/resource-class.js +49 -0
  152. package/plugins/ember-cookie.js +7 -3
  153. package/plugins/steve/subscribe.js +4 -2
  154. package/public/index.html +2 -1
  155. package/rancher-components/Card/Card.vue +1 -1
  156. package/rancher-components/Form/Checkbox/Checkbox.vue +1 -1
  157. package/rancher-components/Form/Radio/RadioButton.vue +1 -1
  158. package/rancher-components/Form/Radio/RadioGroup.vue +1 -1
  159. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +1 -11
  160. package/rancher-components/Pill/RcCounterBadge/RcCounterBadge.test.ts +53 -0
  161. package/rancher-components/Pill/RcCounterBadge/RcCounterBadge.vue +65 -0
  162. package/rancher-components/Pill/RcCounterBadge/index.ts +1 -0
  163. package/rancher-components/Pill/RcCounterBadge/types.ts +7 -0
  164. package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +1 -1
  165. package/rancher-components/Pill/RcStatusBadge/index.ts +1 -1
  166. package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +3 -3
  167. package/rancher-components/Pill/RcStatusIndicator/types.ts +1 -1
  168. package/rancher-components/Pill/RcTag/RcTag.test.ts +64 -0
  169. package/rancher-components/Pill/RcTag/RcTag.vue +94 -0
  170. package/rancher-components/Pill/RcTag/index.ts +1 -0
  171. package/rancher-components/Pill/RcTag/types.ts +9 -0
  172. package/rancher-components/Pill/types.ts +1 -0
  173. package/rancher-components/RcItemCard/RcItemCard.vue +1 -0
  174. package/rancher-components/RcItemCard/RcItemCardAction.vue +12 -0
  175. package/scripts/test-plugins-build.sh +0 -1
  176. package/store/__tests__/catalog.test.ts +63 -0
  177. package/store/__tests__/cookies.test.ts +72 -0
  178. package/store/auth.js +33 -10
  179. package/store/catalog.js +2 -2
  180. package/store/cookies.ts +30 -0
  181. package/store/prefs.js +10 -5
  182. package/store/type-map.js +3 -15
  183. package/types/extension-manager.ts +26 -0
  184. package/types/shell/index.d.ts +123 -27
  185. package/utils/__tests__/product.test.ts +129 -0
  186. package/utils/__tests__/resource.test.ts +87 -0
  187. package/utils/alertmanagerconfig.js +2 -2
  188. package/utils/auth.js +4 -77
  189. package/utils/product.ts +39 -0
  190. package/utils/resource.ts +35 -0
  191. package/utils/select.js +0 -24
  192. package/utils/validators/formRules/__tests__/index.test.ts +3 -0
  193. package/utils/validators/formRules/index.ts +2 -1
  194. package/vue.config.js +1 -1
  195. package/components/Resource/Detail/Metadata/Rectangle.vue +0 -34
  196. package/components/Resource/Detail/Metadata/__tests__/Rectangle.test.ts +0 -24
  197. package/components/ResourceDetail/Masthead/__tests__/legacy.test.ts +0 -65
  198. package/utils/cookie-universal.js +0 -10
  199. /package/components/{ForceDirectedTreeChart.vue → ForceDirectedTreeChart/index.vue} +0 -0
@@ -1,15 +1,22 @@
1
1
  <script>
2
2
  import { mapState } from 'vuex';
3
- import Loading from '@shell/components/Loading';
4
3
  import ResourceTabs from '@shell/components/form/ResourceTabs';
5
4
  import FleetSummary from '@shell/components/fleet/FleetSummary';
6
5
  import { Banner } from '@components/Banner';
7
6
  import FleetResources from '@shell/components/fleet/FleetResources';
8
7
  import Tab from '@shell/components/Tabbed/Tab';
9
- import { FLEET, MANAGEMENT } from '@shell/config/types';
8
+ import { FLEET } from '@shell/config/types';
10
9
  import { isHarvesterCluster } from '@shell/utils/cluster';
11
10
  import FleetBundles from '@shell/components/fleet/FleetBundles.vue';
12
11
  import { checkSchemasForFindAllHash } from '@shell/utils/auth';
12
+ import DetailPage from '@shell/components/Resource/Detail/Page.vue';
13
+ import Masthead from '@shell/components/Resource/Detail/Masthead/index.vue';
14
+ import { useDefaultMastheadProps } from '@shell/components/Resource/Detail/Masthead/composable';
15
+ import ViewOptions from '@shell/components/Resource/Detail/ViewOptions/index.vue';
16
+ import { useCurrentView } from '@shell/components/Resource/Detail/ViewOptions/composable';
17
+ import { _GRAPH } from '@shell/config/query-params';
18
+ import ForceDirectedTreeChart from '@shell/components/ForceDirectedTreeChart';
19
+ import { useDefaultForceDirectTreeChartProps } from '@shell/components/ForceDirectedTreeChart/composable';
13
20
 
14
21
  export default {
15
22
  name: 'DetailGitRepo',
@@ -17,13 +24,16 @@ export default {
17
24
  emits: ['input'],
18
25
 
19
26
  components: {
20
- Loading,
21
27
  FleetResources,
22
28
  FleetSummary,
23
29
  Banner,
24
30
  ResourceTabs,
25
31
  Tab,
26
32
  FleetBundles,
33
+ DetailPage,
34
+ Masthead,
35
+ ViewOptions,
36
+ ForceDirectedTreeChart
27
37
  },
28
38
 
29
39
  props: {
@@ -33,6 +43,16 @@ export default {
33
43
  },
34
44
  },
35
45
 
46
+ setup(props) {
47
+ const defaultMastheadProps = useDefaultMastheadProps(props.value);
48
+ const currentView = useCurrentView();
49
+ const forceDirectedTreeChartProps = useDefaultForceDirectTreeChartProps(props.value);
50
+
51
+ return {
52
+ defaultMastheadProps, currentView, forceDirectedTreeChartProps, _GRAPH
53
+ };
54
+ },
55
+
36
56
  data() {
37
57
  return {
38
58
  allFleetClusters: [],
@@ -100,10 +120,6 @@ export default {
100
120
  }
101
121
  }, this.$store);
102
122
 
103
- if (this.value.authorId && this.$store.getters['management/schemaFor'](MANAGEMENT.USER)) {
104
- await this.$store.dispatch(`management/findAll`, { type: MANAGEMENT.USER }, { root: true });
105
- }
106
-
107
123
  this.allBundles = allDispatches.allBundles || [];
108
124
  this.allFleetClusters = allDispatches.allFleetClusters || [];
109
125
  },
@@ -112,46 +128,57 @@ export default {
112
128
  </script>
113
129
 
114
130
  <template>
115
- <Loading v-if="$fetchState.pending" />
116
- <div
117
- v-else
118
- class="mt-20"
119
- >
120
- <FleetSummary
121
- v-if="gitRepoHasClusters"
122
- :value="value"
123
- :bundles="bundles"
124
- class="mb-20"
125
- />
126
- <Banner
127
- v-else
128
- color="info"
129
- class="mb-20"
130
- >
131
- {{ t('fleet.fleetSummary.noClusters.gitRepo') }}
132
- </Banner>
133
- <ResourceTabs
134
- :value="value"
135
- mode="view"
136
- class="mt-20"
137
- :need-related="false"
138
- @update:value="$emit('input', $event)"
139
- >
140
- <Tab
141
- v-if="!!allBundles.length"
142
- label="Bundles"
143
- name="bundles"
144
- :weight="30"
145
- >
146
- <FleetBundles :value="value" />
147
- </Tab>
148
- <Tab
149
- label="Resources"
150
- name="resources"
151
- :weight="20"
152
- >
153
- <FleetResources :rows="value.resourcesStatuses" />
154
- </Tab>
155
- </ResourceTabs>
156
- </div>
131
+ <DetailPage :loading="$fetchState.pending">
132
+ <template #top-area>
133
+ <Masthead v-bind="defaultMastheadProps">
134
+ <template #additional-actions>
135
+ <ViewOptions />
136
+ </template>
137
+ </Masthead>
138
+ </template>
139
+ <template #bottom-area>
140
+ <template v-if="currentView === _GRAPH">
141
+ <ForceDirectedTreeChart v-bind="forceDirectedTreeChartProps" />
142
+ </template>
143
+
144
+ <template v-else>
145
+ <FleetSummary
146
+ v-if="gitRepoHasClusters"
147
+ :value="value"
148
+ :bundles="bundles"
149
+ class="mb-20"
150
+ />
151
+ <Banner
152
+ v-else
153
+ color="info"
154
+ class="mb-20"
155
+ >
156
+ {{ t('fleet.fleetSummary.noClusters.gitRepo') }}
157
+ </Banner>
158
+ <ResourceTabs
159
+ :value="value"
160
+ mode="view"
161
+ class="mt-20"
162
+ :need-related="false"
163
+ @update:value="$emit('input', $event)"
164
+ >
165
+ <Tab
166
+ v-if="!!allBundles.length"
167
+ label="Bundles"
168
+ name="bundles"
169
+ :weight="30"
170
+ >
171
+ <FleetBundles :value="value" />
172
+ </Tab>
173
+ <Tab
174
+ label="Resources"
175
+ name="resources"
176
+ :weight="20"
177
+ >
178
+ <FleetResources :rows="value.resourcesStatuses" />
179
+ </Tab>
180
+ </ResourceTabs>
181
+ </template>
182
+ </template>
183
+ </DetailPage>
157
184
  </template>
@@ -1,15 +1,22 @@
1
1
  <script>
2
2
  import { mapState } from 'vuex';
3
- import Loading from '@shell/components/Loading';
4
3
  import ResourceTabs from '@shell/components/form/ResourceTabs';
5
4
  import FleetSummary from '@shell/components/fleet/FleetSummary';
6
5
  import { Banner } from '@components/Banner';
7
6
  import FleetResources from '@shell/components/fleet/FleetResources';
8
7
  import Tab from '@shell/components/Tabbed/Tab';
9
- import { FLEET, MANAGEMENT } from '@shell/config/types';
8
+ import { FLEET } from '@shell/config/types';
10
9
  import { isHarvesterCluster } from '@shell/utils/cluster';
11
10
  import FleetBundles from '@shell/components/fleet/FleetBundles.vue';
12
11
  import { checkSchemasForFindAllHash } from '@shell/utils/auth';
12
+ import DetailPage from '@shell/components/Resource/Detail/Page.vue';
13
+ import Masthead from '@shell/components/Resource/Detail/Masthead/index.vue';
14
+ import { useDefaultMastheadProps } from '@shell/components/Resource/Detail/Masthead/composable';
15
+ import ViewOptions from '@shell/components/Resource/Detail/ViewOptions/index.vue';
16
+ import { useCurrentView } from '@shell/components/Resource/Detail/ViewOptions/composable';
17
+ import { _GRAPH } from '@shell/config/query-params';
18
+ import ForceDirectedTreeChart from '@shell/components/ForceDirectedTreeChart';
19
+ import { useDefaultForceDirectTreeChartProps } from '@shell/components/ForceDirectedTreeChart/composable';
13
20
 
14
21
  export default {
15
22
  name: 'DetailsHelmOp',
@@ -17,13 +24,16 @@ export default {
17
24
  emits: ['input'],
18
25
 
19
26
  components: {
20
- Loading,
21
27
  FleetResources,
22
28
  FleetSummary,
23
29
  Banner,
24
30
  ResourceTabs,
25
31
  Tab,
26
32
  FleetBundles,
33
+ DetailPage,
34
+ Masthead,
35
+ ViewOptions,
36
+ ForceDirectedTreeChart
27
37
  },
28
38
 
29
39
  props: {
@@ -33,6 +43,16 @@ export default {
33
43
  },
34
44
  },
35
45
 
46
+ setup(props) {
47
+ const defaultMastheadProps = useDefaultMastheadProps(props.value);
48
+ const currentView = useCurrentView();
49
+ const forceDirectedTreeChartProps = useDefaultForceDirectTreeChartProps(props.value);
50
+
51
+ return {
52
+ defaultMastheadProps, currentView, forceDirectedTreeChartProps, _GRAPH
53
+ };
54
+ },
55
+
36
56
  data() {
37
57
  return {
38
58
  allFleetClusters: [],
@@ -100,10 +120,6 @@ export default {
100
120
  }
101
121
  }, this.$store);
102
122
 
103
- if (this.value.authorId && this.$store.getters['management/schemaFor'](MANAGEMENT.USER)) {
104
- await this.$store.dispatch(`management/findAll`, { type: MANAGEMENT.USER }, { root: true });
105
- }
106
-
107
123
  this.allBundles = allDispatches.allBundles || [];
108
124
  this.allFleetClusters = allDispatches.allFleetClusters || [];
109
125
  },
@@ -112,46 +128,59 @@ export default {
112
128
  </script>
113
129
 
114
130
  <template>
115
- <Loading v-if="$fetchState.pending" />
116
- <div
117
- v-else
118
- class="mt-20"
119
- >
120
- <FleetSummary
121
- v-if="helmOpHasClusters"
122
- :value="value"
123
- :bundles="bundles"
124
- class="mb-20"
125
- />
126
- <Banner
127
- v-else
128
- color="info"
129
- class="mb-20"
130
- >
131
- {{ t('fleet.fleetSummary.noClusters.helmOp') }}
132
- </Banner>
133
- <ResourceTabs
134
- :value="value"
135
- mode="view"
136
- class="mt-20"
137
- :need-related="false"
138
- @update:value="$emit('input', $event)"
139
- >
140
- <Tab
141
- v-if="!!allBundles.length"
142
- label="Bundles"
143
- name="bundles"
144
- :weight="30"
145
- >
146
- <FleetBundles :value="value" />
147
- </Tab>
148
- <Tab
149
- label="Resources"
150
- name="resources"
151
- :weight="20"
152
- >
153
- <FleetResources :rows="value.resourcesStatuses" />
154
- </Tab>
155
- </ResourceTabs>
156
- </div>
131
+ <DetailPage :loading="$fetchState.pending">
132
+ <template #top-area>
133
+ <Masthead v-bind="defaultMastheadProps">
134
+ <template #additional-actions>
135
+ <ViewOptions />
136
+ </template>
137
+ </Masthead>
138
+ </template>
139
+ <template #bottom-area>
140
+ <template v-if="currentView === _GRAPH">
141
+ <ForceDirectedTreeChart v-bind="forceDirectedTreeChartProps" />
142
+ </template>
143
+
144
+ <template v-else>
145
+ <div class="mt-20">
146
+ <FleetSummary
147
+ v-if="helmOpHasClusters"
148
+ :value="value"
149
+ :bundles="bundles"
150
+ class="mb-20"
151
+ />
152
+ <Banner
153
+ v-else
154
+ color="info"
155
+ class="mb-20"
156
+ >
157
+ {{ t('fleet.fleetSummary.noClusters.helmOp') }}
158
+ </Banner>
159
+ <ResourceTabs
160
+ :value="value"
161
+ mode="view"
162
+ class="mt-20"
163
+ :need-related="false"
164
+ @update:value="$emit('input', $event)"
165
+ >
166
+ <Tab
167
+ v-if="!!allBundles.length"
168
+ label="Bundles"
169
+ name="bundles"
170
+ :weight="30"
171
+ >
172
+ <FleetBundles :value="value" />
173
+ </Tab>
174
+ <Tab
175
+ label="Resources"
176
+ name="resources"
177
+ :weight="20"
178
+ >
179
+ <FleetResources :rows="value.resourcesStatuses" />
180
+ </Tab>
181
+ </ResourceTabs>
182
+ </div>
183
+ </template>
184
+ </template>
185
+ </DetailPage>
157
186
  </template>
@@ -27,7 +27,7 @@ export default {
27
27
  if (this.resources[0]) {
28
28
  this.resources[0](value);
29
29
  delete this.resources[0];
30
- this.$emit('close', value);
30
+ this.$emit('close');
31
31
  }
32
32
  },
33
33
 
@@ -47,7 +47,7 @@ export default {
47
47
  decodeHtml,
48
48
  close() {
49
49
  this.confirm(false);
50
- this.$emit('close', false);
50
+ this.$emit('close');
51
51
  },
52
52
 
53
53
  async apply(buttonDone) {
@@ -28,12 +28,19 @@ export default {
28
28
  props: {
29
29
  defaultNamespace: {
30
30
  type: String,
31
- default: 'default'
31
+ default: undefined
32
32
  },
33
33
  },
34
34
 
35
35
  async fetch() {
36
- this.allNamespaces = await this.$store.dispatch('cluster/findAll', { type: NAMESPACE, opt: { url: 'namespaces' } });
36
+ this.allNamespaces = (await this.$store.dispatch('cluster/findAll', { type: NAMESPACE, opt: { url: 'namespaces' } })) || [];
37
+
38
+ if (this.selectedNamespace === undefined) {
39
+ const defaultNamespace = 'default';
40
+ const hasAccessToDefaultNamespace = this.allNamespaces.some((ns) => ns.name === defaultNamespace);
41
+
42
+ this.selectedNamespace = hasAccessToDefaultNamespace ? defaultNamespace : this.allNamespaces[0]?.name;
43
+ }
37
44
  },
38
45
 
39
46
  data() {
@@ -29,9 +29,9 @@ export default {
29
29
  required: true
30
30
  },
31
31
  /**
32
- * Modal mode
32
+ * The action to perform (install, update, rollback)
33
33
  */
34
- mode: {
34
+ action: {
35
35
  type: String,
36
36
  default: '',
37
37
  required: true
@@ -68,14 +68,14 @@ export default {
68
68
  // Default to latest version on install (this is default on the plugin)
69
69
  this.version = chartVersion;
70
70
 
71
- if (this.mode === 'update') {
71
+ if (this.action === 'update') {
72
72
  this.currentVersion = chartVersion;
73
73
 
74
74
  // Update to latest version, so take the first version
75
75
  if (this.plugin?.installableVersions?.length > 0) {
76
76
  this.version = this.plugin?.installableVersions?.[0]?.version;
77
77
  }
78
- } else if (this.mode === 'rollback') {
78
+ } else if (this.action === 'rollback') {
79
79
  // Find the newest version once we remove the current version
80
80
  const versionNames = this.plugin.installableVersions.filter((v) => v.version !== chartVersion);
81
81
 
@@ -94,7 +94,7 @@ export default {
94
94
  }
95
95
 
96
96
  this.busy = false;
97
- this.update = this.mode !== 'install';
97
+ this.update = this.action !== 'install';
98
98
 
99
99
  this.defaultRegistrySetting = await this.$store.dispatch('management/find', {
100
100
  type: MANAGEMENT.SETTING,
@@ -141,7 +141,15 @@ export default {
141
141
  },
142
142
 
143
143
  buttonMode() {
144
- return this.update ? 'update' : 'install';
144
+ if (this.action === 'rollback') {
145
+ return 'rollback';
146
+ }
147
+
148
+ if (this.action === 'update') {
149
+ return 'update';
150
+ }
151
+
152
+ return 'install';
145
153
  },
146
154
 
147
155
  chartVersionLoadsWithoutAuth() {
@@ -149,7 +157,7 @@ export default {
149
157
  },
150
158
 
151
159
  returnFocusSelector() {
152
- return `[data-testid="extension-card-${ this.mode }-btn-${ this.plugin?.name }"]`;
160
+ return `[data-testid="extension-card-${ this.action }-btn-${ this.plugin?.name }"]`;
153
161
  }
154
162
  },
155
163
 
@@ -190,7 +198,7 @@ export default {
190
198
 
191
199
  const plugin = this.plugin;
192
200
 
193
- this.updateStatus(plugin.name, 'install');
201
+ this.updateStatus(plugin.name, this.action);
194
202
 
195
203
  // Find the version that the user wants to install
196
204
  const version = plugin.versions?.find((v) => v.version === this.version);
@@ -287,12 +295,12 @@ export default {
287
295
  <template>
288
296
  <div class="plugin-install-dialog">
289
297
  <h4 class="mt-10">
290
- {{ t(`plugins.${ mode }.title`, { name: plugin?.label }) }}
298
+ {{ t(`plugins.${ action }.title`, { name: plugin?.label }) }}
291
299
  </h4>
292
300
  <div class="custom mt-10">
293
301
  <div class="dialog-panel">
294
302
  <p>
295
- {{ t(`plugins.${ mode }.prompt`) }}
303
+ {{ t(`plugins.${ action }.prompt`) }}
296
304
  </p>
297
305
  <Banner
298
306
  v-if="chartVersionLoadsWithoutAuth"
@@ -17,7 +17,7 @@ export default {
17
17
 
18
18
  computed: {
19
19
  name() {
20
- return this.authProvider?.nameDisplay;
20
+ return this.t(`model.authConfig.provider."${ this.authProvider?.id }"`);
21
21
  }
22
22
  },
23
23
 
@@ -74,7 +74,8 @@ const initGitRepo = (props: any, value?: any) => {
74
74
 
75
75
  return {
76
76
  props: {
77
- value: initValue,
77
+ value: initValue,
78
+ liveValue: initValue,
78
79
  ...props
79
80
  },
80
81
  computed: mockComputed,
@@ -0,0 +1,106 @@
1
+ import { nextTick } from 'vue';
2
+ import { mount } from '@vue/test-utils';
3
+ import RestoreComponent from '@shell/edit/resources.cattle.io.restore.vue';
4
+ import { _CREATE } from '@shell/config/query-params';
5
+
6
+ describe('view: restore storage source switching', () => {
7
+ let wrapper: any;
8
+
9
+ const mockStore = {
10
+ getters: {
11
+ currentStore: () => 'cluster',
12
+ 'cluster/schemaFor': jest.fn(),
13
+ 'cluster/all': jest.fn(),
14
+ 'cluster/paginationEnabled': jest.fn().mockReturnValue(false),
15
+ 'cluster/urlFor': jest.fn(),
16
+ 'i18n/t': (val: string) => val,
17
+ 'i18n/exists': jest.fn(),
18
+ },
19
+ dispatch: jest.fn().mockResolvedValue([])
20
+ };
21
+
22
+ const createWrapper = (propsOverride = {}) => {
23
+ const defaultProps = {
24
+ value: {
25
+ metadata: { name: '', generateName: 'restore-' },
26
+ spec: { prune: true, deleteTimeoutSeconds: 10 }
27
+ },
28
+ mode: _CREATE,
29
+ ...propsOverride
30
+ };
31
+
32
+ return mount(RestoreComponent, {
33
+ global: {
34
+ mocks: {
35
+ $store: mockStore,
36
+ $route: { query: {}, name: 'restore_route' },
37
+ $router: { applyQuery: jest.fn() },
38
+ $fetchState: { pending: false }
39
+ }
40
+ },
41
+ propsData: defaultProps
42
+ });
43
+ };
44
+
45
+ beforeEach(() => {
46
+ jest.clearAllMocks();
47
+ mockStore.dispatch.mockResolvedValue([]);
48
+ });
49
+
50
+ afterEach(() => {
51
+ if (wrapper) {
52
+ wrapper.unmount();
53
+ }
54
+ });
55
+
56
+ it('should not include S3 storageLocation when creating with useDefault', async() => {
57
+ wrapper = createWrapper();
58
+ await wrapper.vm.$nextTick();
59
+
60
+ wrapper.vm.storageSource = 'useDefault';
61
+ await nextTick();
62
+
63
+ expect(wrapper.vm.value.spec).toStrictEqual({
64
+ prune: true,
65
+ deleteTimeoutSeconds: 10
66
+ });
67
+ expect(wrapper.vm.value.spec.storageLocation).toBeUndefined();
68
+ expect(wrapper.vm.s3).toStrictEqual({});
69
+ });
70
+
71
+ it('should include S3 storageLocation when creating with An S3-compatible object store', async() => {
72
+ wrapper = createWrapper();
73
+ await wrapper.vm.$nextTick();
74
+
75
+ wrapper.vm.storageSource = 'configureS3';
76
+ await nextTick();
77
+
78
+ expect(wrapper.vm.value.spec.storageLocation).toBeDefined();
79
+ expect(wrapper.vm.value.spec.storageLocation.s3).toBeDefined();
80
+ expect(wrapper.vm.value.spec.prune).toBe(true);
81
+ expect(wrapper.vm.value.spec.deleteTimeoutSeconds).toBe(10);
82
+ });
83
+
84
+ it('should not include S3 storageLocation when switching from S3-compatible object store back to useDefault', async() => {
85
+ wrapper = createWrapper();
86
+ await wrapper.vm.$nextTick();
87
+
88
+ wrapper.vm.storageSource = 'configureS3';
89
+ wrapper.vm.s3 = {
90
+ bucketName: 'test-bucket',
91
+ endpoint: 'test-endpoint'
92
+ };
93
+ wrapper.vm.value.spec.storageLocation = { s3: wrapper.vm.s3 };
94
+ await nextTick();
95
+
96
+ expect(wrapper.vm.value.spec.storageLocation).toBeDefined();
97
+
98
+ wrapper.vm.storageSource = 'useDefault';
99
+ await nextTick();
100
+
101
+ expect(wrapper.vm.value.spec.storageLocation).toBeUndefined();
102
+ expect(wrapper.vm.s3).toStrictEqual({});
103
+ expect(wrapper.vm.value.spec.prune).toBe(true);
104
+ expect(wrapper.vm.value.spec.deleteTimeoutSeconds).toBe(10);
105
+ });
106
+ });