@rancher/shell 3.0.2-rc.4 → 3.0.2-rc.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,6 +17,7 @@ generic:
17
17
  comma: ', '
18
18
  copy: Copy
19
19
  copyToClipboard: Copy text to Clipboard
20
+ copiedToClipboard: Text copied to Clipboard
20
21
  create: Create
21
22
  created: Created
22
23
  customize: Customize
@@ -950,6 +951,7 @@ catalog:
950
951
  experimentalWarning: '{chartName} has been marked as experimental. Use caution when installing this helm chart as it might not function as expected.'
951
952
  deprecatedAndExperimentalWarning: '{chartName} has been marked as deprecated and experimental. Use caution when installing this helm chart as it might be removed in the future and might not function as expected.'
952
953
  charts:
954
+ iconAlt: Icon for {app} card/grid item
953
955
  refresh: refresh charts
954
956
  all: All
955
957
  categories:
@@ -1133,6 +1135,7 @@ catalog:
1133
1135
  label: Refresh Interval
1134
1136
  placeholder: 'default: {hours}'
1135
1137
  tools:
1138
+ iconAlt: Icon for {app} Cluster Tool
1136
1139
  header: Cluster Tools
1137
1140
  noTools: "No Cluster Tools found"
1138
1141
  action:
@@ -4376,6 +4379,7 @@ inactivity:
4376
4379
 
4377
4380
  # Rancher Extensions
4378
4381
  plugins:
4382
+ altIcon: Icon for {extension} extension card
4379
4383
  incompatibleRancherVersion: "The latest version of this extension ({ version }) is not compatible with the current Rancher version ({ required })."
4380
4384
  incompatibleKubeVersion: "The latest version of this extension ({ version }) is not compatible with the current Kube version ({ required })."
4381
4385
  incompatibleUiExtensionsApiVersionMissing: 'The latest version of this extension ({ version }) is missing the mandatory annotation catalog.cattle.io/ui-extensions-version from Rancher 2.10 and onwards.'
@@ -4711,6 +4715,7 @@ projectMembers:
4711
4715
  workloadsView: View Workloads
4712
4716
 
4713
4717
  projectNamespaces:
4718
+ tableActionsLabel: More actions for project { resource }
4714
4719
  createNamespace: Create Namespace
4715
4720
  createProject: Create Project
4716
4721
  label: Projects/Namespaces
@@ -5386,6 +5391,8 @@ setup:
5386
5391
  welcome: Welcome to {vendor}!
5387
5392
 
5388
5393
  sortableTable:
5394
+ tableActionsLabel: More actions - { resource }
5395
+ tableActionsImgAlt: More actions icon
5389
5396
  bulkActions:
5390
5397
  collapsed:
5391
5398
  label: Actions
@@ -6200,6 +6207,8 @@ wm:
6200
6207
  disconnected: Disconnected
6201
6208
  error: Error
6202
6209
  containerLogs:
6210
+ options: Additional container logs options
6211
+ expand: Expand additional container logs options
6203
6212
  clear: Clear
6204
6213
  containerName: "Container: {label}"
6205
6214
  download: Download
@@ -6226,6 +6235,9 @@ wm:
6226
6235
  timestamps: Show Timestamps
6227
6236
  wrap: Wrap Lines
6228
6237
  containerShell:
6238
+ resizeShellWindow: Resize Shell window
6239
+ tabIcon: Shell tab icon
6240
+ closeShellTab: Close Shell tab - {tab}
6229
6241
  clear: Clear
6230
6242
  containerName: "Container: {label}"
6231
6243
  failed: "Unable to open a shell to the container (none of the shell commands succeeded)\n\r"
@@ -7498,6 +7510,7 @@ advancedSettings:
7498
7510
  none: None
7499
7511
  modified: Modified
7500
7512
  edit:
7513
+ moreActions: More actions for setting - { setting }
7501
7514
  label: Edit Setting
7502
7515
  changeSetting: "Change Setting:"
7503
7516
  trueOption: "True"
