@rancher/shell 0.1.3 → 0.1.21

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 (245) hide show
  1. package/assets/brand/suse/dark/rancher-logo.svg +1 -148
  2. package/assets/brand/suse/favicon.png +0 -0
  3. package/assets/brand/suse/rancher-logo.svg +1 -130
  4. package/assets/images/featured/img1.jpg +0 -0
  5. package/assets/images/featured.jpg +0 -0
  6. package/assets/images/generic-plugin.svg +1 -0
  7. package/assets/styles/themes/_dark.scss +3 -0
  8. package/assets/styles/themes/_light.scss +3 -0
  9. package/assets/styles/themes/_suse.scss +1 -1
  10. package/assets/translations/en-us.yaml +219 -47
  11. package/assets/translations/zh-hans.yaml +21 -24
  12. package/components/AsyncButton.vue +17 -2
  13. package/components/ButtonDropdown.vue +4 -0
  14. package/components/Carousel.vue +291 -0
  15. package/components/CommunityLinks.vue +64 -22
  16. package/components/CruResource.vue +11 -3
  17. package/components/Dialog.vue +102 -0
  18. package/components/ExplorerMembers.vue +2 -4
  19. package/components/ExplorerProjectsNamespaces.vue +25 -9
  20. package/components/IconMessage.vue +9 -1
  21. package/components/LazyImage.vue +21 -8
  22. package/components/LocaleSelector.vue +62 -29
  23. package/components/PromptRemove.vue +2 -2
  24. package/components/ResourceList/Masthead.vue +21 -1
  25. package/components/ResourceList/ResourceLoadingIndicator.vue +0 -8
  26. package/components/ResourceList/index.vue +9 -23
  27. package/components/ResourceTable.vue +7 -2
  28. package/components/SimpleBox.vue +6 -4
  29. package/components/SortableTable/index.vue +18 -25
  30. package/components/Tabbed/Tab.vue +5 -0
  31. package/components/Tabbed/index.vue +54 -9
  32. package/components/TypeDescription.vue +10 -1
  33. package/components/auth/Principal.vue +1 -0
  34. package/components/fleet/FleetBundles.vue +8 -3
  35. package/components/fleet/FleetClusters.vue +6 -0
  36. package/components/fleet/FleetRepos.vue +7 -1
  37. package/components/fleet/FleetSummary.vue +6 -0
  38. package/components/form/Command.vue +5 -0
  39. package/components/form/EnvVars.vue +5 -0
  40. package/components/form/KeyValue.vue +80 -58
  41. package/components/form/NameNsDescription.vue +13 -5
  42. package/components/form/NodeScheduling.vue +6 -1
  43. package/components/form/PodAffinity.vue +5 -0
  44. package/components/form/ResourceTabs/index.vue +5 -1
  45. package/components/form/ServiceNameSelect.vue +5 -0
  46. package/components/form/ValueFromResource.vue +7 -1
  47. package/components/formatter/ClusterLink.vue +3 -7
  48. package/components/nav/NamespaceFilter.vue +3 -3
  49. package/components/nav/TopLevelMenu.vue +12 -29
  50. package/config/home-links.js +155 -0
  51. package/config/labels-annotations.js +2 -1
  52. package/config/private-label.js +1 -1
  53. package/config/product/explorer.js +5 -4
  54. package/config/product/legacy.js +0 -47
  55. package/config/product/manager.js +0 -2
  56. package/config/product/multi-cluster-apps.js +0 -12
  57. package/config/product/settings.js +12 -1
  58. package/config/product/uiplugins.js +17 -0
  59. package/config/settings.js +23 -2
  60. package/config/types.js +5 -1
  61. package/config/uiplugins.js +117 -0
  62. package/config/version.js +17 -0
  63. package/content/docs/en-us/getting-started.md +1 -26
  64. package/core/plugin.ts +12 -0
  65. package/core/plugins.js +38 -2
  66. package/core/types.ts +6 -0
  67. package/creators/app/{.eslintignore → files/.eslintignore} +0 -0
  68. package/creators/app/{.eslintrc.js → files/.eslintrc.js} +0 -0
  69. package/creators/app/{.vscode → files/.vscode}/settings.json +0 -0
  70. package/creators/app/{babel.config.js → files/babel.config.js} +0 -0
  71. package/creators/app/{nuxt.config.js → files/nuxt.config.js} +0 -0
  72. package/creators/app/{tsconfig.json → files/tsconfig.json} +2 -1
  73. package/creators/app/init +16 -17
  74. package/creators/app/package.json +6 -0
  75. package/creators/pkg/{babel.config.js → files/babel.config.js} +0 -0
  76. package/creators/pkg/{index.ts → files/index.ts} +0 -0
  77. package/creators/pkg/{tsconfig.json → files/tsconfig.json} +13 -12
  78. package/creators/pkg/{vue.config.js → files/vue.config.js} +0 -0
  79. package/creators/pkg/init +1 -1
  80. package/creators/update/init +54 -0
  81. package/creators/update/package.json +20 -0
  82. package/creators/update/upgrade +56 -0
  83. package/creators/update/yarn-error.log +54 -0
  84. package/detail/provisioning.cattle.io.cluster.vue +3 -3
  85. package/detail/workload/index.vue +3 -2
  86. package/dialog/DiagnosticTimingsDialog.vue +116 -0
  87. package/dialog/RotateCertificatesDialog.vue +9 -3
  88. package/edit/auth/azuread.vue +28 -9
  89. package/edit/networking.k8s.io.ingress/index.vue +2 -2
  90. package/edit/persistentvolume/index.vue +51 -13
  91. package/edit/persistentvolumeclaim.vue +31 -13
  92. package/edit/pod.vue +27 -0
  93. package/edit/provisioning.cattle.io.cluster/rke2.vue +103 -24
  94. package/edit/service.vue +7 -5
  95. package/edit/workload/__tests__/Upgrading.test.ts +1 -0
  96. package/edit/workload/index.vue +32 -10
  97. package/edit/workload/mixins/workload.js +121 -126
  98. package/edit/workload/storage/ContainerMountPaths.vue +240 -0
  99. package/edit/workload/storage/Mount.vue +1 -0
  100. package/edit/workload/storage/awsElasticBlockStore.vue +20 -1
  101. package/edit/workload/storage/azureDisk.vue +22 -2
  102. package/edit/workload/storage/azureFile.vue +20 -2
  103. package/edit/workload/storage/csi/index.vue +23 -1
  104. package/edit/workload/storage/gcePersistentDisk.vue +20 -2
  105. package/edit/workload/storage/index.vue +33 -65
  106. package/edit/workload/storage/persistentVolumeClaim/index.vue +5 -0
  107. package/edit/workload/storage/secret.vue +6 -1
  108. package/edit/workload/storage/vsphereVolume.vue +11 -1
  109. package/layouts/default.vue +14 -8
  110. package/layouts/home.vue +9 -4
  111. package/layouts/plain.vue +10 -5
  112. package/list/catalog.cattle.io.app.vue +10 -9
  113. package/list/catalog.cattle.io.clusterrepo.vue +6 -61
  114. package/list/cis.cattle.io.clusterscan.vue +12 -12
  115. package/list/fleet.cattle.io.bundle.vue +33 -28
  116. package/list/fleet.cattle.io.cluster.vue +26 -22
  117. package/list/fleet.cattle.io.clustergroup.vue +6 -0
  118. package/list/fleet.cattle.io.clusterregistrationtoken.vue +28 -24
  119. package/list/fleet.cattle.io.gitrepo.vue +25 -14
  120. package/list/helm.cattle.io.projecthelmchart.vue +52 -33
  121. package/list/logging.banzaicloud.io.clusterflow.vue +7 -12
  122. package/list/logging.banzaicloud.io.flow.vue +7 -14
  123. package/list/management.cattle.io.cluster.vue +26 -15
  124. package/list/management.cattle.io.feature.vue +13 -8
  125. package/list/management.cattle.io.setting.vue +3 -3
  126. package/list/management.cattle.io.user.vue +38 -19
  127. package/list/monitoring.coreos.com.alertmanagerconfig.vue +8 -15
  128. package/list/namespace.vue +14 -1
  129. package/list/node.vue +13 -16
  130. package/list/persistentvolume.vue +16 -9
  131. package/list/persistentvolumeclaim.vue +5 -8
  132. package/list/provisioning.cattle.io.cluster.vue +35 -9
  133. package/list/service.vue +24 -12
  134. package/list/ui.cattle.io.navlink.vue +6 -0
  135. package/list/workload.vue +2 -2
  136. package/machine-config/harvester.vue +5 -3
  137. package/middleware/authenticated.js +6 -0
  138. package/mixins/resource-fetch.js +12 -18
  139. package/mixins/resource-manager.js +126 -0
  140. package/models/catalog.cattle.io.uiplugin.js +38 -0
  141. package/models/cluster/node.js +25 -2
  142. package/models/fleet.cattle.io.bundle.js +1 -1
  143. package/models/harvesterhci.io.management.cluster.js +11 -5
  144. package/models/pod.js +15 -5
  145. package/models/provisioning.cattle.io.cluster.js +16 -6
  146. package/models/workload.js +5 -3
  147. package/models/workload.service.js +10 -0
  148. package/nuxt.config.js +70 -25
  149. package/package.json +108 -109
  150. package/pages/auth/login.vue +11 -1
  151. package/pages/auth/verify.vue +9 -0
  152. package/pages/c/_cluster/apps/charts/index.vue +46 -1
  153. package/pages/c/_cluster/apps/charts/install.vue +10 -9
  154. package/pages/c/_cluster/explorer/index.vue +72 -9
  155. package/pages/c/_cluster/explorer/tools/index.vue +12 -5
  156. package/pages/c/_cluster/mcapps/index.vue +1 -1
  157. package/pages/c/_cluster/settings/DefaultLinksEditor.vue +108 -0
  158. package/pages/c/_cluster/settings/brand.vue +0 -40
  159. package/pages/c/_cluster/settings/links.vue +152 -0
  160. package/pages/c/_cluster/settings/performance.vue +90 -7
  161. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +232 -0
  162. package/pages/c/_cluster/uiplugins/InstallDialog.vue +293 -0
  163. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +300 -0
  164. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +125 -0
  165. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +261 -0
  166. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +122 -0
  167. package/pages/c/_cluster/uiplugins/index.vue +808 -0
  168. package/pages/diagnostic.vue +185 -101
  169. package/pages/docs/_doc.vue +3 -1
  170. package/pages/home.vue +21 -56
  171. package/pages/prefs.vue +108 -88
  172. package/pages/safeMode.vue +17 -0
  173. package/pages/support/index.vue +34 -137
  174. package/pkg/dynamic-importer.lib.js +4 -0
  175. package/plugins/dashboard-store/actions.js +19 -0
  176. package/plugins/dashboard-store/getters.js +20 -3
  177. package/plugins/dashboard-store/mutations.js +13 -7
  178. package/plugins/dashboard-store/resource-class.js +2 -2
  179. package/plugins/formatters.js +15 -0
  180. package/plugins/plugin.js +61 -6
  181. package/plugins/steve/getters.js +12 -0
  182. package/plugins/steve/mutations.js +1 -1
  183. package/plugins/steve/subscribe.js +94 -72
  184. package/plugins/steve/web-worker.steve-sub-worker.js +24 -15
  185. package/plugins/version.js +21 -0
  186. package/promptRemove/management.cattle.io.globalrole.vue +47 -0
  187. package/promptRemove/management.cattle.io.roletemplate.vue +47 -0
  188. package/promptRemove/mixin/roleDeletionCheck.js +97 -0
  189. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +6 -7
  190. package/rancher-components/components/BadgeState/BadgeState.spec.ts +12 -0
  191. package/rancher-components/components/BadgeState/BadgeState.vue +107 -0
  192. package/rancher-components/components/BadgeState/index.ts +1 -0
  193. package/rancher-components/components/Banner/Banner.test.ts +13 -0
  194. package/rancher-components/components/Banner/Banner.vue +163 -0
  195. package/rancher-components/components/Banner/index.ts +1 -0
  196. package/rancher-components/components/Card/Card.vue +150 -0
  197. package/rancher-components/components/Card/index.ts +1 -0
  198. package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +77 -0
  199. package/rancher-components/components/Form/Checkbox/Checkbox.vue +395 -0
  200. package/rancher-components/components/Form/Checkbox/index.ts +1 -0
  201. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +29 -0
  202. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +343 -0
  203. package/rancher-components/components/Form/LabeledInput/index.ts +1 -0
  204. package/rancher-components/components/Form/Radio/RadioButton.vue +270 -0
  205. package/rancher-components/components/Form/Radio/RadioGroup.vue +235 -0
  206. package/rancher-components/components/Form/Radio/index.ts +2 -0
  207. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +168 -0
  208. package/rancher-components/components/Form/TextArea/index.ts +1 -0
  209. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +107 -0
  210. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +137 -0
  211. package/rancher-components/components/Form/ToggleSwitch/index.ts +1 -0
  212. package/rancher-components/components/Form/index.ts +5 -0
  213. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +137 -0
  214. package/rancher-components/components/LabeledTooltip/index.ts +1 -0
  215. package/scripts/publish-shell.sh +40 -7
  216. package/scripts/record-deps.js +37 -0
  217. package/scripts/sync-shell-deps +37 -0
  218. package/scripts/test-plugins-build.sh +8 -5
  219. package/scripts/typegen.sh +84 -0
  220. package/store/auth.js +3 -0
  221. package/store/catalog.js +9 -8
  222. package/store/i18n.js +10 -1
  223. package/store/index.js +12 -3
  224. package/store/prefs.js +16 -0
  225. package/store/type-map.js +32 -5
  226. package/store/uiplugins.ts +15 -61
  227. package/types/shell/index.d.ts +3046 -0
  228. package/utils/__tests__/object.test.ts +0 -24
  229. package/utils/__tests__/selector.test.ts +1 -1
  230. package/utils/dynamic-importer.js +4 -0
  231. package/utils/favicon.js +8 -2
  232. package/utils/gc/gc-interval.ts +40 -0
  233. package/utils/gc/gc-root-store.js +76 -0
  234. package/utils/gc/gc-route-changed.ts +44 -0
  235. package/utils/gc/gc-types.ts +21 -0
  236. package/utils/gc/gc.ts +282 -0
  237. package/utils/grafana.js +2 -6
  238. package/utils/socket.js +41 -20
  239. package/utils/string.js +1 -7
  240. package/utils/validators/formRules/__tests__/index.test.ts +108 -0
  241. package/utils/validators/formRules/index.ts +9 -1
  242. package/config/footer.js +0 -19
  243. package/creators/pkg/nuxt.config.js +0 -6
  244. package/pages/plugins.vue +0 -387
  245. package/server/verdaccio-middleware.js +0 -56
