@rancher/shell 3.0.7 → 3.0.8-rc.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 (123) hide show
  1. package/assets/images/vendor/githubapp.svg +13 -0
  2. package/assets/styles/base/_typography.scss +1 -1
  3. package/assets/styles/global/_layout.scss +21 -35
  4. package/assets/styles/themes/_modern.scss +5 -5
  5. package/assets/translations/en-us.yaml +102 -17
  6. package/assets/translations/zh-hans.yaml +0 -4
  7. package/components/EmberPage.vue +1 -1
  8. package/components/Inactivity.vue +222 -106
  9. package/components/InstallHelmCharts.vue +2 -2
  10. package/components/Resource/Detail/CopyToClipboard.vue +1 -1
  11. package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +0 -2
  12. package/components/Resource/Detail/TitleBar/index.vue +10 -6
  13. package/components/ResourceDetail/index.vue +4 -1
  14. package/components/SortableTable/index.vue +18 -2
  15. package/components/{nav/WindowManager → Window}/ContainerLogs.vue +1 -1
  16. package/components/{nav/WindowManager → Window}/ContainerLogsActions.vue +1 -0
  17. package/components/{nav/WindowManager → Window}/__tests__/ContainerLogs.test.ts +1 -1
  18. package/components/{nav/WindowManager → Window}/__tests__/ContainerShell.test.ts +2 -2
  19. package/components/fleet/FleetConfigMapSelector.vue +117 -0
  20. package/components/fleet/FleetSecretSelector.vue +127 -0
  21. package/components/fleet/__tests__/FleetConfigMapSelector.test.ts +125 -0
  22. package/components/fleet/__tests__/FleetSecretSelector.test.ts +82 -0
  23. package/components/form/FileImageSelector.vue +13 -4
  24. package/components/form/FileSelector.vue +11 -2
  25. package/components/form/ResourceLabeledSelect.vue +1 -0
  26. package/components/form/__tests__/ResourceLabeledSelect.test.ts +90 -0
  27. package/components/nav/Header.vue +34 -13
  28. package/components/{DraggableZone.vue → nav/WindowManager/PinArea.vue} +47 -80
  29. package/components/nav/WindowManager/composables/useComponentsMount.ts +70 -0
  30. package/components/nav/WindowManager/composables/useDimensionsHandler.ts +105 -0
  31. package/components/nav/WindowManager/composables/useDragHandler.ts +99 -0
  32. package/components/nav/WindowManager/composables/usePanelHandler.ts +72 -0
  33. package/components/nav/WindowManager/composables/usePanelsHandler.ts +14 -0
  34. package/components/nav/WindowManager/composables/useResizeHandler.ts +167 -0
  35. package/components/nav/WindowManager/composables/useTabsHandler.ts +51 -0
  36. package/components/nav/WindowManager/constants.ts +23 -0
  37. package/components/nav/WindowManager/index.vue +61 -575
  38. package/components/nav/WindowManager/panels/HorizontalPanel.vue +265 -0
  39. package/components/nav/WindowManager/panels/TabBodyContainer.vue +39 -0
  40. package/components/nav/WindowManager/panels/VerticalPanel.vue +308 -0
  41. package/components/templates/default.vue +4 -40
  42. package/components/templates/home.vue +31 -5
  43. package/config/product/auth.js +1 -0
  44. package/config/query-params.js +1 -0
  45. package/config/settings.ts +8 -1
  46. package/config/store.js +4 -2
  47. package/config/types.js +2 -0
  48. package/detail/pod.vue +1 -0
  49. package/dialog/AddonConfigConfirmationDialog.vue +45 -1
  50. package/directives/ui-context.ts +97 -0
  51. package/edit/__tests__/fleet.cattle.io.helmop.test.ts +52 -11
  52. package/edit/auth/AuthProviderWarningBanners.vue +14 -1
  53. package/edit/auth/github-app-steps.vue +97 -0
  54. package/edit/auth/github-steps.vue +75 -0
  55. package/edit/auth/github.vue +94 -65
  56. package/edit/fleet.cattle.io.helmop.vue +51 -2
  57. package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +15 -5
  58. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +11 -9
  59. package/edit/provisioning.cattle.io.cluster/rke2.vue +56 -9
  60. package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +28 -2
  61. package/initialize/install-directives.js +2 -0
  62. package/list/projectsecret.vue +1 -1
  63. package/machine-config/azure.vue +1 -1
  64. package/mixins/chart.js +1 -1
  65. package/models/__tests__/chart.test.ts +17 -9
  66. package/models/__tests__/compliance.cattle.io.clusterscanprofile.spec.js +30 -0
  67. package/models/catalog.cattle.io.app.js +1 -1
  68. package/models/chart.js +3 -1
  69. package/models/compliance.cattle.io.clusterscanprofile.js +1 -1
  70. package/models/management.cattle.io.authconfig.js +1 -0
  71. package/package.json +2 -2
  72. package/pages/auth/login.vue +5 -2
  73. package/pages/auth/verify.vue +1 -1
  74. package/pages/c/_cluster/apps/charts/AppChartCardSubHeader.vue +3 -2
  75. package/pages/c/_cluster/apps/charts/chart.vue +2 -2
  76. package/pages/c/_cluster/explorer/EventsTable.vue +89 -3
  77. package/pages/c/_cluster/explorer/tools/index.vue +3 -3
  78. package/pages/c/_cluster/settings/performance.vue +12 -25
  79. package/pages/home.vue +313 -12
  80. package/plugins/axios.js +2 -1
  81. package/plugins/dashboard-store/actions.js +1 -1
  82. package/plugins/dashboard-store/resource-class.js +17 -2
  83. package/plugins/steve/steve-pagination-utils.ts +2 -2
  84. package/rancher-components/RcDropdown/RcDropdownItemSelect.vue +5 -1
  85. package/scripts/extension/publish +1 -1
  86. package/store/auth.js +8 -3
  87. package/store/aws.js +8 -6
  88. package/store/features.js +1 -0
  89. package/store/index.js +9 -3
  90. package/store/prefs.js +6 -0
  91. package/store/ui-context.ts +86 -0
  92. package/store/wm.ts +244 -0
  93. package/types/kube/kube-api.ts +2 -1
  94. package/types/rancher/index.d.ts +1 -0
  95. package/types/resources/settings.d.ts +29 -7
  96. package/types/shell/index.d.ts +59 -0
  97. package/types/window-manager.ts +22 -0
  98. package/utils/__tests__/cluster.test.ts +379 -1
  99. package/utils/cluster.js +157 -3
  100. package/utils/dynamic-content/__tests__/config.test.ts +187 -0
  101. package/utils/dynamic-content/__tests__/index.test.ts +390 -0
  102. package/utils/dynamic-content/__tests__/info.test.ts +263 -0
  103. package/utils/dynamic-content/__tests__/new-release.test.ts +216 -0
  104. package/utils/dynamic-content/__tests__/support-notice.test.ts +262 -0
  105. package/utils/dynamic-content/__tests__/util.test.ts +235 -0
  106. package/utils/dynamic-content/config.ts +55 -0
  107. package/utils/dynamic-content/index.ts +273 -0
  108. package/utils/dynamic-content/info.ts +219 -0
  109. package/utils/dynamic-content/new-release.ts +126 -0
  110. package/utils/dynamic-content/support-notice.ts +169 -0
  111. package/utils/dynamic-content/types.d.ts +101 -0
  112. package/utils/dynamic-content/util.ts +122 -0
  113. package/utils/dynamic-importer.js +2 -2
  114. package/utils/inactivity.ts +104 -0
  115. package/utils/pagination-utils.ts +19 -4
  116. package/utils/release-notes.ts +1 -1
  117. package/assets/images/icons/document.svg +0 -3
  118. package/store/wm.js +0 -95
  119. /package/components/{nav/WindowManager → Window}/ChartReadme.vue +0 -0
  120. /package/components/{nav/WindowManager → Window}/ContainerShell.vue +0 -0
  121. /package/components/{nav/WindowManager → Window}/KubectlShell.vue +0 -0
  122. /package/components/{nav/WindowManager → Window}/MachineSsh.vue +0 -0
  123. /package/components/{nav/WindowManager → Window}/Window.vue +0 -0
