dashboard-shell-shell 1.0.1000000116 → 1.0.1000000117

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 (124) hide show
  1. package/assets/images/action.svg +6 -0
  2. package/assets/images/pl/logo.png +0 -0
  3. package/assets/styles/base/_functions.scss +0 -0
  4. package/assets/styles/base/_mixins.scss +1 -1
  5. package/assets/styles/global/_button.scss +17 -10
  6. package/assets/styles/global/_form.scss +2 -2
  7. package/assets/styles/global/_labeled-input.scss +6 -2
  8. package/assets/styles/global/_select.scss +6 -7
  9. package/assets/styles/global/_table.scss +3 -2
  10. package/assets/styles/global/_tooltip.scss +8 -1
  11. package/assets/styles/themes/_dark.scss +2 -0
  12. package/assets/styles/themes/_light.scss +5 -2
  13. package/assets/styles/vendor/vue-select.scss +2 -1
  14. package/assets/translations/en-us.yaml +1 -3
  15. package/assets/translations/zh-hans.yaml +51 -28
  16. package/components/ActionDropdown.vue +1 -0
  17. package/components/ActionMenuShell.vue +6 -3
  18. package/components/BrandImage.vue +22 -0
  19. package/components/ClusterIconMenu.vue +1 -1
  20. package/components/CodeMirror.vue +1 -0
  21. package/components/CruResource.vue +1 -1
  22. package/components/CruResourceFooter.vue +1 -1
  23. package/components/ExplorerProjectsNamespaces.vue +4 -24
  24. package/components/GlobalRoleBindings.vue +112 -48
  25. package/components/IndentedPanel.vue +4 -10
  26. package/components/PromptRemove.vue +3 -3
  27. package/components/ResourceDetail/Masthead.vue +190 -242
  28. package/components/ResourceDetail/index.vue +20 -5
  29. package/components/ResourceList/Masthead.vue +146 -84
  30. package/components/ResourceList/ResourceLoadingIndicator.vue +5 -2
  31. package/components/ResourceTable.vue +76 -1
  32. package/components/SideNav.vue +66 -29
  33. package/components/SortableTable/THead.vue +6 -0
  34. package/components/SortableTable/index.vue +481 -388
  35. package/components/Tabbed/index.vue +4 -5
  36. package/components/auth/Principal.vue +3 -2
  37. package/components/auth/RoleDetailEdit.vue +58 -5
  38. package/components/auth/SelectPrincipal.vue +1 -0
  39. package/components/form/BannerSettings.vue +18 -16
  40. package/components/form/ChangePassword.vue +4 -4
  41. package/components/form/ColorInput.vue +32 -8
  42. package/components/form/Footer.vue +1 -1
  43. package/components/form/InputWithSelect.vue +2 -0
  44. package/components/form/KeyValue.vue +31 -7
  45. package/components/form/LabeledSelect.vue +178 -178
  46. package/components/form/Members/ClusterPermissionsEditor.vue +1 -2
  47. package/components/form/Members/MembershipEditor.vue +1 -1
  48. package/components/form/NameNsDescription.vue +24 -11
  49. package/components/form/Password.vue +6 -2
  50. package/components/form/ResourceQuota/Namespace.vue +1 -1
  51. package/components/form/ResourceQuota/NamespaceRow.vue +13 -10
  52. package/components/form/ResourceQuota/ProjectRow.vue +0 -1
  53. package/components/form/Select.vue +2 -2
  54. package/components/nav/Favorite.vue +5 -1
  55. package/components/nav/Group.vue +69 -23
  56. package/components/nav/Header.vue +82 -17
  57. package/components/nav/HeaderPageActionMenu.vue +1 -0
  58. package/components/nav/NamespaceFilter.vue +0 -3
  59. package/components/nav/TopLevelMenu.vue +182 -119
  60. package/components/nav/Type.vue +48 -11
  61. package/composables/useClickOutside.ts +1 -1
  62. package/config/product/auth.js +16 -7
  63. package/config/product/explorer.js +1 -1
  64. package/config/product/settings.js +17 -8
  65. package/config/settings.ts +28 -0
  66. package/edit/management.cattle.io.user.vue +17 -4
  67. package/edit/networking.k8s.io.ingress/RulePath.vue +1 -1
  68. package/edit/token.vue +1 -1
  69. package/list/harvesterhci.io.management.cluster.vue +17 -0
  70. package/list/management.cattle.io.setting.vue +22 -13
  71. package/list/management.cattle.io.user.vue +25 -14
  72. package/list/provisioning.cattle.io.cluster.vue +6 -7
  73. package/mixins/brand.js +17 -0
  74. package/package.json +1 -1
  75. package/pages/auth/login.vue +84 -29
  76. package/pages/c/_cluster/auth/roles/index.vue +61 -14
  77. package/pages/c/_cluster/settings/banners.vue +174 -101
  78. package/pages/c/_cluster/settings/brand.vue +348 -301
  79. package/pages/c/_cluster/settings/performance.vue +61 -38
  80. package/pages/home.vue +70 -21
  81. package/pages/prefs.vue +25 -23
  82. package/pkg/tsconfig.json +9 -9
  83. package/pkg/vue.config.js +1 -1
  84. package/promptRemove/mixin/roleDeletionCheck.js +2 -2
  85. package/scripts/clean +0 -0
  86. package/scripts/extension/bundle +0 -0
  87. package/scripts/extension/helm/scripts/package +0 -0
  88. package/scripts/extension/helm/scripts/patch +0 -0
  89. package/scripts/extension/helm/scripts/version +0 -0
  90. package/scripts/extension/helmpatch +0 -0
  91. package/scripts/extension/parse-tag-name +0 -0
  92. package/scripts/extension/publish +0 -0
  93. package/scripts/publish-shell.sh +86 -60
  94. package/scripts/serve-pkgs +0 -0
  95. package/scripts/sync-shell-deps +0 -0
  96. package/scripts/typegen.sh +44 -28
  97. package/store/i18n.js +5 -5
  98. package/store/prefs.js +17 -5
  99. package/store/type-map.js +2 -1
  100. package/types/shell/index.d.ts +1 -1
  101. package/utils/error.js +4 -0
  102. package/utils/router.js +3 -3
  103. package/vue.config.js +1 -6
  104. package/components/rancherResourceDetail/Masthead.vue +0 -769
  105. package/components/rancherResourceDetail/__tests__/Masthead.test.ts +0 -65
  106. package/components/rancherResourceDetail/index.vue +0 -591
  107. package/components/rancherResourceList/Masthead.vue +0 -375
  108. package/components/rancherResourceList/ResourceLoadingIndicator.vue +0 -140
  109. package/components/rancherResourceList/index.vue +0 -307
  110. package/components/rancherResourceList/resource-list.config.js +0 -7
  111. package/components/rancherResourceTable.vue +0 -783
  112. package/components/rancherSortableTable/THead.vue +0 -561
  113. package/components/rancherSortableTable/actions.js +0 -153
  114. package/components/rancherSortableTable/advanced-filtering.js +0 -272
  115. package/components/rancherSortableTable/debug.js +0 -117
  116. package/components/rancherSortableTable/filtering.js +0 -290
  117. package/components/rancherSortableTable/grouping.js +0 -48
  118. package/components/rancherSortableTable/index.vue +0 -2712
  119. package/components/rancherSortableTable/paging.js +0 -155
  120. package/components/rancherSortableTable/selection.js +0 -629
  121. package/components/rancherSortableTable/sortable-config.ts +0 -4
  122. package/components/rancherSortableTable/sorting.js +0 -129
  123. package/types/cloud-shell/index.d.ts +0 -11014
  124. /package/components/{rancherResourceList → ResourceList}/Masthead-btn.vue +0 -0