@@ -24,8 +24,9 @@ import {
24
24
  COUNT,
25
25
  CATALOG,
26
26
  POD,
27
+ PSP,
27
28
  } from '@shell/config/types';
28
- import { mapPref, CLUSTER_TOOLS_TIP } from '@shell/store/prefs';
29
+ import { mapPref, CLUSTER_TOOLS_TIP, PSP_DEPRECATION_BANNER } from '@shell/store/prefs';
29
30
  import { haveV1Monitoring, monitoringStatus } from '@shell/utils/monitoring';
30
31
  import Tabbed from '@shell/components/Tabbed';
31
32
  import Tab from '@shell/components/Tabbed/Tab';
@@ -111,12 +112,12 @@ export default {
111
112
 
112
113
  return {
113
114
  nodeHeaders,
114
- constraints: [],
115
- events: [],
116
- nodeMetrics: [],
117
- showClusterMetrics: false,
118
- showK8sMetrics: false,
119
- showEtcdMetrics: false,
115
+ constraints: [],
116
+ events: [],
117
+ nodeMetrics: [],
118
+ showClusterMetrics: false,
119
+ showK8sMetrics: false,
120
+ showEtcdMetrics: false,
120
121
  CLUSTER_METRICS_DETAIL_URL,
121
122
  CLUSTER_METRICS_SUMMARY_URL,
122
123
  K8S_METRICS_DETAIL_URL,
@@ -124,7 +125,7 @@ export default {
124
125
  ETCD_METRICS_DETAIL_URL,
125
126
  ETCD_METRICS_SUMMARY_URL,
126
127
  clusterCounts,
127
- selectedTab: 'cluster-events',
128
+ selectedTab: 'cluster-events',
128
129
  };
129
130
  },
130
131
 
@@ -142,6 +143,20 @@ export default {
142
143
  ...mapGetters(['currentCluster']),
143
144
  ...monitoringStatus(),
144
145
 
146
+ displayPspDeprecationBanner() {
147
+ const cluster = this.currentCluster;
148
+ const major = cluster.status?.version?.major ? parseInt(cluster.status?.version?.major) : 0;
149
+ const minor = cluster.status?.version?.minor ? parseInt(cluster.status?.version?.minor) : 0;
150
+
151
+ if (major === 1 && minor >= 21 && minor < 25) {
152
+ const clusterCounts = this.$store.getters[`cluster/all`](COUNT)?.[0]?.counts;
153
+
154
+ return !!clusterCounts?.[PSP]?.summary?.count;
155
+ }
156
+
157
+ return false;
158
+ },
159
+
145
160
  nodes() {
146
161
  return this.$store.getters['cluster/all'](NODE);
147
162
  },
@@ -150,7 +165,8 @@ export default {
150
165
  return this.$store.getters['management/all'](MANAGEMENT.CLUSTER);
151
166
  },
152
167
 
153
- hideClusterToolsTip: mapPref(CLUSTER_TOOLS_TIP),
168
+ hideClusterToolsTip: mapPref(CLUSTER_TOOLS_TIP),
169
+ hidePspDeprecationBanner: mapPref(PSP_DEPRECATION_BANNER),
154
170
 
155
171
  hasV1Monitoring() {
156
172
  return haveV1Monitoring(this.$store.getters);
@@ -324,6 +340,16 @@ export default {
324
340
 
325
341
  hasDescription() {
326
342
  return !!this.currentCluster?.spec?.description;
343
+ },
344
+
345
+ allEventsLink() {
346
+ return {
347
+ name: 'c-cluster-product-resource',
348
+ params: {
349
+ product: 'explorer',
350
+ resource: 'event',
351
+ }
352
+ };
327
353
  }
328
354
  },
329
355
 
@@ -378,6 +404,14 @@ export default {
378
404
  </div>
379
405
  </div>
380
406
  </header>
407
+ <Banner
408
+ v-if="displayPspDeprecationBanner && !hidePspDeprecationBanner"
409
+ :closable="true"
410
+ color="warning"
411
+ @close="hidePspDeprecationBanner = true"
412
+ >
413
+ <t k="landing.deprecatedPsp" :raw="true" />
414
+ </Banner>
381
415
  <Banner
382
416
  v-if="!hideClusterToolsTip"
383
417
  :closable="true"
@@ -403,6 +437,14 @@ export default {
403
437
  <label>{{ t('glance.created') }}: </label>
404
438
  <span><LiveDate :value="currentCluster.metadata.creationTimestamp" :add-suffix="true" :show-tooltip="true" /></span>
405
439
  </div>
440
+ <p
441
+ v-if="displayPspDeprecationBanner && hidePspDeprecationBanner"
442
+ v-tooltip="t('landing.deprecatedPsp')"
443
+ class="alt-psp-deprecation-info"
444
+ >
445
+ <span>{{ t('landing.psps') }}</span>
446
+ <i class="icon icon-warning" />
447
+ </p>
406
448
  <div :style="{'flex':1}" />
407
449
  <div v-if="!monitoringStatus.v2 && !monitoringStatus.v1">
408
450
  <n-link :to="{name: 'c-cluster-explorer-tools'}" class="monitoring-install">
@@ -446,6 +488,11 @@ export default {
446
488
  <div class="mt-30">
447
489
  <Tabbed @changed="tabChange">
448
490
  <Tab name="cluster-events" :label="t('clusterIndexPage.sections.events.label')" :weight="2">
491
+ <span class="events-table-link">
492
+ <n-link :to="allEventsLink">
493
+ <span>{{ t('glance.eventsTable') }}</span>
494
+ </n-link>
495
+ </span>
449
496
  <EventsTable />
450
497
  </Tab>
451
498
  <Tab v-if="hasMonitoring" name="cluster-alerts" :label="t('clusterIndexPage.sections.alerts.label')" :weight="1">
@@ -534,6 +581,16 @@ export default {
534
581
  margin-top: 0;
535
582
  }
536
583
 
584
+ .alt-psp-deprecation-info {
585
+ display: flex;
586
+ align-items: center;
587
+ color: var(--warning);
588
+
589
+ span {
590
+ margin-right: 4px;
591
+ }
592
+ }
593
+
537
594
  .monitoring-install {
538
595
  display: flex;
539
596
  margin-left: 10px;
@@ -548,6 +605,12 @@ export default {
548
605
  }
549
606
  }
550
607
 
608
+ .events-table-link {
609
+ display: flex;
610
+ justify-content: flex-end;
611
+ margin-bottom: 20px;
612
+ }
613
+
551
614
  .k8s-component-status {
552
615
  align-items: center;
553
616
  display: inline-flex;
@@ -121,13 +121,15 @@ export default {
121
121
  showTypes: [CATALOG_ANNOTATIONS._CLUSTER_TOOL],
122
122
  });
123
123
 
124
+ charts = charts.filter(c => c.sideLabel !== 'Experimental');
125
+
124
126
  // If legacy support is enabled, show V1 charts for some V1 Cluster tools
125
127
  if (this.legacyEnabled) {
126
128
  charts = charts.concat(this.legacyCharts);
127
129
  charts = sortBy(charts, ['certifiedSort', 'chartNameDisplay']);
128
130
  }
129
131
 
130
- const chartsWithApps = charts.map((chart) => {
132
+ let chartsWithApps = charts.map((chart) => {
131
133
  return {
132
134
  chart,
133
135
  app: this.installedAppForChart[chart.id],
@@ -136,9 +138,9 @@ export default {
136
138
 
137
139
  // V1 Legacy support
138
140
  if (this.legacyEnabled) {
139
- this.checkLegacyApp(chartsWithApps, this.v1Apps, 'v1-monitoring', 'rancher-monitoring', 'cluster-monitoring');
140
- this.checkLegacyApp(chartsWithApps, this.v1Apps, 'v1-istio', 'rancher-istio', 'cluster-istio');
141
- this.checkLegacyApp(chartsWithApps, this.v1Apps, 'v1-logging', 'rancher-logging', 'rancher-logging');
141
+ chartsWithApps = this.checkLegacyApp(chartsWithApps, this.v1Apps, 'v1-monitoring', 'rancher-monitoring', 'cluster-monitoring', false);
142
+ chartsWithApps = this.checkLegacyApp(chartsWithApps, this.v1Apps, 'v1-istio', 'rancher-istio', 'cluster-istio', true);
143
+ chartsWithApps = this.checkLegacyApp(chartsWithApps, this.v1Apps, 'v1-logging', 'rancher-logging', 'rancher-logging', true);
142
144
  }
143
145
 
144
146
  return chartsWithApps;
@@ -231,7 +233,7 @@ export default {
231
233
  return versions;
232
234
  },
233
235
 
234
- checkLegacyApp(chartsWithApps, v1Apps, v1ChartName, v2ChartName, v1AppName) {
236
+ checkLegacyApp(chartsWithApps, v1Apps, v1ChartName, v2ChartName, v1AppName, showOnlyIfInstalled) {
235
237
  const v1 = chartsWithApps.find(a => a.chart.chartName === v1ChartName);
236
238
  const v2 = chartsWithApps.find(a => a.chart.chartName === v2ChartName);
237
239
 
@@ -251,6 +253,9 @@ export default {
251
253
  v1.app.upgradeAvailable = latest;
252
254
  }
253
255
  }
256
+ } else if (showOnlyIfInstalled) {
257
+ // Remove the v1 chart if it is not already installed for charts which we no longer support
258
+ chartsWithApps = chartsWithApps.filter(c => c !== v1);
254
259
  }
255
260
 
256
261
  if (v2) {
@@ -262,6 +267,8 @@ export default {
262
267
  }
263
268
  }
264
269
  }
270
+
271
+ return chartsWithApps;
265
272
  }
266
273
  }
267
274
  };
@@ -8,7 +8,7 @@ export default {
8
8
  params: {
9
9
  ...route.params,
10
10
  product: NAME,
11
- page: 'apps'
11
+ page: 'catalogs'
12
12
  }
13
13
  });
14
14
  }
@@ -0,0 +1,108 @@
1
+ <script>
2
+ import Vue from 'vue';
3
+
4
+ import { _VIEW } from '@shell/config/query-params';
5
+ import { Checkbox } from '@components/Form/Checkbox';
6
+
7
+ export default {
8
+ name: 'DefaultLinksEditor',
9
+
10
+ components: { Checkbox },
11
+
12
+ props: {
13
+ // Array of objects with key, label, value and enabled properties
14
+ value: {
15
+ type: Array,
16
+ default: () => [],
17
+ },
18
+
19
+ mode: {
20
+ type: String,
21
+ required: true
22
+ },
23
+ },
24
+
25
+ computed: {
26
+ isView() {
27
+ return this.mode === _VIEW;
28
+ }
29
+ },
30
+
31
+ methods: {
32
+ showhide(row, i, e) {
33
+ const value = this.value[i];
34
+
35
+ Vue.set(value, 'enabled', !!value.enabled);
36
+ this.$emit('input', this.value);
37
+ },
38
+ }
39
+ };
40
+ </script>
41
+
42
+ <template>
43
+ <div class="key-value">
44
+ <div class="clearfix">
45
+ <h3>
46
+ {{ t('customLinks.settings.default') }}
47
+ </h3>
48
+ </div>
49
+
50
+ <div class="kv-container">
51
+ <label class="text-label">
52
+ {{ t('customLinks.settings.keyLabel') }}
53
+ </label>
54
+ <label class="text-label">
55
+ {{ t('customLinks.settings.valueLabel') }}
56
+ </label>
57
+ <label class="text-label">
58
+ </label>
59
+
60
+ <template v-for="(row,i) in value">
61
+ <div :key="i+'key'" class="kv-item key" :class="{'link-hidden': !row.enabled}">
62
+ <span>{{ row.label }}</span>
63
+ </div>
64
+
65
+ <div :key="i+'value'" class="kv-item value" :class="{'link-hidden': !row.enabled}">
66
+ <span>{{ row.value }}</span>
67
+ </div>
68
+
69
+ <div v-if="!row.readonly && !isView" :key="i+'show'">
70
+ <Checkbox v-if="!isView" v-model="row.enabled" label-key="customLinks.settings.showLabel" @input="showhide(row, i, $event)" />
71
+ </div>
72
+ <div v-else :key="i+'show'"></div>
73
+ </template>
74
+ </div>
75
+ </div>
76
+ </template>
77
+
78
+ <style lang="scss" scoped>
79
+ .key-value {
80
+ width: 100%;
81
+
82
+ .kv-container {
83
+ display: grid;
84
+ align-items: center;
85
+ grid-template-columns: 1fr 1fr 50px;
86
+ column-gap: $column-gutter;
87
+
88
+ .kv-item {
89
+ background-color: var(--disabled-bg);
90
+ border: 1px solid var(--border);
91
+ border-radius: 5px;
92
+ width: 100%;
93
+ margin: 10px 0px 10px 0px;
94
+ height: 40px;
95
+ line-height: 40px;
96
+ padding: 0 10px;
97
+
98
+ &.link-hidden {
99
+ color: var(--disabled-text);
100
+ }
101
+
102
+ &.key {
103
+ align-self: flex-start;
104
+ }
105
+ }
106
+ }
107
+ }
108
+ </style>
@@ -17,7 +17,6 @@ import { _EDIT, _VIEW } from '@shell/config/query-params';
17
17
  import { setFavIcon } from '@shell/utils/favicon';
18
18
 
19
19
  const Color = require('color');
20
- const parse = require('url-parse');
21
20
 
22
21
  export default {
23
22
  layout: 'authenticated',
@@ -29,12 +28,10 @@ export default {
29
28
  async fetch() {
30
29
  const hash = await allHash({
31
30
  uiPLSetting: this.$store.dispatch('management/find', { type: MANAGEMENT.SETTING, id: SETTING.PL }),
32
- uiIssuesSetting: this.$store.dispatch('management/find', { type: MANAGEMENT.SETTING, id: SETTING.ISSUES }),
33
31
  uiLogoDarkSetting: fetchOrCreateSetting(this.$store, SETTING.LOGO_DARK, ''),
34
32
  uiLogoLightSetting: fetchOrCreateSetting(this.$store, SETTING.LOGO_LIGHT, ''),
35
33
  uiColorSetting: fetchOrCreateSetting(this.$store, SETTING.PRIMARY_COLOR, ''),
36
34
  uiLinkColorSetting: fetchOrCreateSetting(this.$store, SETTING.LINK_COLOR, ''),
37
- uiCommunitySetting: fetchOrCreateSetting(this.$store, SETTING.COMMUNITY_LINKS, 'true'),
38
35
  uiFaviconSetting: fetchOrCreateSetting(this.$store, SETTING.FAVICON, ''),
39
36
  });
40
37
 
@@ -75,8 +72,6 @@ export default {
75
72
  vendor: getVendor(),
76
73
  uiPLSetting: {},
77
74
 
78
- uiIssuesSetting: {},
79
-
80
75
  uiLogoDarkSetting: {},
81
76
  uiLogoDark: '',
82
77
  uiLogoLightSetting: {},
@@ -94,8 +89,6 @@ export default {
94
89
  uiLinkColor: null,
95
90
  customizeLinkColor: false,
96
91
 
97
- uiCommunitySetting: {},
98
-
99
92
  errors: [],
100
93
 
101
94
  };
@@ -134,22 +127,7 @@ export default {
134
127
  this.errors.push(e);
135
128
  },
136
129
 
137
- validateUrl(url) {
138
- const parsed = parse(url, {});
139
-
140
- if (!parsed.protocol) {
141
- this.errors.push(this.t('branding.uiIssues.invalidUrl'));
142
-
143
- return false;
144
- }
145
-
146
- return true;
147
- },
148
-
149
130
  async save(btnCB) {
150
- if (this.uiIssuesSetting.value && !this.validateUrl(this.uiIssuesSetting.value)) {
151
- return btnCB(false);
152
- }
153
131
  this.uiPLSetting.value = this.uiPLSetting.value.replaceAll(/[\<>&=#()"]/gm, '');
154
132
 
155
133
  if (this.customizeLogo) {
@@ -183,12 +161,10 @@ export default {
183
161
  try {
184
162
  await Promise.all([
185
163
  this.uiPLSetting.save(),
186
- this.uiIssuesSetting.save(),
187
164
  this.uiLogoDarkSetting.save(),
188
165
  this.uiLogoLightSetting.save(),
189
166
  this.uiColorSetting.save(),
190
167
  this.uiLinkColorSetting.save(),
191
- this.uiCommunitySetting.save(),
192
168
  this.uiFaviconSetting.save()
193
169
  ]);
194
170
  if (this.uiPLSetting.value !== this.vendor) {
@@ -219,22 +195,6 @@ export default {
219
195
  <LabeledInput v-model="uiPLSetting.value" :label="t('branding.uiPL.label')" :mode="mode" :maxlength="100" />
220
196
  </div>
221
197
  </div>
222
-
223
- <h3 class="mt-20 mb-5 pb-5">
224
- {{ t('branding.uiIssues.label') }}
225
- </h3>
226
- <label class="text-label">
227
- {{ t(`advancedSettings.descriptions.${ 'ui-issues' }`, {}, true) }}
228
- </label>
229
- <div :style="{'align-items':'center'}" class="row mt-10">
230
- <div class="col span-6 pb-5">
231
- <LabeledInput v-model="uiIssuesSetting.value" :label="t('branding.uiIssues.issuesUrl')" :mode="mode" />
232
- </div>
233
- <div class="col span-6">
234
- <Checkbox :value="uiCommunitySetting.value === 'true'" :label="t('branding.uiIssues.communityLinks')" :mode="mode" @input="e=>$set(uiCommunitySetting, 'value', e.toString())" />
235
- </div>
236
- </div>
237
-
238
198
  <h3 class="mt-20 mb-5 pb-5">
239
199
  {{ t('branding.logos.label') }}
240
200
  </h3>
@@ -0,0 +1,152 @@
1
+ <script>
2
+ import Loading from '@shell/components/Loading';
3
+ import AsyncButton from '@shell/components/AsyncButton';
4
+ import Banner from '@components/Banner/Banner.vue';
5
+ import { MANAGEMENT } from '@shell/config/types';
6
+ import { _EDIT, _VIEW } from '@shell/config/query-params';
7
+ import KeyValue from '@shell/components/form/KeyValue';
8
+ import { mapGetters } from 'vuex';
9
+ import { isRancherPrime } from '@shell/config/version';
10
+ import DefaultLinksEditor from './DefaultLinksEditor';
11
+ import { CUSTOM_LINKS_VERSION, fetchLinks } from '@shell/config/home-links';
12
+ import { SETTING, fetchOrCreateSetting } from '@shell/config/settings';
13
+
14
+ export default {
15
+ layout: 'authenticated',
16
+ components: {
17
+ KeyValue,
18
+ Loading,
19
+ AsyncButton,
20
+ Banner,
21
+ DefaultLinksEditor,
22
+ },
23
+ async fetch() {
24
+ this.value = await fetchLinks(this.$store, this.hasSupport, false, str => this.t(str));
25
+ },
26
+
27
+ data() {
28
+ return {
29
+ defaultsDisabled: true,
30
+ isRancherPrime: isRancherPrime(),
31
+ uiCustomLinks: {},
32
+ bannerVal: {},
33
+ value: [],
34
+ errors: [],
35
+ };
36
+ },
37
+ computed: {
38
+ ...mapGetters({ multiWithFallback: 'i18n/multiWithFallback' }),
39
+
40
+ mode() {
41
+ const schema = this.$store.getters[`management/schemaFor`](MANAGEMENT.SETTING);
42
+
43
+ return schema?.resourceMethods?.includes('PUT') ? _EDIT : _VIEW;
44
+ },
45
+
46
+ allValues() {
47
+ return {
48
+ version: CUSTOM_LINKS_VERSION,
49
+ defaults: this.value.defaults.filter(obj => obj.enabled).map(obj => obj.key),
50
+ custom: this.value.custom
51
+ };
52
+ },
53
+
54
+ hasSupport() {
55
+ return isRancherPrime() || this.$store.getters['management/byId'](MANAGEMENT.SETTING, SETTING.SUPPORTED )?.value === 'true';
56
+ },
57
+ },
58
+ methods: {
59
+ deprecateIssueLinks() {
60
+ if (this.uiIssuesSetting.value || this.uiIssuesSetting.value) {
61
+ this.uiIssuesSetting.value = '';
62
+ this.uiCommunitySetting.value = '';
63
+
64
+ return this.uiIssuesSetting.save();
65
+ }
66
+ },
67
+
68
+ async save(btnCB) {
69
+ this.errors = [];
70
+ try {
71
+ const uiCustomLinks = await fetchOrCreateSetting(this.$store, SETTING.UI_CUSTOM_LINKS, '');
72
+
73
+ uiCustomLinks.value = JSON.stringify(this.allValues);
74
+
75
+ await uiCustomLinks.save();
76
+
77
+ this.value = await fetchLinks(this.$store, this.hasSupport, false, str => this.t(str));
78
+ btnCB(true);
79
+ } catch (err) {
80
+ this.errors.push(err);
81
+ btnCB(false);
82
+ }
83
+ },
84
+ }
85
+ };
86
+ </script>
87
+ <template>
88
+ <Loading v-if="$fetchState.pending" />
89
+ <div v-else>
90
+ <h1 class="mb-20">
91
+ {{ t("customLinks.label") }}
92
+ </h1>
93
+ <div>
94
+ <label class="text-label">
95
+ {{ t(`customLinks.description`, {}, true) }}
96
+ </label>
97
+ </div>
98
+ <div class="mt-20">
99
+ <KeyValue
100
+ v-model="value.custom"
101
+ :title="'Custom Links'"
102
+ :as-map="false"
103
+ key-name="label"
104
+ :key-label="t('customLinks.settings.keyLabel')"
105
+ :value-label="t('customLinks.settings.valueLabel')"
106
+ :add-label="t('customLinks.addLink')"
107
+ :read-allowed="false"
108
+ :protip="false"
109
+ :mode="mode"
110
+ />
111
+ </div>
112
+ <div class="ui-links-setting mt-20">
113
+ <DefaultLinksEditor
114
+ v-model="value.defaults"
115
+ :mode="mode"
116
+ />
117
+ </div>
118
+ <template v-for="err in errors">
119
+ <Banner :key="err" color="error" :label="err" />
120
+ </template>
121
+ <div v-if="mode === 'edit'" class="mt-20">
122
+ <AsyncButton class="pull-right" mode="apply" @click="save" />
123
+ </div>
124
+ </div>
125
+ </template>
126
+ <style scoped lang='scss'>
127
+ .overlay {
128
+ width: 100%;
129
+ height: 100%;
130
+ position: absolute;
131
+ top: 0;
132
+ left: 0;
133
+ background-color: var(--overlay-bg);
134
+ z-index: 1;
135
+ }
136
+ .ui-links-setting {
137
+ P {
138
+ line-height: 1.25;
139
+ margin-bottom: 10px;
140
+ }
141
+
142
+ .underline {
143
+ text-decoration: underline;
144
+ }
145
+ }
146
+ .action {
147
+ display: flex;
148
+ input {
149
+ margin-right: 5px;
150
+ }
151
+ }
152
+ </style>