@@ -64,6 +64,12 @@ export default {
64
64
  methods: {
65
65
  change(value) {
66
66
  this.$emit('update:value', value);
67
+ },
68
+ actionDescription(opt) {
69
+ const tooltip = opt.tooltipKey ? this.t(opt.tooltipKey) : opt.tooltip;
70
+ const label = opt.labelKey ? this.t(opt.labelKey) : opt.label;
71
+
72
+ return tooltip || label || '';
67
73
  }
68
74
  }
69
75
  };
@@ -83,7 +89,7 @@ export default {
83
89
  :class="opt.class"
84
90
  :disabled="disabled || opt.disabled"
85
91
  role="button"
86
- :aria-label="opt.labelKey ? t(opt.labelKey) : opt.label"
92
+ :aria-label="actionDescription(opt)"
87
93
  @click="change(opt.value)"
88
94
  >
89
95
  <slot
@@ -94,6 +100,7 @@ export default {
94
100
  <i
95
101
  v-if="opt.icon"
96
102
  :class="{icon: true, [opt.icon]: true, [`icon-${iconSize}`]: !!iconSize }"
103
+ :alt="actionDescription(opt)"
97
104
  />
98
105
  <t
99
106
  v-if="opt.labelKey"
@@ -22,10 +22,14 @@ const buttonClass = computed(() => {
22
22
  <button
23
23
  type="button"
24
24
  class="btn btn-sm role-multi-action actions"
25
+ role="button"
25
26
  :class="buttonClass"
26
27
  @click="(e: Event) => $emit('click', e)"
27
28
  >
28
- <i class="icon icon-actions" />
29
+ <i
30
+ class="icon icon-actions"
31
+ :alt="t('sortableTable.tableActionsImgAlt')"
32
+ />
29
33
  </button>
30
34
  </template>
31
35
 
@@ -55,9 +55,11 @@ export default {
55
55
  @click="clicked"
56
56
  @keyup.space="clicked"
57
57
  >
58
- {{ text }} <i
58
+ {{ text }}
59
+ <i
59
60
  class="icon"
60
61
  :class="{ 'icon-copy': !copied, 'icon-checkmark': copied}"
62
+ :alt="!copied ? t('generic.copyToClipboard') : t('generic.copiedToClipboard')"
61
63
  />
62
64
  </a>
63
65
  </template>
@@ -368,6 +368,12 @@ export default {
368
368
  return project?.description;
369
369
  },
370
370
 
371
+ projectResource(group) {
372
+ const row = group.rows[0];
373
+
374
+ return row.nameDisplay || row.id || '';
375
+ },
376
+
371
377
  clearSelection() {
372
378
  this.$refs.table.clearSelection();
373
379
  },
@@ -462,6 +468,7 @@ export default {
462
468
  <ButtonMultiAction
463
469
  class="project-action mr-10"
464
470
  :borderless="true"
471
+ :aria-label="t('projectNamespaces.tableActionsLabel', { resource: projectResource(group.group) })"
465
472
  :invisible="!showProjectActionButton(group.group)"
466
473
  @click="showProjectAction($event, group.group)"
467
474
  />
@@ -190,20 +190,6 @@ export default {
190
190
  },
191
191
  },
192
192
 
193
- mounted() {
194
- /**
195
- * v-shortkey prevents the event's propagation:
196
- * https://github.com/fgr-araujo/vue-shortkey/blob/55d802ea305cadcc2ea970b55a3b8b86c7b44c05/src/index.js#L156-L157
197
- *
198
- * 'Enter' key press is handled via event listener in order to allow the event propagation
199
- */
200
- window.addEventListener('keyup', this.handleEnterKeyPress);
201
- },
202
-
203
- beforeUnmount() {
204
- window.removeEventListener('keyup', this.handleEnterKeyPress);
205
- },
206
-
207
193
  data() {
208
194
  // Confirm which store we're in, if schema isn't available we're probably showing a list with different types
209
195
  const inStore = this.schema?.id ? this.$store.getters['currentStore'](this.schema.id) : undefined;
@@ -602,6 +588,7 @@ export default {
602
588
  :mandatory-sort="_mandatorySort"
603
589
  @clickedActionButton="handleActionButtonClick"
604
590
  @group-value-change="group = $event"
591
+ @enter="handleEnterKeyPress"
605
592
  >
606
593
  <template
607
594
  v-if="showGrouping"
@@ -148,10 +148,12 @@ export default {
148
148
  <i
149
149
  v-if="r.iconClass"
150
150
  :class="r.iconClass"
151
+ :alt="t('catalog.charts.iconAlt', { app: get(r, nameField) })"
151
152
  />
152
153
  <LazyImage
153
154
  v-else
154
155
  :src="get(r, iconField)"
156
+ :alt="t('catalog.charts.iconAlt', { app: get(r, nameField) })"
155
157
  />
156
158
  </div>
157
159
  <h4 class="name">
@@ -1,6 +1,6 @@
1
1
  <script>
2
2
  import { mapGetters } from 'vuex';
3
- import { defineAsyncComponent } from 'vue';
3
+ import { defineAsyncComponent, useTemplateRef, onMounted, onBeforeUnmount } from 'vue';
4
4
  import day from 'dayjs';
5
5
  import isEmpty from 'lodash/isEmpty';
6
6
  import { dasherize, ucFirst } from '@shell/utils/string';
@@ -42,7 +42,14 @@ import ButtonMultiAction from '@shell/components/ButtonMultiAction.vue';
42
42
  export default {
43
43
  name: 'SortableTable',
44
44
 
45
- emits: ['clickedActionButton', 'pagination-changed', 'group-value-change', 'selection', 'rowClick'],
45
+ emits: [
46
+ 'clickedActionButton',
47
+ 'pagination-changed',
48
+ 'group-value-change',
49
+ 'selection',
50
+ 'rowClick',
51
+ 'enter',
52
+ ],
46
53
 
47
54
  components: {
48
55
  THead,
@@ -518,6 +525,23 @@ export default {
518
525
  immediate: true
519
526
  },
520
527
  },
528
+ setup(_props, { emit }) {
529
+ const table = useTemplateRef('table');
530
+
531
+ const handleEnterKey = (event) => {
532
+ if (event.key === 'Enter' && !event.target?.classList?.contains('checkbox-custom')) {
533
+ emit('enter', event);
534
+ }
535
+ };
536
+
537
+ onMounted(() => {
538
+ table.value.addEventListener('keyup', handleEnterKey);
539
+ });
540
+
541
+ onBeforeUnmount(() => {
542
+ table.value.removeEventListener('keyup', handleEnterKey);
543
+ });
544
+ },
521
545
 
522
546
  created() {
523
547
  this.debouncedRefreshTableData = debounce(this.refreshTableData, 500);
@@ -1056,6 +1080,7 @@ export default {
1056
1080
  :disabled="!act.enabled"
1057
1081
  :data-testid="componentTestid + '-' + act.action"
1058
1082
  @click="applyTableAction(act, null, $event)"
1083
+ @keydown.enter.stop
1059
1084
  @mouseover="setBulkActionOfInterest(act)"
1060
1085
  @mouseleave="setBulkActionOfInterest(null)"
1061
1086
  >
@@ -1221,6 +1246,7 @@ export default {
1221
1246
  </div>
1222
1247
  </div>
1223
1248
  <table
1249
+ ref="table"
1224
1250
  class="sortable-table"
1225
1251
  :class="classObject"
1226
1252
  width="100%"
@@ -1299,6 +1325,7 @@ export default {
1299
1325
  v-for="(groupedRows) in displayRows"
1300
1326
  v-else
1301
1327
  :key="groupedRows.key"
1328
+ tabindex="-1"
1302
1329
  :class="{ group: groupBy }"
1303
1330
  >
1304
1331
  <slot
@@ -1350,7 +1377,8 @@ export default {
1350
1377
  class="row-check"
1351
1378
  align="middle"
1352
1379
  >
1353
- {{ row.mainRowKey }}<Checkbox
1380
+ {{ row.mainRowKey }}
1381
+ <Checkbox
1354
1382
  class="selection-checkbox"
1355
1383
  :data-node-id="row.key"
1356
1384
  :data-testid="componentTestid + '-' + i + '-checkbox'"
@@ -1451,6 +1479,7 @@ export default {
1451
1479
  :ref="`actionButton${i}`"
1452
1480
  aria-haspopup="true"
1453
1481
  aria-expanded="false"
1482
+ :aria-label="t('sortableTable.tableActionsLabel', { resource: row?.row?.id || '' })"
1454
1483
  :data-testid="componentTestid + '-' + i + '-action-button'"
1455
1484
  :borderless="true"
1456
1485
  @click="handleActionButtonClick(i, $event)"
@@ -291,7 +291,8 @@ export default {
291
291
  ]"
292
292
  :tabindex="isView || disabled ? -1 : 0"
293
293
  @click="focusSearch"
294
- @keydown.enter.space.down="focusSearch"
294
+ @keydown.enter.down="focusSearch"
295
+ @keydown.space.prevent="focusSearch"
295
296
  >
296
297
  <div
297
298
  :class="{ 'labeled-container': true, raised, empty, [mode]: true }"
@@ -256,7 +256,8 @@ export default {
256
256
  }"
257
257
  :tabindex="disabled || isView ? -1 : 0"
258
258
  @click="focusSearch"
259
- @keydown.enter.space.down="focusSearch"
259
+ @keydown.enter.down="focusSearch"
260
+ @keydown.space.prevent="focusSearch"
260
261
  >
261
262
  <v-select
262
263
  ref="select-input"
@@ -625,9 +625,19 @@ export default {
625
625
  placement="top"
626
626
  popperClass="containerLogsDropdown"
627
627
  >
628
- <button class="btn bg-primary btn-cog">
629
- <i class="icon icon-gear" />
630
- <i class="icon icon-chevron-up" />
628
+ <button
629
+ class="btn bg-primary btn-cog"
630
+ role="button"
631
+ :aria-label="t('wm.containerLogs.options')"
632
+ >
633
+ <i
634
+ class="icon icon-gear"
635
+ :alt="t('wm.containerLogs.options')"
636
+ />
637
+ <i
638
+ class="icon icon-chevron-up"
639
+ :alt="t('wm.containerLogs.expand')"
640
+ />
631
641
  </button>
632
642
 
633
643
  <template #popper>
@@ -320,7 +320,10 @@ export default {
320
320
  @mousedown.prevent.stop="dragXStart($event)"
321
321
  @touchstart.prevent.stop="dragXStart($event)"
322
322
  >
323
- <i class="icon icon-code" />
323
+ <i
324
+ class="icon icon-code"
325
+ :alt="t('wm.containerShell.resizeShellWindow')"
326
+ />
324
327
  </div>
325
328
  <div
326
329
  v-for="(tab, i) in tabs"
@@ -333,11 +336,13 @@ export default {
333
336
  v-if="tab.icon"
334
337
  class="icon"
335
338
  :class="{['icon-'+ tab.icon]: true}"
339
+ :alt="t('wm.containerShell.tabIcon')"
336
340
  />
337
341
  <span class="tab-label"> {{ tab.label }}</span>
338
342
  <i
339
343
  data-testid="wm-tab-close-button"
340
344
  class="closer icon icon-fw icon-x wm-closer-button"
345
+ :alt="t('wm.containerShell.closeShellTab', { tab: tab.label })"
341
346
  @click.stop="close(tab.id)"
342
347
  />
343
348
  </div>
@@ -348,7 +353,10 @@ export default {
348
353
  @touchstart.prevent.stop="dragYStart($event)"
349
354
  @click="toggle"
350
355
  >
351
- <i class="icon icon-sort" />
356
+ <i
357
+ class="icon icon-sort"
358
+ :alt="t('wm.containerShell.resizeShellWindow')"
359
+ />
352
360
  </div>
353
361
  <div
354
362
  v-if="userPin == 'left'"
@@ -356,7 +364,10 @@ export default {
356
364
  @mousedown.prevent.stop="dragXStart($event)"
357
365
  @touchstart.prevent.stop="dragXStart($event)"
358
366
  >
359
- <i class="icon icon-code" />
367
+ <i
368
+ class="icon icon-code"
369
+ :alt="t('wm.containerShell.resizeShellWindow')"
370
+ />
360
371
  </div>
361
372
  </div>
362
373
  <div
@@ -13,7 +13,7 @@ const DEFAULT_LINKS = [
13
13
  },
14
14
  {
15
15
  key: 'forums',
16
- value: 'https://forums.rancher.com/',
16
+ value: 'https://forums.suse.com/',
17
17
  enabled: true,
18
18
  },
19
19
  {
@@ -173,7 +173,16 @@ export default {
173
173
  },
174
174
 
175
175
  data() {
176
- const subType = this.$route.query[SUB_TYPE] || null;
176
+ let subType = null;
177
+
178
+ subType = this.$route.query[SUB_TYPE] || null;
179
+ if ( this.$route.query[SUB_TYPE]) {
180
+ subType = this.$route.query[SUB_TYPE];
181
+ } else if (this.value.isImported) {
182
+ subType = IMPORTED;
183
+ } else if (this.value.isLocal) {
184
+ subType = LOCAL;
185
+ }
177
186
  const rkeType = this.$route.query[RKE_TYPE] || null;
178
187
  const chart = this.$route.query[CHART] || null;
179
188
  const isImport = this.realMode === _IMPORT;
@@ -213,14 +222,6 @@ export default {
213
222
 
214
223
  emberLink() {
215
224
  if (this.value) {
216
- // for imported and local clusters, set subtype using properties from prov cluster model
217
- //
218
- if (this.value.isImported) {
219
- this.selectType(IMPORTED, false);
220
- } else if (this.value.isLocal) {
221
- this.selectType(LOCAL, false);
222
- }
223
-
224
225
  // set subtype if editing EKS/GKE/AKS cluster -- this ensures that the component provided by extension is loaded instead of iframing old ember ui
225
226
  if (this.value.provisioner) {
226
227
  const matchingSubtype = this.subTypes.find((st) => DRIVER_TO_IMPORT[st.id.toLowerCase()] === this.value.provisioner.toLowerCase());
@@ -239,6 +240,7 @@ export default {
239
240
 
240
241
  return '';
241
242
  }
243
+
242
244
  // For custom RKE2 clusters, don't load an Ember page.
243
245
  // It should be the dashboard.
244
246
  if ( this.value.isRke2 && ((this.value.isCustom && this.mode === _EDIT) || (this.value.isCustom && this.as === _CONFIG && this.mode === _VIEW) || (this.subType || '').toLowerCase() === 'custom')) {
@@ -134,10 +134,13 @@ export default {
134
134
  type="button"
135
135
  class="btn btn-sm role-multi-action actions"
136
136
  role="button"
137
- :aria-label="t('advancedSettings.edit.label')"
137
+ :aria-label="t('advancedSettings.edit.moreActions', { setting: setting.id })"
138
138
  @click="toggleActionMenu($event, setting)"
139
139
  >
140
- <i class="icon icon-actions" />
140
+ <i
141
+ class="icon icon-actions"
142
+ :alt="t('advancedSettings.edit.moreActions', { setting: setting.id })"
143
+ />
141
144
  </button>
142
145
  </div>
143
146
  </div>
@@ -166,7 +166,7 @@ export default {
166
166
  this.model.accessMode = 'unrestricted';
167
167
  }
168
168
  if (this.model.openLdapConfig && !this.showLdap) {
169
- delete this.model.openLdapConfig;
169
+ this.model.openLdapConfig = null;
170
170
  }
171
171
  await this.model.save();
172
172
  await this.$store.dispatch('auth/test', { provider: this.model.id, body: this.model });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rancher/shell",
3
- "version": "3.0.2-rc.4",
3
+ "version": "3.0.2-rc.5",
4
4
  "description": "Rancher Dashboard Shell",
5
5
  "repository": "https://github.com/rancherlabs/dashboard",
6
6
  "license": "Apache-2.0",
@@ -169,6 +169,7 @@ export default {
169
169
  <LazyImage
170
170
  :src="chart.icon"
171
171
  class="logo"
172
+ :alt="t('catalog.charts.iconAlt', { app: chart.chartNameDisplay })"
172
173
  />
173
174
  </div>
174
175
  <h1>
@@ -309,9 +309,11 @@ export default {
309
309
  v-if="opt.chart.iconName"
310
310
  class="icon"
311
311
  :class="opt.chart.iconName"
312
+ :alt="t('catalog.tools.iconAlt', { app: opt.chart.chartNameDisplay })"
312
313
  />
313
314
  <LazyImage
314
315
  v-else
316
+ :alt="t('catalog.tools.iconAlt', { app: opt.chart.chartNameDisplay })"
315
317
  :src="opt.chart.icon"
316
318
  />
317
319
  </div>
@@ -347,6 +349,8 @@ export default {
347
349
  <template v-if="opt.blocked">
348
350
  <button
349
351
  v-clean-html="t('catalog.tools.action.install')"
352
+ role="button"
353
+ :aria-label="t('catalog.tools.action.install')"
350
354
  disabled="true"
351
355
  class="btn btn-sm role-primary"
352
356
  />
@@ -354,12 +358,19 @@ export default {
354
358
  <template v-else-if="opt.app">
355
359
  <button
356
360
  class="btn btn-sm role-secondary"
361
+ role="button"
362
+ :aria-label="t('catalog.tools.action.remove')"
357
363
  @click="remove(opt.app, $event)"
358
364
  >
359
- <i class="icon icon-delete icon-lg" />
365
+ <i
366
+ class="icon icon-delete icon-lg"
367
+ :alt="t('catalog.tools.action.remove')"
368
+ />
360
369
  </button>
361
370
  <button
362
371
  v-clean-html="t('catalog.tools.action.edit')"
372
+ role="button"
373
+ :aria-label="t('catalog.tools.action.edit')"
363
374
  class="btn btn-sm role-secondary"
364
375
  @click="edit(opt.app)"
365
376
  />
@@ -367,6 +378,8 @@ export default {
367
378
  <template v-else>
368
379
  <button
369
380
  v-clean-html="t('catalog.tools.action.install')"
381
+ role="button"
382
+ :aria-label="t('catalog.tools.action.install')"
370
383
  class="btn btn-sm role-primary"
371
384
  @click="install(opt.chart)"
372
385
  />
@@ -843,11 +843,13 @@ export default {
843
843
  :error-src="defaultIcon"
844
844
  :src="plugin.icon"
845
845
  class="icon plugin-icon-img"
846
+ :alt="t('plugins.altIcon', { extension: plugin.name })"
846
847
  />
847
848
  <img
848
849
  v-else
849
850
  :src="defaultIcon"
850
851
  class="icon plugin-icon-img"
852
+ :alt="t('plugins.altIcon', { extension: plugin.name })"
851
853
  >
852
854
  </div>
853
855
  <!-- extension card -->
@@ -71,17 +71,6 @@ const handleActivate = (e: KeyboardEvent) => {
71
71
  e?.target?.click();
72
72
  }
73
73
  };
74
-
75
- /**
76
- * Handles keydown events to focus the dropdown item.
77
- * @param e - The Mouse event.
78
- */
79
- const handleMouseEnter = (e: MouseEvent) => {
80
- if (e?.target instanceof HTMLElement) {
81
- e?.target?.focus();
82
- }
83
- };
84
-
85
74
  </script>
86
75
 
87
76
  <template>
@@ -95,7 +84,6 @@ const handleMouseEnter = (e: MouseEvent) => {
95
84
  @click.stop="handleClick"
96
85
  @keydown.enter.space="handleActivate"
97
86
  @keydown.up.down.stop="handleKeydown"
98
- @mouseenter="handleMouseEnter"
99
87
  >
100
88
  <slot name="default">
101
89
  <!--Empty slot content-->