dashboard-shell-shell 1.0.121 → 1.0.1000000081
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/.DS_Store +0 -0
- package/assets/brand/harvester/favicon.png +0 -0
- package/assets/brand/suse/favicon.png +0 -0
- package/assets/icons/iconfont.css +19 -3
- package/assets/icons/iconfont.js +1 -1
- package/assets/icons/iconfont.json +28 -0
- package/assets/icons/iconfont.ttf +0 -0
- package/assets/icons/iconfont.woff +0 -0
- package/assets/icons/iconfont.woff2 +0 -0
- package/assets/images/pl/half-logo.svg +2 -23
- package/assets/styles/base/_functions.scss +0 -0
- package/assets/styles/base/_mixins.scss +0 -0
- package/assets/styles/base/_variables.scss +1 -1
- package/assets/styles/global/_labeled-input.scss +0 -1
- package/assets/styles/global/_layout.scss +1 -1
- package/assets/styles/global/_select.scss +4 -2
- package/assets/styles/global/_table.scss +5 -0
- package/assets/styles/vendor/vue-select.scss +2 -1
- package/assets/translations/en-us.yaml +1 -1
- package/assets/translations/zh-hans.yaml +25 -15
- package/chart/monitoring/index.vue +3 -1
- package/chart/monitoring/prometheus/index.vue +13 -10
- package/cloud-credential/aws.vue +2 -0
- package/components/ActionDropdown.vue +1 -1
- package/components/ActionDropdownShell.vue +71 -0
- package/components/ActionMenu.vue +2 -2
- package/components/ActionMenuShell.vue +3 -0
- package/components/AppModal.vue +84 -8
- package/components/AssignTo.vue +25 -11
- package/components/AsyncButton.vue +24 -7
- package/components/BannerGraphic.vue +1 -0
- package/components/ButtonDropdown.vue +26 -4
- package/components/ButtonGroup.vue +4 -0
- package/components/ButtonMultiAction.vue +1 -0
- package/components/CodeMirror.vue +19 -6
- package/components/CommunityLinks.vue +3 -3
- package/components/ConsumptionGauge.vue +24 -5
- package/components/CopyToClipboardText.vue +2 -1
- package/components/CruResource.vue +13 -7
- package/components/CruResourceFooter.vue +2 -2
- package/components/DashboardOptions.vue +29 -17
- package/components/DetailText.vue +5 -0
- package/components/DisableAuthProviderModal.vue +1 -0
- package/components/DotState.vue +84 -0
- package/components/ExplorerMembers.vue +1 -1
- package/components/ExplorerProjectsNamespaces.vue +89 -16
- package/components/FixedBanner.vue +19 -12
- package/components/GlobalRoleBindings.vue +5 -1
- package/components/GrafanaDashboard.vue +4 -4
- package/components/GrowlManager.vue +4 -1
- package/components/HardwareResourceGauge.vue +39 -3
- package/components/InfoBox.vue +3 -3
- package/components/InputOrDisplay.vue +28 -2
- package/components/LabelValue.vue +20 -1
- package/components/LandingPagePreference.vue +5 -3
- package/components/LocaleSelector.vue +39 -93
- package/components/ModalManager.vue +55 -0
- package/components/ModalWithCard.vue +13 -3
- package/components/MoveModal.vue +1 -0
- package/components/PodSecurityAdmission.vue +1 -1
- package/components/PromptChangePassword.vue +1 -1
- package/components/PromptModal.vue +16 -3
- package/components/PromptRemove.vue +29 -9
- package/components/PromptRestore.vue +1 -0
- package/components/ResourceCancelModal.vue +1 -0
- package/components/ResourceDetail/Masthead.vue +52 -17
- package/components/ResourceDetail/__tests__/Masthead.test.ts +5 -1
- package/components/ResourceDetail/index.vue +54 -16
- package/components/ResourceList/Masthead.vue +9 -4
- package/components/ResourceList/index.vue +4 -3
- package/components/ResourceTable.vue +1 -0
- package/components/SideNav.vue +20 -15
- package/components/SlideInPanelManager.vue +126 -0
- package/components/SortableTable/THead.vue +10 -4
- package/components/SortableTable/actions.js +1 -1
- package/components/SortableTable/index.vue +540 -554
- package/components/SortableTable/selection.js +2 -13
- package/components/StatusBadge.vue +77 -0
- package/components/Tabbed/Tab.vue +3 -3
- package/components/Tabbed/index.vue +47 -29
- package/components/Wizard.vue +2 -2
- package/components/YamlEditor.vue +1 -1
- package/components/__tests__/AsyncButton.test.ts +2 -2
- package/components/__tests__/FixedBanner.test.ts +3 -3
- package/components/__tests__/ModalManager.spec.ts +176 -0
- package/components/__tests__/SlideInPanelManager.spec.ts +166 -0
- package/components/auth/Principal.vue +10 -3
- package/components/auth/RoleDetailEdit.vue +1 -1
- package/components/auth/__tests__/RoleDetailEdit.test.ts +3 -2
- package/components/form/ArrayList.vue +123 -85
- package/components/form/ArrayListGrouped.vue +10 -2
- package/components/form/ArrayListSelect.vue +1 -1
- package/components/form/Command.vue +6 -15
- package/components/form/EnvVars.vue +16 -8
- package/components/form/Footer.vue +10 -7
- package/components/form/HealthCheck.vue +3 -3
- package/components/form/HookOption.vue +11 -16
- package/components/form/InputWithSelect.vue +6 -5
- package/components/form/KeyValue.vue +39 -10
- package/components/form/LabeledSelect.vue +73 -77
- package/components/form/Labels.vue +6 -3
- package/components/form/LifecycleHooks.vue +3 -3
- package/components/form/MatchExpressions.vue +42 -17
- package/components/form/NameNsDescription.vue +163 -116
- package/components/form/Networking.vue +20 -12
- package/components/form/NodeAffinity.vue +31 -23
- package/components/form/NodeScheduling.vue +13 -3
- package/components/form/Password.vue +11 -5
- package/components/form/PodAffinity.vue +47 -48
- package/components/form/Probe.vue +68 -66
- package/components/form/ResourceQuota/Namespace.vue +4 -4
- package/components/form/ResourceQuota/NamespaceRow.vue +5 -7
- package/components/form/ResourceQuota/Project.vue +9 -5
- package/components/form/ResourceQuota/ProjectRow.vue +4 -6
- package/components/form/ResourceSelector.vue +7 -9
- package/components/form/SSHKnownHosts/KnownHostsEditDialog.vue +6 -3
- package/components/form/SSHKnownHosts/__tests__/KnownHostsEditDialog.test.ts +12 -1
- package/components/form/SSHKnownHosts/index.vue +16 -2
- package/components/form/Security.vue +54 -56
- package/components/form/Select.vue +44 -7
- package/components/form/ShellInput.vue +5 -1
- package/components/form/SimpleSecretSelector.vue +29 -9
- package/components/form/Tolerations.vue +5 -1
- package/components/form/UnitInput.vue +10 -5
- package/components/form/ValueFromResource.vue +134 -121
- package/components/form/WorkloadPorts.vue +18 -18
- package/components/form/__tests__/ArrayList.test.ts +5 -2
- package/components/form/__tests__/MatchExpressions.test.ts +12 -12
- package/components/form/__tests__/NameNsDescription.test.ts +115 -14
- package/components/form/__tests__/Probe.test.ts +12 -8
- package/components/form/__tests__/SSHKnownHosts.test.ts +11 -0
- package/components/form/__tests__/Select.test.ts +37 -0
- package/components/form/__tests__/UnitInput.test.ts +4 -5
- package/components/formatter/BadgeStateFormatter.vue +8 -5
- package/components/formatter/InternalExternalIP.vue +2 -0
- package/components/formatter/LiveDate.vue +3 -3
- package/components/formatter/SecretData.vue +20 -7
- package/components/nav/Favorite.vue +5 -1
- package/components/nav/Group.vue +18 -4
- package/components/nav/Header.vue +39 -13
- package/components/nav/Jump.vue +7 -0
- package/components/nav/NamespaceFilter.vue +21 -11
- package/components/nav/Pinned.vue +1 -1
- package/components/nav/TopLevelMenu.vue +5 -17
- package/components/nav/Type.vue +30 -33
- package/components/nav/__tests__/TopLevelMenu.test.ts +0 -40
- package/components/rancherResourceDetail/Masthead.vue +769 -0
- package/components/rancherResourceDetail/__tests__/Masthead.test.ts +65 -0
- package/components/rancherResourceDetail/index.vue +591 -0
- package/components/rancherResourceList/Masthead-btn.vue +225 -0
- package/components/rancherResourceList/Masthead.vue +375 -0
- package/components/rancherResourceList/ResourceLoadingIndicator.vue +140 -0
- package/components/rancherResourceList/index.vue +307 -0
- package/components/rancherResourceList/resource-list.config.js +7 -0
- package/components/rancherResourceTable.vue +783 -0
- package/components/rancherSortableTable/THead.vue +561 -0
- package/components/rancherSortableTable/actions.js +153 -0
- package/components/rancherSortableTable/advanced-filtering.js +272 -0
- package/components/rancherSortableTable/debug.js +117 -0
- package/components/rancherSortableTable/filtering.js +290 -0
- package/components/rancherSortableTable/grouping.js +48 -0
- package/components/rancherSortableTable/index.vue +2712 -0
- package/components/rancherSortableTable/paging.js +155 -0
- package/components/rancherSortableTable/selection.js +629 -0
- package/components/rancherSortableTable/sortable-config.ts +4 -0
- package/components/rancherSortableTable/sorting.js +129 -0
- package/components/templates/blank.vue +4 -1
- package/components/templates/default.vue +8 -0
- package/components/templates/home.vue +10 -1
- package/components/templates/plain.vue +10 -1
- package/composables/focusTrap.ts +11 -3
- package/composables/useRuntimeFlag.ts +29 -0
- package/config/private-label.js +15 -10
- package/config/router/routes.js +21 -13
- package/config/store.js +4 -0
- package/config/table-headers.js +3 -2
- package/config/uiplugins.js +5 -1
- package/core/plugin-routes.ts +5 -115
- package/core/plugins.js +1 -1
- package/core/types.ts +23 -2
- package/detail/__tests__/autoscaling.horizontalpodautoscaler.test.ts +84 -23
- package/detail/autoscaling.horizontalpodautoscaler/index.vue +13 -3
- package/detail/provisioning.cattle.io.cluster.vue +72 -6
- package/dialog/AddCustomBadgeDialog.vue +1 -0
- package/dialog/DeactivateDriverDialog.vue +5 -4
- package/dialog/ForceMachineRemoveDialog.vue +6 -3
- package/dialog/GitRepoForceUpdateDialog.vue +1 -1
- package/dialog/ScalePoolDownDialog.vue +2 -2
- package/edit/__tests__/monitoring.coreos.com.prometheusrule.test.ts +16 -3
- package/edit/auth/__tests__/oidc.test.ts +162 -88
- package/edit/auth/azuread.vue +2 -1
- package/edit/auth/github.vue +1 -1
- package/edit/auth/googleoauth.vue +5 -1
- package/edit/auth/ldap/__tests__/config.test.ts +0 -14
- package/edit/auth/ldap/config.vue +0 -24
- package/edit/auth/ldap/index.vue +1 -1
- package/edit/auth/oidc.vue +39 -6
- package/edit/auth/saml.vue +1 -1
- package/edit/autoscaling.horizontalpodautoscaler/metric-identifier.vue +5 -2
- package/edit/cloudcredential.vue +24 -9
- package/edit/fleet.cattle.io.clustergroup.vue +5 -3
- package/edit/fleet.cattle.io.gitrepo.vue +2 -0
- package/edit/logging-flow/Match.vue +1 -1
- package/edit/logging.banzaicloud.io.output/__tests__/logging.banzaicloud.io.output.test.ts +40 -9
- package/edit/management.cattle.io.user.vue +28 -3
- package/edit/monitoring.coreos.com.alertmanagerconfig/auth.vue +19 -19
- package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +31 -31
- package/edit/monitoring.coreos.com.alertmanagerconfig/routeConfig.vue +36 -12
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/email.vue +6 -6
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/opsgenie.vue +10 -10
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/pagerduty.vue +4 -4
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/slack.vue +4 -4
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/webhook.vue +1 -1
- package/edit/monitoring.coreos.com.receiver/auth.vue +29 -29
- package/edit/monitoring.coreos.com.receiver/types/email.vue +6 -6
- package/edit/monitoring.coreos.com.receiver/types/opsgenie.vue +10 -10
- package/edit/monitoring.coreos.com.receiver/types/pagerduty.vue +5 -5
- package/edit/monitoring.coreos.com.receiver/types/slack.vue +4 -4
- package/edit/namespace.vue +1 -2
- package/edit/networking.k8s.io.ingress/IngressClass.vue +7 -3
- package/edit/networking.k8s.io.ingress/RulePath.vue +1 -1
- package/edit/networking.k8s.io.ingress/__tests__/IngressClass.test.ts +58 -0
- package/edit/persistentvolume/__tests__/persistentvolume.test.ts +14 -2
- package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +4 -1
- package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +26 -9
- package/edit/provisioning.cattle.io.cluster/__tests__/Advanced.test.ts +8 -10
- package/edit/provisioning.cattle.io.cluster/rke2.vue +31 -40
- package/edit/provisioning.cattle.io.cluster/tabs/Advanced.vue +5 -2
- package/edit/provisioning.cattle.io.cluster/tabs/AgentConfiguration.vue +6 -1
- package/edit/provisioning.cattle.io.cluster/tabs/MachinePool.vue +33 -2
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +3 -3
- package/edit/service.vue +0 -3
- package/edit/token.vue +32 -11
- package/edit/workload/Job.vue +6 -6
- package/edit/workload/__tests__/Job.test.ts +0 -1
- package/edit/workload/index.vue +1 -0
- package/edit/workload/mixins/workload.js +3 -3
- package/initialize/install-plugins.js +2 -1
- package/list/harvesterhci.io.management.cluster.vue +4 -1
- package/list/management.cattle.io.feature.vue +1 -0
- package/list/namespace.vue +3 -1
- package/list/provisioning.cattle.io.cluster.vue +20 -12
- package/list/workload.vue +7 -6
- package/machine-config/__tests__/vmwarevsphere.test.ts +48 -3
- package/machine-config/azure.vue +16 -4
- package/machine-config/vmwarevsphere.vue +16 -0
- package/mixins/resource-fetch.js +2 -1
- package/models/__tests__/logging.banzaicloud.io.flow.test.ts +88 -0
- package/models/__tests__/namespace.test.ts +25 -1
- package/models/cloudcredential.js +5 -0
- package/models/kontainerdriver.js +6 -3
- package/models/logging.banzaicloud.io.flow.js +2 -1
- package/models/management.cattle.io.node.js +3 -3
- package/models/management.cattle.io.setting.js +2 -1
- package/models/namespace.js +4 -5
- package/models/nodedriver.js +6 -3
- package/models/storage.k8s.io.storageclass.js +2 -2
- package/models/workload.js +4 -1
- package/package.json +1 -1
- package/pages/about.vue +16 -8
- package/pages/account/index.vue +80 -24
- package/pages/account/pri.vue +229 -0
- package/pages/auth/login.vue +195 -44
- package/pages/auth/logout.vue +4 -1
- package/pages/auth/setup.vue +144 -19
- package/pages/auth/verify.vue +13 -8
- package/pages/auth copy/login.vue +595 -0
- package/pages/auth copy/logout.vue +47 -0
- package/pages/auth copy/setup.vue +523 -0
- package/pages/auth copy/verify.vue +203 -0
- package/pages/c/_cluster/_product/namespaces.vue +5 -5
- package/pages/c/_cluster/apps/charts/chart.vue +1 -1
- package/pages/c/_cluster/apps/charts/install.vue +26 -26
- package/pages/c/_cluster/auth/config/index.vue +10 -12
- package/pages/c/_cluster/explorer/EventsTable.vue +38 -33
- package/pages/c/_cluster/explorer/index.vue +17 -15
- package/pages/c/_cluster/istio/index.vue +2 -2
- package/pages/c/_cluster/longhorn/index.vue +1 -1
- package/pages/c/_cluster/monitoring/index.vue +1 -1
- package/pages/c/_cluster/monitoring/monitor/_namespace/_id.vue +4 -2
- package/pages/c/_cluster/monitoring/monitor/create.vue +4 -2
- package/pages/c/_cluster/monitoring/monitor/index.vue +2 -2
- package/pages/c/_cluster/monitoring/route-receiver/_id.vue +4 -2
- package/pages/c/_cluster/monitoring/route-receiver/create.vue +5 -2
- package/pages/c/_cluster/neuvector/index.vue +1 -1
- package/pages/c/_cluster/settings/brand.vue +3 -3
- package/pages/c/_cluster/uiplugins/CatalogList/index.vue +8 -10
- package/pages/diagnostic.vue +59 -11
- package/pages/fail-whale.vue +14 -8
- package/pages/home.vue +24 -18
- package/pages/prefs.vue +9 -7
- package/pages/support/index.vue +4 -1
- package/pkg/tsconfig.json +9 -9
- package/pkg/vue.config.js +1 -1
- package/plugins/dashboard-store/normalize.js +3 -1
- package/plugins/dashboard-store/resource-class.js +31 -29
- package/plugins/internal-api/index.ts +37 -0
- package/plugins/internal-api/shared/base-api.ts +13 -0
- package/plugins/internal-api/shell/shell.api.ts +108 -0
- package/promptRemove/management.cattle.io.fleetworkspace.vue +1 -1
- package/promptRemove/management.cattle.io.globalrole.vue +1 -1
- package/promptRemove/management.cattle.io.project.vue +2 -2
- package/promptRemove/management.cattle.io.roletemplate.vue +1 -1
- package/promptRemove/pod.vue +1 -1
- package/public/index.html +2 -1
- package/rancher-components/BadgeState/BadgeState.vue +5 -1
- package/rancher-components/Banner/Banner.vue +8 -2
- package/rancher-components/Card/Card.vue +3 -6
- package/rancher-components/Form/Checkbox/Checkbox.vue +4 -0
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +5 -2
- package/rancher-components/Form/Radio/RadioButton.vue +3 -3
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +1 -5
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +9 -4
- package/rancher-components/RcDropdown/RcDropdownItem.vue +1 -2
- package/rancher-components/RcDropdown/RcDropdownMenu.vue +7 -3
- package/rancher-components/RcDropdown/types.ts +1 -0
- package/scripts/clean +0 -0
- package/scripts/extension/bundle +20 -0
- package/scripts/extension/helm/charts/ui-plugin-server/templates/_helpers.tpl +2 -2
- package/scripts/extension/helm/charts/ui-plugin-server/templates/cr.yaml +2 -1
- package/scripts/extension/helm/charts/ui-plugin-server/values.yaml +2 -0
- package/scripts/extension/helm/scripts/package +0 -0
- package/scripts/extension/helm/scripts/patch +0 -0
- package/scripts/extension/helm/scripts/version +0 -0
- package/scripts/extension/helmpatch +44 -31
- package/scripts/extension/parse-tag-name +0 -0
- package/scripts/extension/publish +12 -12
- package/scripts/publish-shell.sh +18 -23
- package/scripts/serve-pkgs +0 -0
- package/scripts/sync-shell-deps +0 -0
- package/scripts/test-plugins-build.sh +4 -6
- package/scripts/typegen.sh +28 -46
- package/server/har-file.js +25 -3
- package/static/favicon.ico +0 -0
- package/static/favicon.png +0 -0
- package/static/loading-indicator.html +2 -2
- package/store/aws.js +9 -2
- package/store/features.js +2 -1
- package/store/i18n.js +3 -3
- package/store/modal.ts +71 -0
- package/store/slideInPanel.ts +47 -0
- package/store/type-map.js +2 -1
- package/types/cloud-shell/index.d.ts +11014 -0
- package/types/global-vue.d.ts +5 -0
- package/types/internal-api/shell/growl.d.ts +25 -0
- package/types/internal-api/shell/modal.d.ts +77 -0
- package/types/internal-api/shell/slideIn.d.ts +15 -0
- package/types/shell/index.d.ts +118 -128
- package/types/vue-shim.d.ts +4 -1
- package/utils/__tests__/object.test.ts +38 -4
- package/utils/__tests__/string.test.ts +2 -2
- package/utils/auth.js +1 -0
- package/utils/banners.js +0 -45
- package/utils/cluster.js +35 -0
- package/utils/color.js +9 -8
- package/utils/error.js +61 -3
- package/utils/errorTranslate.json +450 -30
- package/utils/object.js +46 -6
- package/utils/router.js +22 -1
- package/utils/select.js +26 -3
- package/utils/string.js +9 -8
- package/utils/title.ts +1 -1
- package/utils/validators/machine-pool.ts +20 -0
- package/vue.config.js +7 -2
- package/components/formatter/ExtensionCache.vue +0 -74
- package/components/formatter/Port.vue +0 -24
- package/components/formatter/SecretType.vue +0 -41
- package/types/resources/fleet.d.ts +0 -57
- package/types/resources/pod-security-admission.ts +0 -36
- package/types/resources/settings.d.ts +0 -93
- package/types/resources/userPreferences.d.ts +0 -13
- package/types/vue-shim.d +0 -20
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { sortBy } from '@shell/utils/sort';
|
|
2
|
+
import { uniq } from '@shell/utils/array';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Always sort by something, this is the best guess on properties
|
|
6
|
+
*
|
|
7
|
+
* Can be overriden
|
|
8
|
+
*/
|
|
9
|
+
const DEFAULT_MANDATORY_SORT = ['nameSort', 'id'];
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
computed: {
|
|
13
|
+
sortFields() {
|
|
14
|
+
let fromGroup = ( this.groupBy ? this.groupSort || this.groupBy : null) || [];
|
|
15
|
+
let fromColumn = [];
|
|
16
|
+
|
|
17
|
+
const column = (this.columns || this.headers).find((x) => x && x.name && x.name.toLowerCase() === this.sortBy.toLowerCase());
|
|
18
|
+
|
|
19
|
+
if ( this.sortBy && column && column.sort ) {
|
|
20
|
+
fromColumn = column.sort;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if ( !Array.isArray(fromGroup) ) {
|
|
24
|
+
fromGroup = [fromGroup];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if ( !Array.isArray(fromColumn) ) {
|
|
28
|
+
fromColumn = [fromColumn];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// return the sorting based on grouping, user selection and fallback
|
|
32
|
+
return uniq([...fromGroup, ...fromColumn].concat(...(this.mandatorySort || DEFAULT_MANDATORY_SORT)));
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
arrangedRows() {
|
|
36
|
+
if (this.externalPaginationEnabled) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let key;
|
|
41
|
+
|
|
42
|
+
// Why is sortGeneration needed when we have sortGenerationFn?
|
|
43
|
+
// 1. sortGenerationFn is called when this fn is kicked off and returns latest and greatest string (given things like namespace)
|
|
44
|
+
// 2. it can be kicked off with stale rows... which is then stored against latest string
|
|
45
|
+
// 3. when updates rows comes through... sortGenerationFn returns same string
|
|
46
|
+
// 4. we therefor think nothing has changed and return old, stale rows
|
|
47
|
+
// This is avoided by outside storage of sortGeneration against rows
|
|
48
|
+
// (it would be nice to have that hash on the rows object itself, but it gets messy)
|
|
49
|
+
const sortGenerationKey = this.sortGeneration || this.sortGenerationFn?.apply(this);
|
|
50
|
+
|
|
51
|
+
if ( sortGenerationKey) {
|
|
52
|
+
key = `${ sortGenerationKey }/${ this.rows.length }/${ this.descending }/${ this.sortFields.join(',') }`;
|
|
53
|
+
if ( this.cacheKey === key ) {
|
|
54
|
+
return this.cachedRows;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const out = sortBy(this.rows, this.sortFields, this.descending);
|
|
59
|
+
|
|
60
|
+
if ( key ) {
|
|
61
|
+
this.cacheKey = key;
|
|
62
|
+
this.cachedRows = out;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return out;
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
data() {
|
|
70
|
+
let sortBy = null;
|
|
71
|
+
|
|
72
|
+
this._defaultSortBy = this.defaultSortBy;
|
|
73
|
+
|
|
74
|
+
// Try to find a reasonable default sort
|
|
75
|
+
if ( !this._defaultSortBy ) {
|
|
76
|
+
const markedColumn = this.headers.find((x) => !!x.defaultSort);
|
|
77
|
+
const nameColumn = this.headers.find( (x) => x.name === 'name');
|
|
78
|
+
|
|
79
|
+
if ( markedColumn ) {
|
|
80
|
+
this._defaultSortBy = markedColumn.name;
|
|
81
|
+
} else if ( nameColumn ) {
|
|
82
|
+
// Use the name column if there is one
|
|
83
|
+
this._defaultSortBy = nameColumn.name;
|
|
84
|
+
} else {
|
|
85
|
+
// The first column that isn't state
|
|
86
|
+
const first = this.headers.filter( (x) => x.name !== 'state' )[0];
|
|
87
|
+
|
|
88
|
+
if ( first ) {
|
|
89
|
+
this._defaultSortBy = first.name;
|
|
90
|
+
} else {
|
|
91
|
+
// I give up
|
|
92
|
+
this._defaultSortBy = 'id';
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// If the sort column doesn't exist or isn't specified, use default
|
|
98
|
+
if ( !sortBy || !this.headers.find((x) => x.name === sortBy ) ) {
|
|
99
|
+
sortBy = this._defaultSortBy;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
sortBy,
|
|
104
|
+
descending: false,
|
|
105
|
+
cachedRows: null,
|
|
106
|
+
cacheKey: null,
|
|
107
|
+
};
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
methods: {
|
|
111
|
+
changeSort(sort, desc) {
|
|
112
|
+
this.sortBy = sort;
|
|
113
|
+
this.descending = desc;
|
|
114
|
+
|
|
115
|
+
// Always go back to the first page when the sort is changed
|
|
116
|
+
this.setPage(1);
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
watch: {
|
|
121
|
+
sortFields() {
|
|
122
|
+
this.debouncedPaginationChanged();
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
descending() {
|
|
126
|
+
this.debouncedPaginationChanged();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
};
|
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
} from '@shell/store/prefs';
|
|
8
8
|
import ActionMenu from '@shell/components/ActionMenu';
|
|
9
9
|
import GrowlManager from '@shell/components/GrowlManager';
|
|
10
|
+
import ModalManager from '@shell/components/ModalManager';
|
|
11
|
+
import SlideInPanelManager from '@shell/components/SlideInPanelManager';
|
|
10
12
|
import WindowManager from '@shell/components/nav/WindowManager';
|
|
11
13
|
import PromptRemove from '@shell/components/PromptRemove';
|
|
12
14
|
import PromptRestore from '@shell/components/PromptRestore';
|
|
@@ -39,6 +41,8 @@ export default {
|
|
|
39
41
|
Header,
|
|
40
42
|
ActionMenu,
|
|
41
43
|
GrowlManager,
|
|
44
|
+
ModalManager,
|
|
45
|
+
SlideInPanelManager,
|
|
42
46
|
WindowManager,
|
|
43
47
|
FixedBanner,
|
|
44
48
|
AwsComplianceBanner,
|
|
@@ -198,6 +202,7 @@ export default {
|
|
|
198
202
|
<main
|
|
199
203
|
v-if="clusterAndRouteReady"
|
|
200
204
|
class="main-layout"
|
|
205
|
+
:aria-label="t('layouts.default')"
|
|
201
206
|
>
|
|
202
207
|
<router-view
|
|
203
208
|
:key="$route.path"
|
|
@@ -208,6 +213,7 @@ export default {
|
|
|
208
213
|
<PromptRestore />
|
|
209
214
|
<AssignTo />
|
|
210
215
|
<PromptModal />
|
|
216
|
+
<ModalManager />
|
|
211
217
|
<button
|
|
212
218
|
v-if="noLocaleShortcut"
|
|
213
219
|
v-shortkey.once="['shift','l']"
|
|
@@ -235,6 +241,7 @@ export default {
|
|
|
235
241
|
<main
|
|
236
242
|
v-else-if="unmatchedRoute"
|
|
237
243
|
class="main-layout"
|
|
244
|
+
:aria-label="t('layouts.default')"
|
|
238
245
|
>
|
|
239
246
|
<router-view
|
|
240
247
|
:key="$route.path"
|
|
@@ -257,6 +264,7 @@ export default {
|
|
|
257
264
|
</div>
|
|
258
265
|
<FixedBanner :footer="true" />
|
|
259
266
|
<GrowlManager />
|
|
267
|
+
<SlideInPanelManager />
|
|
260
268
|
<Inactivity />
|
|
261
269
|
<DraggableZone ref="draggableZone" />
|
|
262
270
|
</div>
|
|
@@ -3,6 +3,8 @@ import Header from '@shell/components/nav/Header';
|
|
|
3
3
|
import Brand from '@shell/mixins/brand';
|
|
4
4
|
import FixedBanner from '@shell/components/FixedBanner';
|
|
5
5
|
import GrowlManager from '@shell/components/GrowlManager';
|
|
6
|
+
import ModalManager from '@shell/components/ModalManager';
|
|
7
|
+
import SlideInPanelManager from '@shell/components/SlideInPanelManager';
|
|
6
8
|
import { mapPref, THEME_SHORTCUT } from '@shell/store/prefs';
|
|
7
9
|
import AwsComplianceBanner from '@shell/components/AwsComplianceBanner';
|
|
8
10
|
import AzureWarning from '@shell/components/auth/AzureWarning';
|
|
@@ -17,6 +19,8 @@ export default {
|
|
|
17
19
|
Header,
|
|
18
20
|
FixedBanner,
|
|
19
21
|
GrowlManager,
|
|
22
|
+
ModalManager,
|
|
23
|
+
SlideInPanelManager,
|
|
20
24
|
AzureWarning,
|
|
21
25
|
AwsComplianceBanner,
|
|
22
26
|
Inactivity,
|
|
@@ -58,6 +62,7 @@ export default {
|
|
|
58
62
|
<AwsComplianceBanner />
|
|
59
63
|
<AzureWarning />
|
|
60
64
|
<PromptModal />
|
|
65
|
+
<ModalManager />
|
|
61
66
|
<div
|
|
62
67
|
class="dashboard-content"
|
|
63
68
|
:class="{'dashboard-padding-left': showTopLevelMenu}"
|
|
@@ -67,7 +72,10 @@ export default {
|
|
|
67
72
|
:simple="true"
|
|
68
73
|
/>
|
|
69
74
|
|
|
70
|
-
<main
|
|
75
|
+
<main
|
|
76
|
+
class="main-layout"
|
|
77
|
+
:aria-label="t('layouts.home')"
|
|
78
|
+
>
|
|
71
79
|
<router-view
|
|
72
80
|
:key="$route.path"
|
|
73
81
|
class="outlet"
|
|
@@ -76,6 +84,7 @@ export default {
|
|
|
76
84
|
</div>
|
|
77
85
|
<FixedBanner :footer="true" />
|
|
78
86
|
<GrowlManager />
|
|
87
|
+
<SlideInPanelManager />
|
|
79
88
|
<button
|
|
80
89
|
v-if="themeShortcut"
|
|
81
90
|
v-shortkey.once="['shift','t']"
|
|
@@ -8,6 +8,8 @@ import IndentedPanel from '@shell/components/IndentedPanel';
|
|
|
8
8
|
import Brand from '@shell/mixins/brand';
|
|
9
9
|
import FixedBanner from '@shell/components/FixedBanner';
|
|
10
10
|
import GrowlManager from '@shell/components/GrowlManager';
|
|
11
|
+
import ModalManager from '@shell/components/ModalManager';
|
|
12
|
+
import SlideInPanelManager from '@shell/components/SlideInPanelManager';
|
|
11
13
|
import AwsComplianceBanner from '@shell/components/AwsComplianceBanner';
|
|
12
14
|
import AzureWarning from '@shell/components/auth/AzureWarning';
|
|
13
15
|
import BrowserTabVisibility from '@shell/mixins/browser-tab-visibility';
|
|
@@ -26,6 +28,8 @@ export default {
|
|
|
26
28
|
PromptModal,
|
|
27
29
|
FixedBanner,
|
|
28
30
|
GrowlManager,
|
|
31
|
+
ModalManager,
|
|
32
|
+
SlideInPanelManager,
|
|
29
33
|
AwsComplianceBanner,
|
|
30
34
|
AzureWarning,
|
|
31
35
|
Inactivity
|
|
@@ -68,7 +72,10 @@ export default {
|
|
|
68
72
|
:class="{'dashboard-padding-left': showTopLevelMenu}"
|
|
69
73
|
>
|
|
70
74
|
<Header :simple="true" />
|
|
71
|
-
<main
|
|
75
|
+
<main
|
|
76
|
+
class="main-layout"
|
|
77
|
+
:aria-label="t('layouts.plain')"
|
|
78
|
+
>
|
|
72
79
|
<IndentedPanel class="pt-20">
|
|
73
80
|
<router-view
|
|
74
81
|
:key="$route.path"
|
|
@@ -78,6 +85,7 @@ export default {
|
|
|
78
85
|
<ActionMenu />
|
|
79
86
|
<PromptRemove />
|
|
80
87
|
<PromptModal />
|
|
88
|
+
<ModalManager />
|
|
81
89
|
<AssignTo />
|
|
82
90
|
<button
|
|
83
91
|
v-if="themeShortcut"
|
|
@@ -96,6 +104,7 @@ export default {
|
|
|
96
104
|
|
|
97
105
|
<FixedBanner :footer="true" />
|
|
98
106
|
<GrowlManager />
|
|
107
|
+
<SlideInPanelManager />
|
|
99
108
|
<Inactivity />
|
|
100
109
|
</div>
|
|
101
110
|
</template>
|
package/composables/focusTrap.ts
CHANGED
|
@@ -46,12 +46,12 @@ export function useBasicSetupFocusTrap(focusElement: string | HTMLElement, opts:
|
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
export function useWatcherBasedSetupFocusTrapWithDestroyIncluded(watchVar:any, focusElement: string | HTMLElement, opts:any = DEFAULT_FOCUS_TRAP_OPTS) {
|
|
49
|
+
export function useWatcherBasedSetupFocusTrapWithDestroyIncluded(watchVar:any, focusElement: string | HTMLElement, opts:any = DEFAULT_FOCUS_TRAP_OPTS, useUnmountHook = false) {
|
|
50
50
|
let focusTrapInstance: FocusTrap;
|
|
51
51
|
let focusEl;
|
|
52
52
|
|
|
53
53
|
watch(watchVar, (neu) => {
|
|
54
|
-
if (neu) {
|
|
54
|
+
if (neu && !focusTrapInstance) {
|
|
55
55
|
nextTick(() => {
|
|
56
56
|
focusEl = typeof focusElement === 'string' ? document.querySelector(focusElement) as HTMLElement : focusElement;
|
|
57
57
|
|
|
@@ -61,8 +61,16 @@ export function useWatcherBasedSetupFocusTrapWithDestroyIncluded(watchVar:any, f
|
|
|
61
61
|
focusTrapInstance.activate();
|
|
62
62
|
});
|
|
63
63
|
});
|
|
64
|
-
} else if (!neu && Object.keys(focusTrapInstance).length) {
|
|
64
|
+
} else if (!neu && Object.keys(focusTrapInstance).length && !useUnmountHook) {
|
|
65
65
|
focusTrapInstance.deactivate();
|
|
66
66
|
}
|
|
67
67
|
});
|
|
68
|
+
|
|
69
|
+
if (useUnmountHook) {
|
|
70
|
+
onBeforeUnmount(() => {
|
|
71
|
+
if (Object.keys(focusTrapInstance).length) {
|
|
72
|
+
focusTrapInstance.deactivate();
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
68
76
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { computed } from 'vue';
|
|
2
|
+
import { Store } from 'vuex';
|
|
3
|
+
import semver from 'semver';
|
|
4
|
+
|
|
5
|
+
import { getVersionInfo } from '@shell/utils/version';
|
|
6
|
+
|
|
7
|
+
let store: Store<any>;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Initializes runtime flags.
|
|
11
|
+
* @param vuexStore The Vuex store instance
|
|
12
|
+
*/
|
|
13
|
+
export const useRuntimeFlag = (vuexStore: Store<any>) => {
|
|
14
|
+
store = vuexStore;
|
|
15
|
+
|
|
16
|
+
return { featureDropdownMenu };
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Check if the dropdown menu feature is enabled
|
|
21
|
+
* @returns A boolean indicating whether the dropdownMenu feature is enabled.
|
|
22
|
+
*/
|
|
23
|
+
const featureDropdownMenu = computed(() => {
|
|
24
|
+
const { fullVersion } = getVersionInfo(store);
|
|
25
|
+
|
|
26
|
+
const coerced = semver.coerce(fullVersion) || { version: '0.0.0' };
|
|
27
|
+
|
|
28
|
+
return semver.gte(coerced.version, '2.11.0');
|
|
29
|
+
});
|
package/config/private-label.js
CHANGED
|
@@ -58,17 +58,22 @@ export function matches(pl) {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export function getVendor() {
|
|
61
|
-
if ( vendor === SETTING.PL_RANCHER_VALUE ) {
|
|
62
|
-
// Custom vendor override based on brand
|
|
63
|
-
if (brand && CUSTOM_VENDOR[brand]) {
|
|
64
|
-
return CUSTOM_VENDOR[brand];
|
|
65
|
-
}
|
|
66
61
|
|
|
67
|
-
return STANDARD_VENDOR;
|
|
68
|
-
}
|
|
69
62
|
|
|
70
|
-
return
|
|
63
|
+
return 'HCI';
|
|
71
64
|
}
|
|
65
|
+
// export function getVendor() {
|
|
66
|
+
// if ( vendor === SETTING.PL_RANCHER_VALUE ) {
|
|
67
|
+
// // Custom vendor override based on brand
|
|
68
|
+
// if (brand && CUSTOM_VENDOR[brand]) {
|
|
69
|
+
// return CUSTOM_VENDOR[brand];
|
|
70
|
+
// }
|
|
71
|
+
|
|
72
|
+
// return STANDARD_VENDOR;
|
|
73
|
+
// }
|
|
74
|
+
|
|
75
|
+
// return vendor;
|
|
76
|
+
// }
|
|
72
77
|
|
|
73
78
|
export function getProduct() {
|
|
74
79
|
return product;
|
|
@@ -80,13 +85,13 @@ export function setTitle() {
|
|
|
80
85
|
if (v === 'Harvester') {
|
|
81
86
|
const ico = require(`~shell/assets/images/pl/harvester.png`);
|
|
82
87
|
|
|
83
|
-
document.title = '
|
|
88
|
+
document.title = 'HCI';
|
|
84
89
|
const link = document.createElement('link');
|
|
85
90
|
|
|
86
91
|
link.hid = 'icon';
|
|
87
92
|
link.rel = 'icon';
|
|
88
93
|
link.type = 'image/x-icon';
|
|
89
|
-
link.
|
|
94
|
+
link.href = ico;
|
|
90
95
|
const head = document.getElementsByTagName('head')[0];
|
|
91
96
|
|
|
92
97
|
head.appendChild(link);
|
package/config/router/routes.js
CHANGED
|
@@ -23,6 +23,7 @@ const interopDefault = (promise) => promise.then((page) => page.default || page)
|
|
|
23
23
|
*/
|
|
24
24
|
export default [
|
|
25
25
|
{
|
|
26
|
+
name: 'root',
|
|
26
27
|
path: '/',
|
|
27
28
|
component: () => interopDefault(import('@shell/pages/index.vue')),
|
|
28
29
|
meta: { requiresAuthentication: true },
|
|
@@ -275,14 +276,24 @@ export default [
|
|
|
275
276
|
name: 'c-cluster-neuvector',
|
|
276
277
|
meta: { ...installRedirectRouteMeta(NEUVECTOR_NAME, NEUVECTOR_CHART_NAME, undefined, false) }
|
|
277
278
|
}, {
|
|
278
|
-
path:
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
279
|
+
path: '/c/:cluster/apps/charts',
|
|
280
|
+
children: [
|
|
281
|
+
{
|
|
282
|
+
path: '',
|
|
283
|
+
component: () => interopDefault(import('@shell/pages/c/_cluster/apps/charts/index.vue')),
|
|
284
|
+
name: 'c-cluster-apps-charts'
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
path: 'chart',
|
|
288
|
+
component: () => interopDefault(import('@shell/pages/c/_cluster/apps/charts/chart.vue')),
|
|
289
|
+
name: 'c-cluster-apps-charts-chart',
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
path: 'install',
|
|
293
|
+
component: () => interopDefault(import('@shell/pages/c/_cluster/apps/charts/install.vue')),
|
|
294
|
+
name: 'c-cluster-apps-charts-install',
|
|
295
|
+
},
|
|
296
|
+
]
|
|
286
297
|
},
|
|
287
298
|
{
|
|
288
299
|
path: '/c/:cluster/auth/config',
|
|
@@ -352,10 +363,6 @@ export default [
|
|
|
352
363
|
path: '/c/:cluster/settings/performance',
|
|
353
364
|
component: () => interopDefault(import('@shell/pages/c/_cluster/settings/performance.vue')),
|
|
354
365
|
name: 'c-cluster-settings-performance'
|
|
355
|
-
}, {
|
|
356
|
-
path: '/c/:cluster/apps/charts/chart',
|
|
357
|
-
component: () => interopDefault(import('@shell/pages/c/_cluster/apps/charts/chart.vue')),
|
|
358
|
-
name: 'c-cluster-apps-charts-chart'
|
|
359
366
|
}, {
|
|
360
367
|
path: '/c/:cluster/auth/group.principal/assign-edit',
|
|
361
368
|
component: () => interopDefault(import('@shell/pages/c/_cluster/auth/group.principal/assign-edit.vue')),
|
|
@@ -363,7 +370,8 @@ export default [
|
|
|
363
370
|
}, {
|
|
364
371
|
path: '/c/:cluster/auth/user.retention',
|
|
365
372
|
component: () => interopDefault(import('@shell/pages/c/_cluster/auth/user.retention/index.vue')),
|
|
366
|
-
name: 'c-cluster-auth-user.retention'
|
|
373
|
+
name: 'c-cluster-auth-user.retention',
|
|
374
|
+
meta: { nav: '/c/:cluster/auth/management.cattle.io.user' }
|
|
367
375
|
}, {
|
|
368
376
|
path: '/c/:cluster/manager/cloudCredential/create',
|
|
369
377
|
component: () => interopDefault(import('@shell/pages/c/_cluster/manager/cloudCredential/create.vue')),
|
package/config/store.js
CHANGED
|
@@ -27,10 +27,12 @@ let store = {};
|
|
|
27
27
|
resolveStoreModules(require('../store/growl.js'), 'growl.js');
|
|
28
28
|
resolveStoreModules(require('../store/i18n.js'), 'i18n.js');
|
|
29
29
|
resolveStoreModules(require('../store/linode.js'), 'linode.js');
|
|
30
|
+
resolveStoreModules(require('../store/modal.ts'), 'modal.ts');
|
|
30
31
|
resolveStoreModules(require('../store/plugins.js'), 'plugins.js');
|
|
31
32
|
resolveStoreModules(require('../store/pnap.js'), 'pnap.js');
|
|
32
33
|
resolveStoreModules(require('../store/prefs.js'), 'prefs.js');
|
|
33
34
|
resolveStoreModules(require('../store/resource-fetch.js'), 'resource-fetch.js');
|
|
35
|
+
resolveStoreModules(require('../store/slideInPanel.ts'), 'slideInPanel.ts');
|
|
34
36
|
resolveStoreModules(require('../store/type-map.js'), 'type-map.js');
|
|
35
37
|
resolveStoreModules(require('../store/uiplugins.ts'), 'uiplugins.ts');
|
|
36
38
|
resolveStoreModules(require('../store/wm.js'), 'wm.js');
|
|
@@ -54,10 +56,12 @@ let store = {};
|
|
|
54
56
|
'../store/i18n.js',
|
|
55
57
|
'../store/index.js',
|
|
56
58
|
'../store/linode.js',
|
|
59
|
+
'../store/modal.ts',
|
|
57
60
|
'../store/plugins.js',
|
|
58
61
|
'../store/pnap.js',
|
|
59
62
|
'../store/prefs.js',
|
|
60
63
|
'../store/resource-fetch.js',
|
|
64
|
+
'../store/slideInPanel.ts',
|
|
61
65
|
'../store/type-map.js',
|
|
62
66
|
'../store/uiplugins.ts',
|
|
63
67
|
'../store/wm.js',
|
package/config/table-headers.js
CHANGED
|
@@ -52,6 +52,7 @@ export const NAME = {
|
|
|
52
52
|
getValue: (row) => row.nameDisplay,
|
|
53
53
|
sort: ['nameSort'],
|
|
54
54
|
formatter: 'LinkDetail',
|
|
55
|
+
width: 200,
|
|
55
56
|
canBeVariable: true,
|
|
56
57
|
};
|
|
57
58
|
|
|
@@ -161,7 +162,7 @@ export const NAMESPACE = {
|
|
|
161
162
|
name: 'namespace',
|
|
162
163
|
labelKey: 'tableHeaders.namespace',
|
|
163
164
|
value: 'namespace',
|
|
164
|
-
getValue:
|
|
165
|
+
getValue: row => row && row.namespace && row.namespace.replace('harvester', 'cloud'),
|
|
165
166
|
sort: 'namespace',
|
|
166
167
|
dashIfEmpty: true,
|
|
167
168
|
};
|
|
@@ -278,7 +279,7 @@ export const NS_SNAPSHOT_QUOTA = {
|
|
|
278
279
|
labelKey: 'harvester.tableHeaders.totalSnapshotQuota',
|
|
279
280
|
value: 'snapshotSizeQuota',
|
|
280
281
|
sort: 'snapshotSizeQuota',
|
|
281
|
-
align: '
|
|
282
|
+
align: 'left',
|
|
282
283
|
formatter: 'Si',
|
|
283
284
|
formatterOpts: {
|
|
284
285
|
opts: {
|
package/config/uiplugins.js
CHANGED
|
@@ -148,7 +148,11 @@ function checkIncompatibility(currentVersion, requiredVersion, incompatibilityDa
|
|
|
148
148
|
* @returns String | Boolean
|
|
149
149
|
*/
|
|
150
150
|
export function shouldNotLoadPlugin(UIPluginResource, { rancherVersion, kubeVersion }, loadedPlugins) {
|
|
151
|
-
|
|
151
|
+
const {
|
|
152
|
+
name, version, endpoint, compressedEndpoint
|
|
153
|
+
} = UIPluginResource;
|
|
154
|
+
|
|
155
|
+
if (!name || !version || (!endpoint && !compressedEndpoint)) {
|
|
152
156
|
return 'plugins.error.generic';
|
|
153
157
|
}
|
|
154
158
|
|
package/core/plugin-routes.ts
CHANGED
|
@@ -22,123 +22,13 @@ export class PluginRoutes {
|
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
public addRoutes(
|
|
26
|
-
|
|
27
|
-
...(this.router.options.routes || [])
|
|
28
|
-
];
|
|
29
|
-
|
|
30
|
-
// Need to take into account if routes are being replaced
|
|
31
|
-
// Despite what the docs say, routes are not replaced, so we use a workaround
|
|
32
|
-
// Remove all routes that are being replaced
|
|
33
|
-
const newRoutes = newRouteInfos.map((ri) => ri.route);
|
|
34
|
-
|
|
35
|
-
this.forEachNestedRoutes(newRoutes, (route: RouteRecordRaw) => {
|
|
36
|
-
// Patch colliding legacy routes that start /:product
|
|
37
|
-
if (route.path?.startsWith('/:product')) {
|
|
38
|
-
// Legacy pattern used by extensions - routes may collide, so modify them not to
|
|
39
|
-
let productName;
|
|
40
|
-
|
|
41
|
-
// If the route has a name (which is always the case for the extensions we have written), use it to get the product name
|
|
42
|
-
if (route.name && typeof route.name === 'string') {
|
|
43
|
-
const nameParts = route.name.split('-');
|
|
44
|
-
|
|
45
|
-
// First part of the route name is the product name
|
|
46
|
-
productName = nameParts[0];
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Use the plugin name as the product, if the route does not have a name
|
|
50
|
-
productName = productName || plugin.name;
|
|
51
|
-
|
|
52
|
-
// Replace the path - removing :product and using the actual product name instead - this avoids route collisions
|
|
53
|
-
route.path = `/${ productName }${ route.path.substr(9) }`;
|
|
54
|
-
route.meta = route.meta || {};
|
|
55
|
-
|
|
56
|
-
route.meta.product = route.meta.product || productName;
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
this.updateMatcher(newRouteInfos, allRoutes);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
private updateMatcher(newRoutes: RouteInfo[], allRoutes: RouteRecordRaw[]) {
|
|
64
|
-
// Note - Always use a new router and replace the existing router's matching
|
|
65
|
-
// Using the existing router and adding routes to it will force nuxt middleware to
|
|
66
|
-
// execute many times (nuxt middleware boils down to route.beforeEach). This issue was seen refreshing in a harvester cluster with a
|
|
67
|
-
// dynamically loaded cluster
|
|
68
|
-
|
|
69
|
-
if (newRoutes.length === 0) {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const orderedPluginRoutes: RouteRecordRaw[] = [];
|
|
74
|
-
|
|
75
|
-
// separate plugin routes that have parent and not, you want to push the new routes in REVERSE order to the front of the existing list so that the order of routes specified by the extension is preserved
|
|
76
|
-
newRoutes.reverse().forEach((routeInfo: RouteInfo) => {
|
|
77
|
-
let foundParentRoute;
|
|
78
|
-
|
|
25
|
+
public addRoutes(newRouteInfos: RouteInfo[]) {
|
|
26
|
+
newRouteInfos.forEach((routeInfo) => {
|
|
79
27
|
if (routeInfo.parent) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
foundParentRoute.children = foundParentRoute?.children || [];
|
|
84
|
-
foundParentRoute.children.unshift(routeInfo.route);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (!foundParentRoute) {
|
|
89
|
-
orderedPluginRoutes.unshift(routeInfo.route);
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
this.router.clearRoutes();
|
|
94
|
-
|
|
95
|
-
const allRoutesToAdd = [...orderedPluginRoutes, ...allRoutes];
|
|
96
|
-
|
|
97
|
-
allRoutesToAdd.forEach((route) => this.router.addRoute(route));
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Traverse the entire tree of nested routes
|
|
102
|
-
*
|
|
103
|
-
* @param routes The routes we wish to traverse through
|
|
104
|
-
* @param fn -> Return true if you'd like to break the loop early (small)
|
|
105
|
-
* @returns {@boolean} -> Returns true if breaking early
|
|
106
|
-
*/
|
|
107
|
-
private forEachNestedRoutes(
|
|
108
|
-
routes: RouteRecordRaw[] = [],
|
|
109
|
-
fn: (route: RouteRecordRaw) => boolean | undefined | void
|
|
110
|
-
) {
|
|
111
|
-
for (let i = 0; i < routes.length; ++i) {
|
|
112
|
-
const route = routes[i];
|
|
113
|
-
const result = fn(route);
|
|
114
|
-
|
|
115
|
-
if (result || this.forEachNestedRoutes(route.children, fn)) {
|
|
116
|
-
return true;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Find a route that matches the criteria defined by fn.
|
|
123
|
-
*
|
|
124
|
-
* @param routes The routes we wish to search through
|
|
125
|
-
* @param fn -> Returns true if the passed in route matches the expected criteria
|
|
126
|
-
* @returns The found route or undefined
|
|
127
|
-
*/
|
|
128
|
-
private findInNestedRoutes(
|
|
129
|
-
routes: RouteRecordRaw[] = [],
|
|
130
|
-
fn: (route: RouteRecordRaw) => boolean
|
|
131
|
-
): RouteRecordRaw | undefined {
|
|
132
|
-
let found: RouteRecordRaw | undefined;
|
|
133
|
-
|
|
134
|
-
this.forEachNestedRoutes(routes, (route) => {
|
|
135
|
-
if (fn(route)) {
|
|
136
|
-
found = route;
|
|
137
|
-
|
|
138
|
-
return true;
|
|
28
|
+
this.router.addRoute(routeInfo.parent, routeInfo.route);
|
|
29
|
+
} else {
|
|
30
|
+
this.router.addRoute(routeInfo.route);
|
|
139
31
|
}
|
|
140
32
|
});
|
|
141
|
-
|
|
142
|
-
return found;
|
|
143
33
|
}
|
|
144
34
|
}
|
package/core/plugins.js
CHANGED