@rancher/shell 3.0.8 → 3.0.9-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.
- package/apis/intf/modal.ts +38 -0
- package/apis/intf/slide-in.ts +3 -1
- package/apis/shell/__tests__/slide-in.test.ts +36 -0
- package/apis/shell/slide-in.ts +5 -1
- package/assets/styles/base/_color.scss +1 -0
- package/assets/styles/base/_typography.scss +14 -5
- package/assets/styles/themes/_light.scss +1 -1
- package/assets/styles/themes/_modern.scss +1 -1
- package/assets/translations/en-us.yaml +94 -33
- package/assets/translations/zh-hans.yaml +0 -2
- package/components/ActionMenuShell.vue +4 -4
- package/components/CodeMirror.vue +4 -3
- package/components/DetailText.vue +54 -7
- package/components/Drawer/Chrome.vue +11 -4
- package/components/Drawer/DrawerCard.vue +19 -0
- package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +3 -11
- package/components/Drawer/ResourceDetailDrawer/__tests__/ConfigTab.test.ts +2 -2
- package/components/Drawer/ResourceDetailDrawer/index.vue +3 -20
- package/components/Drawer/types.ts +1 -0
- package/components/DynamicContent/DynamicContentCloseButton.vue +2 -2
- package/components/LocaleSelector.vue +1 -1
- package/components/Markdown.vue +1 -1
- package/components/PopoverCard.vue +3 -3
- package/components/Resource/Detail/Card/ExtrasCard.vue +39 -0
- package/components/Resource/Detail/Card/StateCard/__tests__/composables.test.ts +142 -0
- package/components/Resource/Detail/Card/StateCard/composables.ts +41 -11
- package/components/Resource/Detail/Card/StateCard/index.vue +3 -9
- package/components/Resource/Detail/Card/StateCard/types.ts +6 -0
- package/components/Resource/Detail/Card/{PodsCard → StatusCard}/index.vue +11 -10
- package/components/Resource/Detail/Card/__tests__/PodsCard.test.ts +24 -25
- package/components/Resource/Detail/Cards.vue +27 -0
- package/components/Resource/Detail/Masthead/__tests__/index.test.ts +70 -0
- package/components/Resource/Detail/Masthead/index.vue +5 -0
- package/components/Resource/Detail/Metadata/KeyValueRow.vue +4 -2
- package/components/Resource/Detail/ResourcePopover/ResourcePopoverCard.vue +2 -2
- package/components/Resource/Detail/ResourceRow.types.ts +14 -0
- package/components/Resource/Detail/ResourceRow.vue +23 -35
- package/components/Resource/Detail/StatusRow.vue +5 -2
- package/components/Resource/Detail/TitleBar/__tests__/composables.test.ts +38 -7
- package/components/Resource/Detail/TitleBar/__tests__/index.test.ts +106 -2
- package/components/Resource/Detail/TitleBar/composables.ts +2 -1
- package/components/Resource/Detail/TitleBar/index.vue +41 -6
- package/components/ResourceDetail/Masthead/__tests__/index.test.ts +49 -1
- package/components/ResourceDetail/Masthead/__tests__/latest.test.ts +85 -0
- package/components/ResourceDetail/Masthead/index.vue +1 -0
- package/components/ResourceDetail/Masthead/latest.vue +8 -1
- package/components/ResourceDetail/Masthead/legacy.vue +1 -1
- package/components/Setting.vue +1 -1
- package/components/SortableTable/index.vue +25 -0
- package/components/SortableTable/selection.js +25 -12
- package/components/SortableTable/sorting.js +1 -1
- package/components/Tabbed/Tab.vue +1 -0
- package/components/Tabbed/index.vue +29 -6
- package/components/Window/ContainerShell.vue +10 -13
- package/components/fleet/FleetClusterTargets/TargetsList.vue +47 -29
- package/components/fleet/FleetClusterTargets/index.vue +82 -29
- package/components/fleet/FleetClusters.vue +26 -12
- package/components/fleet/FleetGitRepoPaths.vue +2 -2
- package/components/fleet/FleetResources.vue +14 -0
- package/components/fleet/FleetValuesFrom.vue +2 -2
- package/components/fleet/__tests__/FleetClusterTargets.test.ts +531 -0
- package/components/fleet/__tests__/FleetClusters.test.ts +576 -0
- package/components/fleet/dashboard/ResourceDetails.vue +96 -123
- package/components/form/Conditions.vue +1 -15
- package/components/form/HookOption.vue +5 -0
- package/components/form/LabeledSelect.vue +1 -1
- package/components/form/LifecycleHooks.vue +2 -6
- package/components/form/ResourceLabeledSelect.vue +12 -1
- package/components/form/SeccompProfile.vue +113 -0
- package/components/form/Security.vue +244 -133
- package/components/form/__tests__/LabeledSelect.test.ts +1 -1
- package/components/form/__tests__/SeccompProfile.test.js +124 -0
- package/components/form/__tests__/Security.test.ts +125 -37
- package/components/formatter/Autoscaler.vue +2 -2
- package/components/formatter/FleetSummaryGraph.vue +4 -1
- package/components/nav/Group.vue +5 -0
- package/components/nav/Header.vue +3 -3
- package/components/nav/HeaderPageActionMenu.vue +1 -1
- package/components/nav/NamespaceFilter.vue +6 -6
- package/components/nav/NotificationCenter/index.vue +1 -1
- package/components/nav/TopLevelMenu.helper.ts +41 -16
- package/components/nav/TopLevelMenu.vue +45 -25
- package/components/nav/WorkspaceSwitcher.vue +1 -1
- package/components/nav/__tests__/TopLevelMenu.helper.test.ts +277 -0
- package/components/nav/__tests__/TopLevelMenu.test.ts +160 -4
- package/components/templates/default.vue +0 -3
- package/components/templates/home.vue +0 -3
- package/components/templates/plain.vue +0 -3
- package/composables/useClickOutside.ts +1 -1
- package/config/product/explorer.js +1 -2
- package/config/types.js +41 -8
- package/detail/__tests__/workload.test.ts +8 -16
- package/detail/catalog.cattle.io.app.vue +6 -0
- package/detail/fleet.cattle.io.cluster.vue +6 -0
- package/detail/workload/index.vue +7 -109
- package/edit/__tests__/projectsecret.test.ts +42 -0
- package/edit/auth/__tests__/oidc.test.ts +50 -0
- package/edit/auth/oidc.vue +68 -44
- package/edit/autoscaling.horizontalpodautoscaler/index.vue +140 -59
- package/edit/autoscaling.horizontalpodautoscaler/metrics-row.vue +41 -5
- package/edit/projectsecret.vue +29 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +89 -200
- package/edit/provisioning.cattle.io.cluster/__tests__/Networking.test.ts +58 -17
- package/edit/provisioning.cattle.io.cluster/rke2.vue +11 -0
- package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +3 -63
- package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +82 -14
- package/edit/workload/__tests__/index.test.ts +122 -85
- package/edit/workload/index.vue +48 -29
- package/edit/workload/mixins/workload.js +85 -32
- package/list/catalog.cattle.io.clusterrepo.vue +1 -1
- package/list/projectsecret.vue +2 -2
- package/machine-config/__tests__/vmwarevsphere.test.ts +64 -0
- package/machine-config/amazonec2.vue +2 -2
- package/machine-config/vmwarevsphere.vue +58 -4
- package/mixins/__tests__/brand.spec.ts +18 -13
- package/mixins/__tests__/chart.test.ts +63 -0
- package/mixins/chart.js +56 -51
- package/models/__tests__/catalog.cattle.io.app.test.ts +33 -0
- package/models/__tests__/workload.test.ts +333 -0
- package/models/catalog.cattle.io.app.js +8 -0
- package/models/pod.js +14 -0
- package/models/secret.js +1 -1
- package/models/workload.js +93 -27
- package/package.json +4 -4
- package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +91 -0
- package/pages/c/_cluster/apps/charts/install.vue +4 -4
- package/pages/c/_cluster/explorer/EventsTable.vue +2 -2
- package/pages/c/_cluster/fleet/index.vue +18 -12
- package/pages/c/_cluster/manager/hostedprovider/index.vue +1 -19
- package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +1 -1
- package/pages/c/_cluster/uiplugins/index.vue +1 -1
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +234 -0
- package/plugins/dashboard-store/actions.js +9 -8
- package/plugins/dashboard-store/resource-class.js +97 -1
- package/plugins/steve/__tests__/revision.test.ts +84 -0
- package/plugins/steve/__tests__/steve-pagination-utils.test.ts +30 -0
- package/plugins/steve/__tests__/subscribe.spec.ts +134 -0
- package/plugins/steve/mutations.js +9 -0
- package/plugins/steve/revision.ts +26 -0
- package/plugins/steve/steve-pagination-utils.ts +6 -5
- package/plugins/steve/subscribe.js +211 -51
- package/plugins/subscribe-events.ts +2 -2
- package/rancher-components/Form/Checkbox/Checkbox.vue +13 -0
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +1 -1
- package/rancher-components/Pill/RcCounterBadge/RcCounterBadge.vue +1 -1
- package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +3 -1
- package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +3 -1
- package/rancher-components/Pill/RcTag/RcTag.vue +1 -1
- package/rancher-components/Pill/index.ts +4 -0
- package/rancher-components/RcButton/RcButton.test.ts +53 -9
- package/rancher-components/RcButton/RcButton.vue +217 -25
- package/rancher-components/RcButton/types.ts +27 -1
- package/rancher-components/RcDropdown/RcDropdownMenu.vue +4 -4
- package/rancher-components/RcDropdown/types.ts +3 -3
- package/rancher-components/RcIcon/RcIcon.test.ts +42 -0
- package/rancher-components/RcIcon/RcIcon.vue +9 -6
- package/rancher-components/RcIcon/types.ts +13 -9
- package/rancher-components/utils/status.test.ts +10 -15
- package/rancher-components/utils/status.ts +5 -6
- package/store/aws.js +18 -12
- package/store/index.js +4 -8
- package/store/type-map.utils.ts +1 -1
- package/types/kube/kube-api.ts +29 -3
- package/types/rancher/steve.api.ts +40 -0
- package/types/shell/index.d.ts +99 -0
- package/types/store/dashboard-store.types.ts +29 -7
- package/types/store/pagination.types.ts +1 -0
- package/types/store/subscribe-events.types.ts +1 -0
- package/utils/__tests__/azure.test.ts +56 -0
- package/utils/__tests__/back-off.test.ts +364 -245
- package/utils/__tests__/error.test.ts +44 -0
- package/utils/__tests__/fleet.test.ts +8 -1
- package/utils/__tests__/pagination-wrapper.test.ts +167 -0
- package/utils/__tests__/version.test.ts +55 -1
- package/utils/azure.js +12 -0
- package/utils/back-off.ts +302 -69
- package/utils/cspAdaptor.ts +32 -14
- package/utils/dynamic-content/__tests__/index.test.ts +1 -1
- package/utils/dynamic-content/__tests__/new-release.test.ts +48 -7
- package/utils/dynamic-content/__tests__/support-notice.test.ts +1 -4
- package/utils/dynamic-content/index.ts +1 -6
- package/utils/dynamic-content/new-release.ts +5 -3
- package/utils/dynamic-content/types.d.ts +0 -1
- package/utils/error.js +9 -0
- package/utils/fleet.ts +2 -2
- package/utils/inactivity.ts +2 -3
- package/utils/pagination-wrapper.ts +101 -17
- package/utils/validators/formRules/index.ts +3 -0
- package/utils/version.js +38 -0
- package/components/auth/AzureWarning.vue +0 -77
- /package/components/Resource/Detail/{Card/PodsCard/Bubble.vue → Bubble.vue} +0 -0
- /package/components/Resource/Detail/Card/{PodsCard → StatusCard}/composable.ts +0 -0
package/components/Setting.vue
CHANGED
|
@@ -1590,6 +1590,18 @@ export default {
|
|
|
1590
1590
|
:onRowMouseEnter="onRowMouseEnter"
|
|
1591
1591
|
:onRowMouseLeave="onRowMouseLeave"
|
|
1592
1592
|
>
|
|
1593
|
+
<slot
|
|
1594
|
+
:full-colspan="fullColspan"
|
|
1595
|
+
:row="row.row"
|
|
1596
|
+
:show-sub-row="row.row.stateDescription"
|
|
1597
|
+
:sub-matches="subMatches"
|
|
1598
|
+
:keyField="keyField"
|
|
1599
|
+
:componentTestid="componentTestid"
|
|
1600
|
+
:i="i"
|
|
1601
|
+
:onRowMouseEnter="onRowMouseEnter"
|
|
1602
|
+
:onRowMouseLeave="onRowMouseLeave"
|
|
1603
|
+
name="additional-sub-row"
|
|
1604
|
+
/>
|
|
1593
1605
|
<tr
|
|
1594
1606
|
v-if="row.row.stateDescription"
|
|
1595
1607
|
:key="row.row[keyField] + '-description'"
|
|
@@ -1924,12 +1936,25 @@ export default {
|
|
|
1924
1936
|
&.main-row.has-sub-row {
|
|
1925
1937
|
border-bottom: 0;
|
|
1926
1938
|
}
|
|
1939
|
+
&.additional-sub-row.has-sub-row {
|
|
1940
|
+
border-bottom: 0;
|
|
1941
|
+
}
|
|
1927
1942
|
|
|
1928
1943
|
// if a main-row is hovered also hover it's sibling sub row. note - the reverse is handled in selection.js
|
|
1929
1944
|
&.main-row:not(.row-selected):hover + .sub-row {
|
|
1930
1945
|
background-color: var(--sortable-table-hover-bg);
|
|
1931
1946
|
}
|
|
1932
1947
|
|
|
1948
|
+
// Case with only additional-sub-row
|
|
1949
|
+
&.main-row:not(.row-selected):hover + .additional-sub-row {
|
|
1950
|
+
background-color: var(--sortable-table-hover-bg);
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
// Case with both additional-sub-row and sub-row
|
|
1954
|
+
&.main-row:not(.row-selected):hover + .additional-sub-row + .sub-row{
|
|
1955
|
+
background-color: var(--sortable-table-hover-bg);
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1933
1958
|
&:last-of-type {
|
|
1934
1959
|
border-bottom: 0;
|
|
1935
1960
|
}
|
|
@@ -177,24 +177,32 @@ export default {
|
|
|
177
177
|
}
|
|
178
178
|
},
|
|
179
179
|
|
|
180
|
-
|
|
180
|
+
removeOrAddHover(option, e) {
|
|
181
|
+
// Hardcoded logic to not overcomplicate just adding the conditions of next and previous
|
|
181
182
|
const tr = e.target.closest('TR');
|
|
182
183
|
|
|
183
|
-
if (tr.classList.contains('sub-row')) {
|
|
184
|
-
const
|
|
184
|
+
if (tr.classList.contains('sub-row') || tr.classList.contains('additional-sub-row')) {
|
|
185
|
+
const trPreviousRow = tr.previousElementSibling;
|
|
186
|
+
const trNextRow = tr.nextElementSibling;
|
|
187
|
+
|
|
188
|
+
trPreviousRow.classList[option]('sub-row-hovered');
|
|
185
189
|
|
|
186
|
-
|
|
190
|
+
if (!trPreviousRow.classList.contains('main-row')) {
|
|
191
|
+
const trMainRow = trPreviousRow.previousElementSibling;
|
|
192
|
+
|
|
193
|
+
trMainRow.classList[option]('sub-row-hovered');
|
|
194
|
+
}
|
|
195
|
+
if (trNextRow?.classList.contains('sub-row')) {
|
|
196
|
+
trNextRow.classList[option]('sub-row-hovered');
|
|
197
|
+
}
|
|
187
198
|
}
|
|
188
199
|
},
|
|
200
|
+
onRowMouseEnter(e) {
|
|
201
|
+
this.removeOrAddHover('add', e);
|
|
202
|
+
},
|
|
189
203
|
|
|
190
204
|
onRowMouseLeave(e) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
if (tr.classList.contains('sub-row')) {
|
|
194
|
-
const trMainRow = tr.previousElementSibling;
|
|
195
|
-
|
|
196
|
-
trMainRow.classList.remove('sub-row-hovered');
|
|
197
|
-
}
|
|
205
|
+
this.removeOrAddHover('remove', e);
|
|
198
206
|
},
|
|
199
207
|
|
|
200
208
|
nodeForEvent(e) {
|
|
@@ -486,6 +494,11 @@ export default {
|
|
|
486
494
|
|
|
487
495
|
this.$nextTick(() => {
|
|
488
496
|
this.$emit('selection', this.selectedRows);
|
|
497
|
+
if (this.selectedRows && this.selectedRows.length) {
|
|
498
|
+
for ( let i = 0 ; i < this.selectedRows.length ; i++ ) {
|
|
499
|
+
this.updateInput(this.selectedRows[i], true, this.keyField);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
489
502
|
});
|
|
490
503
|
},
|
|
491
504
|
|
|
@@ -505,7 +518,7 @@ export default {
|
|
|
505
518
|
let tr = input.closest('tr');
|
|
506
519
|
let first = true;
|
|
507
520
|
|
|
508
|
-
while ( tr && (first || tr.classList.contains('sub-row') ) ) {
|
|
521
|
+
while ( tr && (first || tr.classList.contains('sub-row') || tr.classList.contains('additional-sub-row')) ) {
|
|
509
522
|
if (on) {
|
|
510
523
|
tr.classList.add('row-selected');
|
|
511
524
|
} else {
|
|
@@ -79,7 +79,7 @@ export default {
|
|
|
79
79
|
|
|
80
80
|
if ( markedColumn ) {
|
|
81
81
|
this._defaultSortBy = markedColumn.name;
|
|
82
|
-
descending = markedColumn.defaultSortDescending;
|
|
82
|
+
descending = markedColumn.defaultSortDescending || false;
|
|
83
83
|
} else if ( nameColumn ) {
|
|
84
84
|
// Use the name column if there is one
|
|
85
85
|
this._defaultSortBy = nameColumn.name;
|
|
@@ -83,6 +83,11 @@ export default {
|
|
|
83
83
|
componentTestid: {
|
|
84
84
|
type: String,
|
|
85
85
|
default: 'tabbed'
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
removeBorders: {
|
|
89
|
+
type: Boolean,
|
|
90
|
+
default: false,
|
|
86
91
|
}
|
|
87
92
|
},
|
|
88
93
|
|
|
@@ -128,7 +133,8 @@ export default {
|
|
|
128
133
|
return {
|
|
129
134
|
tabs: [...parsedExtTabs],
|
|
130
135
|
extensionTabs: parsedExtTabs,
|
|
131
|
-
activeTabName: null
|
|
136
|
+
activeTabName: null,
|
|
137
|
+
tabRefs: {}
|
|
132
138
|
};
|
|
133
139
|
},
|
|
134
140
|
|
|
@@ -263,7 +269,10 @@ export default {
|
|
|
263
269
|
this.select(nextName);
|
|
264
270
|
|
|
265
271
|
this.$nextTick(() => {
|
|
266
|
-
this.$refs.tablist.
|
|
272
|
+
this.$refs.tablist.removeAttribute('tabindex');
|
|
273
|
+
if (this.tabRefs[nextName]) {
|
|
274
|
+
this.tabRefs[nextName].focus();
|
|
275
|
+
}
|
|
267
276
|
});
|
|
268
277
|
|
|
269
278
|
function getCyclicalIdx(currentIdx, direction, tabsLength) {
|
|
@@ -299,7 +308,8 @@ export default {
|
|
|
299
308
|
class="tabbed-container"
|
|
300
309
|
:class="{
|
|
301
310
|
'side-tabs': !!sideTabs,
|
|
302
|
-
'tabs-only': tabsOnly
|
|
311
|
+
'tabs-only': tabsOnly,
|
|
312
|
+
'remove-borders': removeBorders
|
|
303
313
|
}"
|
|
304
314
|
:data-testid="componentTestid"
|
|
305
315
|
>
|
|
@@ -308,7 +318,7 @@ export default {
|
|
|
308
318
|
ref="tablist"
|
|
309
319
|
role="tablist"
|
|
310
320
|
class="tabs"
|
|
311
|
-
:class="{'clearfix':!sideTabs, 'vertical': sideTabs, 'horizontal': !sideTabs}"
|
|
321
|
+
:class="{'clearfix':!sideTabs, 'vertical': sideTabs, 'horizontal': !sideTabs, 'remove-borders': removeBorders}"
|
|
312
322
|
:data-testid="`${componentTestid}-block`"
|
|
313
323
|
tabindex="0"
|
|
314
324
|
@keydown.right.prevent="selectNext(1)"
|
|
@@ -323,14 +333,16 @@ export default {
|
|
|
323
333
|
:key="tab.name"
|
|
324
334
|
:data-testid="tab.name"
|
|
325
335
|
:class="{tab: true, active: tab.active, disabled: tab.disabled, error: (tab.error)}"
|
|
326
|
-
role="presentation"
|
|
327
336
|
>
|
|
328
337
|
<a
|
|
338
|
+
:id="`tab-${tab.name}`"
|
|
339
|
+
:ref="(el) => { if (el) tabRefs[tab.name] = el; }"
|
|
329
340
|
:data-testid="`btn-${tab.name}`"
|
|
330
341
|
:aria-controls="tab.name"
|
|
331
342
|
:aria-selected="tab.active"
|
|
332
343
|
:aria-label="tab.labelDisplay || ''"
|
|
333
344
|
role="tab"
|
|
345
|
+
:tabindex="tab.active ? '0' : '-1'"
|
|
334
346
|
@click.prevent="select(tab.name, $event)"
|
|
335
347
|
@keyup.enter.space="select(tab.name, $event)"
|
|
336
348
|
>
|
|
@@ -442,6 +454,17 @@ export default {
|
|
|
442
454
|
display: flex;
|
|
443
455
|
flex-direction: row;
|
|
444
456
|
|
|
457
|
+
&.remove-borders {
|
|
458
|
+
border: none;
|
|
459
|
+
|
|
460
|
+
+ .tab-container {
|
|
461
|
+
border: none;
|
|
462
|
+
border-top: 1px solid var(--border);
|
|
463
|
+
padding: 0;
|
|
464
|
+
padding-top: 24px;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
445
468
|
+ .tab-container {
|
|
446
469
|
border: solid thin var(--border);
|
|
447
470
|
}
|
|
@@ -458,7 +481,7 @@ export default {
|
|
|
458
481
|
.tab {
|
|
459
482
|
position: relative;
|
|
460
483
|
float: left;
|
|
461
|
-
padding: 0
|
|
484
|
+
padding: 0 4px 0 4px;
|
|
462
485
|
cursor: pointer;
|
|
463
486
|
|
|
464
487
|
A {
|
|
@@ -172,8 +172,11 @@ export default {
|
|
|
172
172
|
await this.$store.dispatch('cluster/find', { type: NODE, id: nodeId });
|
|
173
173
|
}
|
|
174
174
|
} catch {}
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
try {
|
|
176
|
+
await this.setupTerminal();
|
|
177
|
+
} catch (e) {
|
|
178
|
+
this.errorMsg = e;
|
|
179
|
+
}
|
|
177
180
|
await this.connect();
|
|
178
181
|
|
|
179
182
|
clearInterval(this.keepAliveTimer);
|
|
@@ -234,26 +237,20 @@ export default {
|
|
|
234
237
|
|
|
235
238
|
this.fitAddon = new addons.fit.FitAddon();
|
|
236
239
|
this.searchAddon = new addons.search.SearchAddon();
|
|
240
|
+
terminal.loadAddon(this.fitAddon);
|
|
241
|
+
terminal.loadAddon(this.searchAddon);
|
|
242
|
+
terminal.loadAddon(new addons.weblinks.WebLinksAddon());
|
|
243
|
+
terminal.open(this.$refs.xterm);
|
|
237
244
|
|
|
238
245
|
try {
|
|
239
246
|
this.webglAddon = new addons.webgl.WebglAddon();
|
|
247
|
+
terminal.loadAddon(this.webglAddon);
|
|
240
248
|
} catch (e) {
|
|
241
249
|
// Some browsers (Safari) don't support the webgl renderer, so don't use it.
|
|
242
250
|
this.webglAddon = null;
|
|
243
251
|
this.canvasAddon = new addons.canvas.CanvasAddon();
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
terminal.loadAddon(this.fitAddon);
|
|
247
|
-
terminal.loadAddon(this.searchAddon);
|
|
248
|
-
terminal.loadAddon(new addons.weblinks.WebLinksAddon());
|
|
249
|
-
terminal.open(this.$refs.xterm);
|
|
250
|
-
|
|
251
|
-
if (this.webglAddon) {
|
|
252
|
-
terminal.loadAddon(this.webglAddon);
|
|
253
|
-
} else {
|
|
254
252
|
terminal.loadAddon(this.canvasAddon);
|
|
255
253
|
}
|
|
256
|
-
|
|
257
254
|
this.fit();
|
|
258
255
|
this.flush();
|
|
259
256
|
|
|
@@ -18,49 +18,67 @@ export default {
|
|
|
18
18
|
},
|
|
19
19
|
|
|
20
20
|
computed: {
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
21
|
+
clustersRenderList() {
|
|
22
|
+
const clustersRenderList = this.clusters.map(({ nameDisplay, name, detailLocation }) => ({
|
|
23
|
+
name: nameDisplay || name,
|
|
24
|
+
detailLocation,
|
|
25
|
+
}));
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (remaining > 0) {
|
|
28
|
-
return [
|
|
29
|
-
...names.filter((_, i) => i < max),
|
|
30
|
-
this.t('fleet.clusterTargets.rules.matching.plusMore', { n: remaining }, true),
|
|
31
|
-
];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return names;
|
|
27
|
+
return clustersRenderList;
|
|
35
28
|
}
|
|
36
29
|
}
|
|
37
30
|
};
|
|
38
31
|
</script>
|
|
39
32
|
|
|
40
33
|
<template>
|
|
41
|
-
<div class="targets-list">
|
|
42
|
-
<h3>{{ t('fleet.clusterTargets.rules.matching.title') }}</h3>
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
34
|
+
<div class="targets-list-main">
|
|
35
|
+
<h3>{{ t('fleet.clusterTargets.rules.matching.title', { n: clustersRenderList.length }) }}</h3>
|
|
36
|
+
<div class="targets-list-list">
|
|
37
|
+
<span
|
|
38
|
+
v-for="(cluster, i) in clustersRenderList"
|
|
39
|
+
:key="i"
|
|
40
|
+
class="row mt-5"
|
|
41
|
+
>
|
|
42
|
+
<router-link
|
|
43
|
+
:to="cluster.detailLocation"
|
|
44
|
+
target="_blank"
|
|
45
|
+
class="link-main"
|
|
46
|
+
>
|
|
47
|
+
{{ cluster.name }} <i class="link-icon icon icon-external-link" />
|
|
48
|
+
</router-link>
|
|
49
|
+
</span>
|
|
50
|
+
<span
|
|
51
|
+
v-if="!clustersRenderList.length"
|
|
52
|
+
class="text-label"
|
|
53
|
+
>
|
|
54
|
+
{{ emptyLabel || t('fleet.clusterTargets.rules.matching.empty') }}
|
|
55
|
+
</span>
|
|
56
|
+
</div>
|
|
56
57
|
</div>
|
|
57
58
|
</template>
|
|
58
59
|
|
|
59
60
|
<style lang="scss" scoped>
|
|
60
|
-
.targets-list {
|
|
61
|
+
.targets-list-main {
|
|
61
62
|
height: 100%;
|
|
62
63
|
border-radius: 4px;
|
|
63
64
|
padding: 16px;
|
|
64
65
|
background-color: var(--tabbed-sidebar-bg);
|
|
66
|
+
display: flex;
|
|
67
|
+
flex-direction: column;
|
|
68
|
+
}
|
|
69
|
+
.targets-list-list {
|
|
70
|
+
overflow-y: scroll;
|
|
71
|
+
}
|
|
72
|
+
.link-main{
|
|
73
|
+
word-spacing: 22px;
|
|
74
|
+
}
|
|
75
|
+
.link-icon {
|
|
76
|
+
position: absolute;
|
|
77
|
+
margin-left: -14px; // Remove the space of the icon to make it float to accomodate the underline
|
|
78
|
+
display: none; // Make the icon disappear by default
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.link-main:hover .link-icon {
|
|
82
|
+
display: inline; // Only appear when hovered
|
|
65
83
|
}
|
|
66
84
|
</style>
|
|
@@ -16,13 +16,16 @@ import TargetsList from '@shell/components/fleet/FleetClusterTargets/TargetsList
|
|
|
16
16
|
|
|
17
17
|
export interface Cluster {
|
|
18
18
|
name: string,
|
|
19
|
-
nameDisplay: string
|
|
19
|
+
nameDisplay: string,
|
|
20
|
+
detailLocation: object,
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
interface DataType {
|
|
23
24
|
targetMode: TargetMode,
|
|
24
25
|
allClusters: any[],
|
|
26
|
+
allClusterGroups: any[],
|
|
25
27
|
selectedClusters: string[],
|
|
28
|
+
selectedClusterGroups: string[],
|
|
26
29
|
clusterSelectors: Selector[],
|
|
27
30
|
key: number,
|
|
28
31
|
}
|
|
@@ -76,19 +79,26 @@ export default {
|
|
|
76
79
|
allClusters: {
|
|
77
80
|
inStoreType: 'management',
|
|
78
81
|
type: FLEET.CLUSTER
|
|
79
|
-
}
|
|
80
|
-
|
|
82
|
+
},
|
|
83
|
+
allClusterGroups: {
|
|
84
|
+
inStoreType: 'management',
|
|
85
|
+
type: FLEET.CLUSTER_GROUP
|
|
86
|
+
},
|
|
87
|
+
}, this.$store) as { allClusters: any[], allClusterGroups: any[] };
|
|
81
88
|
|
|
82
89
|
this.allClusters = hash.allClusters || [];
|
|
90
|
+
this.allClusterGroups = hash.allClusterGroups || [];
|
|
83
91
|
},
|
|
84
92
|
|
|
85
93
|
data(): DataType {
|
|
86
94
|
return {
|
|
87
|
-
targetMode:
|
|
88
|
-
allClusters:
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
95
|
+
targetMode: 'all',
|
|
96
|
+
allClusters: [],
|
|
97
|
+
allClusterGroups: [],
|
|
98
|
+
selectedClusters: [],
|
|
99
|
+
selectedClusterGroups: [],
|
|
100
|
+
clusterSelectors: [],
|
|
101
|
+
key: 0 // Generates a unique key to handle Targets
|
|
92
102
|
};
|
|
93
103
|
},
|
|
94
104
|
|
|
@@ -96,10 +106,9 @@ export default {
|
|
|
96
106
|
this.fromTargets();
|
|
97
107
|
|
|
98
108
|
if (this.mode === _CREATE) {
|
|
99
|
-
this.update();
|
|
100
|
-
|
|
101
109
|
// Restore the targetMode from parent component; this is the case of edit targets in CREATE mode, go to YAML editor and come back to the form
|
|
102
110
|
this.targetMode = this.created || 'all';
|
|
111
|
+
this.update();
|
|
103
112
|
} else {
|
|
104
113
|
this.targetMode = FleetUtils.Application.getTargetMode(this.targets || [], this.namespace);
|
|
105
114
|
}
|
|
@@ -153,6 +162,14 @@ export default {
|
|
|
153
162
|
.map((x) => ({ label: x.nameDisplay, value: x.metadata.name }));
|
|
154
163
|
},
|
|
155
164
|
|
|
165
|
+
clusterGroupsOptions() {
|
|
166
|
+
return this.allClusterGroups
|
|
167
|
+
.filter((x) => x.metadata.namespace === this.namespace)
|
|
168
|
+
.map((x) => {
|
|
169
|
+
return { label: x.nameDisplay, value: x.metadata.name };
|
|
170
|
+
});
|
|
171
|
+
},
|
|
172
|
+
|
|
156
173
|
isLocal() {
|
|
157
174
|
return this.namespace === 'fleet-local';
|
|
158
175
|
},
|
|
@@ -178,6 +195,12 @@ export default {
|
|
|
178
195
|
this.update();
|
|
179
196
|
},
|
|
180
197
|
|
|
198
|
+
selectClusterGroups(list: string[]) {
|
|
199
|
+
this.selectedClusterGroups = list;
|
|
200
|
+
|
|
201
|
+
this.update();
|
|
202
|
+
},
|
|
203
|
+
|
|
181
204
|
addMatchExpressions() {
|
|
182
205
|
const neu = { key: this.key++ };
|
|
183
206
|
|
|
@@ -224,11 +247,15 @@ export default {
|
|
|
224
247
|
clusterGroupSelector,
|
|
225
248
|
} = target;
|
|
226
249
|
|
|
227
|
-
// If
|
|
228
|
-
if (
|
|
250
|
+
// If clusterGroupSelector are defined, targets are marked as complex and won't handle by the UI
|
|
251
|
+
if (clusterGroupSelector) {
|
|
229
252
|
return;
|
|
230
253
|
}
|
|
231
254
|
|
|
255
|
+
if (clusterGroup) {
|
|
256
|
+
this.selectedClusterGroups.push(clusterGroup);
|
|
257
|
+
}
|
|
258
|
+
|
|
232
259
|
if (clusterName) {
|
|
233
260
|
this.selectedClusters.push(clusterName);
|
|
234
261
|
}
|
|
@@ -254,20 +281,22 @@ export default {
|
|
|
254
281
|
case 'all':
|
|
255
282
|
return [excludeHarvesterRule];
|
|
256
283
|
case 'clusters':
|
|
257
|
-
return this.normalizeTargets(this.selectedClusters, this.clusterSelectors);
|
|
284
|
+
return this.normalizeTargets(this.selectedClusters, this.clusterSelectors, this.selectedClusterGroups);
|
|
258
285
|
case 'advanced':
|
|
259
286
|
case 'local':
|
|
260
287
|
return this.targets;
|
|
261
288
|
}
|
|
262
289
|
},
|
|
263
290
|
|
|
264
|
-
normalizeTargets(selected: string[], clusterMatchExpressions: Selector[]) {
|
|
291
|
+
normalizeTargets(selected: string[], clusterMatchExpressions: Selector[], selectedClusterGroups: string[]): Target[] | undefined {
|
|
265
292
|
const targets: Target[] = [];
|
|
266
293
|
|
|
294
|
+
// Select by name
|
|
267
295
|
selected.forEach((clusterName) => {
|
|
268
296
|
targets.push({ clusterName });
|
|
269
297
|
});
|
|
270
298
|
|
|
299
|
+
// Select by labels
|
|
271
300
|
clusterMatchExpressions.forEach((elem) => {
|
|
272
301
|
const { matchLabels: labels, matchExpressions: expressions } = elem || {};
|
|
273
302
|
|
|
@@ -311,6 +340,11 @@ export default {
|
|
|
311
340
|
}
|
|
312
341
|
});
|
|
313
342
|
|
|
343
|
+
// Select by cluster group
|
|
344
|
+
selectedClusterGroups.forEach((clusterGroup) => {
|
|
345
|
+
targets.push({ clusterGroup });
|
|
346
|
+
});
|
|
347
|
+
|
|
314
348
|
if (targets.length) {
|
|
315
349
|
return targets;
|
|
316
350
|
}
|
|
@@ -321,6 +355,7 @@ export default {
|
|
|
321
355
|
reset() {
|
|
322
356
|
this.targetMode = 'all';
|
|
323
357
|
this.selectedClusters = [];
|
|
358
|
+
this.selectedClusterGroups = [];
|
|
324
359
|
this.clusterSelectors = [];
|
|
325
360
|
}
|
|
326
361
|
},
|
|
@@ -356,25 +391,25 @@ export default {
|
|
|
356
391
|
>
|
|
357
392
|
<div class="col span-9">
|
|
358
393
|
<h3 class="m-0">
|
|
359
|
-
{{ t('fleet.clusterTargets.title') }}
|
|
394
|
+
{{ t('fleet.clusterTargets.clusters.title') }}
|
|
360
395
|
</h3>
|
|
361
396
|
<LabeledSelect
|
|
362
397
|
data-testid="fleet-target-cluster-name-selector"
|
|
363
398
|
class="mmt-4"
|
|
364
399
|
:value="selectedClusters"
|
|
365
|
-
:label="t('fleet.clusterTargets.label')"
|
|
400
|
+
:label="t('fleet.clusterTargets.clusters.byName.label')"
|
|
366
401
|
:options="clustersOptions"
|
|
367
402
|
:taggable="true"
|
|
368
403
|
:close-on-select="false"
|
|
369
404
|
:mode="mode"
|
|
370
405
|
:multiple="true"
|
|
371
|
-
:placeholder="t('fleet.clusterTargets.
|
|
406
|
+
:placeholder="t('fleet.clusterTargets.clusters.byName.placeholder')"
|
|
372
407
|
@update:value="selectClusters"
|
|
373
408
|
/>
|
|
374
|
-
<div class="mmt-
|
|
375
|
-
<
|
|
376
|
-
{{ t('fleet.clusterTargets.
|
|
377
|
-
</
|
|
409
|
+
<div class="mmt-6">
|
|
410
|
+
<h4 class="m-0">
|
|
411
|
+
{{ t('fleet.clusterTargets.clusters.byLabel.title') }}
|
|
412
|
+
</h4>
|
|
378
413
|
<div
|
|
379
414
|
v-for="(selector, i) in clusterSelectors"
|
|
380
415
|
:key="selector.key"
|
|
@@ -386,29 +421,47 @@ export default {
|
|
|
386
421
|
:value="selector"
|
|
387
422
|
:mode="mode"
|
|
388
423
|
:initial-empty-row="true"
|
|
389
|
-
:label-key="t('fleet.clusterTargets.
|
|
424
|
+
:label-key="t('fleet.clusterTargets.clusters.byLabel.labelKey')"
|
|
390
425
|
:add-icon="'icon-plus'"
|
|
391
426
|
:add-class="'btn-sm'"
|
|
392
427
|
@update:value="updateMatchExpressions(i, $event, selector.key)"
|
|
393
428
|
/>
|
|
394
429
|
<RcButton
|
|
395
|
-
small
|
|
396
|
-
link
|
|
430
|
+
size="small"
|
|
431
|
+
variant="link"
|
|
397
432
|
@click="removeMatchExpressions(selector.key)"
|
|
398
433
|
>
|
|
399
434
|
<i class="icon icon-x" />
|
|
400
435
|
</RcButton>
|
|
401
436
|
</div>
|
|
402
437
|
<RcButton
|
|
403
|
-
small
|
|
404
|
-
secondary
|
|
405
|
-
class="mmt-
|
|
438
|
+
size="small"
|
|
439
|
+
variant="secondary"
|
|
440
|
+
class="mmt-4"
|
|
406
441
|
@click="addMatchExpressions"
|
|
407
442
|
>
|
|
408
443
|
<i class="icon icon-plus" />
|
|
409
|
-
<span>{{ t('fleet.clusterTargets.
|
|
444
|
+
<span>{{ t('fleet.clusterTargets.clusters.byLabel.addSelector') }}</span>
|
|
410
445
|
</RcButton>
|
|
411
446
|
</div>
|
|
447
|
+
<div class="mmt-8">
|
|
448
|
+
<h3 class="m-0">
|
|
449
|
+
{{ t('fleet.clusterTargets.clusterGroups.title') }}
|
|
450
|
+
</h3>
|
|
451
|
+
<LabeledSelect
|
|
452
|
+
data-testid="fleet-target-cluster-group-selector"
|
|
453
|
+
class="mmt-4"
|
|
454
|
+
:value="selectedClusterGroups"
|
|
455
|
+
:label="t('fleet.clusterTargets.clusterGroups.byName.label')"
|
|
456
|
+
:options="clusterGroupsOptions"
|
|
457
|
+
:taggable="true"
|
|
458
|
+
:close-on-select="false"
|
|
459
|
+
:mode="mode"
|
|
460
|
+
:multiple="true"
|
|
461
|
+
:placeholder="t('fleet.clusterTargets.clusterGroups.byName.placeholder')"
|
|
462
|
+
@update:value="selectClusterGroups"
|
|
463
|
+
/>
|
|
464
|
+
</div>
|
|
412
465
|
</div>
|
|
413
466
|
<div class="col span-3">
|
|
414
467
|
<TargetsList
|
|
@@ -450,6 +503,6 @@ export default {
|
|
|
450
503
|
}
|
|
451
504
|
|
|
452
505
|
.target-list {
|
|
453
|
-
max-height:
|
|
506
|
+
max-height: 320px;
|
|
454
507
|
}
|
|
455
508
|
</style>
|