package/pages/home.vue CHANGED
@@ -8,9 +8,9 @@ import { BadgeState } from '@components/BadgeState';
8
8
  import CommunityLinks from '@shell/components/CommunityLinks.vue';
9
9
  import SingleClusterInfo from '@shell/components/SingleClusterInfo.vue';
10
10
  import { mapGetters, mapState } from 'vuex';
11
- import { MANAGEMENT, CAPI } from '@shell/config/types';
11
+ import { MANAGEMENT, CAPI, COUNT } from '@shell/config/types';
12
12
  import { NAME as MANAGER } from '@shell/config/product/manager';
13
- import { STATE } from '@shell/config/table-headers';
13
+ import { AGE, STATE } from '@shell/config/table-headers';
14
14
  import { MODE, _IMPORT } from '@shell/config/query-params';
15
15
  import { createMemoryFormat, formatSi, parseSi, createMemoryValues } from '@shell/utils/units';
16
16
  import { markSeenReleaseNotes } from '@shell/utils/version';
@@ -28,8 +28,12 @@ import { PaginationParamFilter, FilterArgs, PaginationFilterField, PaginationArg
28
28
  import ProvCluster from '@shell/models/provisioning.cattle.io.cluster';
29
29
  import { sameContents } from '@shell/utils/array';
30
30
  import { PagTableFetchPageSecondaryResourcesOpts, PagTableFetchSecondaryResourcesOpts, PagTableFetchSecondaryResourcesReturns } from '@shell/types/components/paginatedResourceTable';
31
- import { CURRENT_RANCHER_VERSION } from '@shell/config/version';
31
+ import { CURRENT_RANCHER_VERSION, getVersionData } from '@shell/config/version';
32
32
  import { CAPI as CAPI_LAB_AND_ANO } from '@shell/config/labels-annotations';
33
+ import paginationUtils from '@shell/utils/pagination-utils';
34
+ import ResourceTable from '@shell/components/ResourceTable.vue';
35
+ import Preset from '@shell/mixins/preset';
36
+ import { PaginationFeatureHomePageClusterConfig } from '@shell/types/resources/settings';
33
37
 
34
38
  export default defineComponent({
35
39
  name: 'Home',
@@ -42,9 +46,10 @@ export default defineComponent({
42
46
  CommunityLinks,
43
47
  SingleClusterInfo,
44
48
  TabTitle,
49
+ ResourceTable,
45
50
  },
46
51
 
47
- mixins: [PageHeaderActions],
52
+ mixins: [PageHeaderActions, Preset],
48
53
 
49
54
  data() {
50
55
  const options = this.$store.getters[`type-map/optionsFor`](CAPI.RANCHER_CLUSTER)?.custom || {};
@@ -200,15 +205,41 @@ export default defineComponent({
200
205
 
201
206
  clusterCount: 0,
202
207
 
203
- CURRENT_RANCHER_VERSION
208
+ CURRENT_RANCHER_VERSION,
209
+
210
+ /**
211
+ * User has decided to disable the alt list
212
+ */
213
+ altClusterListDisabled: false,
214
+ /**
215
+ * There are too many clusters to show in the home page list.
216
+ *
217
+ * If not disabled, show alt table
218
+ */
219
+ tooManyClusters: undefined as boolean | undefined,
220
+ altClusterListRows: undefined as any[] | undefined,
221
+ altClusterListFeature: paginationUtils.getFeature<PaginationFeatureHomePageClusterConfig>({ rootGetters: this.$store.getters }, 'homePageCluster'),
222
+
223
+ presetVersion: getVersionData()?.Version,
204
224
  };
205
225
  },
206
226
 
227
+ mounted() {
228
+ this.preset('altClusterListDisabled', 'boolean');
229
+ },
230
+
207
231
  computed: {
208
232
  ...mapState(['managementReady']),
209
233
  ...mapGetters(['currentCluster', 'defaultClusterId']),
210
234
  mcm: mapFeature(MULTI_CLUSTER),
211
235
 
236
+ vaiOnSettingsHeaders() {
237
+ return [
238
+ ...this.headers, // include age as we're sorting by it
239
+ AGE
240
+ ];
241
+ },
242
+
212
243
  canCreateCluster() {
213
244
  return !!this.provClusterSchema?.collectionMethods.find((x: string) => x.toLowerCase() === 'post');
214
245
  },
@@ -216,6 +247,21 @@ export default defineComponent({
216
247
  afterLoginRoute: mapPref(AFTER_LOGIN_ROUTE),
217
248
  homePageCards: mapPref(HIDE_HOME_PAGE_CARDS),
218
249
 
250
+ /**
251
+ * Show the alt table
252
+ */
253
+ altClusterList() {
254
+ return this.tooManyClusters && !this.altClusterListDisabled;
255
+ }
256
+
257
+ },
258
+
259
+ watch: {
260
+ async altClusterList(neu) {
261
+ if (neu) {
262
+ await this.initAltClusters();
263
+ }
264
+ },
219
265
  },
220
266
 
221
267
  async created() {
@@ -227,6 +273,12 @@ export default defineComponent({
227
273
  // If we do not, then if they set the landing page, that won't work unless the release notes are marked read
228
274
  // otherwise we always take them to the home page to see the release notes
229
275
  markSeenReleaseNotes(this.$store);
276
+
277
+ this.tooManyClusters = this.isTooManyClusters();
278
+
279
+ if (this.altClusterList) {
280
+ await this.initAltClusters();
281
+ }
230
282
  },
231
283
 
232
284
  // Forget the types when we leave the page
@@ -458,7 +510,83 @@ export default defineComponent({
458
510
  }
459
511
 
460
512
  return pagination;
461
- }
513
+ },
514
+
515
+ async toggleAltClusterListDisabled(disabled: boolean) {
516
+ // Clear the cache so the table doesn't show the previous mode's results
517
+ await this.$store.dispatch('management/forgetType', CAPI.RANCHER_CLUSTER);
518
+
519
+ this.altClusterListDisabled = disabled;
520
+ },
521
+
522
+ /**
523
+ * Determine if we should use an alternative cluster list which contains most recently created clusters
524
+ *
525
+ * Checks
526
+ * - can view clusters
527
+ * - if vai is on
528
+ * - if alt list feature is on
529
+ * - if cluster count exceeds threshold
530
+ */
531
+ isTooManyClusters(): boolean {
532
+ if (!this.provClusterSchema || !this.canViewMgmtClusters) {
533
+ return false;
534
+ }
535
+
536
+ const featureConfig = this.altClusterListFeature;
537
+
538
+ if (!featureConfig || !featureConfig.enabled) { // vai is off, or feature is explicitly disabled
539
+ return false;
540
+ }
541
+
542
+ const threshold = featureConfig.configuration?.threshold;
543
+
544
+ if (threshold === undefined) { // invalid config
545
+ return false;
546
+ }
547
+
548
+ const counts = this.$store.getters[`management/all`](COUNT)?.[0]?.counts || {};
549
+
550
+ this.clusterCount = counts[CAPI.RANCHER_CLUSTER]?.summary.count;
551
+
552
+ return this.clusterCount > threshold;
553
+ },
554
+
555
+ /**
556
+ * Fetch clusters used to populate alt table
557
+ */
558
+ async initAltClusters() {
559
+ const featureConfig = this.altClusterListFeature;
560
+ const results = featureConfig?.configuration?.results || 50;
561
+
562
+ // Fetch a limited number of provisioning clusters
563
+ const opt1: ActionFindPageArgs = {
564
+ pagination: {
565
+ projectsOrNamespaces: [],
566
+ filters: paginationFilterClusters(this.$store, false),
567
+ page: 1,
568
+ pageSize: results, // We're fetching the total results... then paging locally
569
+ sort: [{ field: 'metadata.creationTimestamp', asc: false }]
570
+ },
571
+ watch: false,
572
+ };
573
+ const provClusters = await this.$store.dispatch('management/findPage', { type: CAPI.RANCHER_CLUSTER, opt: opt1 });
574
+
575
+ // Also fetch the management clusters associated with the provisioning clusters
576
+ const opt2: ActionFindPageArgs = {
577
+ pagination: new FilterArgs({
578
+ filters: PaginationParamFilter.createMultipleFields(provClusters.map((r: any) => new PaginationFilterField({
579
+ field: 'id',
580
+ value: r.mgmtClusterId
581
+ }))),
582
+ }),
583
+ watch: false,
584
+ };
585
+
586
+ await this.$store.dispatch(`management/findPage`, { type: MANAGEMENT.CLUSTER, opt: opt2 });
587
+
588
+ this.altClusterListRows = provClusters;
589
+ },
462
590
  }
463
591
  });
464
592
 
@@ -485,9 +613,164 @@ export default defineComponent({
485
613
  <IndentedPanel class="mt-20 mb-20">
486
614
  <div class="row home-panels">
487
615
  <div class="col main-panel">
488
- <div class="row panel">
616
+ <div
617
+ v-if="altClusterList !== undefined"
618
+ class="row panel"
619
+ >
620
+ <div
621
+ v-if="mcm && altClusterList"
622
+ class="col span-12"
623
+ >
624
+ <ResourceTable
625
+ :schema="provClusterSchema"
626
+ :table-actions="false"
627
+ :row-actions="false"
628
+ key-field="id"
629
+
630
+ :headers="vaiOnSettingsHeaders"
631
+ defaultSortBy="age"
632
+
633
+ :loading="!altClusterListRows"
634
+
635
+ :rows="altClusterListRows || []"
636
+ :rowsPerPage="altClusterListFeature?.configuration.pagesPerRow || 10"
637
+
638
+ :namespaced="false"
639
+ :groupable="false"
640
+ >
641
+ <template #header-left>
642
+ <div class="row table-heading">
643
+ <h1 class="mb-0">
644
+ {{ t('landing.clusters.title') }}
645
+ </h1>
646
+ </div>
647
+ </template>
648
+ <template #sub-header-row>
649
+ <h2 class="too-many-clusters">
650
+ {{ t('landing.clusters.tooMany.showingSome', { rows: altClusterListRows?.length || '...', total: clusterCount}) }}
651
+ <a @click="toggleAltClusterListDisabled(true)">{{ t('landing.clusters.tooMany.showAll') }}</a>
652
+ </h2>
653
+ </template>
654
+ <!--
655
+ Below is a big copy & paste from PaginatedResourceTable, however should be temporary (altClusterList removed in 2.14 once full SSP support for clusters if available)
656
+ -->
657
+ <template
658
+ v-if="canCreateCluster || !!provClusterSchema"
659
+ #header-middle
660
+ >
661
+ <div class="table-heading">
662
+ <router-link
663
+ v-if="!!provClusterSchema"
664
+ :to="manageLocation"
665
+ class="btn btn-sm role-secondary"
666
+ data-testid="cluster-management-manage-button"
667
+ role="button"
668
+ :aria-label="t('cluster.manageAction')"
669
+ @keyup.space="$router.push(manageLocation)"
670
+ >
671
+ {{ t('cluster.manageAction') }}
672
+ </router-link>
673
+ <router-link
674
+ v-if="canCreateCluster"
675
+ :to="importLocation"
676
+ class="btn btn-sm role-primary"
677
+ data-testid="cluster-create-import-button"
678
+ role="button"
679
+ :aria-label="t('cluster.importAction')"
680
+ @keyup.space="$router.push(importLocation)"
681
+ >
682
+ {{ t('cluster.importAction') }}
683
+ </router-link>
684
+ <router-link
685
+ v-if="canCreateCluster"
686
+ :to="createLocation"
687
+ class="btn btn-sm role-primary"
688
+ data-testid="cluster-create-button"
689
+ role="button"
690
+ :aria-label="t('generic.create')"
691
+ @keyup.space="$router.push(createLocation)"
692
+ >
693
+ {{ t('generic.create') }}
694
+ </router-link>
695
+ </div>
696
+ </template>
697
+ <template #col:name="{row}">
698
+ <td class="col-name">
699
+ <div class="list-cluster-name">
700
+ <p
701
+ v-if="row.mgmt"
702
+ class="cluster-name"
703
+ >
704
+ <router-link
705
+ v-if="row.mgmt.isReady && !row.hasError"
706
+ :to="{ name: 'c-cluster-explorer', params: { cluster: row.mgmt.id }}"
707
+ role="link"
708
+ :aria-label="row.nameDisplay"
709
+ >
710
+ {{ row.nameDisplay }}
711
+ </router-link>
712
+ <span v-else>{{ row.nameDisplay }}</span>
713
+ <i
714
+ v-if="row.unavailableMachines"
715
+ v-clean-tooltip="row.unavailableMachines"
716
+ class="conditions-alert-icon icon-alert icon"
717
+ />
718
+ <i
719
+ v-if="row.isRke1"
720
+ v-clean-tooltip="t('cluster.rke1Unsupported')"
721
+ class="rke1-unsupported-icon icon-warning icon"
722
+ />
723
+ </p>
724
+ <p
725
+ v-if="row.description"
726
+ class="cluster-description"
727
+ >
728
+ {{ row.description }}
729
+ </p>
730
+ </div>
731
+ </td>
732
+ </template>
733
+ <template #col:kubernetesVersion="{row}">
734
+ <td class="col-name">
735
+ <span>
736
+ {{ row.kubernetesVersion }}
737
+ </span>
738
+ <div
739
+ v-clean-tooltip="{content: row.architecture.tooltip, placement: 'left'}"
740
+ class="text-muted"
741
+ >
742
+ {{ row.architecture.label }}
743
+ </div>
744
+ </td>
745
+ </template>
746
+ <template #col:cpu="{row}">
747
+ <td v-if="row.mgmt && cpuAllocatable(row.mgmt)">
748
+ {{ `${cpuAllocatable(row.mgmt)} ${t('landing.clusters.cores', {count:cpuAllocatable(row.mgmt) })}` }}
749
+ </td>
750
+ <td v-else>
751
+ &mdash;
752
+ </td>
753
+ </template>
754
+ <template #col:memory="{row}">
755
+ <td v-if="row.mgmt && memoryAllocatable(row.mgmt) && !memoryAllocatable(row.mgmt).match(/^0 [a-zA-z]/)">
756
+ {{ memoryAllocatable(row.mgmt) }}
757
+ </td>
758
+ <td v-else>
759
+ &mdash;
760
+ </td>
761
+ </template>
762
+ <!-- <template #cell:explorer="{row}">
763
+ <router-link v-if="row && row.isReady" class="btn btn-sm role-primary" :to="{name: 'c-cluster', params: {cluster: row.id}}">
764
+ {{ t('landing.clusters.explore') }}
765
+ </router-link>
766
+ <button v-else :disabled="true" class="btn btn-sm role-primary">
767
+ {{ t('landing.clusters.explore') }}
768
+ </button>
769
+ </template> -->
770
+ </ResourceTable>
771
+ </div>
489
772
  <div
490
- v-if="mcm"
773
+ v-else-if="mcm"
491
774
  class="col span-12"
492
775
  >
493
776
  <PaginatedResourceTable
@@ -511,16 +794,25 @@ export default defineComponent({
511
794
  >
512
795
  <template #header-left>
513
796
  <div class="row table-heading">
514
- <h2 class="mb-0">
797
+ <h1 class="mb-0">
515
798
  {{ t('landing.clusters.title') }}
516
- </h2>
799
+ </h1>
517
800
  <BadgeState
518
- v-if="clusterCount"
801
+ v-if="clusterCount && !tooManyClusters"
519
802
  :label="clusterCount.toString()"
520
- color="role-tertiary ml-20 mr-20"
803
+ color="bg-info ml-20 mr-20"
521
804
  />
522
805
  </div>
523
806
  </template>
807
+ <template
808
+ v-if="tooManyClusters"
809
+ #sub-header-row
810
+ >
811
+ <h2 class="too-many-clusters">
812
+ {{ t('landing.clusters.tooMany.showingAll', { rows: altClusterListRows?.length || '...', total: clusterCount}) }}
813
+ <a @click="toggleAltClusterListDisabled(false)">{{ t('landing.clusters.tooMany.showSome') }}</a>
814
+ </h2>
815
+ </template>
524
816
  <template
525
817
  v-if="canCreateCluster || !!provClusterSchema"
526
818
  #header-middle
@@ -663,6 +955,14 @@ export default defineComponent({
663
955
  }
664
956
  .main-panel {
665
957
  flex: auto;
958
+
959
+ .too-many-clusters {
960
+ margin-bottom: 5px;
961
+
962
+ a {
963
+ cursor: pointer;
964
+ }
965
+ }
666
966
  }
667
967
 
668
968
  .side-panel {
@@ -744,6 +1044,7 @@ export default defineComponent({
744
1044
  .search {
745
1045
  align-items: center;
746
1046
  display: flex;
1047
+ height: 39px;
747
1048
 
748
1049
  > INPUT {
749
1050
  background-color: transparent;
package/plugins/axios.js CHANGED
@@ -11,7 +11,8 @@ export default function({
11
11
  const options = { parseJSON: false };
12
12
  const csrf = store.getters['cookies/get']({ key: CSRF, options });
13
13
 
14
- if ( csrf ) {
14
+ // Request can ask not to send the CSRF header
15
+ if (csrf && !config.noApiCsrf) {
15
16
  config.headers['x-api-csrf'] = csrf;
16
17
  }
17
18
  });
@@ -698,7 +698,7 @@ export default {
698
698
 
699
699
  const res = await dispatch('request', { opt, type });
700
700
 
701
- await dispatch('load', { data: res });
701
+ await dispatch('load', { data: res, invalidatePageCache: opt.invalidatePageCache });
702
702
 
703
703
  if ( opt.watch !== false ) {
704
704
  dispatch('watch', createFindWatchArg({
@@ -1264,6 +1264,12 @@ export default class Resource {
1264
1264
  delete opt.replace;
1265
1265
  }
1266
1266
 
1267
+ // Will loading this resource invalidate the resources in the cache that represent a page (resource is not from page)
1268
+ // By default we set this to no, it won't pollute the cache. Most likely either
1269
+ // 1. The resource came from a list already (loaded resource is already in the page that is in the cache)
1270
+ // 2. UI is not on a page with a list (cache doesn't represent a list)
1271
+ const invalidatePageCache = opt.invalidatePageCache || false;
1272
+
1267
1273
  try {
1268
1274
  const res = await this.$dispatch('request', { opt, type: this.type } );
1269
1275
 
@@ -1272,7 +1278,9 @@ export default class Resource {
1272
1278
 
1273
1279
  // Steve sometimes returns Table responses instead of the resource you just saved.. ignore
1274
1280
  if ( res && res.kind !== 'Table') {
1275
- await this.$dispatch('load', { data: res, existing: (forNew ? this : undefined ) });
1281
+ await this.$dispatch('load', {
1282
+ data: res, existing: (forNew ? this : undefined ), invalidatePageCache
1283
+ });
1276
1284
  }
1277
1285
  } catch (e) {
1278
1286
  if ( this.type && this.id && e?._status === 409) {
@@ -1280,7 +1288,14 @@ export default class Resource {
1280
1288
  await this.$dispatch('find', {
1281
1289
  type: this.type,
1282
1290
  id: this.id,
1283
- opt: { force: true }
1291
+ opt: {
1292
+ // We want to update the value in cache, so force the request
1293
+ force: true,
1294
+ // We're not interested in opening a watch for this specific resource
1295
+ watch: false,
1296
+ // Unless overridden, this will be false, we're probably from a list and we don't want to clear it's state
1297
+ invalidatePageCache
1298
+ }
1284
1299
  });
1285
1300
  }
1286
1301
 
@@ -676,8 +676,8 @@ export const PAGINATION_SETTINGS_STORE_DEFAULTS: PaginationSettingsStores = {
676
676
  enableAll: false,
677
677
  enableSome: {
678
678
  enabled: [
679
- // { resource: CAPI.RANCHER_CLUSTER, context: ['home', 'side-bar'] },
680
- // { resource: MANAGEMENT.CLUSTER, context: ['side-bar'] },
679
+ { resource: CAPI.RANCHER_CLUSTER, context: ['side-bar'] },
680
+ { resource: MANAGEMENT.CLUSTER, context: ['side-bar'] },
681
681
  { resource: CATALOG.APP, context: ['branding'] },
682
682
  SECRET
683
683
  ],
@@ -22,6 +22,10 @@ defineProps({
22
22
  return [];
23
23
  }
24
24
  },
25
+ label: {
26
+ type: String,
27
+ default: ''
28
+ }
25
29
  });
26
30
  const emits = defineEmits(['click', 'select']);
27
31
 
@@ -55,7 +59,7 @@ const focusMenuItem = () => {
55
59
  <LabeledSelect
56
60
  ref="menuItemSelect"
57
61
  :value="modelValue"
58
- :label="t('wm.containerLogs.range.label')"
62
+ :label="label"
59
63
  :options="options"
60
64
  :clearable="false"
61
65
  placement="top"
@@ -164,7 +164,7 @@ if [ "${HAVE_COMMANDS}" == "false" ]; then
164
164
  fi
165
165
 
166
166
  # --------------------------------------------------------------------------------
167
- # Only do conatiner args checks if not GitHub publish
167
+ # Only do container args checks if not GitHub publish
168
168
  # --------------------------------------------------------------------------------
169
169
  if [ "${GITHUB_BUILD}" == "false" ]; then
170
170
  BASE_EXT=$(jq -r .name ${BASE_DIR}/package.json)
package/store/auth.js CHANGED
@@ -17,6 +17,7 @@ const SLO_TOKENS_ENDPOINT_LOGOUT_RES_BASETYPE = ['authConfigLogoutOutput'];
17
17
 
18
18
  export const BASE_SCOPES = {
19
19
  github: ['read:org'],
20
+ githubapp: ['read:org'],
20
21
  googleoauth: ['openid profile email'],
21
22
  azuread: [],
22
23
  keycloakoidc: ['openid profile email'],
@@ -374,11 +375,11 @@ export const actions = {
374
375
  commit('cookies/remove', { key: KEY }, { root: true });
375
376
  },
376
377
 
377
- uiLogout({ commit, dispatch }) {
378
+ uiLogout({ commit, dispatch }, options = {}) {
378
379
  removeEmberPage();
379
380
 
380
381
  commit('loggedOut');
381
- dispatch('onLogout', null, { root: true });
382
+ dispatch('onLogout', options, { root: true });
382
383
 
383
384
  dispatch('uiplugins/setReady', false, { root: true });
384
385
  },
@@ -430,6 +431,10 @@ export const actions = {
430
431
  } catch (e) {
431
432
  }
432
433
 
433
- dispatch('uiLogout');
434
+ const propagateOptions = {};
435
+
436
+ propagateOptions.sessionIdle = options.sessionIdle;
437
+
438
+ dispatch('uiLogout', propagateOptions);
434
439
  }
435
440
  };
package/store/aws.js CHANGED
@@ -213,18 +213,20 @@ export const actions = {
213
213
 
214
214
  list.push({
215
215
  apiName,
216
- currentGeneration: row.CurrentGeneration || false,
216
+ currentGeneration: row.CurrentGeneration || false,
217
217
  groupLabel,
218
218
  instanceClass,
219
- memoryBytes: row.MemoryInfo.SizeInMiB * 1024 * 1024,
220
- supportedUsageClasses: row.SupportedUsageClasses,
221
- label: rootGetters['i18n/t']('cluster.machineConfig.aws.sizeLabel', {
219
+ memoryBytes: row.MemoryInfo.SizeInMiB * 1024 * 1024,
220
+ supportedUsageClasses: row.SupportedUsageClasses,
221
+ supportedArchitectures: row.ProcessorInfo.SupportedArchitectures || [],
222
+ label: rootGetters['i18n/t']('cluster.machineConfig.aws.sizeLabel', {
222
223
  apiName,
223
- cpu: row.VCpuInfo.DefaultVCpus,
224
- memory: row.MemoryInfo.SizeInMiB / 1024,
224
+ cpu: row.VCpuInfo.DefaultVCpus,
225
+ memory: row.MemoryInfo.SizeInMiB / 1024,
225
226
  storageSize,
226
227
  storageUnit,
227
228
  storageType,
229
+ architecture: (row.ProcessorInfo.SupportedArchitectures || []).map((a) => (a === 'arm64' ? 'ARM' : a)).join(', ')
228
230
  }),
229
231
  });
230
232
  }
package/store/features.js CHANGED
@@ -37,6 +37,7 @@ export const STEVE_CACHE = create('ui-sql-cache', false);
37
37
  export const UIEXTENSION = create('uiextension', true);
38
38
  export const PROVISIONING_PRE_BOOTSTRAP = create('provisioningprebootstrap', false);
39
39
  export const SCHEDULING_CUSTOMIZATION = create(SCHEDULING_CUSTOMIZATION_FEATURE, false);
40
+ export const SCC = create('rancher-scc-registration-extension', true);
40
41
 
41
42
  // Not currently used.. no point defining ones we don't use
42
43
  // export const EMBEDDED_CLUSTER_API = create('embedded-cluster-api', true);
package/store/index.js CHANGED
@@ -2,7 +2,7 @@ import { BACK_TO } from '@shell/config/local-storage';
2
2
  import { setBrand, setVendor } from '@shell/config/private-label';
3
3
  import { NAME as EXPLORER } from '@shell/config/product/explorer';
4
4
  import {
5
- LOGGED_OUT, IS_SSO, IS_SLO, TIMED_OUT, UPGRADED, _FLAGGED
5
+ LOGGED_OUT, IS_SSO, IS_SLO, TIMED_OUT, UPGRADED, _FLAGGED, IS_SESSION_IDLE
6
6
  } from '@shell/config/query-params';
7
7
  import { SETTING } from '@shell/config/settings';
8
8
  import {
@@ -41,6 +41,7 @@ import { markRaw } from 'vue';
41
41
  import paginationUtils from '@shell/utils/pagination-utils';
42
42
  import { addReleaseNotesNotification } from '@shell/utils/release-notes';
43
43
  import sideNavService from '@shell/components/nav/TopLevelMenu.helper';
44
+ import { fetchAndProcessDynamicContent } from '@shell/utils/dynamic-content';
44
45
 
45
46
  // Disables strict mode for all store instances to prevent warning about changing state outside of mutations
46
47
  // because it's more efficient to do that sometimes.
@@ -890,6 +891,8 @@ export const actions = {
890
891
  // Add the notification for the release notes
891
892
  if (isRancher) {
892
893
  await addReleaseNotesNotification(dispatch, getters);
894
+
895
+ fetchAndProcessDynamicContent(dispatch, getters, this.$axios);
893
896
  }
894
897
 
895
898
  if (systemNamespaces) {
@@ -1168,7 +1171,7 @@ export const actions = {
1168
1171
  }
1169
1172
  },
1170
1173
 
1171
- async onLogout(store) {
1174
+ async onLogout(store, options = {}) {
1172
1175
  const { dispatch, commit, state } = store;
1173
1176
 
1174
1177
  store.dispatch('gcStopIntervals');
@@ -1210,7 +1213,10 @@ export const actions = {
1210
1213
  window.localStorage.setItem(BACK_TO, window.location.href);
1211
1214
  }
1212
1215
 
1213
- let QUERY = (LOGGED_OUT in route.query) ? LOGGED_OUT : TIMED_OUT;
1216
+ let QUERY = (LOGGED_OUT in route.query) || options.sessionIdle ? LOGGED_OUT : TIMED_OUT;
1217
+
1218
+ // adds IS_SESSION_IDLE query param to login route if logout came from a session idle (check auth/logout action)
1219
+ QUERY += options.sessionIdle ? `&${ IS_SESSION_IDLE }` : '';
1214
1220
 
1215
1221
  // adds IS_SSO query param to login route if logout came with an auth provider enabled
1216
1222
  QUERY += (IS_SSO in route.query) ? `&${ IS_SSO }` : '';
package/store/prefs.js CHANGED
@@ -114,6 +114,12 @@ export const PROVISIONER = create('provisioner', _RKE2, { options: [_RKE1, _RKE2
114
114
  export const MENU_MAX_CLUSTERS = 10;
115
115
  // Prompt for confirm when scaling down node pool in GUI and save the pref
116
116
  export const SCALE_POOL_PROMPT = create('scale-pool-prompt', null, { parseJSON });
117
+
118
+ // Dynamic content
119
+ export const READ_NEW_RELEASE = create('read-new-release', '', { parseJSON });
120
+ export const READ_SUPPORT_NOTICE = create('read-support-notice', '', { parseJSON });
121
+ export const READ_UPCOMING_SUPPORT_NOTICE = create('read-upcoming-support-notice', '', { parseJSON });
122
+
117
123
  // --------------------
118
124
 
119
125
  const cookiePrefix = 'R_';