@@ -1,561 +0,0 @@
1
- <script>
2
- import { Checkbox } from '@components/Form/Checkbox';
3
- import { SOME, NONE } from './selection';
4
- import { AUTO, CENTER, fitOnScreen } from '@shell/utils/position';
5
- import LabeledSelect from '@shell/components/form/LabeledSelect';
6
-
7
- export default {
8
- emits: ['update-cols-options', 'on-toggle-all', 'group-value-change', 'on-sort-change', 'col-visibility-change'],
9
-
10
- components: { Checkbox, LabeledSelect },
11
- props: {
12
- columns: {
13
- type: Array,
14
- required: true
15
- },
16
- sortBy: {
17
- type: String,
18
- required: true
19
- },
20
- defaultSortBy: {
21
- type: String,
22
- default: ''
23
- },
24
- group: {
25
- type: String,
26
- default: ''
27
- },
28
- groupOptions: {
29
- type: Array,
30
- default: () => []
31
- },
32
- descending: {
33
- type: Boolean,
34
- required: true
35
- },
36
- hasAdvancedFiltering: {
37
- type: Boolean,
38
- required: false
39
- },
40
- tableColsOptions: {
41
- type: Array,
42
- default: () => [],
43
- },
44
- tableActions: {
45
- type: Boolean,
46
- required: true,
47
- },
48
- rowActions: {
49
- type: Boolean,
50
- required: true,
51
- },
52
- howMuchSelected: {
53
- type: String,
54
- required: true,
55
- },
56
- checkWidth: {
57
- type: Number,
58
- default: 30,
59
- },
60
- rowActionsWidth: {
61
- type: Number,
62
- required: true
63
- },
64
- subExpandColumn: {
65
- type: Boolean,
66
- default: false,
67
- },
68
- expandWidth: {
69
- type: Number,
70
- default: 30,
71
- },
72
- labelFor: {
73
- type: Function,
74
- required: true,
75
- },
76
- noRows: {
77
- type: Boolean,
78
- default: true,
79
- },
80
- noResults: {
81
- type: Boolean,
82
- default: true,
83
- },
84
- loading: {
85
- type: Boolean,
86
- required: false,
87
- },
88
- },
89
-
90
- data() {
91
- return {
92
- tableColsOptionsVisibility: false,
93
- tableColsMenuPosition: null
94
- };
95
- },
96
-
97
- watch: {
98
- advancedFilteringValues() {
99
- // passing different dummy args to make sure update is triggered
100
- this.watcherUpdateLiveAndDelayed(true, false);
101
- },
102
- tableColsOptionsVisibility(neu) {
103
- if (neu) {
104
- // check if user clicked outside the table cols options box
105
- window.addEventListener('click', this.onClickOutside);
106
-
107
- // update filtering options and toggable cols every time dropdown is open
108
- this.$emit('update-cols-options');
109
- } else {
110
- // unregister click event
111
- window.removeEventListener('click', this.onClickOutside);
112
- }
113
- }
114
- },
115
- computed: {
116
- isAll: {
117
- get() {
118
- return this.howMuchSelected !== NONE;
119
- },
120
-
121
- set(value) {
122
- this.$emit('on-toggle-all', value);
123
- }
124
- },
125
- hasAdvGrouping() {
126
- return this.group?.length && this.groupOptions?.length;
127
- },
128
- advGroup: {
129
- get() {
130
- return this.group || this.advGroup;
131
- },
132
-
133
- set(val) {
134
- this.$emit('group-value-change', val);
135
- }
136
- },
137
-
138
- isIndeterminate() {
139
- return this.howMuchSelected === SOME;
140
- },
141
- hasColumnWithSubLabel() {
142
- return this.columns.some((col) => col.subLabel);
143
- }
144
- },
145
-
146
- methods: {
147
- changeSort(e, col) {
148
- if ( !col.sort ) {
149
- return;
150
- }
151
-
152
- let desc = false;
153
-
154
- if ( this.sortBy === col.name ) {
155
- desc = !this.descending;
156
- }
157
-
158
- this.$emit('on-sort-change', col.name, desc);
159
- },
160
-
161
- isCurrent(col) {
162
- return col.name === this.sortBy;
163
- },
164
-
165
- ariaSort(col) {
166
- if (this.isCurrent(col)) {
167
- return this.descending ? this.t('generic.descending') : this.t('generic.ascending');
168
- }
169
-
170
- return this.t('generic.none');
171
- },
172
-
173
- tableColsOptionsClick(ev) {
174
- // set menu position
175
- const menu = document.querySelector('.table-options-container');
176
- const elem = document.querySelector('.table-options-btn');
177
-
178
- this.tableColsMenuPosition = fitOnScreen(menu, ev || elem, {
179
- overlapX: true,
180
- fudgeX: 326,
181
- fudgeY: -22,
182
- positionX: CENTER,
183
- positionY: AUTO,
184
- });
185
-
186
- // toggle visibility
187
- this.tableColsOptionsVisibility = !this.tableColsOptionsVisibility;
188
- },
189
-
190
- onClickOutside(event) {
191
- const tableOpts = this.$refs['table-options'];
192
-
193
- if (!tableOpts || tableOpts.contains(event.target)) {
194
- return;
195
- }
196
- this.tableColsOptionsVisibility = false;
197
- },
198
-
199
- tableOptionsCheckbox(value, label) {
200
- this.$emit('col-visibility-change', {
201
- label,
202
- value
203
- });
204
- },
205
-
206
- tooltip(col) {
207
- if (!col.tooltip) {
208
- return null;
209
- }
210
-
211
- const exists = this.$store.getters['i18n/exists'];
212
-
213
- return exists(col.tooltip) ? this.t(col.tooltip) : col.tooltip;
214
- },
215
- }
216
-
217
- };
218
- </script>
219
-
220
- <template>
221
- <thead>
222
- <tr :class="{'loading': loading, 'top-aligned': hasColumnWithSubLabel}">
223
- <th
224
- v-if="tableActions"
225
- :width="checkWidth"
226
- >
227
- <Checkbox
228
- v-model:value="isAll"
229
- class="check"
230
- data-testid="sortable-table_check_select_all"
231
- :indeterminate="isIndeterminate"
232
- :disabled="noRows || noResults"
233
- :alternate-label="t('sortableTable.genericGroupCheckbox')"
234
- />
235
- </th>
236
- <th
237
- v-if="subExpandColumn"
238
- :width="expandWidth"
239
- />
240
- <!-- <th
241
- v-for="(col) in columns"
242
- v-show="!hasAdvancedFiltering || (hasAdvancedFiltering && col.isColVisible)"
243
- :key="col.name"
244
- :align="col.align || 'left'"
245
- :width="col.width"
246
- :class="{ sortable: col.sort, [col.breakpoint]: !!col.breakpoint}"
247
- :tabindex="col.sort ? 0 : -1"
248
- class="sortable-table-head-element"
249
- :aria-sort="ariaSort(col)"
250
- @click.prevent="changeSort($event, col)"
251
- @keyup.enter="changeSort($event, col)"
252
- @keyup.space="changeSort($event, col)"
253
- > -->
254
- <th
255
- v-for="(col) in columns"
256
- v-show="!hasAdvancedFiltering || (hasAdvancedFiltering && col.isColVisible)"
257
- :key="col.name"
258
- :align="'left'"
259
- :width="col.width"
260
- :class="{ sortable: col.sort, [col.breakpoint]: !!col.breakpoint}"
261
- :tabindex="col.sort ? 0 : -1"
262
- class="sortable-table-head-element"
263
- :aria-sort="ariaSort(col)"
264
- @click.prevent="changeSort($event, col)"
265
- @keyup.enter="changeSort($event, col)"
266
- @keyup.space="changeSort($event, col)"
267
- >
268
- <div
269
- class="table-header-container"
270
- :class="{ 'not-filterable': hasAdvancedFiltering && !col.isFilter }"
271
- >
272
- <div
273
- v-clean-tooltip="tooltip(col)"
274
- class="content"
275
- >
276
- <span
277
- v-if="(col.name === 'harvester' || col.name === 'explorer') && col.label === ' '"
278
- >
279
- 管理
280
- </span>
281
- <span
282
- v-if="!((col.name === 'harvester' || col.name === 'explorer') && col.label === ' ')"
283
- v-clean-html="labelFor(col)"
284
- class="text-no-break"
285
- />
286
- <span
287
- v-if="col.subLabel"
288
- class="text-muted text-no-break"
289
- >
290
- {{ col.subLabel }}
291
- </span>
292
- </div>
293
- <div
294
- v-if="col.sort"
295
- class="sort"
296
- aria-hidden="true"
297
- >
298
- <i
299
- v-show="hasAdvancedFiltering && !col.isFilter"
300
- v-clean-tooltip="t('sortableTable.tableHeader.noFilter')"
301
- class="icon icon-info not-filter-icon"
302
- />
303
- <span class="icon-stack">
304
- <i class="icon icon-sort icon-stack-1x faded" />
305
- <i
306
- v-if="isCurrent(col) && !descending"
307
- class="icon icon-sort-down icon-stack-1x"
308
- :alt="t('sortableTable.alt.sortingIconDesc')"
309
- />
310
- <i
311
- v-if="isCurrent(col) && descending"
312
- class="icon icon-sort-up icon-stack-1x"
313
- :alt="t('sortableTable.alt.sortingIconAsc')"
314
- />
315
- </span>
316
- </div>
317
- </div>
318
- </th>
319
- <th
320
- v-if="rowActions && hasAdvancedFiltering && tableColsOptions.length"
321
- :width="rowActionsWidth"
322
- :align="'left'"
323
- >
324
- <div
325
- ref="table-options"
326
- class="table-options-group"
327
- >
328
- <button
329
- aria-haspopup="true"
330
- aria-expanded="false"
331
- type="button"
332
- class="btn btn-sm role-multi-action table-options-btn"
333
- @click="tableColsOptionsClick"
334
- >
335
- <i class="icon icon-actions" />
336
- </button>
337
- <div
338
- v-show="tableColsOptionsVisibility"
339
- class="table-options-container"
340
- :style="tableColsMenuPosition"
341
- >
342
- <div
343
- v-if="hasAdvGrouping"
344
- class="table-options-grouping"
345
- >
346
- <span class="table-options-col-subtitle">{{ t('sortableTable.tableHeader.groupBy') }}:</span>
347
- <LabeledSelect
348
- v-model:value="advGroup"
349
- class="table-options-grouping-select"
350
- :clearable="true"
351
- :options="groupOptions"
352
- :disabled="false"
353
- :searchable="false"
354
- mode="edit"
355
- :multiple="false"
356
- :taggable="false"
357
- />
358
- </div>
359
- <p class="table-options-col-subtitle mb-20">
360
- {{ t('sortableTable.tableHeader.show') }}:
361
- </p>
362
- <ul>
363
- <li
364
- v-for="(col, index) in tableColsOptions"
365
- v-show="col.isTableOption"
366
- :key="index"
367
- :class="{ 'visible': !col.preventColToggle }"
368
- >
369
- <Checkbox
370
- v-show="!col.preventColToggle"
371
- v-model:value="col.isColVisible"
372
- class="table-options-checkbox"
373
- :label="col.label"
374
- @update:value="tableOptionsCheckbox($event, col.label)"
375
- />
376
- </li>
377
- </ul>
378
- </div>
379
- </div>
380
- </th>
381
- <!-- <th
382
- v-else-if="rowActions"
383
- :width="rowActionsWidth"
384
- /> -->
385
- <th
386
- v-else-if="rowActions"
387
- :width="rowActionsWidth"
388
- :align="'left'"
389
- >
390
- 操作
391
- </th>
392
- </tr>
393
- </thead>
394
- </template>
395
-
396
- <style lang="scss" scoped>
397
- .table-options-group {
398
-
399
- .table-options-btn.role-multi-action {
400
- background-color: transparent;
401
- border: none;
402
- font-size: 18px;
403
- &:hover, &:focus {
404
- background-color: var(--accent-btn);
405
- box-shadow: none;
406
- }
407
- }
408
- .table-options-container {
409
- width: 350px;
410
- border: 1px solid var(--primary);
411
- background-color: var(--body-bg);
412
- padding: 20px;
413
- z-index: 1;
414
-
415
- .table-options-grouping {
416
- display: flex;
417
- align-items: center;
418
- margin-bottom: 20px;
419
-
420
- span {
421
- white-space: nowrap;
422
- margin-right: 10px;
423
- }
424
- }
425
-
426
- ul {
427
- list-style: none;
428
- margin: 0;
429
- padding: 0;
430
- max-height: 200px;
431
- overflow-y: auto;
432
-
433
- li {
434
- margin: 0;
435
- padding: 0;
436
-
437
- &.visible {
438
- margin: 0 0 10px 0;
439
- }
440
- }
441
- }
442
- }
443
- }
444
-
445
- .sortable > SPAN {
446
- cursor: pointer;
447
- user-select: none;
448
- white-space: nowrap;
449
- &:hover,
450
- &:active {
451
- text-decoration: underline;
452
- color: var(--body-text);
453
- }
454
- }
455
-
456
- .top-aligned th {
457
- vertical-align: top;
458
- padding-top: 10px;
459
- }
460
-
461
- thead {
462
- tr {
463
- background-color: var(--sortable-table-header-bg);
464
- color: var(--body-text);
465
- text-align: left;
466
- border-bottom: 1px solid var(--sortable-table-top-divider);
467
- }
468
- }
469
-
470
- th {
471
- padding: 16.5px 5px;
472
- font-weight: normal;
473
- border: 0;
474
- color: var(--body-text);
475
-
476
- &.sortable-table-head-element:focus-visible {
477
- @include focus-outline;
478
- outline-offset: -4px;
479
- }
480
-
481
- .table-header-container {
482
- display: inline-flex;
483
-
484
- .content {
485
- display: flex;
486
- flex-direction: column;
487
- }
488
-
489
- &.not-filterable {
490
- margin-top: -2px;
491
-
492
- .icon-stack {
493
- margin-top: -2px;
494
- }
495
- }
496
-
497
- .not-filter-icon {
498
- font-size: 16px;
499
- color: var(--primary);
500
- vertical-align: super;
501
- }
502
- }
503
-
504
- &:first-child {
505
- padding-left: 10px;
506
- }
507
-
508
- &:last-child {
509
- padding-right: 10px;
510
- padding-left: 12px;
511
- width: 200px;
512
- }
513
-
514
- &:not(.sortable) > SPAN {
515
- display: block;
516
- margin-bottom: 2px;
517
- }
518
-
519
- & A {
520
- color: var(--body-text);
521
- }
522
-
523
- // Aligns with COLUMN_BREAKPOINTS
524
- @media only screen and (max-width: map-get($breakpoints, '--viewport-4')) {
525
- // HIDE column on sizes below 480px
526
- &.tablet, &.laptop, &.desktop {
527
- display: none;
528
- }
529
- }
530
- @media only screen and (max-width: map-get($breakpoints, '--viewport-9')) {
531
- // HIDE column on sizes below 992px
532
- &.laptop, &.desktop {
533
- display: none;
534
- }
535
- }
536
- @media only screen and (max-width: map-get($breakpoints, '--viewport-12')) {
537
- // HIDE column on sizes below 1281px
538
- &.desktop {
539
- display: none;
540
- }
541
- }
542
- }
543
-
544
- .icon-stack {
545
- width: 12px;
546
- }
547
-
548
- .icon-sort {
549
- &.faded {
550
- opacity: .3;
551
- }
552
- }
553
- </style>
554
- <style lang="scss">
555
- .table-options-checkbox .checkbox-custom {
556
- min-width: 14px;
557
- }
558
- .table-options-checkbox .checkbox-label {
559
- color: var(--body-text);
560
- }
561
- </style>
@@ -1,153 +0,0 @@
1
- import debounce from 'lodash/debounce';
2
-
3
- // Use a visible display type to reduce flickering
4
- const displayType = 'inline-flex';
5
-
6
- export default {
7
-
8
- data() {
9
- return {
10
- bulkActionsClass: 'bulk',
11
- bulkActionClass: 'bulk-action',
12
- bulkActionsDropdownClass: 'bulk-actions-dropdown',
13
- bulkActionAvailabilityClass: 'action-availability',
14
-
15
- hiddenActions: [],
16
-
17
- updateHiddenBulkActions: debounce(this.protectedUpdateHiddenBulkActions, 10)
18
- };
19
- },
20
-
21
- beforeUnmount() {
22
- window.removeEventListener('resize', this.onWindowResize);
23
- },
24
-
25
- mounted() {
26
- window.addEventListener('resize', this.onWindowResize);
27
- this.updateHiddenBulkActions();
28
- },
29
-
30
- watch: {
31
- selectedRows() {
32
- this.updateHiddenBulkActions();
33
- },
34
- keyedAvailableActions() {
35
- this.updateHiddenBulkActions();
36
- },
37
- },
38
-
39
- computed: {
40
- availableActions() {
41
- return this.bulkActionsForSelection.filter((act) => !act.external);
42
- },
43
-
44
- keyedAvailableActions() {
45
- return this.availableActions.map((aa) => aa.action);
46
- },
47
-
48
- selectedRowsText() {
49
- if (!this.selectedRows.length) {
50
- return null;
51
- }
52
-
53
- return this.t('sortableTable.actionAvailability.selected', { actionable: this.selectedRows.length });
54
- },
55
-
56
- // Shows a tooltip if the bulk action that the user is hovering over can not be applied to all selected rows
57
- actionTooltip() {
58
- if (!this.selectedRows.length || !this.actionOfInterest) {
59
- return null;
60
- }
61
-
62
- const runnableTotal = this.selectedRows.filter(this.canRunBulkActionOfInterest).length;
63
-
64
- if (runnableTotal === this.selectedRows.length) {
65
- return null;
66
- }
67
-
68
- return this.t('sortableTable.actionAvailability.some', {
69
- actionable: runnableTotal,
70
- total: this.selectedRows.length,
71
- });
72
- },
73
- },
74
-
75
- methods: {
76
- onWindowResize() {
77
- this.updateHiddenBulkActions();
78
- this.onScroll();
79
- },
80
-
81
- /**
82
- * Determine if any actions wrap over to a new line, if so group them into a dropdown instead
83
- */
84
- protectedUpdateHiddenBulkActions() {
85
- if (!this.$refs.container) {
86
- return;
87
- }
88
-
89
- const actionsContainer = this.$refs.container.querySelector(`.${ this.bulkActionsClass }`);
90
- const actionsDropdown = this.$refs.container.querySelector(`.${ this.bulkActionsDropdownClass }`);
91
-
92
- if (!actionsContainer || !actionsDropdown) {
93
- return;
94
- }
95
-
96
- const actionsContainerWidth = actionsContainer.offsetWidth;
97
- const actionsHTMLCollection = this.$refs.container.querySelectorAll(`.${ this.bulkActionClass }`);
98
- const actions = Array.from(actionsHTMLCollection || []);
99
-
100
- // Determine if the 'x selected' label should show and it's size
101
- const selectedRowsText = this.$refs.container.querySelector(`.${ this.bulkActionAvailabilityClass }`);
102
- let selectedRowsTextWidth = 0;
103
-
104
- if (this.selectedRowsText) {
105
- if (selectedRowsText) {
106
- selectedRowsText.style.display = displayType;
107
- selectedRowsTextWidth = selectedRowsText.offsetWidth;
108
- } else {
109
- selectedRowsText.style.display = 'none;';
110
- }
111
- }
112
-
113
- this.hiddenActions = [];
114
-
115
- let cumulativeWidth = 0;
116
- let showActionsDropdown = false;
117
- let totalAvailableWidth = actionsContainerWidth - selectedRowsTextWidth;
118
-
119
- // Loop through all actions to determine if some exceed the available space in the row, if so hide them and instead show in a dropdown
120
- for (let i = 0; i < actions.length; i++) {
121
- const ba = actions[i];
122
-
123
- ba.style.display = displayType;
124
- const actionWidth = ba.offsetWidth;
125
-
126
- cumulativeWidth += actionWidth + 15;
127
- if (cumulativeWidth >= totalAvailableWidth) {
128
- // There are too many actions so the drop down will be visible.
129
- if (!showActionsDropdown) {
130
- // If we haven't previously enabled the drop down...
131
- actionsDropdown.style.display = displayType;
132
- // By showing the drop down some previously visible actions may now be hidden, so start the process again
133
- // ... except taking into account the width of drop down width in the available space
134
- i = -1;
135
- cumulativeWidth = 0;
136
- showActionsDropdown = true;
137
- totalAvailableWidth = actionsContainerWidth - actionsDropdown.offsetWidth - selectedRowsTextWidth;
138
- } else {
139
- // Collate the actions in an array and hide in the normal row
140
- const id = ba.attributes.getNamedItem('id').value;
141
-
142
- this.hiddenActions.push(this.availableActions.find((aa) => aa.action === id));
143
- ba.style.display = 'none';
144
- }
145
- }
146
- }
147
-
148
- if (!showActionsDropdown) {
149
- actionsDropdown.style.display = 'none';
150
- }
151
- }
152
- }
153
- };