@rancher/shell 0.3.1 → 0.3.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 (44) hide show
  1. package/assets/styles/global/_gauges.scss +1 -1
  2. package/assets/styles/global/_layout.scss +4 -0
  3. package/assets/styles/themes/_dark.scss +1 -0
  4. package/assets/translations/en-us.yaml +4 -0
  5. package/assets/translations/zh-hans.yaml +175 -44
  6. package/components/ActionMenu.vue +28 -7
  7. package/components/DetailTop.vue +14 -1
  8. package/components/ExtensionPanel.vue +42 -0
  9. package/components/IconOrSvg.vue +31 -2
  10. package/components/ResourceDetail/Masthead.vue +16 -3
  11. package/components/ResourceList/index.vue +15 -2
  12. package/components/ResourceTable.vue +3 -1
  13. package/components/SortableTable/THead.vue +6 -9
  14. package/components/SortableTable/filtering.js +1 -1
  15. package/components/SortableTable/selection.js +15 -3
  16. package/components/Tabbed/Tab.vue +1 -1
  17. package/components/form/ResourceTabs/index.vue +23 -0
  18. package/components/nav/Header.vue +69 -5
  19. package/config/product/backup.js +1 -1
  20. package/config/query-params.js +1 -0
  21. package/config/uiplugins.js +3 -3
  22. package/core/plugin-helpers.js +171 -0
  23. package/core/plugin.ts +61 -1
  24. package/core/plugins.js +33 -0
  25. package/core/types.ts +128 -2
  26. package/edit/catalog.cattle.io.clusterrepo.vue +3 -0
  27. package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +14 -2
  28. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +3 -0
  29. package/edit/provisioning.cattle.io.cluster/rke2.vue +21 -18
  30. package/package.json +1 -1
  31. package/pages/c/_cluster/apps/charts/index.vue +17 -0
  32. package/pages/c/_cluster/explorer/index.vue +39 -0
  33. package/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue +2 -0
  34. package/pages/c/_cluster/uiplugins/InstallDialog.vue +3 -0
  35. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +8 -1
  36. package/pages/c/_cluster/uiplugins/RemoveUIPlugins.vue +2 -0
  37. package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +1 -0
  38. package/pages/c/_cluster/uiplugins/UninstallDialog.vue +2 -0
  39. package/pages/c/_cluster/uiplugins/index.vue +14 -1
  40. package/plugins/dashboard-store/resource-class.js +16 -1
  41. package/rancher-components/components/Banner/Banner.vue +1 -0
  42. package/store/action-menu.js +4 -3
  43. package/store/type-map.js +26 -0
  44. package/types/shell/index.d.ts +1 -0
@@ -3,15 +3,16 @@ import { mapGetters } from 'vuex';
3
3
  import $ from 'jquery';
4
4
  import { AUTO, CENTER, fitOnScreen } from '@shell/utils/position';
5
5
  import { isAlternate } from '@shell/utils/platform';
6
+ import IconOrSvg from '@shell/components/IconOrSvg';
6
7
 
7
8
  const HIDDEN = 'hide';
8
9
  const CALC = 'calculate';
9
10
  const SHOW = 'show';
10
11
 
