@rancher/shell 3.0.0 → 3.0.1-rc.1

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 (83) hide show
  1. package/assets/brand/harvester/favicon.png +0 -0
  2. package/assets/brand/harvester/metadata.json +3 -0
  3. package/assets/images/pl/harvester.svg +1 -0
  4. package/assets/translations/en-us.yaml +25 -4
  5. package/assets/translations/zh-hans.yaml +1 -1
  6. package/components/BrandImage.vue +5 -1
  7. package/components/CopyToClipboardText.vue +2 -0
  8. package/components/CruResourceFooter.vue +1 -0
  9. package/components/DetailTop.vue +1 -1
  10. package/components/ExplorerMembers.vue +5 -1
  11. package/components/ExplorerProjectsNamespaces.vue +39 -15
  12. package/components/HardwareResourceGauge.vue +12 -2
  13. package/components/InputOrDisplay.vue +6 -2
  14. package/components/LandingPagePreference.vue +2 -2
  15. package/components/MessageLink.vue +1 -1
  16. package/components/ResourceDetail/Masthead.vue +22 -1
  17. package/components/ResourceDetail/index.vue +2 -8
  18. package/components/ResourceTable.vue +14 -6
  19. package/components/ResourceYaml.vue +1 -1
  20. package/components/SideNav.vue +1 -1
  21. package/components/TableDataUserIcon.vue +1 -1
  22. package/components/fleet/FleetRepos.vue +0 -7
  23. package/components/form/ArrayList.vue +5 -1
  24. package/components/form/ArrayListSelect.vue +5 -1
  25. package/components/form/KeyValue.vue +1 -1
  26. package/components/form/LabeledSelect.vue +26 -6
  27. package/components/form/Password.vue +7 -1
  28. package/components/form/UnitInput.vue +10 -1
  29. package/components/form/__tests__/UnitInput.test.ts +1 -0
  30. package/components/formatter/ClusterProvider.vue +3 -3
  31. package/components/formatter/ImagePercentageBar.vue +1 -1
  32. package/components/formatter/Si.vue +5 -1
  33. package/components/formatter/Translate.vue +1 -1
  34. package/components/nav/Header.vue +29 -5
  35. package/components/nav/NamespaceFilter.vue +5 -8
  36. package/components/nav/TopLevelMenu.vue +11 -11
  37. package/config/labels-annotations.js +2 -0
  38. package/config/table-headers.js +15 -0
  39. package/config/types.js +3 -0
  40. package/detail/fleet.cattle.io.bundle.vue +5 -68
  41. package/detail/fleet.cattle.io.gitrepo.vue +2 -1
  42. package/directives/clean-tooltip.js +4 -4
  43. package/edit/logging-flow/Match.vue +75 -42
  44. package/edit/logging-flow/index.vue +89 -10
  45. package/edit/logging.banzaicloud.io.output/index.vue +2 -2
  46. package/edit/management.cattle.io.project.vue +2 -2
  47. package/edit/namespace.vue +1 -1
  48. package/edit/provisioning.cattle.io.cluster/index.vue +2 -1
  49. package/edit/provisioning.cattle.io.cluster/rke2.vue +1 -3
  50. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryMirrors.vue +1 -1
  51. package/list/harvesterhci.io.management.cluster.vue +244 -0
  52. package/list/namespace.vue +16 -4
  53. package/models/__tests__/management.cattle.io.cluster.test.ts +45 -3
  54. package/models/__tests__/provisioning.cattle.io.cluster.test.ts +0 -86
  55. package/models/fleet.cattle.io.bundle.js +3 -1
  56. package/models/fleet.cattle.io.gitrepo.js +43 -50
  57. package/models/k8s.cni.cncf.io.networkattachmentdefinition.js +88 -0
  58. package/models/management.cattle.io.cluster.js +26 -5
  59. package/models/management.cattle.io.setting.js +25 -0
  60. package/models/provisioning.cattle.io.cluster.js +5 -14
  61. package/models/storage.k8s.io.storageclass.js +15 -4
  62. package/package.json +3 -3
  63. package/pages/auth/login.vue +3 -2
  64. package/pages/auth/setup.vue +1 -1
  65. package/pages/c/_cluster/fleet/index.vue +2 -4
  66. package/pages/c/_cluster/settings/brand.vue +4 -1
  67. package/pages/prefs.vue +22 -10
  68. package/plugins/dashboard-store/resource-class.js +11 -3
  69. package/plugins/steve/steve-pagination-utils.ts +1 -1
  70. package/rancher-components/Form/LabeledInput/LabeledInput.vue +7 -2
  71. package/store/features.js +1 -0
  72. package/store/i18n.js +5 -1
  73. package/store/prefs.js +8 -0
  74. package/types/resources/fleet.d.ts +40 -0
  75. package/types/shell/index.d.ts +428 -395
  76. package/utils/auth.js +1 -1
  77. package/utils/create-yaml.js +1 -1
  78. package/utils/favicon.js +2 -0
  79. package/utils/fleet.ts +159 -0
  80. package/utils/gc/gc.ts +1 -1
  81. package/utils/v-sphere.ts +31 -0
  82. package/utils/validators/cron-schedule.js +1 -1
  83. package/utils/validators/formRules/index.ts +1 -1
