@rancher/shell 0.3.29 → 0.5.0
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/assets/images/providers/ovhcloudmks.svg +122 -0
- package/assets/images/providers/ovhcloudpubliccloud.svg +122 -0
- package/assets/styles/global/_layout.scss +99 -0
- package/assets/translations/en-us.yaml +31 -6
- package/assets/translations/zh-hans.yaml +2 -2
- package/babel.config.js +7 -1
- package/chart/monitoring/alerting/index.vue +7 -21
- package/chart/monitoring/grafana/index.vue +55 -0
- package/chart/monitoring/index.vue +51 -17
- package/chart/monitoring/prometheus/index.vue +37 -43
- package/chart/rancher-backup/index.vue +2 -1
- package/cloud-credential/azure.vue +4 -17
- package/components/AsyncButton.vue +17 -5
- package/components/Certificates.vue +164 -0
- package/components/CodeMirror.vue +19 -21
- package/components/CopyCode.vue +6 -2
- package/components/CopyToClipboard.vue +2 -1
- package/components/CopyToClipboardText.vue +14 -9
- package/components/CruResource.vue +1 -0
- package/components/DraggableZone.vue +2 -2
- package/components/EtcdInfoBanner.vue +5 -5
- package/components/ExplorerProjectsNamespaces.vue +25 -1
- package/components/IconOrSvg.vue +1 -1
- package/components/LandingPagePreference.vue +1 -4
- package/components/Markdown.vue +16 -12
- package/components/PodSecurityAdmission.vue +2 -2
- package/components/Questions/index.vue +1 -1
- package/components/ResourceDetail/Masthead.vue +25 -9
- package/components/ResourceTable.vue +14 -2
- package/components/ResourceYaml.vue +5 -0
- package/components/SideNav.vue +1 -1
- package/components/SingleClusterInfo.vue +1 -4
- package/components/StatusTable.vue +5 -1
- package/components/Tabbed/index.vue +12 -0
- package/components/__tests__/CopyCode.test.ts +5 -4
- package/components/fleet/FleetBundles.vue +5 -11
- package/components/fleet/FleetRepos.vue +62 -27
- package/components/fleet/FleetResources.vue +6 -1
- package/components/fleet/FleetSummary.vue +3 -3
- package/components/fleet/__tests__/FleetSummary.test.ts +316 -0
- package/components/form/ArrayListSelect.vue +10 -0
- package/components/form/Error.vue +3 -3
- package/components/form/Footer.vue +2 -2
- package/components/form/GitPicker.vue +83 -38
- package/components/form/KeyValue.vue +4 -0
- package/components/form/LabeledSelect.vue +4 -0
- package/components/form/Password.vue +3 -1
- package/components/formatter/Checked.vue +11 -3
- package/components/formatter/FleetClusterSummaryGraph.vue +27 -0
- package/components/formatter/FleetSummaryGraph.vue +23 -11
- package/components/formatter/LiveDuration.vue +1 -1
- package/components/formatter/PercentageBar.vue +1 -1
- package/components/formatter/__tests__/Checked.test.ts +19 -0
- package/components/nav/Group.vue +2 -2
- package/components/nav/Header.vue +1 -2
- package/components/nav/TopLevelMenu.vue +36 -6
- package/components/nav/Type.vue +1 -3
- package/components/nav/WindowManager/ContainerLogs.vue +101 -3
- package/components/nav/WindowManager/ContainerShell.vue +6 -1
- package/components/nav/WindowManager/__tests__/ContainerLogs.test.ts +186 -0
- package/components/nav/WindowManager/index.vue +11 -10
- package/components/nav/__tests__/TopLevelMenu.test.ts +33 -0
- package/components/nav/__tests__/Type.test.ts +1 -1
- package/components/nuxt/nuxt-child.js +14 -78
- package/components/nuxt/nuxt.js +1 -1
- package/{layouts → components/templates}/blank.vue +1 -1
- package/{layouts → components/templates}/default.vue +8 -98
- package/{layouts → components/templates}/error.vue +10 -19
- package/{layouts → components/templates}/home.vue +4 -1
- package/{layouts → components/templates}/plain.vue +4 -1
- package/{layouts → components/templates}/standalone.vue +1 -1
- package/{layouts → components/templates}/unauthenticated.vue +1 -1
- package/composables/useCompactInput.test.ts +36 -0
- package/composables/useCompactInput.ts +20 -0
- package/composables/useLabeledFormElement.test.ts +135 -0
- package/composables/useLabeledFormElement.ts +138 -0
- package/config/harvester-manager-types.js +2 -0
- package/config/home-links.js +1 -1
- package/config/private-label.js +22 -0
- package/config/product/explorer.js +3 -0
- package/config/product/fleet.js +6 -1
- package/config/product/manager.js +8 -2
- package/config/query-params.js +1 -0
- package/config/router.js +385 -364
- package/config/settings.ts +1 -0
- package/config/store.js +1 -1
- package/config/system-namespaces.js +3 -0
- package/config/table-headers.js +47 -0
- package/core/plugin-helpers.js +3 -5
- package/core/plugin-routes.ts +56 -114
- package/core/plugin.ts +16 -10
- package/core/plugins-loader.js +7 -9
- package/core/plugins.js +0 -3
- package/creators/app/files/.gitlab-ci.yml +14 -0
- package/creators/app/init +19 -0
- package/detail/fleet.cattle.io.cluster.vue +11 -1
- package/detail/provisioning.cattle.io.cluster.vue +4 -3
- package/dialog/ScaleMachineDownDialog.vue +34 -17
- package/edit/__tests__/service.test.ts +89 -0
- package/edit/auth/googleoauth.vue +1 -5
- package/edit/cloudcredential.vue +2 -0
- package/edit/configmap.vue +2 -1
- package/edit/management.cattle.io.podsecurityadmissionconfigurationtemplate.vue +2 -2
- package/edit/monitoring.coreos.com.prometheusrule/AlertingRule.vue +12 -3
- package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +2 -1
- package/edit/networking.k8s.io.networkpolicy/__tests__/PolicyRuleTarget.spec.ts +1 -1
- package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +15 -7
- package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +112 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +473 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/{CustomCommand.tests.ts → CustomCommand.test.ts} +6 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/DrainOptions.test.ts +1 -1
- package/edit/provisioning.cattle.io.cluster/__tests__/index.test.ts +73 -0
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +7 -1
- package/edit/provisioning.cattle.io.cluster/__tests__/utils/cluster.ts +386 -0
- package/edit/provisioning.cattle.io.cluster/import.vue +2 -2
- package/edit/provisioning.cattle.io.cluster/index.vue +92 -36
- package/edit/provisioning.cattle.io.cluster/rke2.vue +171 -583
- package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +137 -0
- package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +157 -0
- package/edit/provisioning.cattle.io.cluster/{Basics.vue → tabs/Basics.vue} +94 -19
- package/edit/provisioning.cattle.io.cluster/{MachinePool.vue → tabs/MachinePool.vue} +1 -0
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +135 -0
- package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +189 -0
- package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +144 -0
- package/edit/provisioning.cattle.io.cluster/tabs/upgrade/index.vue +76 -0
- package/edit/service.vue +12 -0
- package/edit/workload/Upgrading.vue +3 -2
- package/edit/workload/mixins/workload.js +1 -1
- package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +2 -1
- package/initialize/App.js +25 -71
- package/initialize/client.js +21 -162
- package/initialize/index.js +47 -124
- package/list/management.cattle.io.feature.vue +1 -7
- package/list/node.vue +1 -0
- package/machine-config/__tests__/vmwarevsphere.test.ts +100 -21
- package/machine-config/vmwarevsphere.vue +73 -51
- package/middleware/authenticated.js +10 -17
- package/mixins/auth-config.js +2 -7
- package/mixins/brand.js +29 -41
- package/mixins/create-edit-view/index.js +2 -2
- package/mixins/labeled-form-element.ts +6 -1
- package/models/__tests__/management.cattle.io.cluster.test.ts +4 -0
- package/models/__tests__/management.cattle.io.node.ts +85 -0
- package/models/__tests__/management.cattle.io.nodepool.ts +83 -0
- package/models/__tests__/namespace.test.ts +49 -9
- package/models/__tests__/workload.test.ts +91 -0
- package/models/cluster/node.js +4 -4
- package/models/cluster.x-k8s.io.machinedeployment.js +14 -0
- package/models/fleet.cattle.io.cluster.js +4 -0
- package/models/fleet.cattle.io.gitrepo.js +56 -13
- package/models/management.cattle.io.cluster.js +7 -3
- package/models/management.cattle.io.kontainerdriver.js +1 -1
- package/models/management.cattle.io.node.js +18 -14
- package/models/management.cattle.io.nodepool.js +17 -0
- package/models/namespace.js +1 -1
- package/models/pod.js +20 -0
- package/models/provisioning.cattle.io.cluster.js +39 -4
- package/models/secret.js +117 -18
- package/models/workload.js +16 -0
- package/models/workload.service.js +18 -0
- package/package.json +11 -10
- package/pages/about.vue +0 -1
- package/pages/account/create-key.vue +0 -1
- package/pages/account/index.vue +0 -1
- package/pages/auth/login.vue +0 -1
- package/pages/auth/logout.vue +0 -2
- package/pages/auth/setup.vue +0 -4
- package/pages/auth/verify.vue +14 -8
- package/pages/c/_cluster/apps/charts/index.vue +64 -43
- package/pages/c/_cluster/apps/charts/install.vue +4 -4
- package/pages/c/_cluster/apps/index.vue +0 -2
- package/pages/c/_cluster/auth/index.vue +0 -2
- package/pages/c/_cluster/ecm/index.vue +0 -2
- package/pages/c/_cluster/explorer/index.vue +28 -2
- package/pages/c/_cluster/fleet/index.vue +1 -1
- package/pages/c/_cluster/index.vue +0 -2
- package/pages/c/_cluster/settings/banners.vue +0 -2
- package/pages/c/_cluster/settings/brand.vue +0 -2
- package/pages/c/_cluster/settings/index.vue +0 -2
- package/pages/c/_cluster/settings/links.vue +0 -1
- package/pages/c/_cluster/settings/performance.vue +0 -1
- package/pages/c/_cluster/uiplugins/CatalogList/CatalogLoadDialog.vue +2 -1
- package/pages/c/_cluster/uiplugins/CatalogList/index.vue +10 -46
- package/pages/c/_cluster/uiplugins/index.vue +0 -2
- package/pages/diagnostic.vue +1 -2
- package/pages/fail-whale.vue +0 -1
- package/pages/prefs.vue +0 -1
- package/pages/support/index.vue +2 -8
- package/pkg/auto-import.js +1 -1
- package/plugins/axios.js +0 -36
- package/plugins/back-button.js +3 -5
- package/plugins/clean-html-directive.js +1 -19
- package/plugins/clean-html.js +53 -0
- package/plugins/clean-tooltip-directive.js +1 -1
- package/plugins/codemirror-loader.js +1 -1
- package/plugins/codemirror.js +41 -0
- package/plugins/dashboard-store/__tests__/{mutations.spec.ts → mutations.test.ts} +1 -1
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +49 -0
- package/plugins/dashboard-store/__tests__/utils/store-mocks.ts +7 -0
- package/plugins/dashboard-store/actions.js +30 -4
- package/plugins/dashboard-store/classify.js +1 -18
- package/plugins/dashboard-store/getters.js +10 -5
- package/plugins/dashboard-store/index.js +0 -12
- package/plugins/dashboard-store/mutations.js +0 -4
- package/plugins/dashboard-store/resource-class.js +59 -18
- package/plugins/index.js +11 -0
- package/plugins/steve/__tests__/steve-class.spec.ts +59 -0
- package/plugins/steve/__tests__/utils/steve-mocks.ts +31 -0
- package/plugins/steve/getters.js +4 -1
- package/plugins/steve/norman-class.js +19 -0
- package/plugins/steve/steve-class.js +22 -0
- package/plugins/steve/subscribe.js +4 -10
- package/rancher-components/Accordion/Accordion.test.ts +45 -0
- package/rancher-components/Accordion/Accordion.vue +86 -0
- package/rancher-components/Accordion/index.ts +1 -0
- package/rancher-components/BadgeState/BadgeState.vue +3 -3
- package/rancher-components/Banner/Banner.vue +2 -2
- package/rancher-components/Card/Card.vue +3 -3
- package/rancher-components/Form/Checkbox/Checkbox.vue +3 -3
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +18 -1
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +65 -24
- package/rancher-components/Form/Radio/RadioButton.test.ts +7 -3
- package/rancher-components/Form/Radio/RadioButton.vue +13 -7
- package/rancher-components/Form/Radio/RadioGroup.test.ts +30 -0
- package/rancher-components/Form/Radio/RadioGroup.vue +8 -3
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +6 -4
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +9 -4
- package/rancher-components/StringList/StringList.test.ts +270 -0
- package/rancher-components/StringList/StringList.vue +65 -26
- package/rancher-components/components/Accordion/Accordion.test.ts +45 -0
- package/rancher-components/components/Accordion/Accordion.vue +86 -0
- package/rancher-components/components/Accordion/index.ts +1 -0
- package/rancher-components/components/BadgeState/BadgeState.vue +3 -3
- package/rancher-components/components/Banner/Banner.vue +2 -2
- package/rancher-components/components/Card/Card.vue +3 -3
- package/rancher-components/components/Form/Checkbox/Checkbox.vue +3 -3
- package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +18 -1
- package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +57 -24
- package/rancher-components/components/Form/Radio/RadioButton.vue +13 -7
- package/rancher-components/components/Form/Radio/RadioGroup.vue +4 -3
- package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +6 -4
- package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +7 -4
- package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +9 -4
- package/rancher-components/components/StringList/StringList.vue +8 -8
- package/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml +50 -0
- package/scripts/extension/bundle +19 -7
- package/scripts/extension/helm/scripts/package +11 -3
- package/scripts/extension/parse-tag-name +2 -2
- package/scripts/extension/publish +20 -9
- package/scripts/publish-shell.sh +10 -0
- package/scripts/test-plugins-build.sh +85 -9
- package/server/har-file.js +183 -0
- package/store/catalog.js +1 -1
- package/store/features.js +1 -0
- package/store/i18n.js +11 -0
- package/store/index.js +13 -15
- package/store/prefs.js +33 -35
- package/store/type-map.js +8 -7
- package/tsconfig.json +35 -9
- package/tsconfig.paths.json +21 -0
- package/types/shell/index.d.ts +433 -234
- package/types/vue-shim.d.ts +42 -0
- package/utils/__tests__/create-yaml.test.ts +60 -0
- package/utils/axios.js +0 -19
- package/utils/azure.js +24 -0
- package/utils/clipboard.js +5 -0
- package/utils/create-yaml.js +17 -10
- package/utils/git.ts +1 -1
- package/utils/monitoring.js +1 -1
- package/utils/nuxt.js +18 -39
- package/utils/object.js +14 -0
- package/utils/router.scrollBehavior.js +12 -14
- package/utils/time.js +1 -1
- package/utils/url.ts +1 -1
- package/vue.config.js +23 -2
- package/.DS_Store +0 -0
- package/assets/images/providers/aks-black.svg +0 -28
- package/assets/images/providers/aks.svg +0 -31
- package/edit/provisioning.cattle.io.cluster/__tests__/Basics.tests.ts +0 -234
- package/initialize/layouts.ts +0 -26
- package/mixins/fetch.server.js +0 -73
- package/pages/c/index.vue +0 -9
- package/pages/rio/mesh.vue +0 -508
- package/plugins/transitions.js +0 -4
- package/plugins/vue-clipboard2.js +0 -4
- package/tsconfig.default.json +0 -46
- package/yarn-error.log +0 -200
- /package/components/form/__tests__/{NameNsDescription.ts → NameNsDescription.test.ts} +0 -0
- /package/edit/networking.k8s.io.networkpolicy/__tests__/utils/{selectors.ts → selectors.test.ts} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{AgentConfiguration.vue → tabs/AgentConfiguration.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{MemberRoles.vue → tabs/MemberRoles.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{S3Config.vue → tabs/etcd/S3Config.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{ACE.vue → tabs/networking/ACE.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{RegistryConfigs.vue → tabs/registries/RegistryConfigs.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{RegistryMirrors.vue → tabs/registries/RegistryMirrors.vue} +0 -0
- /package/edit/provisioning.cattle.io.cluster/{DrainOptions.vue → tabs/upgrade/DrainOptions.vue} +0 -0
- /package/plugins/dashboard-store/__tests__/{actions.spec.ts → actions.test.ts} +0 -0
- /package/plugins/dashboard-store/__tests__/{getters.spec.ts → getters.test.ts} +0 -0
- /package/rancher-components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
- /package/rancher-components/components/BadgeState/{BadgeState.spec.ts → BadgeState.test.ts} +0 -0
|
@@ -343,6 +343,7 @@ export default {
|
|
|
343
343
|
|
|
344
344
|
for ( const row of input ) {
|
|
345
345
|
let value = row[this.valueName] || '';
|
|
346
|
+
|
|
346
347
|
const decodedValue = base64Decode(row[this.valueName]);
|
|
347
348
|
const asciiValue = asciiLike(decodedValue);
|
|
348
349
|
|
|
@@ -644,6 +645,7 @@ export default {
|
|
|
644
645
|
:clearable="false"
|
|
645
646
|
:taggable="keyTaggable"
|
|
646
647
|
:options="calculateOptions(row[keyName])"
|
|
648
|
+
:data-testid="`select-kv-item-key-${i}`"
|
|
647
649
|
@input="queueUpdate"
|
|
648
650
|
/>
|
|
649
651
|
<input
|
|
@@ -652,6 +654,7 @@ export default {
|
|
|
652
654
|
v-model="row[keyName]"
|
|
653
655
|
:disabled="isView || disabled || !keyEditable || isProtected(row.key)"
|
|
654
656
|
:placeholder="keyPlaceholder"
|
|
657
|
+
:data-testid="`input-kv-item-key-${i}`"
|
|
655
658
|
@input="queueUpdate"
|
|
656
659
|
@paste="onPaste(i, $event)"
|
|
657
660
|
>
|
|
@@ -661,6 +664,7 @@ export default {
|
|
|
661
664
|
<!-- Value -->
|
|
662
665
|
<div
|
|
663
666
|
:key="i+'value'"
|
|
667
|
+
:data-testid="`kv-item-value-${i}`"
|
|
664
668
|
class="kv-item value"
|
|
665
669
|
>
|
|
666
670
|
<slot
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { mapGetters } from 'vuex';
|
|
3
3
|
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
4
4
|
import { CHARSET, randomStr } from '@shell/utils/string';
|
|
5
|
+
import { copyTextToClipboard } from '@shell/utils/clipboard';
|
|
5
6
|
|
|
6
7
|
export default {
|
|
7
8
|
components: { LabeledInput },
|
|
@@ -75,6 +76,7 @@ export default {
|
|
|
75
76
|
}
|
|
76
77
|
},
|
|
77
78
|
methods: {
|
|
79
|
+
copyTextToClipboard,
|
|
78
80
|
generatePassword() {
|
|
79
81
|
this.password = randomStr(16, CHARSET.ALPHA_NUM);
|
|
80
82
|
},
|
|
@@ -109,7 +111,7 @@ export default {
|
|
|
109
111
|
>
|
|
110
112
|
<a
|
|
111
113
|
href="#"
|
|
112
|
-
@click.prevent.stop="
|
|
114
|
+
@click.prevent.stop="copyTextToClipboard(password)"
|
|
113
115
|
>{{ t('action.copy') }}</a>
|
|
114
116
|
</div>
|
|
115
117
|
<div
|
|
@@ -2,16 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
export default {
|
|
4
4
|
props: {
|
|
5
|
+
// When sortabletable calculates these values it converts null and undefined to ''
|
|
6
|
+
// passing '' to a prop typed as Boolean coerces it to true
|
|
5
7
|
value: {
|
|
6
|
-
type: Boolean,
|
|
8
|
+
type: [String, Boolean],
|
|
7
9
|
default: true
|
|
8
10
|
},
|
|
9
|
-
}
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
computed: {
|
|
14
|
+
checked() {
|
|
15
|
+
return this.value === true || this.value === 'true';
|
|
16
|
+
}
|
|
17
|
+
},
|
|
10
18
|
};
|
|
11
19
|
</script>
|
|
12
20
|
|
|
13
21
|
<template>
|
|
14
|
-
<span v-if="
|
|
22
|
+
<span v-if="checked">
|
|
15
23
|
<i class="icon icon-checkmark" />
|
|
16
24
|
</span>
|
|
17
25
|
<span
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import FleetSummaryGraph from '@shell/components/formatter/FleetSummaryGraph';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
name: 'FleetClusterSummaryGraph',
|
|
6
|
+
components: { FleetSummaryGraph },
|
|
7
|
+
|
|
8
|
+
props: {
|
|
9
|
+
row: {
|
|
10
|
+
type: Object,
|
|
11
|
+
required: true
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
clusterLabel: {
|
|
15
|
+
type: String,
|
|
16
|
+
required: true
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<template>
|
|
23
|
+
<FleetSummaryGraph
|
|
24
|
+
:row="row"
|
|
25
|
+
:clusterLabel="clusterLabel"
|
|
26
|
+
/>
|
|
27
|
+
</template>
|
|
@@ -12,10 +12,22 @@ export default {
|
|
|
12
12
|
type: Object,
|
|
13
13
|
required: true
|
|
14
14
|
},
|
|
15
|
+
|
|
16
|
+
clusterLabel: {
|
|
17
|
+
type: String,
|
|
18
|
+
required: false,
|
|
19
|
+
default: null,
|
|
20
|
+
}
|
|
15
21
|
},
|
|
16
22
|
|
|
17
23
|
computed: {
|
|
18
24
|
summary() {
|
|
25
|
+
if (this.clusterLabel) {
|
|
26
|
+
return this.row.clusterResourceStatus.find((x) => {
|
|
27
|
+
return x.clusterLabel === this.clusterLabel;
|
|
28
|
+
})?.status.resourceCounts || {};
|
|
29
|
+
}
|
|
30
|
+
|
|
19
31
|
return this.row.status?.resourceCounts || {};
|
|
20
32
|
},
|
|
21
33
|
|
|
@@ -73,7 +85,7 @@ export default {
|
|
|
73
85
|
>
|
|
74
86
|
<td
|
|
75
87
|
class="text-left pr-20"
|
|
76
|
-
:class="{[obj.textColor]: true}"
|
|
88
|
+
:class="{ [obj.textColor]: true }"
|
|
77
89
|
>
|
|
78
90
|
{{ obj.label }}
|
|
79
91
|
</td>
|
|
@@ -94,17 +106,17 @@ export default {
|
|
|
94
106
|
</template>
|
|
95
107
|
|
|
96
108
|
<style lang="scss">
|
|
97
|
-
|
|
98
|
-
|
|
109
|
+
.col-scale {
|
|
110
|
+
position: relative;
|
|
99
111
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
112
|
+
.trigger {
|
|
113
|
+
width: 100%;
|
|
103
114
|
}
|
|
115
|
+
}
|
|
104
116
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
117
|
+
.scale {
|
|
118
|
+
margin: 0;
|
|
119
|
+
padding: 0;
|
|
120
|
+
line-height: initial;
|
|
121
|
+
}
|
|
110
122
|
</style>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import Checked from '@shell/components/formatter/Checked.vue';
|
|
3
|
+
|
|
4
|
+
describe('component: Checked', () => {
|
|
5
|
+
it.each([true, 'true'])('should display a checkmark when the value is true or "true"', (value: any) => {
|
|
6
|
+
const wrapper = mount(Checked, { propsData: { value } });
|
|
7
|
+
const checkmark = wrapper.find('.icon-checkmark');
|
|
8
|
+
|
|
9
|
+
expect(checkmark.exists()).toBe(true);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it.each([false, '', 'abc'])('should not display a checkmark when the value is anything other than true or "true"', (value: any) => {
|
|
13
|
+
const wrapper = mount(Checked, { propsData: { value } });
|
|
14
|
+
|
|
15
|
+
const checkmark = wrapper.find('.icon-checkmark');
|
|
16
|
+
|
|
17
|
+
expect(checkmark.exists()).toBe(false);
|
|
18
|
+
});
|
|
19
|
+
});
|
package/components/nav/Group.vue
CHANGED
|
@@ -390,8 +390,8 @@ export default {
|
|
|
390
390
|
}
|
|
391
391
|
}
|
|
392
392
|
|
|
393
|
-
.body ::v-deep > .child.
|
|
394
|
-
.header ::v-deep > .child.
|
|
393
|
+
.body ::v-deep > .child.router-link-active,
|
|
394
|
+
.header ::v-deep > .child.router-link-exact-active {
|
|
395
395
|
padding: 0;
|
|
396
396
|
|
|
397
397
|
A, A I {
|
|
@@ -311,7 +311,7 @@ export default {
|
|
|
311
311
|
product: this.currentProduct.name,
|
|
312
312
|
cluster: this.currentCluster,
|
|
313
313
|
};
|
|
314
|
-
const enabled = action.enabled ? action.enabled.apply(this, [
|
|
314
|
+
const enabled = action.enabled ? action.enabled.apply(this, [this.ctx]) : true;
|
|
315
315
|
|
|
316
316
|
if (fn && enabled) {
|
|
317
317
|
fn.apply(this, [opts, [], { $route: this.$route }]);
|
|
@@ -441,7 +441,6 @@ export default {
|
|
|
441
441
|
|
|
442
442
|
<div class="rd-header-right">
|
|
443
443
|
<component :is="navHeaderRight" />
|
|
444
|
-
|
|
445
444
|
<div
|
|
446
445
|
v-if="showFilter"
|
|
447
446
|
class="top"
|
|
@@ -13,6 +13,7 @@ import { getVersionInfo } from '@shell/utils/version';
|
|
|
13
13
|
import { LEGACY } from '@shell/store/features';
|
|
14
14
|
import { SETTING } from '@shell/config/settings';
|
|
15
15
|
import { filterOnlyKubernetesClusters, filterHiddenLocalCluster } from '@shell/utils/cluster';
|
|
16
|
+
import { getProductFromRoute } from '@shell/middleware/authenticated';
|
|
16
17
|
import { isRancherPrime } from '@shell/config/version';
|
|
17
18
|
import Pinned from '@shell/components/nav/Pinned';
|
|
18
19
|
|
|
@@ -72,12 +73,17 @@ export default {
|
|
|
72
73
|
if (bannerSettings) {
|
|
73
74
|
const parsed = JSON.parse(bannerSettings.value);
|
|
74
75
|
const {
|
|
75
|
-
showFooter, showHeader, bannerFooter, bannerHeader
|
|
76
|
+
showFooter, showHeader, bannerFooter, bannerHeader, banner
|
|
76
77
|
} = parsed;
|
|
77
78
|
|
|
79
|
+
// add defaults to accomodate older JSON structures for banner definitions without breaking the UI
|
|
80
|
+
// https://github.com/rancher/dashboard/issues/10140
|
|
81
|
+
const bannerHeaderFontSize = bannerHeader?.fontSize || banner?.fontSize || '14px';
|
|
82
|
+
const bannerFooterFontSize = bannerFooter?.fontSize || banner?.fontSize || '14px';
|
|
83
|
+
|
|
78
84
|
return {
|
|
79
|
-
headerFont: showHeader === 'true' ? this.pxToEm(
|
|
80
|
-
footerFont: showFooter === 'true' ? this.pxToEm(
|
|
85
|
+
headerFont: showHeader === 'true' ? this.pxToEm(bannerHeaderFontSize) : '0px',
|
|
86
|
+
footerFont: showFooter === 'true' ? this.pxToEm(bannerFooterFontSize) : '0px'
|
|
81
87
|
};
|
|
82
88
|
}
|
|
83
89
|
|
|
@@ -242,7 +248,15 @@ export default {
|
|
|
242
248
|
|
|
243
249
|
hasSupport() {
|
|
244
250
|
return isRancherPrime() || this.$store.getters['management/byId'](MANAGEMENT.SETTING, SETTING.SUPPORTED )?.value === 'true';
|
|
245
|
-
}
|
|
251
|
+
},
|
|
252
|
+
|
|
253
|
+
isCurrRouteClusterExplorer() {
|
|
254
|
+
return this.$route?.name?.startsWith('c-cluster');
|
|
255
|
+
},
|
|
256
|
+
|
|
257
|
+
productFromRoute() {
|
|
258
|
+
return getProductFromRoute(this.$route);
|
|
259
|
+
},
|
|
246
260
|
},
|
|
247
261
|
|
|
248
262
|
watch: {
|
|
@@ -273,6 +287,16 @@ export default {
|
|
|
273
287
|
return `${ lineHeightInEm }em`;
|
|
274
288
|
},
|
|
275
289
|
|
|
290
|
+
checkActiveRoute(obj, isClusterRoute) {
|
|
291
|
+
// for Cluster links in main nav: check if route is a cluster explorer one + check if route cluster matches cluster obj id + check if curr product matches route product
|
|
292
|
+
if (isClusterRoute) {
|
|
293
|
+
return this.isCurrRouteClusterExplorer && this.$route?.params?.cluster === obj?.id && this.productFromRoute === this.currentProduct?.name;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// for remaining main nav items, check if curr product matches route product is enough
|
|
297
|
+
return this.productFromRoute === obj?.value;
|
|
298
|
+
},
|
|
299
|
+
|
|
276
300
|
handler(e) {
|
|
277
301
|
if (e.keyCode === KEY.ESCAPE ) {
|
|
278
302
|
this.hide();
|
|
@@ -435,6 +459,7 @@ export default {
|
|
|
435
459
|
<nuxt-link
|
|
436
460
|
class="option"
|
|
437
461
|
:to="a.to"
|
|
462
|
+
:class="{'active-menu-link': checkActiveRoute(a) }"
|
|
438
463
|
>
|
|
439
464
|
<IconOrSvg
|
|
440
465
|
:icon="a.icon"
|
|
@@ -466,6 +491,7 @@ export default {
|
|
|
466
491
|
v-if="c.ready"
|
|
467
492
|
:data-testid="`menu-cluster-${ c.id }`"
|
|
468
493
|
class="cluster selector option"
|
|
494
|
+
:class="{'active-menu-link': checkActiveRoute(c, true) }"
|
|
469
495
|
:to="{ name: 'c-cluster-explorer', params: { cluster: c.id } }"
|
|
470
496
|
>
|
|
471
497
|
<ClusterIconMenu
|
|
@@ -515,6 +541,7 @@ export default {
|
|
|
515
541
|
v-if="c.ready"
|
|
516
542
|
:data-testid="`menu-cluster-${ c.id }`"
|
|
517
543
|
class="cluster selector option"
|
|
544
|
+
:class="{'active-menu-link': checkActiveRoute(c, true) }"
|
|
518
545
|
:to="{ name: 'c-cluster-explorer', params: { cluster: c.id } }"
|
|
519
546
|
>
|
|
520
547
|
<ClusterIconMenu
|
|
@@ -592,6 +619,7 @@ export default {
|
|
|
592
619
|
>
|
|
593
620
|
<nuxt-link
|
|
594
621
|
class="option"
|
|
622
|
+
:class="{'active-menu-link': checkActiveRoute(a) }"
|
|
595
623
|
:to="a.to"
|
|
596
624
|
>
|
|
597
625
|
<IconOrSvg
|
|
@@ -619,6 +647,7 @@ export default {
|
|
|
619
647
|
>
|
|
620
648
|
<nuxt-link
|
|
621
649
|
class="option"
|
|
650
|
+
:class="{'active-menu-link': checkActiveRoute(a) }"
|
|
622
651
|
:to="a.to"
|
|
623
652
|
>
|
|
624
653
|
<IconOrSvg
|
|
@@ -648,6 +677,7 @@ export default {
|
|
|
648
677
|
>
|
|
649
678
|
<nuxt-link
|
|
650
679
|
class="option"
|
|
680
|
+
:class="{'active-menu-link': checkActiveRoute(a) }"
|
|
651
681
|
:to="a.to"
|
|
652
682
|
>
|
|
653
683
|
<IconOrSvg
|
|
@@ -867,7 +897,7 @@ export default {
|
|
|
867
897
|
margin-right: 16px;
|
|
868
898
|
}
|
|
869
899
|
|
|
870
|
-
&.
|
|
900
|
+
&.router-link-active, &.active-menu-link {
|
|
871
901
|
background: var(--primary-hover-bg);
|
|
872
902
|
color: var(--primary-hover-text);
|
|
873
903
|
|
|
@@ -991,7 +1021,7 @@ export default {
|
|
|
991
1021
|
font-size: 14px;
|
|
992
1022
|
}
|
|
993
1023
|
|
|
994
|
-
.
|
|
1024
|
+
.router-link-active {
|
|
995
1025
|
&:hover {
|
|
996
1026
|
text-decoration: none;
|
|
997
1027
|
}
|
package/components/nav/Type.vue
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import Favorite from '@shell/components/nav/Favorite';
|
|
3
3
|
import { FAVORITE, USED } from '@shell/store/type-map';
|
|
4
|
-
import { linkActiveClass } from '@shell/config/router';
|
|
5
4
|
|
|
6
5
|
const showFavoritesFor = [FAVORITE, USED];
|
|
7
6
|
|
|
@@ -31,7 +30,6 @@ export default {
|
|
|
31
30
|
near: false,
|
|
32
31
|
over: false,
|
|
33
32
|
menuPath: this.type.route ? this.$router.resolve(this.type.route)?.route?.path : undefined,
|
|
34
|
-
linkActiveClass
|
|
35
33
|
};
|
|
36
34
|
},
|
|
37
35
|
|
|
@@ -134,7 +132,7 @@ export default {
|
|
|
134
132
|
:to="type.route"
|
|
135
133
|
tag="li"
|
|
136
134
|
class="child nav-type"
|
|
137
|
-
:class="{'root': isRoot, [`depth-${depth}`]: true,
|
|
135
|
+
:class="{'root': isRoot, [`depth-${depth}`]: true, 'router-link-active': isCurrent}"
|
|
138
136
|
:exact="type.exact"
|
|
139
137
|
>
|
|
140
138
|
<a
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { saveAs } from 'file-saver';
|
|
3
3
|
import AnsiUp from 'ansi_up';
|
|
4
4
|
import { addParams } from '@shell/utils/url';
|
|
5
|
-
import {
|
|
5
|
+
import { base64DecodeToBuffer } from '@shell/utils/crypto';
|
|
6
6
|
import { LOGS_RANGE, LOGS_TIME, LOGS_WRAP } from '@shell/store/prefs';
|
|
7
7
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
8
8
|
import { Checkbox } from '@components/Form/Checkbox';
|
|
@@ -25,6 +25,61 @@ import Window from './Window';
|
|
|
25
25
|
|
|
26
26
|
let lastId = 1;
|
|
27
27
|
const ansiup = new AnsiUp();
|
|
28
|
+
// Convert arrayBuffer(Uint8Array) to string
|
|
29
|
+
// ref: https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder
|
|
30
|
+
// ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/of
|
|
31
|
+
const ab2str = (input, outputEncoding = 'utf8') => {
|
|
32
|
+
const decoder = new TextDecoder(outputEncoding);
|
|
33
|
+
|
|
34
|
+
return decoder.decode(input);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// The utf-8 encoded messages pushed by websocket may truncate multi-byte utf-8 characters,
|
|
38
|
+
// which causes the front-end to be unable to parse the truncated multi-byte utf-8 characters in the previous and next messages when decoding.
|
|
39
|
+
// Therefore, we need to determine whether the last 4 bytes of the current pushed message contain incomplete utf-8 encoded characters.
|
|
40
|
+
// ref: https://en.wikipedia.org/wiki/UTF-8#Encoding
|
|
41
|
+
const isLogTruncated = (uint8ArrayBuffer) => {
|
|
42
|
+
const len = uint8ArrayBuffer.length;
|
|
43
|
+
const count = Math.min(4, len);
|
|
44
|
+
let isTruncated = false;
|
|
45
|
+
|
|
46
|
+
// Parses the last ${count} bytes of the array to determine if there are any truncated utf-8 characters.
|
|
47
|
+
for ( let i = 0; i < count; i++ ) {
|
|
48
|
+
const a = uint8ArrayBuffer[len - (1 + i)];
|
|
49
|
+
|
|
50
|
+
// 1 byte utf-8 character in binary form: 0xxxxxxxxx
|
|
51
|
+
if ((a & 0b10000000) === 0b00000000) {
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
// Multi-byte utf-8 character, intermediate binary form: 10xxxxxx
|
|
55
|
+
if ((a & 0b11000000) === 0b10000000) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
// 2 byte utf-8 character in binary form: 110xxxxx 10xxxxxx
|
|
59
|
+
if ((a & 0b11100000) === 0b11000000) {
|
|
60
|
+
if ( i !== 1) {
|
|
61
|
+
isTruncated = true;
|
|
62
|
+
}
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
// 3 byte utf-8 character in binary form: 1110xxxx 10xxxxxx 10xxxxxx
|
|
66
|
+
if ((a & 0b11110000) === 0b11100000) {
|
|
67
|
+
if (i !== 2) {
|
|
68
|
+
isTruncated = true;
|
|
69
|
+
}
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
// 4 byte utf-8 character in binary form: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
|
73
|
+
if ((a & 0b11111000) === 0b11110000) {
|
|
74
|
+
if (i !== 3) {
|
|
75
|
+
isTruncated = true;
|
|
76
|
+
}
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return isTruncated;
|
|
82
|
+
};
|
|
28
83
|
|
|
29
84
|
export default {
|
|
30
85
|
components: {
|
|
@@ -273,11 +328,54 @@ export default {
|
|
|
273
328
|
console.error('Connect Error', e); // eslint-disable-line no-console
|
|
274
329
|
});
|
|
275
330
|
|
|
331
|
+
let logBuffer = [];
|
|
332
|
+
let truncatedLog = '';
|
|
333
|
+
|
|
276
334
|
this.socket.addEventListener(EVENT_MESSAGE, (e) => {
|
|
277
|
-
const
|
|
335
|
+
const decodedData = e.detail?.data || '';
|
|
336
|
+
const replacedData = decodedData.replace(/[-_]/g, (char) => char === '-' ? '+' : '/');
|
|
337
|
+
const b = base64DecodeToBuffer(replacedData);
|
|
338
|
+
const isTruncated = isLogTruncated(b);
|
|
339
|
+
|
|
340
|
+
if (isTruncated === true) {
|
|
341
|
+
logBuffer.push(...b);
|
|
342
|
+
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
let d;
|
|
347
|
+
|
|
348
|
+
// If the logBuffer is not empty,
|
|
349
|
+
// there are truncated utf-8 characters in the previous message
|
|
350
|
+
// that need to be merged with the current message before decoding.
|
|
351
|
+
if (logBuffer.length > 0) {
|
|
352
|
+
// Convert arrayBuffer(Uint8Array) to string
|
|
353
|
+
// ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/of
|
|
354
|
+
d = ab2str(Uint8Array.of(...logBuffer, ...b));
|
|
355
|
+
logBuffer = [];
|
|
356
|
+
} else {
|
|
357
|
+
d = b.toString();
|
|
358
|
+
}
|
|
359
|
+
let data = d;
|
|
278
360
|
|
|
361
|
+
if (truncatedLog) {
|
|
362
|
+
data = `${ truncatedLog }${ d }`;
|
|
363
|
+
truncatedLog = '';
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (!d.endsWith('\n')) {
|
|
367
|
+
const lines = data.split(/\n/);
|
|
368
|
+
|
|
369
|
+
if (lines.length === 1) {
|
|
370
|
+
truncatedLog = data;
|
|
371
|
+
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
data = lines.slice(0, -1).join('\n');
|
|
375
|
+
truncatedLog = lines.slice(-1);
|
|
376
|
+
}
|
|
279
377
|
// Websocket message may contain multiple lines - loop through each line, one by one
|
|
280
|
-
data.split('\n').forEach((line) => {
|
|
378
|
+
data.split('\n').filter((line) => line).forEach((line) => {
|
|
281
379
|
let msg = line;
|
|
282
380
|
let time = null;
|
|
283
381
|
|
|
@@ -79,6 +79,7 @@ export default {
|
|
|
79
79
|
fitAddon: null,
|
|
80
80
|
searchAddon: null,
|
|
81
81
|
webglAddon: null,
|
|
82
|
+
canvasAddon: null,
|
|
82
83
|
isOpen: false,
|
|
83
84
|
isOpening: false,
|
|
84
85
|
backlog: [],
|
|
@@ -155,6 +156,7 @@ export default {
|
|
|
155
156
|
webgl: import(/* webpackChunkName: "xterm" */ 'xterm-addon-webgl'),
|
|
156
157
|
weblinks: import(/* webpackChunkName: "xterm" */ 'xterm-addon-web-links'),
|
|
157
158
|
search: import(/* webpackChunkName: "xterm" */ 'xterm-addon-search'),
|
|
159
|
+
canvas: import(/* webpackChunkName: "xterm" */ 'xterm-addon-canvas')
|
|
158
160
|
});
|
|
159
161
|
|
|
160
162
|
const terminal = new xterm.Terminal({
|
|
@@ -171,10 +173,11 @@ export default {
|
|
|
171
173
|
this.searchAddon = new addons.search.SearchAddon();
|
|
172
174
|
|
|
173
175
|
try {
|
|
174
|
-
this.webglAddon = new addons.webgl.
|
|
176
|
+
this.webglAddon = new addons.webgl.WebglAddon();
|
|
175
177
|
} catch (e) {
|
|
176
178
|
// Some browsers (Safari) don't support the webgl renderer, so don't use it.
|
|
177
179
|
this.webglAddon = null;
|
|
180
|
+
this.canvasAddon = new addons.canvas.CanvasAddon();
|
|
178
181
|
}
|
|
179
182
|
|
|
180
183
|
terminal.loadAddon(this.fitAddon);
|
|
@@ -184,6 +187,8 @@ export default {
|
|
|
184
187
|
|
|
185
188
|
if (this.webglAddon) {
|
|
186
189
|
terminal.loadAddon(this.webglAddon);
|
|
190
|
+
} else {
|
|
191
|
+
terminal.loadAddon(this.canvasAddon);
|
|
187
192
|
}
|
|
188
193
|
|
|
189
194
|
this.fit();
|