@rancher/shell 3.0.8-rc.7 → 3.0.8-rc.9
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/brand/suse/dark/rancher-logo.svg +1 -64
- package/assets/translations/en-us.yaml +9 -1
- package/components/BackLink.vue +8 -0
- package/components/BannerGraphic.vue +1 -5
- package/components/BrandImage.vue +17 -6
- package/components/Cron/CronExpressionEditor.vue +1 -1
- package/components/Cron/CronExpressionEditorModal.vue +1 -1
- package/components/Drawer/Chrome.vue +2 -6
- package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +4 -9
- package/components/Drawer/ResourceDetailDrawer/YamlTab.vue +3 -8
- package/components/Drawer/ResourceDetailDrawer/composables.ts +3 -4
- package/components/Drawer/ResourceDetailDrawer/index.vue +4 -9
- package/components/Drawer/ResourceDetailDrawer/types.ts +17 -0
- package/components/Drawer/types.ts +3 -0
- package/components/PaginatedResourceTable.vue +2 -6
- package/components/Questions/__tests__/index.test.ts +159 -0
- package/components/Resource/Detail/Metadata/Annotations/index.vue +2 -2
- package/components/Resource/Detail/Metadata/Labels/index.vue +2 -2
- package/components/Resource/Detail/Metadata/composables.ts +9 -9
- package/components/Resource/Detail/Metadata/index.vue +3 -3
- package/components/Resource/Detail/TitleBar/composables.ts +2 -1
- package/components/Resource/Detail/composables.ts +12 -0
- package/components/Tabbed/__tests__/index.test.ts +86 -0
- package/components/auth/SelectPrincipal.vue +24 -6
- package/components/auth/__tests__/SelectPrincipal.test.ts +119 -0
- package/components/formatter/InternalExternalIP.vue +4 -1
- package/components/formatter/__tests__/InternalExternalIP.test.ts +1 -1
- package/components/nav/Header.vue +1 -2
- package/components/nav/TopLevelMenu.helper.ts +16 -6
- package/components/templates/standalone.vue +1 -1
- package/composables/useI18n.ts +10 -1
- package/config/__test__/uiplugins.test.ts +309 -0
- package/config/labels-annotations.js +1 -0
- package/config/product/explorer.js +3 -1
- package/config/router/routes.js +6 -2
- package/config/types.js +7 -0
- package/config/uiplugins.js +46 -2
- package/core/__test__/extension-manager-impl.test.js +236 -0
- package/core/extension-manager-impl.js +23 -6
- package/core/types-provisioning.ts +1 -1
- package/detail/provisioning.cattle.io.cluster.vue +1 -0
- package/dialog/DeveloperLoadExtensionDialog.vue +12 -3
- package/dialog/RollbackWorkloadDialog.vue +2 -5
- package/edit/__tests__/fleet.cattle.io.helmop.test.ts +2 -2
- package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -0
- package/edit/configmap.vue +1 -0
- package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
- package/edit/fleet.cattle.io.helmop.vue +6 -6
- package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
- package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
- package/edit/logging-flow/index.vue +1 -0
- package/edit/logging.banzaicloud.io.output/index.vue +1 -0
- package/edit/management.cattle.io.fleetworkspace.vue +1 -1
- package/edit/management.cattle.io.project.vue +1 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +4 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +2 -1
- package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
- package/edit/monitoring.coreos.com.receiver/index.vue +2 -1
- package/edit/monitoring.coreos.com.route.vue +1 -1
- package/edit/namespace.vue +1 -0
- package/edit/networking.istio.io.destinationrule/index.vue +1 -0
- package/edit/networking.k8s.io.ingress/index.vue +1 -0
- package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +1 -0
- package/edit/networking.k8s.io.networkpolicy/index.vue +1 -0
- package/edit/node.vue +1 -0
- package/edit/persistentvolume/index.vue +27 -22
- package/edit/persistentvolume/plugins/awsElasticBlockStore.vue +13 -14
- package/edit/persistentvolume/plugins/azureDisk.vue +49 -48
- package/edit/persistentvolume/plugins/azureFile.vue +15 -14
- package/edit/persistentvolume/plugins/cephfs.vue +15 -14
- package/edit/persistentvolume/plugins/cinder.vue +15 -14
- package/edit/persistentvolume/plugins/csi.vue +18 -16
- package/edit/persistentvolume/plugins/fc.vue +13 -14
- package/edit/persistentvolume/plugins/flexVolume.vue +15 -14
- package/edit/persistentvolume/plugins/flocker.vue +1 -3
- package/edit/persistentvolume/plugins/gcePersistentDisk.vue +13 -14
- package/edit/persistentvolume/plugins/glusterfs.vue +15 -14
- package/edit/persistentvolume/plugins/hostPath.vue +40 -39
- package/edit/persistentvolume/plugins/iscsi.vue +13 -14
- package/edit/persistentvolume/plugins/local.vue +1 -3
- package/edit/persistentvolume/plugins/longhorn.vue +23 -22
- package/edit/persistentvolume/plugins/nfs.vue +15 -14
- package/edit/persistentvolume/plugins/photonPersistentDisk.vue +1 -14
- package/edit/persistentvolume/plugins/portworxVolume.vue +15 -14
- package/edit/persistentvolume/plugins/quobyte.vue +15 -14
- package/edit/persistentvolume/plugins/rbd.vue +15 -14
- package/edit/persistentvolume/plugins/scaleIO.vue +15 -14
- package/edit/persistentvolume/plugins/storageos.vue +15 -14
- package/edit/persistentvolume/plugins/vsphereVolume.vue +1 -3
- package/edit/provisioning.cattle.io.cluster/rke2.vue +1 -0
- package/edit/secret/index.vue +1 -1
- package/edit/service.vue +1 -0
- package/edit/serviceaccount.vue +1 -0
- package/edit/storage.k8s.io.storageclass/index.vue +1 -0
- package/edit/workload/index.vue +2 -1
- package/edit/workload/mixins/workload.js +1 -1
- package/initialize/App.vue +4 -4
- package/initialize/install-plugins.js +17 -2
- package/machine-config/components/EC2Networking.vue +5 -2
- package/machine-config/components/__tests__/EC2Networking.test.ts +24 -0
- package/mixins/__tests__/brand.spec.ts +2 -2
- package/mixins/__tests__/chart.test.ts +21 -0
- package/mixins/brand.js +1 -7
- package/mixins/chart.js +7 -1
- package/mixins/create-edit-view/index.js +5 -0
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +112 -5
- package/models/management.cattle.io.cluster.js +21 -3
- package/models/provisioning.cattle.io.cluster.js +21 -9
- package/package.json +5 -4
- package/pages/auth/login.vue +1 -3
- package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +135 -0
- package/pages/c/_cluster/apps/charts/chart.vue +33 -15
- package/pages/c/_cluster/explorer/index.vue +8 -6
- package/pages/c/_cluster/manager/hostedprovider/index.vue +12 -6
- package/pages/c/_cluster/settings/brand.vue +1 -1
- package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +7 -0
- package/pages/c/_cluster/uiplugins/catalogs.vue +147 -0
- package/pages/c/_cluster/uiplugins/index.vue +126 -184
- package/pages/home.vue +5 -2
- package/pkg/dynamic-importer.lib.js +4 -0
- package/plugins/dashboard-client-init.js +3 -0
- package/plugins/dashboard-store/getters.js +18 -1
- package/plugins/dashboard-store/resource-class.js +4 -4
- package/plugins/i18n.js +8 -0
- package/plugins/steve/__tests__/steve-pagination-utils.test.ts +333 -0
- package/plugins/steve/steve-pagination-utils.ts +39 -20
- package/plugins/steve/subscribe.js +17 -9
- package/plugins/subscribe-events.ts +4 -2
- package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +6 -42
- package/rancher-components/Pill/RcStatusBadge/index.ts +0 -1
- package/rancher-components/Pill/RcStatusBadge/types.ts +1 -1
- package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +5 -28
- package/rancher-components/Pill/RcStatusIndicator/types.ts +2 -1
- package/rancher-components/Pill/types.ts +0 -1
- package/rancher-components/RcIcon/RcIcon.test.ts +51 -0
- package/rancher-components/RcIcon/RcIcon.vue +46 -0
- package/rancher-components/RcIcon/index.ts +1 -0
- package/rancher-components/RcIcon/types.ts +160 -0
- package/rancher-components/utils/status.test.ts +67 -0
- package/rancher-components/utils/status.ts +77 -0
- package/scripts/typegen.sh +1 -0
- package/store/action-menu.js +8 -0
- package/store/auth.js +3 -3
- package/store/catalog.js +6 -0
- package/store/index.js +36 -17
- package/store/prefs.js +4 -5
- package/store/type-map.js +3 -3
- package/store/wm.ts +4 -4
- package/types/shell/index.d.ts +39 -2
- package/types/store/__tests__/pagination.types.spec.ts +137 -0
- package/types/store/pagination.types.ts +157 -9
- package/types/store/subscribe-events.types.ts +8 -1
- package/types/store/subscribe.types.ts +1 -0
- package/utils/__tests__/provider.test.ts +98 -0
- package/utils/__tests__/selector-typed.test.ts +263 -0
- package/utils/__tests__/version.test.ts +19 -1
- package/utils/back-off.ts +3 -3
- package/utils/color.js +1 -1
- package/utils/dynamic-content/__tests__/info.test.ts +21 -9
- package/utils/dynamic-content/info.ts +44 -2
- package/utils/favicon.js +4 -4
- package/utils/pagination-wrapper.ts +12 -8
- package/utils/provider.ts +14 -0
- package/utils/selector-typed.ts +6 -2
- package/utils/version.js +15 -0
- package/plugins/nuxt-client-init.js +0 -3
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { shallowMount } from '@vue/test-utils';
|
|
2
|
+
import RcIcon from './RcIcon.vue';
|
|
3
|
+
|
|
4
|
+
describe('rcIcon.vue', () => {
|
|
5
|
+
it('renders with the correct type class and size classes', () => {
|
|
6
|
+
const wrapper = shallowMount(RcIcon, {
|
|
7
|
+
props: {
|
|
8
|
+
size: 'medium',
|
|
9
|
+
type: 'search',
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
expect(wrapper.classes()).toContain('icon-search');
|
|
14
|
+
expect(wrapper.classes()).toContain('medium');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('sets aria-hidden to true by default', () => {
|
|
18
|
+
const wrapper = shallowMount(RcIcon, {
|
|
19
|
+
props: {
|
|
20
|
+
size: 'medium',
|
|
21
|
+
type: 'search',
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
expect(wrapper.attributes('aria-hidden')).toBe('true');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('sets aria-hidden to false when explicitly provided', () => {
|
|
29
|
+
const wrapper = shallowMount(RcIcon, {
|
|
30
|
+
props: {
|
|
31
|
+
size: 'medium',
|
|
32
|
+
type: 'search',
|
|
33
|
+
ariaHidden: false,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
expect(wrapper.attributes('aria-hidden')).toBe('false');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('sets aria-hidden to true when explicitly provided', () => {
|
|
41
|
+
const wrapper = shallowMount(RcIcon, {
|
|
42
|
+
props: {
|
|
43
|
+
size: 'medium',
|
|
44
|
+
type: 'search',
|
|
45
|
+
ariaHidden: true,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
expect(wrapper.attributes('aria-hidden')).toBe('true');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { RcIconProps, RcIconType, RcIconSize } from '@components/RcIcon/types';
|
|
3
|
+
import { computed } from 'vue';
|
|
4
|
+
import { useStatusColors } from '@components/utils/status';
|
|
5
|
+
const props = withDefaults(defineProps<RcIconProps>(), { size: 'small', ariaHidden: true });
|
|
6
|
+
const fontSize = computed(() => {
|
|
7
|
+
return RcIconSize[props.size];
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const iconClass = computed(() => {
|
|
11
|
+
return RcIconType[props.type];
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const status = computed(() => {
|
|
15
|
+
if (props.status && props.status !== 'inherit') {
|
|
16
|
+
return props.status;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return 'none';
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const { textColor } = useStatusColors({ status: status.value }, 'outlined');
|
|
23
|
+
|
|
24
|
+
const color = computed(() => {
|
|
25
|
+
if (props.status === 'inherit') {
|
|
26
|
+
return 'inherit';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return textColor.value;
|
|
30
|
+
});
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<template>
|
|
34
|
+
<i
|
|
35
|
+
class="rc-icon"
|
|
36
|
+
:class="{[props.size]: true, [iconClass]: true}"
|
|
37
|
+
:aria-hidden="props.ariaHidden"
|
|
38
|
+
/>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<style lang="scss" scoped>
|
|
42
|
+
.rc-icon {
|
|
43
|
+
font-size: v-bind(fontSize);
|
|
44
|
+
color: v-bind(color);
|
|
45
|
+
}
|
|
46
|
+
</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as RcIcon } from './RcIcon.vue';
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { Status } from '../utils/status';
|
|
2
|
+
|
|
3
|
+
export const RcIconType = {
|
|
4
|
+
actions: 'icon-actions',
|
|
5
|
+
ai: 'icon-ai',
|
|
6
|
+
'alert-alt': 'icon-alert-alt',
|
|
7
|
+
alert: 'icon-alert',
|
|
8
|
+
anchor: 'icon-anchor',
|
|
9
|
+
apple: 'icon-apple',
|
|
10
|
+
application: 'icon-application',
|
|
11
|
+
apps: 'icon-apps',
|
|
12
|
+
archive: 'icon-archive',
|
|
13
|
+
'backup-restore': 'icon-backup-restore',
|
|
14
|
+
backup: 'icon-backup',
|
|
15
|
+
'brush-icon': 'icon-brush-icon',
|
|
16
|
+
'category-alt': 'icon-category-alt',
|
|
17
|
+
checkmark: 'icon-checkmark',
|
|
18
|
+
'chevron-beginning': 'icon-chevron-beginning',
|
|
19
|
+
'chevron-down': 'icon-chevron-down',
|
|
20
|
+
'chevron-end': 'icon-chevron-end',
|
|
21
|
+
'chevron-left': 'icon-chevron-left',
|
|
22
|
+
'chevron-right': 'icon-chevron-right',
|
|
23
|
+
'chevron-up': 'icon-chevron-up',
|
|
24
|
+
'circle-plus': 'icon-circle-plus',
|
|
25
|
+
cis: 'icon-cis',
|
|
26
|
+
close: 'icon-close',
|
|
27
|
+
'cluster-management': 'icon-cluster-management',
|
|
28
|
+
cluster: 'icon-cluster',
|
|
29
|
+
code: 'icon-code',
|
|
30
|
+
comment: 'icon-comment',
|
|
31
|
+
commit: 'icon-commit',
|
|
32
|
+
compass: 'icon-compass',
|
|
33
|
+
'confirmation-alt': 'icon-confirmation-alt',
|
|
34
|
+
copy: 'icon-copy',
|
|
35
|
+
dashboard: 'icon-dashboard',
|
|
36
|
+
dock: 'icon-dock',
|
|
37
|
+
docker: 'icon-docker',
|
|
38
|
+
document: 'icon-document',
|
|
39
|
+
'dot-half': 'icon-dot-half',
|
|
40
|
+
'dot-open': 'icon-dot-open',
|
|
41
|
+
dot: 'icon-dot',
|
|
42
|
+
'downgrade-alt': 'icon-downgrade-alt',
|
|
43
|
+
download: 'icon-download',
|
|
44
|
+
edit: 'icon-edit',
|
|
45
|
+
elemental: 'icon-elemental',
|
|
46
|
+
endpoints_connected: 'icon-endpoints_connected',
|
|
47
|
+
endpoints_disconnected: 'icon-endpoints_disconnected',
|
|
48
|
+
epinio: 'icon-epinio',
|
|
49
|
+
error: 'icon-error',
|
|
50
|
+
explore: 'icon-explore',
|
|
51
|
+
extension: 'icon-extension',
|
|
52
|
+
'external-link': 'icon-external-link',
|
|
53
|
+
file: 'icon-file',
|
|
54
|
+
filter_alt: 'icon-filter_alt',
|
|
55
|
+
flask: 'icon-flask',
|
|
56
|
+
fleet: 'icon-fleet',
|
|
57
|
+
folder: 'icon-folder',
|
|
58
|
+
fork: 'icon-fork',
|
|
59
|
+
gatekeeper: 'icon-gatekeeper',
|
|
60
|
+
gear: 'icon-gear',
|
|
61
|
+
gemini: 'icon-gemini',
|
|
62
|
+
git: 'icon-git',
|
|
63
|
+
github: 'icon-github',
|
|
64
|
+
gitlab: 'icon-gitlab',
|
|
65
|
+
globe: 'icon-globe',
|
|
66
|
+
groups: 'icon-groups',
|
|
67
|
+
harvester: 'icon-harvester',
|
|
68
|
+
helm: 'icon-helm',
|
|
69
|
+
hide: 'icon-hide',
|
|
70
|
+
history: 'icon-history',
|
|
71
|
+
home: 'icon-home',
|
|
72
|
+
'info-circle': 'icon-info-circle',
|
|
73
|
+
info: 'icon-info',
|
|
74
|
+
init_container: 'icon-init_container',
|
|
75
|
+
istio: 'icon-istio',
|
|
76
|
+
keyboard: 'icon-keyboard',
|
|
77
|
+
keyboard_tab: 'icon-keyboard_tab',
|
|
78
|
+
linux: 'icon-linux',
|
|
79
|
+
'list-flat': 'icon-list-flat',
|
|
80
|
+
'list-grouped': 'icon-list-grouped',
|
|
81
|
+
lock: 'icon-lock',
|
|
82
|
+
logging: 'icon-logging',
|
|
83
|
+
longhorn: 'icon-longhorn',
|
|
84
|
+
marketplace: 'icon-marketplace',
|
|
85
|
+
menu: 'icon-menu',
|
|
86
|
+
minus: 'icon-minus',
|
|
87
|
+
monitoring: 'icon-monitoring',
|
|
88
|
+
more: 'icon-more',
|
|
89
|
+
namespace: 'icon-namespace',
|
|
90
|
+
notifier: 'icon-notifier',
|
|
91
|
+
'notify-announcement': 'icon-notify-announcement',
|
|
92
|
+
'notify-bell': 'icon-notify-bell',
|
|
93
|
+
'notify-busy': 'icon-notify-busy',
|
|
94
|
+
'notify-error': 'icon-notify-error',
|
|
95
|
+
'notify-info': 'icon-notify-info',
|
|
96
|
+
'notify-tick': 'icon-notify-tick',
|
|
97
|
+
'notify-warning': 'icon-notify-warning',
|
|
98
|
+
ollama: 'icon-ollama',
|
|
99
|
+
openai: 'icon-openai',
|
|
100
|
+
'os-management': 'icon-os-management',
|
|
101
|
+
pause: 'icon-pause',
|
|
102
|
+
'pin-outlined': 'icon-pin-outlined',
|
|
103
|
+
pin: 'icon-pin',
|
|
104
|
+
pipeline: 'icon-pipeline',
|
|
105
|
+
play: 'icon-play',
|
|
106
|
+
plus: 'icon-plus',
|
|
107
|
+
pod_security: 'icon-pod_security',
|
|
108
|
+
print: 'icon-print',
|
|
109
|
+
'question-mark': 'icon-question-mark',
|
|
110
|
+
'quick-action': 'icon-quick-action',
|
|
111
|
+
'rancher-desktop': 'icon-rancher-desktop',
|
|
112
|
+
'rancher-observability': 'icon-rancher-observability',
|
|
113
|
+
'refresh-alt': 'icon-refresh-alt',
|
|
114
|
+
refresh: 'icon-refresh',
|
|
115
|
+
'repository-alt': 'icon-repository-alt',
|
|
116
|
+
repository: 'icon-repository',
|
|
117
|
+
rio: 'icon-rio',
|
|
118
|
+
'role-binding': 'icon-role-binding',
|
|
119
|
+
search: 'icon-search',
|
|
120
|
+
send: 'icon-send',
|
|
121
|
+
service: 'icon-service',
|
|
122
|
+
show: 'icon-show',
|
|
123
|
+
snapshot: 'icon-snapshot',
|
|
124
|
+
'sort-down': 'icon-sort-down',
|
|
125
|
+
'sort-up': 'icon-sort-up',
|
|
126
|
+
sort: 'icon-sort',
|
|
127
|
+
sources: 'icon-sources',
|
|
128
|
+
spinner: 'icon-spinner',
|
|
129
|
+
stackstate: 'icon-stackstate',
|
|
130
|
+
'star-open': 'icon-star-open',
|
|
131
|
+
star: 'icon-star',
|
|
132
|
+
storage: 'icon-storage',
|
|
133
|
+
'tag-alt': 'icon-tag-alt',
|
|
134
|
+
terminal: 'icon-terminal',
|
|
135
|
+
'thinking-process': 'icon-thinking-process',
|
|
136
|
+
trash: 'icon-trash',
|
|
137
|
+
unlock: 'icon-unlock',
|
|
138
|
+
'upgrade-alt': 'icon-upgrade-alt',
|
|
139
|
+
upload: 'icon-upload',
|
|
140
|
+
'user-check': 'icon-user-check',
|
|
141
|
+
'user-xmark': 'icon-user-xmark',
|
|
142
|
+
user: 'icon-user',
|
|
143
|
+
'version-alt': 'icon-version-alt',
|
|
144
|
+
warning: 'icon-warning',
|
|
145
|
+
windows: 'icon-windows',
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export const RcIconSize = {
|
|
149
|
+
large: '25px',
|
|
150
|
+
medium: '18px',
|
|
151
|
+
small: '14px',
|
|
152
|
+
none: undefined
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
export interface RcIconProps {
|
|
156
|
+
size: keyof typeof RcIconSize;
|
|
157
|
+
type: keyof typeof RcIconType;
|
|
158
|
+
ariaHidden?: boolean;
|
|
159
|
+
status?: Status | 'inherit';
|
|
160
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
|
|
2
|
+
import { reactive } from 'vue';
|
|
3
|
+
import { wrapIfVar, useStatusColors, Status } from './status';
|
|
4
|
+
|
|
5
|
+
describe('utils: status', () => {
|
|
6
|
+
describe('wrapIfVar', () => {
|
|
7
|
+
it('should wrap a CSS variable', () => {
|
|
8
|
+
const result = wrapIfVar('--rc-info');
|
|
9
|
+
|
|
10
|
+
expect(result).toBe('var(--rc-info)');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should not wrap a normal color', () => {
|
|
14
|
+
const result = wrapIfVar('red');
|
|
15
|
+
|
|
16
|
+
expect(result).toBe('red');
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
describe('useStatusColors', () => {
|
|
21
|
+
it.each([
|
|
22
|
+
'info',
|
|
23
|
+
'success',
|
|
24
|
+
'warning',
|
|
25
|
+
'error',
|
|
26
|
+
'unknown',
|
|
27
|
+
'none'
|
|
28
|
+
])('solid: should return the correct colors for status: %p', (status: Status) => {
|
|
29
|
+
const props = reactive({ status });
|
|
30
|
+
const {
|
|
31
|
+
borderColor,
|
|
32
|
+
backgroundColor,
|
|
33
|
+
textColor
|
|
34
|
+
} = useStatusColors(props, 'solid');
|
|
35
|
+
|
|
36
|
+
expect(borderColor.value).toBe(`var(--rc-${ status })`);
|
|
37
|
+
if (status !== 'none') {
|
|
38
|
+
// eslint-disable-next-line jest/no-conditional-expect
|
|
39
|
+
expect(backgroundColor.value).toBe(`var(--rc-${ status })`);
|
|
40
|
+
}
|
|
41
|
+
expect(textColor.value).toBe(`var(--rc-${ status }-secondary)`);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it.each([
|
|
45
|
+
'info',
|
|
46
|
+
'success',
|
|
47
|
+
'warning',
|
|
48
|
+
'error',
|
|
49
|
+
'unknown',
|
|
50
|
+
'none'
|
|
51
|
+
])('outlined: should return the correct colors for status: %p', (status: Status) => {
|
|
52
|
+
const props = reactive({ status });
|
|
53
|
+
const {
|
|
54
|
+
borderColor,
|
|
55
|
+
backgroundColor,
|
|
56
|
+
textColor
|
|
57
|
+
} = useStatusColors(props, 'outlined');
|
|
58
|
+
|
|
59
|
+
expect(borderColor.value).toBe(`var(--rc-${ status }-secondary)`);
|
|
60
|
+
if (status !== 'none') {
|
|
61
|
+
// eslint-disable-next-line jest/no-conditional-expect
|
|
62
|
+
expect(backgroundColor.value).toBe(`var(--rc-${ status }-secondary)`);
|
|
63
|
+
}
|
|
64
|
+
expect(textColor.value).toBe(`var(--rc-${ status })`);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { computed } from 'vue';
|
|
2
|
+
|
|
3
|
+
export const StatusDefinitions = {
|
|
4
|
+
info: {
|
|
5
|
+
primary: '--rc-info',
|
|
6
|
+
secondary: '--rc-info-secondary'
|
|
7
|
+
},
|
|
8
|
+
success: {
|
|
9
|
+
primary: '--rc-success',
|
|
10
|
+
secondary: '--rc-success-secondary'
|
|
11
|
+
},
|
|
12
|
+
warning: {
|
|
13
|
+
primary: '--rc-warning',
|
|
14
|
+
secondary: '--rc-warning-secondary'
|
|
15
|
+
},
|
|
16
|
+
error: {
|
|
17
|
+
primary: '--rc-error',
|
|
18
|
+
secondary: '--rc-error-secondary'
|
|
19
|
+
},
|
|
20
|
+
unknown: {
|
|
21
|
+
primary: '--rc-unknown',
|
|
22
|
+
secondary: '--rc-unknown-secondary'
|
|
23
|
+
},
|
|
24
|
+
none: {
|
|
25
|
+
primary: '--rc-none',
|
|
26
|
+
secondary: '--rc-none-secondary'
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export type Status = keyof typeof StatusDefinitions;
|
|
31
|
+
export type StatusObject = { status: Status };
|
|
32
|
+
export type Style = 'solid' | 'outlined';
|
|
33
|
+
|
|
34
|
+
export function wrapIfVar(colorVar: string) {
|
|
35
|
+
return colorVar.startsWith('--') ? `var(${ colorVar })` : colorVar;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* A composable to make it easier to use status colors in multiple components
|
|
40
|
+
*
|
|
41
|
+
* @param propsWithStatus The props which contain a `status: Status` property. Ideally I'd prefer to just pass status but doing so either forces the consumer to wrap the values in a Ref or this code is no longer reactive.
|
|
42
|
+
* @param style {@link Style} Will the block of code being using the solid or outlined styling
|
|
43
|
+
* @returns An object containing the relevant style colors
|
|
44
|
+
*/
|
|
45
|
+
export function useStatusColors(propsWithStatus: StatusObject, style: Style) {
|
|
46
|
+
const statusColors = computed(() => {
|
|
47
|
+
return StatusDefinitions[propsWithStatus.status];
|
|
48
|
+
});
|
|
49
|
+
const isOutlined = style === 'outlined';
|
|
50
|
+
|
|
51
|
+
const borderColor = computed(() => {
|
|
52
|
+
const colorVar = isOutlined ? statusColors.value.secondary : statusColors.value.primary;
|
|
53
|
+
|
|
54
|
+
return wrapIfVar(colorVar);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const backgroundColor = computed(() => {
|
|
58
|
+
if (propsWithStatus.status === 'none') {
|
|
59
|
+
return 'none';
|
|
60
|
+
}
|
|
61
|
+
const colorVar = isOutlined ? statusColors.value.secondary : statusColors.value.primary;
|
|
62
|
+
|
|
63
|
+
return wrapIfVar(colorVar);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const textColor = computed(() => {
|
|
67
|
+
const colorVar = isOutlined ? statusColors.value.primary : statusColors.value.secondary;
|
|
68
|
+
|
|
69
|
+
return wrapIfVar(colorVar);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
borderColor,
|
|
74
|
+
backgroundColor,
|
|
75
|
+
textColor
|
|
76
|
+
};
|
|
77
|
+
}
|
package/scripts/typegen.sh
CHANGED
|
@@ -29,6 +29,7 @@ ${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/store/prefs.js --declaration --al
|
|
|
29
29
|
${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/store/plugins.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/store > /dev/null
|
|
30
30
|
|
|
31
31
|
# # plugins
|
|
32
|
+
${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/plugins/i18n.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/ > /dev/null
|
|
32
33
|
${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/plugins/dashboard-store/normalize.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/plugins/dashboard-store/ > /dev/null
|
|
33
34
|
${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/plugins/dashboard-store/resource-class.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/plugins/dashboard-store/ > /dev/null
|
|
34
35
|
${BASE_DIR}/node_modules/.bin/tsc ${SHELL_DIR}/plugins/dashboard-store/classify.js --declaration --allowJs --emitDeclarationOnly --outDir ${SHELL_DIR}/tmp/plugins/dashboard-store/ > /dev/null
|
package/store/action-menu.js
CHANGED
|
@@ -111,6 +111,14 @@ export const mutations = {
|
|
|
111
111
|
state.modalData = data;
|
|
112
112
|
},
|
|
113
113
|
|
|
114
|
+
updateModalData(state, data) {
|
|
115
|
+
state.modalData = state.modalData || {};
|
|
116
|
+
|
|
117
|
+
data.forEach(({ key, value }) => {
|
|
118
|
+
state.modalData[key] = value;
|
|
119
|
+
});
|
|
120
|
+
},
|
|
121
|
+
|
|
114
122
|
clearCallbackData(state) {
|
|
115
123
|
state.performCallbackData = undefined;
|
|
116
124
|
},
|
package/store/auth.js
CHANGED
|
@@ -404,18 +404,18 @@ export const actions = {
|
|
|
404
404
|
// Unload plugins - we will load again on login
|
|
405
405
|
await rootState.$plugin.logout();
|
|
406
406
|
|
|
407
|
-
let logoutAction = '
|
|
407
|
+
let logoutAction = '';
|
|
408
408
|
const data = {};
|
|
409
409
|
|
|
410
410
|
// SLO - Single-sign logout - will logout auth provider from all places where it's logged in
|
|
411
411
|
if (options.slo) {
|
|
412
|
-
logoutAction = 'logoutAll';
|
|
412
|
+
logoutAction = '?logoutAll';
|
|
413
413
|
data.finalRedirectUrl = returnTo({ isSlo: true }, this);
|
|
414
414
|
}
|
|
415
415
|
|
|
416
416
|
try {
|
|
417
417
|
const res = await dispatch('rancher/request', {
|
|
418
|
-
url: `/
|
|
418
|
+
url: `/v1/logout${ logoutAction }`,
|
|
419
419
|
method: 'post',
|
|
420
420
|
data,
|
|
421
421
|
headers: { 'Content-Type': 'application/json' },
|
package/store/catalog.js
CHANGED
|
@@ -504,11 +504,16 @@ function addChart(ctx, map, chart, repo) {
|
|
|
504
504
|
|
|
505
505
|
if ( !obj ) {
|
|
506
506
|
if ( ctx ) { }
|
|
507
|
+
|
|
508
|
+
const primeOnly = chart.annotations?.[CATALOG_ANNOTATIONS.PRIME_ONLY] === 'true';
|
|
507
509
|
const experimental = !!chart.annotations?.[CATALOG_ANNOTATIONS.EXPERIMENTAL];
|
|
508
510
|
const windowsIncompatible = !(chart.annotations?.[CATALOG_ANNOTATIONS.PERMITTED_OS] || '').includes('windows');
|
|
509
511
|
const deploysOnWindows = (chart.annotations?.[CATALOG_ANNOTATIONS.DEPLOYED_OS] || '').includes('windows');
|
|
510
512
|
const tags = [];
|
|
511
513
|
|
|
514
|
+
if (primeOnly) {
|
|
515
|
+
tags.push(ctx.rootGetters['i18n/withFallback']('generic.primeOnly'));
|
|
516
|
+
}
|
|
512
517
|
if (experimental) {
|
|
513
518
|
tags.push(ctx.rootGetters['i18n/withFallback']('generic.experimental'));
|
|
514
519
|
}
|
|
@@ -542,6 +547,7 @@ function addChart(ctx, map, chart, repo) {
|
|
|
542
547
|
keywords: chart.keywords || [],
|
|
543
548
|
categories: filterCategories(chart.keywords),
|
|
544
549
|
deprecated: !!chart.deprecated,
|
|
550
|
+
primeOnly,
|
|
545
551
|
experimental,
|
|
546
552
|
hidden: !!chart.annotations?.[CATALOG_ANNOTATIONS.HIDDEN],
|
|
547
553
|
targetNamespace: chart.annotations?.[CATALOG_ANNOTATIONS.NAMESPACE],
|
package/store/index.js
CHANGED
|
@@ -263,7 +263,7 @@ export const state = () => {
|
|
|
263
263
|
$route: markRaw({}),
|
|
264
264
|
$plugin: markRaw({}),
|
|
265
265
|
showWorkspaceSwitcher: true,
|
|
266
|
-
|
|
266
|
+
localCluster: null,
|
|
267
267
|
};
|
|
268
268
|
};
|
|
269
269
|
|
|
@@ -272,10 +272,20 @@ export const getters = {
|
|
|
272
272
|
return state.clusterReady === true;
|
|
273
273
|
},
|
|
274
274
|
|
|
275
|
+
/**
|
|
276
|
+
* Cache of the mgmt cluster fetched at start up
|
|
277
|
+
*
|
|
278
|
+
* We cannot rely on the store to cache this as the store may contain a page without the local cluster
|
|
279
|
+
*/
|
|
280
|
+
localCluster(state) {
|
|
281
|
+
return state.localCluster;
|
|
282
|
+
},
|
|
283
|
+
|
|
275
284
|
isMultiCluster(state, getters) {
|
|
276
|
-
const
|
|
285
|
+
const clusterCount = getters['management/all'](COUNT)?.[0]?.counts?.[MANAGEMENT.CLUSTER]?.summary?.count || 0;
|
|
286
|
+
const localCluster = getters['localCluster'];
|
|
277
287
|
|
|
278
|
-
if (
|
|
288
|
+
if (clusterCount === 1 && !!localCluster) {
|
|
279
289
|
return false;
|
|
280
290
|
} else {
|
|
281
291
|
return true;
|
|
@@ -592,10 +602,9 @@ export const getters = {
|
|
|
592
602
|
},
|
|
593
603
|
|
|
594
604
|
isStandaloneHarvester(state, getters) {
|
|
595
|
-
const
|
|
596
|
-
const cluster = clusters.find((c) => c.id === 'local') || {};
|
|
605
|
+
const localCluster = getters['localCluster'];
|
|
597
606
|
|
|
598
|
-
return getters['isSingleProduct'] &&
|
|
607
|
+
return getters['isSingleProduct'] && localCluster?.isHarvester && !getters['isRancherInHarvester'];
|
|
599
608
|
},
|
|
600
609
|
|
|
601
610
|
showTopLevelMenu(getters) {
|
|
@@ -640,9 +649,10 @@ export const mutations = {
|
|
|
640
649
|
clearPageActionHandler(state) {
|
|
641
650
|
state.pageActionHandler = null;
|
|
642
651
|
},
|
|
643
|
-
managementChanged(state, { ready, isRancher }) {
|
|
652
|
+
managementChanged(state, { ready, isRancher, localCluster }) {
|
|
644
653
|
state.managementReady = ready;
|
|
645
654
|
state.isRancher = isRancher;
|
|
655
|
+
state.localCluster = localCluster;
|
|
646
656
|
},
|
|
647
657
|
clusterReady(state, ready) {
|
|
648
658
|
state.clusterReady = ready;
|
|
@@ -846,11 +856,21 @@ export const actions = {
|
|
|
846
856
|
|
|
847
857
|
res = await allHash(promises);
|
|
848
858
|
|
|
859
|
+
let localCluster = null;
|
|
860
|
+
|
|
849
861
|
if (!res[MANAGEMENT.SETTING] || !paginateClusters({ rootGetters, state })) {
|
|
850
862
|
// This introduces a synchronous request, however we need settings to determine if SSP is enabled
|
|
851
|
-
|
|
852
|
-
res[MANAGEMENT.CLUSTER] = await dispatch('management/findAll', { type: MANAGEMENT.CLUSTER, opt: { watch: false } });
|
|
863
|
+
await dispatch('management/findAll', { type: MANAGEMENT.CLUSTER, opt: { watch: false } });
|
|
853
864
|
toWatch.push(MANAGEMENT.CLUSTER);
|
|
865
|
+
|
|
866
|
+
localCluster = getters['management/byId'](MANAGEMENT.CLUSTER, 'local');
|
|
867
|
+
} else {
|
|
868
|
+
try {
|
|
869
|
+
localCluster = await dispatch('management/find', {
|
|
870
|
+
type: MANAGEMENT.CLUSTER, id: 'local', opt: { watch: false }
|
|
871
|
+
});
|
|
872
|
+
} catch (e) { // we don't care about errors, specifically 404s
|
|
873
|
+
}
|
|
854
874
|
}
|
|
855
875
|
|
|
856
876
|
// See comment above. Now that we have feature flags we can watch resources
|
|
@@ -858,11 +878,7 @@ export const actions = {
|
|
|
858
878
|
dispatch('management/watch', { type });
|
|
859
879
|
});
|
|
860
880
|
|
|
861
|
-
const isMultiCluster = getters['isMultiCluster'];
|
|
862
|
-
|
|
863
881
|
// If the local cluster is a Harvester cluster and 'rancher-manager-support' is true, it means that the embedded Rancher is being used.
|
|
864
|
-
const localCluster = res[MANAGEMENT.CLUSTER]?.find((c) => c.id === 'local');
|
|
865
|
-
|
|
866
882
|
if (localCluster?.isHarvester) {
|
|
867
883
|
const harvesterSetting = await dispatch('cluster/findAll', { type: HCI.SETTING, opt: { url: `/v1/harvester/${ HCI.SETTING }s` } });
|
|
868
884
|
const rancherManagerSupport = harvesterSetting.find((setting) => setting.id === 'rancher-manager-support');
|
|
@@ -904,6 +920,7 @@ export const actions = {
|
|
|
904
920
|
commit('managementChanged', {
|
|
905
921
|
ready: true,
|
|
906
922
|
isRancher,
|
|
923
|
+
localCluster
|
|
907
924
|
});
|
|
908
925
|
|
|
909
926
|
if ( res[FLEET.WORKSPACE] ) {
|
|
@@ -914,6 +931,8 @@ export const actions = {
|
|
|
914
931
|
});
|
|
915
932
|
}
|
|
916
933
|
|
|
934
|
+
const isMultiCluster = getters['isMultiCluster'];
|
|
935
|
+
|
|
917
936
|
console.log(`Done loading management; isRancher=${ isRancher }; isMultiCluster=${ isMultiCluster }`); // eslint-disable-line no-console
|
|
918
937
|
},
|
|
919
938
|
|
|
@@ -1232,10 +1251,10 @@ export const actions = {
|
|
|
1232
1251
|
}
|
|
1233
1252
|
},
|
|
1234
1253
|
|
|
1235
|
-
|
|
1236
|
-
commit('setRouter',
|
|
1237
|
-
commit('setRoute',
|
|
1238
|
-
commit('setPlugin',
|
|
1254
|
+
dashboardClientInit({ dispatch, commit, rootState }, context) {
|
|
1255
|
+
commit('setRouter', context.app.router);
|
|
1256
|
+
commit('setRoute', context.route);
|
|
1257
|
+
commit('setPlugin', context.app.$plugin);
|
|
1239
1258
|
|
|
1240
1259
|
dispatch('management/rehydrateSubscribe');
|
|
1241
1260
|
dispatch('cluster/rehydrateSubscribe');
|
package/store/prefs.js
CHANGED
|
@@ -523,15 +523,14 @@ export const actions = {
|
|
|
523
523
|
setBrandStyle({ rootState, rootGetters }, dark = false) {
|
|
524
524
|
if (rootState.managementReady) {
|
|
525
525
|
try {
|
|
526
|
-
const brandSetting = rootGetters['management/
|
|
526
|
+
const brandSetting = rootGetters['management/brand'];
|
|
527
527
|
|
|
528
|
-
if (brandSetting
|
|
529
|
-
const
|
|
530
|
-
const brandMeta = getBrandMeta(brand);
|
|
528
|
+
if (brandSetting !== '') {
|
|
529
|
+
const brandMeta = getBrandMeta(brandSetting);
|
|
531
530
|
const hasStylesheet = brandMeta.hasStylesheet === 'true';
|
|
532
531
|
|
|
533
532
|
if (hasStylesheet) {
|
|
534
|
-
document.body.classList.add(
|
|
533
|
+
document.body.classList.add(brandMeta);
|
|
535
534
|
} else {
|
|
536
535
|
// TODO option apply color at runtime
|
|
537
536
|
}
|
package/store/type-map.js
CHANGED
|
@@ -1895,7 +1895,7 @@ function ifHave(getters, option) {
|
|
|
1895
1895
|
case IF_HAVE.NOT_V1_ISTIO: {
|
|
1896
1896
|
return !isV1Istio(getters);
|
|
1897
1897
|
}
|
|
1898
|
-
case IF_HAVE.MULTI_CLUSTER: {
|
|
1898
|
+
case IF_HAVE.MULTI_CLUSTER: { // Used by harvester extension
|
|
1899
1899
|
return getters.isMultiCluster;
|
|
1900
1900
|
}
|
|
1901
1901
|
case IF_HAVE.NEUVECTOR_NAMESPACE: {
|
|
@@ -1904,10 +1904,10 @@ function ifHave(getters, option) {
|
|
|
1904
1904
|
case IF_HAVE.ADMIN: {
|
|
1905
1905
|
return isAdminUser(getters);
|
|
1906
1906
|
}
|
|
1907
|
-
case IF_HAVE.MCM_DISABLED: {
|
|
1907
|
+
case IF_HAVE.MCM_DISABLED: { // There's a general MCM ff, this is conflating it with a harvester concept
|
|
1908
1908
|
return !getters['isRancherInHarvester'];
|
|
1909
1909
|
}
|
|
1910
|
-
case IF_HAVE.NOT_STANDALONE_HARVESTER: {
|
|
1910
|
+
case IF_HAVE.NOT_STANDALONE_HARVESTER: { // Not used by harvester extension...
|
|
1911
1911
|
return !getters['isStandaloneHarvester'];
|
|
1912
1912
|
}
|
|
1913
1913
|
default:
|
package/store/wm.ts
CHANGED
|
@@ -80,11 +80,11 @@ export const mutations = {
|
|
|
80
80
|
addTab(state: State, tab: Tab) {
|
|
81
81
|
const existing = state.tabs.find((x) => x.id === tab.id);
|
|
82
82
|
|
|
83
|
-
if (
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
83
|
+
if (tab.position === undefined || tab.position as string === 'undefined') {
|
|
84
|
+
tab.position = (window.localStorage.getItem(STORAGE_KEY['pin']) || BOTTOM) as Position;
|
|
85
|
+
}
|
|
87
86
|
|
|
87
|
+
if (!existing) {
|
|
88
88
|
if (state.lockedPositions.includes(BOTTOM)) {
|
|
89
89
|
tab.position = BOTTOM;
|
|
90
90
|
}
|