@@ -717,7 +717,7 @@ export default {
717
717
  @onFocus="onFocusMarkdownMultiline(i, $event)"
718
718
  />
719
719
  <TextAreaAutoGrow
720
- v-else-if="valueMultiline"
720
+ v-else-if="valueMultiline && row[valueName] !== undefined"
721
721
  v-model:value="row[valueName]"
722
722
  data-testid="value-multiline"
723
723
  :class="{'conceal': valueConcealed}"
@@ -7,8 +7,7 @@ import VueSelectOverrides from '@shell/mixins/vue-select-overrides';
7
7
  import { onClickOption, calculatePosition } from '@shell/utils/select';
8
8
  import LabeledSelectPagination from '@shell/components/form/labeled-select-utils/labeled-select-pagination';
9
9
  import { LABEL_SELECT_NOT_OPTION_KINDS } from '@shell/types/components/labeledSelect';
10
-
11
- // In theory this would be nicer as LabeledSelect/index.vue, however that would break a lot of places where we import this (which includes extensions)
10
+ import { mapGetters } from 'vuex';
12
11
 
13
12
  export default {
14
13
  name: 'LabeledSelect',
@@ -23,7 +22,7 @@ export default {
23
22
  LabeledSelectPagination
24
23
  ],
25
24
 
26
- emits: ['on-open', 'on-close', 'selecting', 'update:validation', 'update:value'],
25
+ emits: ['on-open', 'on-close', 'selecting', 'deselecting', 'update:validation', 'update:value'],
27
26
 
28
27
  props: {
29
28
  appendToBody: {
@@ -122,6 +121,7 @@ export default {
122
121
  },
123
122
 
124
123
  computed: {
124
+ ...mapGetters({ t: 'i18n/t' }),
125
125
  hasLabel() {
126
126
  return this.isCompact ? false : !!this.label || !!this.labelKey || !!this.$slots.label;
127
127
  },
@@ -144,6 +144,11 @@ export default {
144
144
 
145
145
  return rest;
146
146
  },
147
+
148
+ // update placeholder text to inform user they can add their own opts when none are found
149
+ showTagPrompts() {
150
+ return !this.options.length && this.$attrs.taggable;
151
+ }
147
152
  },
148
153
 
149
154
  methods: {
@@ -320,10 +325,16 @@ export default {
320
325
  @search="onSearch"
321
326
  @open="onOpen"
322
327
  @close="onClose"
323
- @option:selected="$emit('selecting', $event)"
328
+ @option:selecting="$emit('selecting', $event)"
329
+ @option:deselecting="$emit('deselecting', $event)"
324
330
  >
325
331
  <template #option="option">
326
- <template v-if="option.kind === 'group'">
332
+ <template v-if="showTagPrompts">
333
+ <div class="only-user-opts">
334
+ {{ t('labeledSelect.pressEnter', {input:getOptionLabel(option.label)}) }}
335
+ </div>
336
+ </template>
337
+ <template v-else-if="option.kind === 'group'">
327
338
  <div class="vs__option-kind-group">
328
339
  <i
329
340
  v-if="option.icon"
@@ -395,8 +406,11 @@ export default {
395
406
  </template>
396
407
  <template #no-options="{ search }">
397
408
  <div class="no-options-slot">
409
+ <template v-if="showTagPrompts">
410
+ <span v-if="!searching">{{ t('labeledSelect.startTyping') }}</span>
411
+ </template>
398
412
  <div
399
- v-if="paginating"
413
+ v-else-if="paginating"
400
414
  class="paginating"
401
415
  >
402
416
  <i class="icon icon-spinner icon-spin" />
@@ -674,4 +688,10 @@ $icon-size: 18px;
674
688
  }
675
689
  }
676
690
 
691
+ .vs__dropdown-menu .vs__dropdown-option .only-user-opts{
692
+ color: var(--dropdown-text);
693
+ background-color: var(--dropdown-bg);
694
+ margin: 0px calc(-#{$input-padding-sm}/2);
695
+ padding: 3px 20px;
696
+ }
677
697
  </style>
@@ -3,6 +3,7 @@ import { mapGetters } from 'vuex';
3
3
  import { LabeledInput } from '@components/Form/LabeledInput';
4
4
  import { CHARSET, randomStr } from '@shell/utils/string';
5
5
  import { copyTextToClipboard } from '@shell/utils/clipboard';
6
+ import { _CREATE } from '@shell/config/query-params';
6
7
 
7
8
  export default {
8
9
  emits: ['update:value', 'blur'],
@@ -36,7 +37,11 @@ export default {
36
37
  ignorePasswordManagers: {
37
38
  default: false,
38
39
  type: Boolean,
39
- }
40
+ },
41
+ mode: {
42
+ type: String,
43
+ default: _CREATE,
44
+ },
40
45
  },
41
46
  data() {
42
47
  return { reveal: false };
@@ -104,6 +109,7 @@ export default {
104
109
  :required="required"
105
110
  :disabled="isRandom"
106
111
  :ignore-password-managers="ignorePasswordManagers"
112
+ :mode="mode"
107
113
  @blur="$emit('blur', $event)"
108
114
  >
109
115
  <template #suffix>
@@ -128,7 +128,12 @@ export default {
128
128
  delay: {
129
129
  type: Number,
130
130
  default: 0
131
- }
131
+ },
132
+
133
+ positive: {
134
+ type: Boolean,
135
+ default: false,
136
+ },
132
137
  },
133
138
 
134
139
  computed: {
@@ -196,6 +201,10 @@ export default {
196
201
  update(inputValue) {
197
202
  let out = inputValue === '' ? null : inputValue;
198
203
 
204
+ if (this.positive && inputValue < 0) {
205
+ out = 0;
206
+ }
207
+
199
208
  if (this.outputModifier) {
200
209
  out = out === null ? null : `${ inputValue }${ this.unit }`;
201
210
  } else if ( this.outputAs === 'string' ) {
@@ -17,6 +17,7 @@ describe('component: UnitInput', () => {
17
17
 
18
18
  await input.setValue(2);
19
19
  await input.setValue(4);
20
+ input.trigger(event);
20
21
 
21
22
  expect(wrapper.emitted('update:value')).toBeTruthy();
22
23
  expect(wrapper.emitted('update:value')[2]).toStrictEqual([4]);
@@ -25,12 +25,12 @@ export default {
25
25
  {{ row.machineProviderDisplay }}
26
26
  </span>
27
27
  </template>
28
- <template v-else-if="row.isCustom">
29
- {{ t('cluster.provider.custom') }}
30
- </template>
31
28
  <template v-else-if="row.isImported">
32
29
  {{ t('cluster.provider.imported') }}
33
30
  </template>
31
+ <template v-else-if="row.isCustom">
32
+ {{ t('cluster.provider.custom') }}
33
+ </template>
34
34
  <div class="text-muted">
35
35
  {{ row.provisionerDisplay }}
36
36
  </div>
@@ -38,7 +38,7 @@ export default {
38
38
  },
39
39
 
40
40
  completed() {
41
- return Number.parseFloat(this.value) === 100 && !this.failed;
41
+ return Number.parseFloat(this.value) === 100;
42
42
  },
43
43
  },
44
44
  };
@@ -38,5 +38,9 @@ export default {
38
38
  </script>
39
39
 
40
40
  <template>
41
- <span>{{ formattedValue }}</span>
41
+ <span v-if="value">{{ formattedValue }}</span>
42
+ <span
43
+ v-else
44
+ class="text-muted"
45
+ >&mdash;</span>
42
46
  </template>
@@ -19,7 +19,7 @@ export default {
19
19
 
20
20
  computed: {
21
21
  text() {
22
- return this.$store.getters['i18n/withFallback'](`${ this.prefix }.${ this.row.id }`, null, this.value);
22
+ return this.$store.getters['i18n/withFallback'](`${ this.prefix }.${ this.value || this.row.id }`, null, this.value);
23
23
  },
24
24
  },
25
25
  };
@@ -1,12 +1,13 @@
1
1
  <script>
2
2
  import { mapGetters } from 'vuex';
3
3
  import debounce from 'lodash/debounce';
4
- import { NORMAN, STEVE } from '@shell/config/types';
4
+ import { MANAGEMENT, NORMAN, STEVE } from '@shell/config/types';
5
+ import { HARVESTER_NAME as HARVESTER } from '@shell/config/features';
5
6
  import { ucFirst } from '@shell/utils/string';
6
7
  import { isAlternate, isMac } from '@shell/utils/platform';
7
8
  import Import from '@shell/components/Import';
8
9
  import BrandImage from '@shell/components/BrandImage';
9
- import { getProduct } from '@shell/config/private-label';
10
+ import { getProduct, getVendor } from '@shell/config/private-label';
10
11
  import ClusterProviderIcon from '@shell/components/ClusterProviderIcon';
11
12
  import ClusterBadge from '@shell/components/ClusterBadge';
12
13
  import AppModal from '@shell/components/AppModal';
@@ -14,6 +15,7 @@ import { LOGGED_OUT, IS_SSO } from '@shell/config/query-params';
14
15
  import NamespaceFilter from './NamespaceFilter';
15
16
  import WorkspaceSwitcher from './WorkspaceSwitcher';
16
17
  import TopLevelMenu from './TopLevelMenu';
18
+
17
19
  import Jump from './Jump';
18
20
  import { allHash } from '@shell/utils/promise';
19
21
  import { ActionLocation, ExtensionPoint } from '@shell/core/types';
@@ -86,7 +88,8 @@ export default {
86
88
  'pageActions',
87
89
  'isSingleProduct',
88
90
  'isRancherInHarvester',
89
- 'showTopLevelMenu'
91
+ 'showTopLevelMenu',
92
+ 'isMultiCluster'
90
93
  ]),
91
94
 
92
95
  samlAuthProviderEnabled() {
@@ -110,6 +113,12 @@ export default {
110
113
  return getProduct();
111
114
  },
112
115
 
116
+ vendor() {
117
+ this.$store.getters['management/all'](MANAGEMENT.SETTING)?.find((setting) => setting.id === 'ui-pl');
118
+
119
+ return getVendor();
120
+ },
121
+
113
122
  authEnabled() {
114
123
  return this.$store.getters['auth/enabled'];
115
124
  },
@@ -219,6 +228,9 @@ export default {
219
228
  };
220
229
  },
221
230
 
231
+ isHarvester() {
232
+ return this.$store.getters['currentProduct'].inStore === HARVESTER;
233
+ },
222
234
  },
223
235
 
224
236
  watch: {
@@ -379,7 +391,7 @@ export default {
379
391
  data-testid="header"
380
392
  >
381
393
  <div>
382
- <TopLevelMenu v-if="showTopLevelMenu" />
394
+ <TopLevelMenu v-if="isRancherInHarvester || isMultiCluster || !isSingleProduct" />
383
395
  </div>
384
396
  <div
385
397
  class="menu-spacer"
@@ -389,7 +401,14 @@ export default {
389
401
  v-if="isSingleProduct && !isRancherInHarvester"
390
402
  :to="singleProductLogoRoute"
391
403
  >
404
+ <BrandImage
405
+ v-if="isSingleProduct.supportCustomLogo && isHarvester"
406
+ class="side-menu-logo"
407
+ file-name="harvester.svg"
408
+ :support-custom-logo="true"
409
+ />
392
410
  <img
411
+ v-else
393
412
  class="side-menu-logo"
394
413
  :src="isSingleProduct.logo"
395
414
  >
@@ -409,7 +428,12 @@ export default {
409
428
  v-if="isSingleProduct && !isRancherInHarvester"
410
429
  class="product-name"
411
430
  >
412
- {{ t(isSingleProduct.productNameKey) }}
431
+ <template v-if="isSingleProduct.supportCustomLogo">
432
+ {{ vendor }}
433
+ </template>
434
+ <template v-else>
435
+ {{ t(isSingleProduct.productNameKey) }}
436
+ </template>
413
437
  </div>
414
438
  <template v-else>
415
439
  <ClusterProviderIcon
@@ -140,9 +140,11 @@ export default {
140
140
  options() {
141
141
  const t = this.$store.getters['i18n/t'];
142
142
  let out = [];
143
+ const inStore = this.$store.getters['currentStore'](NAMESPACE);
143
144
 
144
145
  const params = { ...this.$route.params };
145
146
  const resource = params.resource;
147
+
146
148
  // Sometimes, different pages may have different namespaces to filter
147
149
  const notFilterNamespaces = this.$store.getters[`type-map/optionsFor`](resource).notFilterNamespace || [];
148
150
 
@@ -198,8 +200,6 @@ export default {
198
200
  divider(out);
199
201
  }
200
202
 
201
- const inStore = this.$store.getters['currentStore'](NAMESPACE);
202
-
203
203
  if (!inStore) {
204
204
  return out;
205
205
  }
@@ -893,9 +893,6 @@ export default {
893
893
  width: 280px;
894
894
  display: inline-block;
895
895
 
896
- $glass-z-index: 2;
897
- $dropdown-z-index: 1000;
898
-
899
896
  .ns-glass {
900
897
  height: 100vh;
901
898
  left: 0;
@@ -903,7 +900,7 @@ export default {
903
900
  position: absolute;
904
901
  top: 0;
905
902
  width: 100vw;
906
- z-index: $glass-z-index;
903
+ z-index: z-index('overContent');
907
904
  }
908
905
 
909
906
  .ns-controls {
@@ -955,7 +952,7 @@ export default {
955
952
  margin-top: -1px;
956
953
  padding-bottom: 10px;
957
954
  position: relative;
958
- z-index: $dropdown-z-index;
955
+ z-index: z-index('dropdownOverlay');
959
956
 
960
957
  .ns-options {
961
958
  max-height: 50vh;
@@ -1067,7 +1064,7 @@ export default {
1067
1064
  height: 40px;
1068
1065
  padding: 0 10px;
1069
1066
  position: relative;
1070
- z-index: $dropdown-z-index;
1067
+ z-index: z-index('dropdownOverlay');
1071
1068
 
1072
1069
  &.ns-open {
1073
1070
  border-bottom-left-radius: 0;
@@ -546,7 +546,7 @@ export default {
546
546
  :to="{ name: 'home' }"
547
547
  >
548
548
  <svg
549
- v-tooltip="getTooltipConfig(t('nav.home'))"
549
+ v-clean-tooltip="getTooltipConfig(t('nav.home'))"
550
550
  xmlns="http://www.w3.org/2000/svg"
551
551
  height="24"
552
552
  viewBox="0 0 24 24"
@@ -660,13 +660,13 @@ export default {
660
660
  @shortkey="handleKeyComboClick"
661
661
  >
662
662
  <ClusterIconMenu
663
- v-tooltip="getTooltipConfig(c, true)"
663
+ v-clean-tooltip="getTooltipConfig(c, true)"
664
664
  :cluster="c"
665
665
  :route-combo="routeCombo"
666
666
  class="rancher-provider-icon"
667
667
  />
668
668
  <div
669
- v-tooltip="getTooltipConfig(c)"
669
+ v-clean-tooltip="getTooltipConfig(c)"
670
670
  class="cluster-name"
671
671
  >
672
672
  <p>{{ c.label }}</p>
@@ -687,12 +687,12 @@ export default {
687
687
  :data-testid="`pinned-menu-cluster-disabled-${ c.id }`"
688
688
  >
689
689
  <ClusterIconMenu
690
- v-tooltip="getTooltipConfig(c, true)"
690
+ v-clean-tooltip="getTooltipConfig(c, true)"
691
691
  :cluster="c"
692
692
  class="rancher-provider-icon"
693
693
  />
694
694
  <div
695
- v-tooltip="getTooltipConfig(c)"
695
+ v-clean-tooltip="getTooltipConfig(c)"
696
696
  class="cluster-name"
697
697
  >
698
698
  <p>{{ c.label }}</p>
@@ -735,13 +735,13 @@ export default {
735
735
  @shortkey="handleKeyComboClick"
736
736
  >
737
737
  <ClusterIconMenu
738
- v-tooltip="getTooltipConfig(c, true)"
738
+ v-clean-tooltip="getTooltipConfig(c, true)"
739
739
  :cluster="c"
740
740
  :route-combo="routeCombo"
741
741
  class="rancher-provider-icon"
742
742
  />
743
743
  <div
744
- v-tooltip="getTooltipConfig(c)"
744
+ v-clean-tooltip="getTooltipConfig(c)"
745
745
  class="cluster-name"
746
746
  >
747
747
  <!-- HERE LOCAL CLUSTER! -->
@@ -764,12 +764,12 @@ export default {
764
764
  :data-testid="`menu-cluster-disabled-${ c.id }`"
765
765
  >
766
766
  <ClusterIconMenu
767
- v-tooltip="getTooltipConfig(c, true)"
767
+ v-clean-tooltip="getTooltipConfig(c, true)"
768
768
  :cluster="c"
769
769
  class="rancher-provider-icon"
770
770
  />
771
771
  <div
772
- v-tooltip="getTooltipConfig(c)"
772
+ v-clean-tooltip="getTooltipConfig(c)"
773
773
  class="cluster-name"
774
774
  >
775
775
  <p>{{ c.label }}</p>
@@ -836,7 +836,7 @@ export default {
836
836
  :to="a.to"
837
837
  >
838
838
  <IconOrSvg
839
- v-tooltip="getTooltipConfig(a.label)"
839
+ v-clean-tooltip="getTooltipConfig(a.label)"
840
840
  :icon="a.icon"
841
841
  :src="a.svg"
842
842
  />
@@ -866,7 +866,7 @@ export default {
866
866
  :to="a.to"
867
867
  >
868
868
  <IconOrSvg
869
- v-tooltip="getTooltipConfig(a.label)"
869
+ v-clean-tooltip="getTooltipConfig(a.label)"
870
870
  :icon="a.icon"
871
871
  :src="a.svg"
872
872
  />
@@ -113,6 +113,7 @@ export const FLEET = {
113
113
  CLUSTER_NAME: 'management.cattle.io/cluster-name',
114
114
  BUNDLE_ID: 'fleet.cattle.io/bundle-id',
115
115
  MANAGED: 'fleet.cattle.io/managed',
116
+ CLUSTER_NAMESPACE: 'fleet.cattle.io/cluster-namespace',
116
117
  CLUSTER: 'fleet.cattle.io/cluster'
117
118
  };
118
119
 
@@ -145,6 +146,7 @@ export const HCI = {
145
146
  NETWORK_ROUTE: 'network.harvesterhci.io/route',
146
147
  IMAGE_NAME: 'harvesterhci.io/image-name',
147
148
  NETWORK_TYPE: 'network.harvesterhci.io/type',
149
+ CLUSTER_NETWORK: 'network.harvesterhci.io/clusternetwork',
148
150
  PRIMARY_SERVICE: 'cloudprovider.harvesterhci.io/primary-service',
149
151
  };
150
152
 
@@ -267,6 +267,21 @@ export const DESCRIPTION = {
267
267
  width: 300,
268
268
  };
269
269
 
270
+ export const NS_SNAPSHOT_QUOTA = {
271
+ name: 'NamespaceSnapshotQuota',
272
+ labelKey: 'harvester.tableHeaders.totalSnapshotQuota',
273
+ value: 'snapshotSizeQuota',
274
+ sort: 'snapshotSizeQuota',
275
+ align: 'center',
276
+ formatter: 'Si',
277
+ formatterOpts: {
278
+ opts: {
279
+ increment: 1024, addSuffix: true, suffix: 'i',
280
+ },
281
+ needParseSi: false
282
+ },
283
+ };
284
+
270
285
  export const DURATION = {
271
286
  name: 'duration',
272
287
  labelKey: 'tableHeaders.duration',
package/config/types.js CHANGED
@@ -172,6 +172,8 @@ export const LONGHORN = {
172
172
  };
173
173
 
174
174
  export const LONGHORN_DRIVER = 'driver.longhorn.io';
175
+ export const LONGHORN_VERSION_V1 = 'LonghornV1';
176
+ export const LONGHORN_VERSION_V2 = 'LonghornV2';
175
177
 
176
178
  export const SNAPSHOT = 'rke.cattle.io.etcdsnapshot';
177
179
 
@@ -313,6 +315,7 @@ export const HCI = {
313
315
  IMAGE: 'harvesterhci.io.virtualmachineimage',
314
316
  VGPU_DEVICE: 'devices.harvesterhci.io.vgpudevice',
315
317
  SETTING: 'harvesterhci.io.setting',
318
+ RESOURCE_QUOTA: 'harvesterhci.io.resourcequota',
316
319
  HARVESTER_CONFIG: 'rke-machine-config.cattle.io.harvesterconfig',
317
320
  };
318
321
 
@@ -1,77 +1,25 @@
1
1
  <script>
2
- import { FLEET } from '@shell/config/types';
3
2
  import FleetBundleResources from '@shell/components/fleet/FleetBundleResources.vue';
4
- import SortableTable from '@shell/components/SortableTable';
3
+ import FleetUtils from '@shell/utils/fleet';
5
4
 
6
5
  export default {
7
6
  name: 'FleetBundleDetail',
8
7
 
9
- components: {
10
- FleetBundleResources,
11
- SortableTable,
12
- },
13
- props: {
8
+ components: { FleetBundleResources },
9
+ props: {
14
10
  value: {
15
11
  type: Object,
16
12
  required: true,
17
13
  }
18
14
  },
19
15
 
20
- data() {
21
- return { repo: null };
22
- },
23
-
24
- async fetch() {
25
- const { namespace, labels } = this.value.metadata;
26
- const repoName = `${ namespace }/${ labels['fleet.cattle.io/repo-name'] }`;
27
-
28
- if (this.hasRepoLabel) {
29
- this.repo = await this.$store.dispatch('management/find', { type: FLEET.GIT_REPO, id: repoName });
30
- }
31
- },
32
-
33
16
  computed: {
34
- hasRepoLabel() {
35
- return !!(this.value?.metadata?.labels && this.value?.metadata?.labels['fleet.cattle.io/repo-name']);
36
- },
37
17
  bundleResources() {
38
- if (this.hasRepoLabel) {
39
- const bundleResourceIds = this.bundleResourceIds;
40
-
41
- return this.repo?.status?.resources?.filter((resource) => {
42
- return bundleResourceIds.includes(resource.name);
43
- });
44
- } else if (this.value?.spec?.resources?.length) {
45
- return this.value?.spec?.resources.map((item) => {
46
- return {
47
- content: item.content,
48
- name: item.name.includes('.') ? item.name.split('.')[0] : item.name
49
- };
50
- });
51
- }
52
-
53
- return [];
54
- },
55
- resourceHeaders() {
56
- return [
57
- {
58
- name: 'name',
59
- value: 'name',
60
- sort: ['name'],
61
- labelKey: 'tableHeaders.name',
62
- },
63
- ];
18
+ return FleetUtils.resourcesFromBundleStatus(this.value?.status);
64
19
  },
65
20
  resourceCount() {
66
- return (this.bundleResources && this.bundleResources.length) || this.value?.spec?.resources?.length;
21
+ return this.bundleResources.length;
67
22
  },
68
- bundleResourceIds() {
69
- if (this.value.status?.resourceKey) {
70
- return this.value?.status?.resourceKey.map((item) => item.name);
71
- }
72
-
73
- return [];
74
- }
75
23
  }
76
24
  };
77
25
 
@@ -84,19 +32,8 @@ export default {
84
32
  <span>{{ resourceCount }}</span>
85
33
  </div>
86
34
  <FleetBundleResources
87
- v-if="hasRepoLabel"
88
35
  :value="bundleResources"
89
36
  />
90
- <SortableTable
91
- v-else
92
- :rows="bundleResources"
93
- :headers="resourceHeaders"
94
- :table-actions="false"
95
- :row-actions="false"
96
- key-field="tableKey"
97
- default-sort-by="state"
98
- :paged="true"
99
- />
100
37
  </div>
101
38
  </template>
102
39
 
@@ -82,7 +82,8 @@ export default {
82
82
  const allDispatches = await checkSchemasForFindAllHash({
83
83
  allBundles: {
84
84
  inStoreType: 'management',
85
- type: FLEET.BUNDLE
85
+ type: FLEET.BUNDLE,
86
+ opt: { excludeFields: ['metadata.managedFields', 'spec.resources'] },
86
87
  },
87
88
 
88
89
  allBundleDeployments: {
@@ -13,10 +13,10 @@ function purifyContent(value) {
13
13
  }
14
14
  }
15
15
 
16
- function bind(el, { value, oldValue, modifiers }) {
16
+ function beforeMount(el, { value, oldValue, modifiers }) {
17
17
  const purifiedValue = purifyContent(value);
18
18
 
19
- VTooltip.bind(
19
+ VTooltip.beforeMount(
20
20
  el,
21
21
  {
22
22
  value: purifiedValue, oldValue, modifiers
@@ -25,8 +25,8 @@ function bind(el, { value, oldValue, modifiers }) {
25
25
 
26
26
  const cleanTooltipDirective = {
27
27
  ...VTooltip,
28
- bind,
29
- update: bind,
28
+ beforeMount,
29
+ updated: beforeMount,
30
30
  };
31
31
 
32
32
  export default cleanTooltipDirective;