11
12
  export default {
12
- name: 'ActionMenu',
13
-
14
- props: {
13
+ name: 'ActionMenu',
14
+ components: { IconOrSvg },
15
+ props: {
15
16
  customActions: {
16
17
  // Custom actions can be used if you need the action
17
18
  // menu to work for something that is not a Kubernetes
@@ -194,7 +195,23 @@ export default {
194
195
  return;
195
196
  }
196
197
 
197
- if (this.useCustomTargetElement) {
198
+ // this will come from extensions...
199
+ if (action.invoke) {
200
+ const fn = action.invoke;
201
+
202
+ if (fn && action.enabled) {
203
+ const resources = this.$store.getters['action-menu/resources'];
204
+ const opts = {
205
+ event,
206
+ action,
207
+ isAlt: isAlternate(event)
208
+ };
209
+
210
+ if (resources.length === 1) {
211
+ fn.apply(this, [opts, resources]);
212
+ }
213
+ }
214
+ } else if (this.useCustomTargetElement) {
198
215
  // If the state of this component is controlled
199
216
  // by props instead of Vuex, we assume you wouldn't want
200
217
  // the mutation to have a dependency on Vuex either.
@@ -247,12 +264,16 @@ export default {
247
264
  :data-testid="componentTestid + '-' + i + '-item'"
248
265
  @click="execute(opt, $event)"
249
266
  >
250
- <i
251
- v-if="opt.icon"
252
- :class="{icon: true, [opt.icon]: true}"
267
+ <IconOrSvg
268
+ v-if="opt.icon || opt.svg"
269
+ :icon="opt.icon"
270
+ :src="opt.svg"
271
+ class="icon"
272
+ color="header"
253
273
  />
254
274
  <span v-html="opt.label" />
255
275
  </li>
276
+
256
277
  <li
257
278
  v-if="!hasOptions(menuOptions)"
258
279
  class="no-actions"
@@ -3,11 +3,15 @@ import Tag from '@shell/components/Tag';
3
3
  import isEmpty from 'lodash/isEmpty';
4
4
  import DetailText from '@shell/components/DetailText';
5
5
  import { _VIEW } from '@shell/config/query-params';
6
+ import { ExtensionPoint, PanelLocation } from '@shell/core/types';
7
+ import ExtensionPanel from '@shell/components/ExtensionPanel';
6
8
 
7
9
  export const SEPARATOR = { separator: true };
8
10
 
9
11
  export default {
10
- components: { DetailText, Tag },
12
+ components: {
13
+ DetailText, Tag, ExtensionPanel
14
+ },
11
15
 
12
16
  props: {
13
17
  value: {
@@ -49,6 +53,8 @@ export default {
49
53
 
50
54
  data() {
51
55
  return {
56
+ extensionType: ExtensionPoint.PANEL,
57
+ extensionLocation: PanelLocation.DETAIL_TOP,
52
58
  annotationsVisible: false,
53
59
  showAllLabels: false,
54
60
  view: _VIEW
@@ -287,6 +293,13 @@ export default {
287
293
  />
288
294
  </div>
289
295
  </div>
296
+
297
+ <!-- Extensions area -->
298
+ <ExtensionPanel
299
+ :resource="value"
300
+ :type="extensionType"
301
+ :location="extensionLocation"
302
+ />
290
303
  </div>
291
304
  </template>
292
305
 
@@ -0,0 +1,42 @@
1
+ <script>
2
+ import { getApplicableExtensionEnhancements } from '@shell/core/plugin-helpers';
3
+
4
+ export default {
5
+ name: 'ExtensionPanel',
6
+ props: {
7
+ resource: {
8
+ type: Object,
9
+ default: () => {
10
+ return {};
11
+ }
12
+ },
13
+ type: {
14
+ type: String,
15
+ default: ''
16
+ },
17
+ location: {
18
+ type: String,
19
+ default: ''
20
+ },
21
+ },
22
+ data() {
23
+ return { extensionData: getApplicableExtensionEnhancements(this, this.type, this.location, this.$route) };
24
+ },
25
+ };
26
+ </script>
27
+
28
+ <template>
29
+ <div
30
+ v-if="extensionData.length"
31
+ >
32
+ <div
33
+ v-for="item, i in extensionData"
34
+ :key="`extensionData${location}${i}`"
35
+ >
36
+ <component
37
+ :is="item.component"
38
+ :resource="resource"
39
+ />
40
+ </div>
41
+ </div>
42
+ </template>
@@ -63,8 +63,34 @@ export default {
63
63
 
64
64
  methods: {
65
65
  setColor() {
66
- const uiColor = mapStandardColors(getComputedStyle(document.body).getPropertyValue(colors[this.color].color).trim());
67
- const hoverColor = mapStandardColors(getComputedStyle(document.body).getPropertyValue(colors[this.color].hover).trim());
66
+ const currTheme = this.$store.getters['prefs/theme'];
67
+ let uiColor, hoverColor;
68
+
69
+ // grab css vars values based on the actual stylesheets, depending on the theme applied
70
+ // use for loops to minimize computation
71
+ for (let i = 0; i < Object.keys(document.styleSheets).length; i++) {
72
+ let found = false;
73
+ const stylesheet = document.styleSheets[i];
74
+
75
+ if (stylesheet && stylesheet.cssRules) {
76
+ for (let x = 0; x < Object.keys(stylesheet.cssRules).length; x++) {
77
+ const cssRules = stylesheet.cssRules[x];
78
+ const selectorText = currTheme === 'light' ? 'body, .theme-light' : '.theme-dark';
79
+
80
+ if (cssRules.selectorText && cssRules.selectorText === selectorText) {
81
+ uiColor = mapStandardColors(cssRules.style.getPropertyValue(colors[this.color].color).trim());
82
+ hoverColor = mapStandardColors(cssRules.style.getPropertyValue(colors[this.color].hover).trim());
83
+ found = true;
84
+ break;
85
+ }
86
+ }
87
+ }
88
+ if (found) {
89
+ break;
90
+ } else {
91
+ continue;
92
+ }
93
+ }
68
94
 
69
95
  const uiColorRGB = colorToRgb(uiColor);
70
96
  const hoverColorRGB = colorToRgb(hoverColor);
@@ -105,6 +131,9 @@ export default {
105
131
  button:hover > img.${ className } {
106
132
  ${ hoverFilter };
107
133
  }
134
+ li:hover > img.${ className } {
135
+ ${ hoverFilter };
136
+ }
108
137
  a.option:hover > img.${ className } {
109
138
  ${ hoverFilter };
110
139
  } `;
@@ -10,6 +10,8 @@ import { HIDE_SENSITIVE } from '@shell/store/prefs';
10
10
  import {
11
11
  AS, _DETAIL, _CONFIG, _YAML, MODE, _CREATE, _EDIT, _VIEW, _UNFLAG, _GRAPH
12
12
  } from '@shell/config/query-params';
13
+ import { ExtensionPoint, PanelLocation } from '@shell/core/types';
14
+ import ExtensionPanel from '@shell/components/ExtensionPanel';
13
15
 
14
16
  /**
15
17
  * Resource Detail Masthead component.
@@ -21,7 +23,7 @@ export default {
21
23
  name: 'MastheadResourceDetail',
22
24
 
23
25
  components: {
24
- BadgeState, Banner, ButtonGroup
26
+ BadgeState, Banner, ButtonGroup, ExtensionPanel
25
27
  },
26
28
  props: {
27
29
  value: {
@@ -83,7 +85,11 @@ export default {
83
85
  },
84
86
 
85
87
  data() {
86
- return { DETAIL_VIEW: _DETAIL };
88
+ return {
89
+ DETAIL_VIEW: _DETAIL,
90
+ extensionType: ExtensionPoint.PANEL,
91
+ extensionLocation: PanelLocation.DETAILS_MASTHEAD,
92
+ };
87
93
  },
88
94
 
89
95
  computed: {
@@ -451,7 +457,7 @@ export default {
451
457
  </div>
452
458
  </div>
453
459
  <slot name="right">
454
- <div class="actions-container">
460
+ <div class="actions-container align-start">
455
461
  <div class="actions">
456
462
  <button
457
463
  v-if="detailsAction && currentView === DETAIL_VIEW && isView"
@@ -493,6 +499,13 @@ export default {
493
499
  </slot>
494
500
  </header>
495
501
 
502
+ <!-- Extension area -->
503
+ <ExtensionPanel
504
+ :resource="value"
505
+ :type="extensionType"
506
+ :location="extensionLocation"
507
+ />
508
+
496
509
  <Banner
497
510
  v-if="banner && isView && !parent.hideBanner"
498
511
  class="state-banner mb-10"
@@ -6,6 +6,8 @@ import ResourceLoadingIndicator from './ResourceLoadingIndicator';
6
6
  import ResourceFetch from '@shell/mixins/resource-fetch';
7
7
  import IconMessage from '@shell/components/IconMessage.vue';
8
8
  import { ResourceListComponentName } from './resource-list.config';
9
+ import { PanelLocation, ExtensionPoint } from '@shell/core/types';
10
+ import ExtensionPanel from '@shell/components/ExtensionPanel';
9
11
 
10
12
  export default {
11
13
  name: ResourceListComponentName,
@@ -15,7 +17,8 @@ export default {
15
17
  ResourceTable,
16
18
  Masthead,
17
19
  ResourceLoadingIndicator,
18
- IconMessage
20
+ IconMessage,
21
+ ExtensionPanel
19
22
  },
20
23
  mixins: [ResourceFetch],
21
24
 
@@ -96,6 +99,8 @@ export default {
96
99
  hasListComponent,
97
100
  showMasthead: showMasthead === undefined ? true : showMasthead,
98
101
  resource,
102
+ extensionType: ExtensionPoint.PANEL,
103
+ extensionLocation: PanelLocation.RESOURCE_LIST,
99
104
  loadResources: [resource], // List of resources that will be loaded, this could be many (`Workloads`)
100
105
  hasFetch: false,
101
106
  // manual refresh
@@ -127,7 +132,8 @@ export default {
127
132
 
128
133
  showIncrementalLoadingIndicator() {
129
134
  return this.perfConfig?.incrementalLoading?.enabled;
130
- }
135
+ },
136
+
131
137
  },
132
138
 
133
139
  watch: {
@@ -191,6 +197,13 @@ export default {
191
197
  <slot name="extraActions" />
192
198
  </template>
193
199
  </Masthead>
200
+ <!-- Extensions area -->
201
+ <ExtensionPanel
202
+ :resource="{}"
203
+ :type="extensionType"
204
+ :location="extensionLocation"
205
+ />
206
+
194
207
  <div v-if="hasListComponent">
195
208
  <component
196
209
  :is="listComponent"
@@ -404,7 +404,9 @@ export default {
404
404
  },
405
405
 
406
406
  handleEnterKeyPress(event) {
407
- this.keyAction('detail');
407
+ if (event.key === 'Enter') {
408
+ this.keyAction('detail');
409
+ }
408
410
  }
409
411
  }
410
412
  };
@@ -348,7 +348,7 @@ export default {
348
348
  }
349
349
  }
350
350
  .table-options-container {
351
- width: 320px;
351
+ width: 350px;
352
352
  border: 1px solid var(--primary);
353
353
  background-color: var(--body-bg);
354
354
  padding: 20px;
@@ -369,11 +369,10 @@ export default {
369
369
  list-style: none;
370
370
  margin: 0;
371
371
  padding: 0;
372
- display: flex;
373
- flex-wrap: wrap;
372
+ max-height: 200px;
373
+ overflow-y: auto;
374
374
 
375
375
  li {
376
- flex: 1 1 136px;
377
376
  margin: 0;
378
377
  padding: 0;
379
378
 
@@ -486,12 +485,10 @@ export default {
486
485
  }
487
486
  </style>
488
487
  <style lang="scss">
488
+ .table-options-checkbox .checkbox-custom {
489
+ min-width: 14px;
490
+ }
489
491
  .table-options-checkbox .checkbox-label {
490
492
  color: var(--body-text);
491
- text-overflow: ellipsis;
492
- width: 100px;
493
- display: inline-block;
494
- white-space: nowrap;
495
- overflow: hidden;
496
493
  }
497
494
  </style>
@@ -254,7 +254,7 @@ function matches(fields, token, item) {
254
254
  }
255
255
 
256
256
  if ( !modifier ) {
257
- if ( val.includes(token) ) {
257
+ if ( val.includes((`${ token }`).toLowerCase()) ) {
258
258
  return true;
259
259
  }
260
260
  } else if ( modifier === 'exact' ) {
@@ -504,7 +504,7 @@ export default {
504
504
  },
505
505
 
506
506
  applyTableAction(action, args, event) {
507
- const opts = { alt: event && isAlternate(event) };
507
+ const opts = { alt: event && isAlternate(event), event };
508
508
 
509
509
  // Go through the table selection and filter out those actions that can't run the chosen action
510
510
  const executableSelection = this.selectedRows.filter((row) => {
@@ -513,7 +513,7 @@ export default {
513
513
  return matchingResourceAction?.enabled;
514
514
  });
515
515
 
516
- _execute(executableSelection, action, args, opts);
516
+ _execute(executableSelection, action, args, opts, this);
517
517
 
518
518
  this.actionOfInterest = null;
519
519
  },
@@ -575,8 +575,20 @@ function _filter(map, disableAll = false) {
575
575
  return out;
576
576
  }
577
577
 
578
- function _execute(resources, action, args, opts = {}) {
578
+ function _execute(resources, action, args, opts = {}, ctx) {
579
579
  args = args || [];
580
+
581
+ // New pattern for extensions - always call invoke
582
+ if (action.invoke) {
583
+ const actionOpts = {
584
+ action,
585
+ event: opts.event,
586
+ isAlt: !!opts.alt,
587
+ };
588
+
589
+ return action.invoke.apply(ctx, [actionOpts, resources || [], args]);
590
+ }
591
+
580
592
  if ( resources.length > 1 && action.bulkAction && !opts.alt ) {
581
593
  const fn = resources[0][action.bulkAction];
582
594
 
@@ -99,7 +99,7 @@ export default {
99
99
  class="tab-header"
100
100
  >
101
101
  <h2>
102
- {{ label }}
102
+ {{ labelDisplay }}
103
103
  <i
104
104
  v-if="tooltip"
105
105
  v-tooltip="tooltip"
@@ -11,6 +11,8 @@ import { EVENT } from '@shell/config/types';
11
11
  import SortableTable from '@shell/components/SortableTable';
12
12
  import { _VIEW } from '@shell/config/query-params';
13
13
  import RelatedResources from '@shell/components/RelatedResources';
14
+ import { ExtensionPoint, TabLocation } from '@shell/core/types';
15
+ import { getApplicableExtensionEnhancements } from '@shell/core/plugin-helpers';
14
16
 
15
17
  export default {
16
18
 
@@ -69,6 +71,7 @@ export default {
69
71
  allEvents: [],
70
72
  selectedTab: this.defaultTab,
71
73
  didLoadEvents: false,
74
+ extensionTabs: getApplicableExtensionEnhancements(this, ExtensionPoint.TAB, TabLocation.RESOURCE_DETAIL, this.$route),
72
75
  };
73
76
  },
74
77
 
@@ -221,5 +224,25 @@ export default {
221
224
  direction="to"
222
225
  />
223
226
  </Tab>
227
+
228
+ <!-- Extension tabs -->
229
+ <Tab
230
+ v-for="tab, i in extensionTabs"
231
+ :key="`${tab.name}${i}`"
232
+ :name="tab.name"
233
+ :label="tab.label"
234
+ :label-key="tab.labelKey"
235
+ :weight="tab.weight"
236
+ :tooltip="tab.tooltip"
237
+ :show-header="tab.showHeader"
238
+ :display-alert-icon="tab.displayAlertIcon"
239
+ :error="tab.error"
240
+ :badge="tab.badge"
241
+ >
242
+ <component
243
+ :is="tab.component"
244
+ :resource="value"
245
+ />
246
+ </Tab>
224
247
  </Tabbed>
225
248
  </template>
@@ -3,7 +3,7 @@ import { mapGetters } from 'vuex';
3
3
  import debounce from 'lodash/debounce';
4
4
  import { NORMAN, STEVE } from '@shell/config/types';
5
5
  import { ucFirst } from '@shell/utils/string';
6
- import { isMac } from '@shell/utils/platform';
6
+ import { isAlternate, isMac } from '@shell/utils/platform';
7
7
  import Import from '@shell/components/Import';
8
8
  import BrandImage from '@shell/components/BrandImage';
9
9
  import { getProduct } from '@shell/config/private-label';
@@ -15,6 +15,9 @@ import WorkspaceSwitcher from './WorkspaceSwitcher';
15
15
  import TopLevelMenu from './TopLevelMenu';
16
16
  import Jump from './Jump';
17
17
  import { allHash } from '@shell/utils/promise';
18
+ import { ActionLocation, ExtensionPoint } from '@shell/core/types';
19
+ import { getApplicableExtensionEnhancements } from '@shell/core/plugin-helpers';
20
+ import IconOrSvg from '@shell/components/IconOrSvg';
18
21
 
19
22
  const PAGE_HEADER_ACTION = 'page-action';
20
23
 
@@ -29,6 +32,7 @@ export default {
29
32
  BrandImage,
30
33
  ClusterBadge,
31
34
  ClusterProviderIcon,
35
+ IconOrSvg
32
36
  },
33
37
 
34
38
  props: {
@@ -43,13 +47,15 @@ export default {
43
47
  const shellShortcut = '(Ctrl+`)';
44
48
 
45
49
  return {
46
- show: false,
47
- showTooltip: false,
48
- kubeConfigCopying: false,
50
+ show: false,
51
+ showTooltip: false,
52
+ kubeConfigCopying: false,
49
53
  searchShortcut,
50
54
  shellShortcut,
51
55
  LOGGED_OUT,
52
- navHeaderRight: null,
56
+ navHeaderRight: null,
57
+ extensionHeaderActions: getApplicableExtensionEnhancements(this, ExtensionPoint.ACTION, ActionLocation.HEADER, this.$route),
58
+ ctx: this
53
59
  };
54
60
  },
55
61
 
@@ -170,6 +176,12 @@ export default {
170
176
  if (nue && old && nue.id !== old.id) {
171
177
  this.checkClusterName();
172
178
  }
179
+ },
180
+ // since the Header is a "persistent component" we need to update it at every route change...
181
+ $route(nue) {
182
+ if (nue) {
183
+ this.extensionHeaderActions = getApplicableExtensionEnhancements(this, ExtensionPoint.ACTION, ActionLocation.HEADER, nue);
184
+ }
173
185
  }
174
186
  },
175
187
 
@@ -288,6 +300,33 @@ export default {
288
300
  button.classList.remove('header-btn-active');
289
301
  }
290
302
  });
303
+ },
304
+
305
+ handleExtensionAction(action, event) {
306
+ const fn = action.invoke;
307
+ const opts = {
308
+ event,
309
+ action,
310
+ isAlt: isAlternate(event),
311
+ product: this.currentProduct.name,
312
+ cluster: this.currentCluster,
313
+ };
314
+ const enabled = action.enabled ? action.enabled.apply(this, [opts]) : true;
315
+
316
+ if (fn && enabled) {
317
+ fn.apply(this, [opts, []]);
318
+ }
319
+ },
320
+
321
+ handleExtensionTooltip(action) {
322
+ if (action.tooltipKey || action.tooltip) {
323
+ const tooltip = action.tooltipKey ? this.t(action.tooltipKey) : action.tooltip;
324
+ const shortcut = action.shortcutLabel ? action.shortcutLabel() : '';
325
+
326
+ return `${ tooltip } ${ shortcut }`;
327
+ }
328
+
329
+ return null;
291
330
  }
292
331
  }
293
332
  };
@@ -502,6 +541,31 @@ export default {
502
541
  </modal>
503
542
  </div>
504
543
 
544
+ <!-- Extension header actions -->
545
+ <div
546
+ v-if="extensionHeaderActions.length"
547
+ class="header-buttons"
548
+ >
549
+ <button
550
+ v-for="action, i in extensionHeaderActions"
551
+ :key="`${action.label}${i}`"
552
+ v-tooltip="handleExtensionTooltip(action)"
553
+ v-shortkey="action.shortcutKey"
554
+ :disabled="action.enabled ? !action.enabled(ctx) : false"
555
+ type="button"
556
+ class="btn header-btn role-tertiary"
557
+ @shortkey="handleExtensionAction(action, $event)"
558
+ @click="handleExtensionAction(action, $event)"
559
+ >
560
+ <IconOrSvg
561
+ class="icon icon-lg"
562
+ :icon="action.icon"
563
+ :src="action.svg"
564
+ color="header"
565
+ />
566
+ </button>
567
+ </div>
568
+
505
569
  <div
506
570
  v-if="showPageActions"
507
571
  id="page-actions"
@@ -43,7 +43,7 @@ export function init(store) {
43
43
  formatter: 'Date'
44
44
  },
45
45
  {
46
- name: 'nextBackup',
46
+ name: 'lastBackup',
47
47
  labelKey: 'backupRestoreOperator.lastBackup',
48
48
  value: 'status.lastSnapshotTs',
49
49
  formatter: 'Date'
@@ -30,6 +30,7 @@ export const MODE = 'mode';
30
30
  export const _CREATE = 'create';
31
31
  export const _VIEW = 'view';
32
32
  export const _EDIT = 'edit';
33
+ export const _LIST = 'list';
33
34
  export const _CLONE = 'clone';
34
35
  export const _STAGE = 'stage';
35
36
  export const _IMPORT = 'import';
@@ -1,7 +1,7 @@
1
1
  import semver from 'semver';
2
2
 
3
3
  // Version of the plugin API supported
4
- export const UI_PLUGIN_API_VERSION = '1.0.0';
4
+ export const UI_PLUGIN_API_VERSION = '1.1.0';
5
5
  export const UI_PLUGIN_HOST_APP = 'rancher-manager';
6
6
 
7
7
  export const UI_PLUGIN_BASE_URL = '/api/v1/namespaces/cattle-ui-plugin-system/services/http:ui-plugin-operator:80/proxy';
@@ -32,8 +32,8 @@ export const UI_PLUGINS_REPO_BRANCH = 'main';
32
32
  // Chart annotations
33
33
  export const UI_PLUGIN_CHART_ANNOTATIONS = {
34
34
  RANCHER_VERSION: 'catalog.cattle.io/rancher-version',
35
- EXTENSIONS_VERSION: 'catalog.cattle.io/ui-extenstions-version',
36
- EXTENSIONS_HOST: 'catalog.cattle.io/ui-extenstions-host',
35
+ EXTENSIONS_VERSION: 'catalog.cattle.io/ui-extensions-version',
36
+ EXTENSIONS_HOST: 'catalog.cattle.io/ui-extensions-host',
37
37
  DISPLAY_NAME: 'catalog.cattle.io/display-name',
38
38
  };
39
39