This is an automated email from the ASF dual-hosted git repository.
wuzhiguo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/bigtop-manager.git
The following commit(s) were added to refs/heads/main by this push:
new 68a055d2 BIGTOP-4409: Fix duplicate menus (#209)
68a055d2 is described below
commit 68a055d27314d28672a7d8dfa00519e4d037b943
Author: Fdefined <[email protected]>
AuthorDate: Tue Apr 15 15:28:14 2025 +0800
BIGTOP-4409: Fix duplicate menus (#209)
---
.../components/component-installer.vue | 11 +-
bigtop-manager-ui/src/components/job/index.vue | 71 +++++++--
.../src/components/service-management/configs.vue | 1 -
.../src/components/user-avatar/index.vue | 3 -
bigtop-manager-ui/src/layouts/header.vue | 36 ++---
bigtop-manager-ui/src/layouts/index.vue | 28 ++--
bigtop-manager-ui/src/layouts/sider.vue | 131 +++++++++-------
bigtop-manager-ui/src/locales/en_US/cluster.ts | 4 +-
bigtop-manager-ui/src/locales/en_US/menu.ts | 2 +-
bigtop-manager-ui/src/locales/zh_CN/menu.ts | 2 +-
.../cluster/components/check-workflow.vue | 11 +-
.../src/pages/cluster-manage/cluster/create.vue | 11 +-
.../src/pages/cluster-manage/cluster/service.vue | 2 +-
.../src/pages/cluster-manage/components/index.vue | 15 +-
.../cluster-manage/infrastructures/service.vue | 2 +-
bigtop-manager-ui/src/pages/login/index.vue | 13 +-
bigtop-manager-ui/src/plugins/index.ts | 3 +-
bigtop-manager-ui/src/router/guard.ts | 18 ++-
bigtop-manager-ui/src/router/routes/index.ts | 1 +
.../src/router/routes/modules/clusters.ts | 77 +++++----
.../src/router/routes/modules/system.ts | 18 ++-
bigtop-manager-ui/src/store/cluster/index.ts | 12 +-
bigtop-manager-ui/src/store/menu/index.ts | 174 ++++++---------------
bigtop-manager-ui/src/utils/router-util.ts | 27 +---
24 files changed, 324 insertions(+), 349 deletions(-)
diff --git
a/bigtop-manager-ui/src/components/create-service/components/component-installer.vue
b/bigtop-manager-ui/src/components/create-service/components/component-installer.vue
index af08100d..78f282d1 100644
---
a/bigtop-manager-ui/src/components/create-service/components/component-installer.vue
+++
b/bigtop-manager-ui/src/components/create-service/components/component-installer.vue
@@ -75,10 +75,12 @@
}
}
- const pollJobDetails = (execFunc: Function, interval: number = 200): void =>
{
+ const pollJobDetails = (execFunc: Function, interval: number = 1000): void
=> {
let firstPoll = true
let firstPollCompleted = false
- const intervalId = setInterval(async () => {
+ let intervalId: NodeJS.Timeout
+
+ const poll = async () => {
if (firstPoll) {
spinning.value = true
firstPoll = false
@@ -91,7 +93,10 @@
if (result) {
clearInterval(intervalId)
}
- }, interval)
+ }
+
+ intervalId = setInterval(poll, interval)
+ poll()
}
const viewLogs = (stage: StageVO, task: TaskVO) => {
diff --git a/bigtop-manager-ui/src/components/job/index.vue
b/bigtop-manager-ui/src/components/job/index.vue
index 3f2bfe00..842145b8 100644
--- a/bigtop-manager-ui/src/components/job/index.vue
+++ b/bigtop-manager-ui/src/components/job/index.vue
@@ -27,10 +27,12 @@
import CustomProgress from './custom-progress.vue'
import type { JobVO, StageVO, StateType, TaskListParams, TaskVO } from
'@/api/job/types'
import type { ClusterVO } from '@/api/cluster/types'
+ import type { ListParams } from '@/api/types'
interface BreadcrumbItem {
id: string
name: ComputedRef<string> | string
+ pagination: ListParams
}
const POLLING_INTERVAL = 3000
const { t } = useI18n()
@@ -39,17 +41,15 @@
const breadcrumbs = ref<BreadcrumbItem[]>([
{
name: computed(() => t('job.job_list')),
- id: `clusterId-${clusterInfo.id}`
+ id: `clusterId-${clusterInfo.id}`,
+ pagination: {
+ pageNum: 1,
+ pageSize: 10,
+ sort: 'desc'
+ }
}
])
- const status = shallowRef<Record<StateType, string>>({
- Pending: 'installing',
- Processing: 'processing',
- Failed: 'failed',
- Canceled: 'canceled',
- Successful: 'success'
- })
- const apiMap = shallowRef([
+ const apiMap = ref([
{
key: 'clusterId',
api: getJobList
@@ -63,6 +63,13 @@
api: getTaskList
}
])
+ const status = shallowRef<Record<StateType, string>>({
+ Pending: 'installing',
+ Processing: 'processing',
+ Failed: 'failed',
+ Canceled: 'canceled',
+ Successful: 'success'
+ })
const logsViewState = reactive<LogViewProps>({
open: false
})
@@ -100,13 +107,14 @@
const apiParams = computed(
(): TaskListParams =>
breadcrumbs.value.reduce((pre, val, index) => {
+ const apiMapKey = apiMap.value[index].key
return Object.assign(pre, {
- [`${apiMap.value[index].key}`]:
val.id.replace(`${apiMap.value[index].key}-`, '')
+ [`${apiMapKey}`]: val.id.replace(`${apiMapKey}-`, '')
})
}, {} as TaskListParams)
)
- const { dataSource, loading, filtersParams, paginationProps, onChange } =
useBaseTable<JobVO | StageVO | TaskVO>({
+ const { dataSource, loading, paginationProps, onChange } =
useBaseTable<JobVO | StageVO | TaskVO>({
columns: columns.value
})
@@ -114,14 +122,15 @@
if (breadcrumb.id !== currBreadcrumb.value?.id) {
const index = breadcrumbs.value.findIndex((v) => v.id === breadcrumb.id)
breadcrumbs.value.splice(index + 1, breadcrumbLen.value - index - 1)
+ updataPaginationsInBaseTable(currBreadcrumb.value?.pagination)
stopPolling()
startPolling()
}
}
const updateBreadcrumbs = (data: BreadcrumbItem) => {
+ // task log open
if (breadcrumbLen.value + 1 > apiMap.value.length) {
- // task log open
logsViewState.open = true
logsViewState.subTitle = data.name as string
logsViewState.payLoad = {
@@ -130,18 +139,29 @@
}
return
}
+
const currId = `${apiMap.value[breadcrumbLen.value].key}-${data.id}`
const index = breadcrumbs.value.findIndex((v) => v.id === currId)
if (index === -1) {
- breadcrumbs.value.push({
- id: currId,
- name: data.name as string
- })
+ const newBreadcrumb = createBreadcrumbItem({ id: currId, name: data.name
as string })
+ breadcrumbs.value.push(newBreadcrumb)
stopPolling()
+ updataPaginationsInBaseTable()
startPolling()
}
}
+ const createBreadcrumbItem = (item: { id: string; name: string }) => {
+ return {
+ id: item.id,
+ name: item.name,
+ pagination: {
+ pageNum: 1,
+ pageSize: 10
+ }
+ }
+ }
+
const getListData = async (isFirstCall = false) => {
if (!paginationProps.value) {
loading.value = false
@@ -152,7 +172,7 @@
loading.value = true
}
const { api } = apiMap.value[breadcrumbs.value.length - 1]
- const res = await api(apiParams.value, { ...filtersParams.value, sort:
'desc' })
+ const res = await api(apiParams.value, currBreadcrumb.value!.pagination)
dataSource.value = res.content
paginationProps.value.total = res.total
} catch (error) {
@@ -163,7 +183,24 @@
}
}
+ const updataPaginationsInBaseTable = (pagination: ListParams = { pageNum: 1,
pageSize: 10 }) => {
+ if (paginationProps.value) {
+ paginationProps.value.current = pagination.pageNum
+ paginationProps.value.pageSize = pagination.pageSize
+ }
+ }
+
+ const updataPaginationsInBreadcrumbs = (pagination: ListParams) => {
+ const index = breadcrumbs.value.findIndex((v) => v.id ===
currBreadcrumb.value?.id)
+ if (index != -1) {
+ breadcrumbs.value[index].pagination.pageNum = pagination.pageNum
+ breadcrumbs.value[index].pagination.pageSize = pagination.pageSize
+ }
+ }
+
const tableChange: TableProps['onChange'] = (...args) => {
+ const { current: pageNum, pageSize } = args[0]
+ updataPaginationsInBreadcrumbs({ pageNum, pageSize })
onChange(...args)
stopPolling()
startPolling()
diff --git a/bigtop-manager-ui/src/components/service-management/configs.vue
b/bigtop-manager-ui/src/components/service-management/configs.vue
index 8515026b..346e2b89 100644
--- a/bigtop-manager-ui/src/components/service-management/configs.vue
+++ b/bigtop-manager-ui/src/components/service-management/configs.vue
@@ -127,7 +127,6 @@
await getServiceDetail()
configs.value = attrs.configs as ServiceConfig[]
filterConfigs.value = [...configs.value]
- activeKey.value = filterConfigs.value.map((v) => v.id!)
debouncedOnSearch.value = debounce(filterConfigurations, 300)
})
diff --git a/bigtop-manager-ui/src/components/user-avatar/index.vue
b/bigtop-manager-ui/src/components/user-avatar/index.vue
index 8e67e101..403ab283 100644
--- a/bigtop-manager-ui/src/components/user-avatar/index.vue
+++ b/bigtop-manager-ui/src/components/user-avatar/index.vue
@@ -24,12 +24,10 @@
import { storeToRefs } from 'pinia'
import router from '@/router'
import { useI18n } from 'vue-i18n'
- import { useMenuStore } from '@/store/menu'
const i18n = useI18n()
const userStore = useUserStore()
- const menuStore = useMenuStore()
const { userVO } = storeToRefs(userStore)
const logout = async () => {
@@ -37,7 +35,6 @@
try {
await userStore.logout()
message.success(i18n.t('login.logout_success'))
- menuStore.cleanUpMenu()
await router.push({ path: '/login' })
} catch (e) {
console.warn(e)
diff --git a/bigtop-manager-ui/src/layouts/header.vue
b/bigtop-manager-ui/src/layouts/header.vue
index 201da620..7b7f18dd 100644
--- a/bigtop-manager-ui/src/layouts/header.vue
+++ b/bigtop-manager-ui/src/layouts/header.vue
@@ -18,38 +18,19 @@
-->
<script setup lang="ts">
- import { ref, toRefs } from 'vue'
+ import { ref } from 'vue'
+ import { storeToRefs } from 'pinia'
+ import { useMenuStore } from '@/store/menu/index'
import SelectLang from '@/components/select-lang/index.vue'
import UserAvatar from '@/components/user-avatar/index.vue'
import AiAssistant from '@/components/ai-assistant/index.vue'
- import { RouteRecordRaw } from 'vue-router'
-
- interface Props {
- headerSelectedKey: string
- headerMenus: RouteRecordRaw[]
- }
-
- interface Emits {
- (event: 'onHeaderClick', key: string): void
- }
-
- const props = withDefaults(defineProps<Props>(), {
- headerSelectedKey: '',
- headerMenus: () => []
- })
-
- const { headerSelectedKey, headerMenus } = toRefs(props)
const githubUrl = import.meta.env.VITE_GITHUB_URL
const bigtopMangerDocURL = import.meta.env.VITE_BIGTOP_MANAGER_DOC_URL
+ const menuStore = useMenuStore()
const spaceSize = ref(16)
const aiAssistantRef = ref<InstanceType<typeof AiAssistant> | null>(null)
-
- const emits = defineEmits<Emits>()
-
- const handleHeaderSelect = ({ key }: any) => {
- emits('onHeaderClick', key)
- }
+ const { headerSelectedKey, headerMenus } = storeToRefs(menuStore)
const handleCommunication = () => {
aiAssistantRef.value?.controlVisible()
@@ -62,7 +43,12 @@
<svg-icon name="bm_logo" />
</h1>
<div class="header-menu">
- <a-menu :selected-keys="[headerSelectedKey]" theme="dark"
mode="horizontal" @select="handleHeaderSelect">
+ <a-menu
+ :selected-keys="[headerSelectedKey]"
+ theme="dark"
+ mode="horizontal"
+ @select="({ key }) => menuStore.onHeaderClick(key)"
+ >
<a-menu-item v-for="route of headerMenus" :key="route.path">
{{ $t(route.meta?.title || '') }}
</a-menu-item>
diff --git a/bigtop-manager-ui/src/layouts/index.vue
b/bigtop-manager-ui/src/layouts/index.vue
index 37bb1ed5..11e3604a 100644
--- a/bigtop-manager-ui/src/layouts/index.vue
+++ b/bigtop-manager-ui/src/layouts/index.vue
@@ -18,43 +18,37 @@
-->
<script setup lang="ts">
- import { onMounted } from 'vue'
import LayoutFooter from '@/layouts/footer.vue'
import LayoutHeader from '@/layouts/header.vue'
import LayoutSider from '@/layouts/sider.vue'
+
import { useUserStore } from '@/store/user'
import { useMenuStore } from '@/store/menu'
- import { useStackStore } from '@/store/stack'
import { useInstalledStore } from '@/store/installed'
- import { storeToRefs } from 'pinia'
+ import { useClusterStore } from '@/store/cluster'
+ import { useStackStore } from '@/store/stack'
+ import { onMounted } from 'vue'
const userStore = useUserStore()
const menuStore = useMenuStore()
const installedStore = useInstalledStore()
const stackStore = useStackStore()
- const { headerSelectedKey, headerMenus, siderMenuSelectedKey, siderMenus } =
storeToRefs(menuStore)
+ const clusterStore = useClusterStore()
- onMounted(() => {
+ onMounted(async () => {
+ stackStore.loadStacks()
+ await clusterStore.loadClusters()
installedStore.getServicesOfInfra()
userStore.getUserInfo()
- menuStore.setUpMenu()
- stackStore.loadStacks()
+ menuStore.setupMenu()
})
</script>
<template>
<a-layout class="layout">
- <layout-header
- :header-selected-key="headerSelectedKey"
- :header-menus="headerMenus"
- @on-header-click="menuStore.onHeaderClick"
- />
+ <layout-header />
<a-layout>
- <layout-sider
- :sider-menu-selected-key="siderMenuSelectedKey"
- :sider-menus="siderMenus"
- @on-sider-click="menuStore.onSiderClick"
- />
+ <layout-sider />
<a-layout class="layout-inner">
<router-view :key="$route.fullPath" />
<layout-footer />
diff --git a/bigtop-manager-ui/src/layouts/sider.vue
b/bigtop-manager-ui/src/layouts/sider.vue
index 09b55480..060a7b06 100644
--- a/bigtop-manager-ui/src/layouts/sider.vue
+++ b/bigtop-manager-ui/src/layouts/sider.vue
@@ -18,100 +18,116 @@
-->
<script setup lang="ts">
- import { toRefs, ref, watch } from 'vue'
- import { useRouter } from 'vue-router'
- import { RouteExceptions } from '@/enums'
- import { useMenuStore } from '@/store/menu'
- import type { MenuItem } from '@/store/menu/types'
+ import { useRouter, useRoute } from 'vue-router'
+ import { useMenuStore } from '@/store/menu/index'
+ import { storeToRefs } from 'pinia'
+ import { computed, ref, watch } from 'vue'
+ import { useClusterStore } from '@/store/cluster'
import type { ClusterStatusType } from '@/api/cluster/types'
- interface Props {
- siderMenuSelectedKey: string
- siderMenus: MenuItem[]
- }
-
- const props = withDefaults(defineProps<Props>(), {
- siderMenuSelectedKey: ''
- })
-
- const { siderMenuSelectedKey } = toRefs(props)
const router = useRouter()
+ const route = useRoute()
const menuStore = useMenuStore()
- const menus = ref<MenuItem[]>([])
- const emits = defineEmits(['onSiderClick'])
- const clusterStatus = ref<Record<ClusterStatusType, string>>({
- 1: 'success',
- 2: 'error',
- 3: 'warning'
- })
+ const clusterStore = useClusterStore()
+ const routeParamsLen = ref(0)
+ const openKeys = ref<string[]>(['clusters'])
+ const { siderMenuSelectedKey, headerSelectedKey, siderMenus,
routePathFromClusters } = storeToRefs(menuStore)
+ const { clusters, clusterCount } = storeToRefs(clusterStore)
+
+ const showCreateClusterBtn = computed(() => headerSelectedKey.value ===
'/cluster-manage')
+ const selectMenuKeyFromClusters = computed(() =>
siderMenuSelectedKey.value.includes(routePathFromClusters.value))
+ const clusterStatus = computed(
+ (): Record<ClusterStatusType, string> => ({
+ 1: 'success',
+ 2: 'error',
+ 3: 'warning'
+ })
+ )
watch(
- () => props.siderMenus,
- (val) => {
- menus.value = []
- menus.value = val
+ () => route,
+ (newRoute) => {
+ const { params, path, meta } = newRoute
+ routeParamsLen.value = Object.keys(params).length
+ if (path.includes(routePathFromClusters.value) && routeParamsLen.value >
0 && clusterCount.value > 0) {
+ const cluster = clusters.value.find((v) => `${v.id}` === params.id)
+ cluster && (siderMenuSelectedKey.value =
`${routePathFromClusters.value}/${cluster.name}/${cluster.id}`)
+ } else {
+ siderMenuSelectedKey.value = meta.activeMenu ?? path
+ }
},
{
- deep: true
+ deep: true,
+ immediate: true
}
)
- const toggleActivatedIcon = (menuItem: MenuItem) => {
+ const toggleActivatedIcon = (menuItem: { key: string; icon: string }) => {
const { key, icon } = menuItem
- if (menuStore.isDynamicRouteMatched) {
- return key === RouteExceptions.SPECIAL_ROUTE_PATH ? `${icon}_activated`
: icon
- } else {
- return key === siderMenuSelectedKey.value ? `${icon}_activated` : icon
- }
+ const matchedRouteFromClusters = selectMenuKeyFromClusters.value &&
routeParamsLen.value > 0
+ return key === siderMenuSelectedKey.value || (matchedRouteFromClusters &&
key === 'clusters')
+ ? `${icon}_activated`
+ : icon
}
const addCluster = () => {
router.push({ name: 'CreateCluster' })
}
-
- const onSiderClick = ({ key }: any) => {
- emits('onSiderClick', key)
- }
</script>
<template>
<a-layout-sider class="sider">
- <a-menu :selected-keys="[siderMenuSelectedKey]" mode="inline"
@select="onSiderClick">
- <template v-for="menuItem in menus" :key="menuItem.key">
- <a-sub-menu
- v-if="menuItem.children && menuItem.name ===
RouteExceptions.SPECIAL_ROUTE_NAME"
- :key="menuItem.key"
- >
+ <a-menu
+ v-model="openKeys"
+ :selected-keys="[siderMenuSelectedKey]"
+ mode="inline"
+ @select="({ key }) => menuStore.onSiderClick(key)"
+ >
+ <template v-for="menuItem in siderMenus" :key="menuItem.path">
+ <a-sub-menu v-if="menuItem.name === 'Clusters'" :key="menuItem.path">
<template #icon>
- <svg-icon style="height: 16px; width: 16px"
:name="toggleActivatedIcon(menuItem)" />
+ <svg-icon
+ style="height: 16px; width: 16px"
+ :name="
+ toggleActivatedIcon({
+ key: (menuItem.redirect as string) || menuItem.path,
+ icon: menuItem.meta?.icon || ''
+ })
+ "
+ />
</template>
<template #title>
- <span>{{ $t(menuItem.label) }}</span>
+ <span>{{ $t(menuItem.meta!.title!) }}</span>
</template>
- <a-menu-item v-for="child in menuItem.children" :key="child.key">
+ <a-menu-item
+ v-for="child in clusters"
+ :key="`${routePathFromClusters}/${child.name}/${child.id}`"
+ :title="child.displayName"
+ >
<template #icon>
- <div
- style="height: 10px; margin-inline: 7px; display: flex;
justify-content: center; align-items: flex-end"
- >
+ <div class="cluster-status">
<status-dot :size="8" :color="clusterStatus[child.status as
ClusterStatusType] as any" />
</div>
</template>
<div>
- <span>{{ child.label }}</span>
+ <span>{{ child.displayName }}</span>
</div>
</a-menu-item>
</a-sub-menu>
<template v-else>
- <a-menu-item :key="menuItem.key">
+ <a-menu-item v-if="!menuItem.meta?.hidden" :key="menuItem.redirect">
<template #icon>
- <svg-icon style="height: 16px; width: 16px"
:name="toggleActivatedIcon(menuItem)" />
+ <svg-icon
+ style="height: 16px; width: 16px"
+ :name="toggleActivatedIcon({ key: menuItem.redirect as string,
icon: menuItem.meta?.icon || '' })"
+ />
</template>
- <span>{{ $t(menuItem.label) }}</span>
+ <span>{{ $t(menuItem.meta!.title!) }}</span>
</a-menu-item>
</template>
</template>
</a-menu>
- <div v-show="menuStore.isCreateClusterVisible">
+ <div v-if="showCreateClusterBtn">
<a-divider />
<div class="create-option">
<a-button type="primary" ghost @click="addCluster">
@@ -125,6 +141,13 @@
</template>
<style scoped lang="scss">
+ .cluster-status {
+ height: 10px;
+ margin-inline: 7px;
+ display: flex;
+ justify-content: center;
+ align-items: flex-end;
+ }
@mixin reset-sider-menu {
width: 100%;
border-radius: 0;
diff --git a/bigtop-manager-ui/src/locales/en_US/cluster.ts
b/bigtop-manager-ui/src/locales/en_US/cluster.ts
index ad9de32b..11979d82 100644
--- a/bigtop-manager-ui/src/locales/en_US/cluster.ts
+++ b/bigtop-manager-ui/src/locales/en_US/cluster.ts
@@ -29,12 +29,12 @@ export default {
description: 'Description',
root_directory: 'Root Directory',
user_group: 'User Group',
- config_source: 'Configuration Source',
+ config_source: 'Repository',
install_dependencies: 'Install Dependencies',
add_host: 'Add Host',
edit_host: 'Edit Host',
view_log: 'View Log',
- source: 'Source',
+ source: 'Repository',
show_hosts_resolved: 'Resolved Hostnames',
cluster_unavailable_message: 'Sorry, you need to create cluster to use this
feature.'
}
diff --git a/bigtop-manager-ui/src/locales/en_US/menu.ts
b/bigtop-manager-ui/src/locales/en_US/menu.ts
index 192158c8..19d20bf2 100644
--- a/bigtop-manager-ui/src/locales/en_US/menu.ts
+++ b/bigtop-manager-ui/src/locales/en_US/menu.ts
@@ -20,7 +20,7 @@
export default {
cluster: 'Cluster',
infra: 'Infrastructure',
- component: 'Component',
+ stacks: 'Stacks',
host: 'Host',
create: 'Create Cluster',
system: 'System',
diff --git a/bigtop-manager-ui/src/locales/zh_CN/menu.ts
b/bigtop-manager-ui/src/locales/zh_CN/menu.ts
index 170f822a..e206c3dd 100644
--- a/bigtop-manager-ui/src/locales/zh_CN/menu.ts
+++ b/bigtop-manager-ui/src/locales/zh_CN/menu.ts
@@ -20,7 +20,7 @@
export default {
cluster: '集群管理',
infra: '基础服务',
- component: '组件信息',
+ stacks: '组件栈',
host: '主机管理',
create: '添加集群',
system: '系统管理',
diff --git
a/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/check-workflow.vue
b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/check-workflow.vue
index 7e3e4974..d09f541f 100644
---
a/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/check-workflow.vue
+++
b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/check-workflow.vue
@@ -77,10 +77,12 @@
}
}
- const pollJobDetails = (execFunc: Function, interval: number = 200): void =>
{
+ const pollJobDetails = (execFunc: Function, interval: number = 1000): void
=> {
let firstPoll = true
let firstPollCompleted = false
- const intervalId = setInterval(async () => {
+ let intervalId: NodeJS.Timeout
+
+ const poll = async () => {
if (firstPoll) {
spinning.value = true
firstPoll = false
@@ -93,7 +95,10 @@
if (result) {
clearInterval(intervalId)
}
- }, interval)
+ }
+
+ intervalId = setInterval(poll, interval)
+ poll()
}
const viewLogs = (stage: StageVO, task: TaskVO) => {
diff --git a/bigtop-manager-ui/src/pages/cluster-manage/cluster/create.vue
b/bigtop-manager-ui/src/pages/cluster-manage/cluster/create.vue
index 944f2f98..2c58d5b8 100644
--- a/bigtop-manager-ui/src/pages/cluster-manage/cluster/create.vue
+++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/create.vue
@@ -124,7 +124,9 @@
const pollUntilInstalled = (interval: number = 1000): void => {
let isInitialized = false
- const intervalId = setInterval(async () => {
+ let intervalId: NodeJS.Timeout
+
+ const poll = async () => {
if (!isInitialized) {
stepData.value[current.value] =
stepData.value[current.value].map((item: HostReq) => ({
...item,
@@ -137,7 +139,10 @@
installing.value = false
clearInterval(intervalId)
}
- }, interval)
+ }
+
+ intervalId = setInterval(poll, interval)
+ poll()
}
const mergeByHostname = (arr1: any[], arr2: any[]): any[] => {
@@ -167,7 +172,7 @@
// }
const onSave = () => {
- menuStore.updateSiderMenu()
+ menuStore.updateSider()
}
</script>
diff --git a/bigtop-manager-ui/src/pages/cluster-manage/cluster/service.vue
b/bigtop-manager-ui/src/pages/cluster-manage/cluster/service.vue
index be4e1a71..03165b57 100644
--- a/bigtop-manager-ui/src/pages/cluster-manage/cluster/service.vue
+++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/service.vue
@@ -178,7 +178,7 @@
</div>
<div class="header-restart-status">
<span class="small-gray">{{ `${$t('common.restart')}` }}</span>
- <status-dot :color="CommonStatus[statusColors[item.status]]" />
+ <status-dot :color="item.restartFlag ? 'error' : 'success'" />
<span class="small">{{ `${item.restartFlag ? $t('common.required')
: $t('common.not_required')}` }}</span>
</div>
</div>
diff --git a/bigtop-manager-ui/src/pages/cluster-manage/components/index.vue
b/bigtop-manager-ui/src/pages/cluster-manage/components/index.vue
index 07e54bd9..e020f244 100644
--- a/bigtop-manager-ui/src/pages/cluster-manage/components/index.vue
+++ b/bigtop-manager-ui/src/pages/cluster-manage/components/index.vue
@@ -19,11 +19,12 @@
<script setup lang="ts">
import { ref, reactive, computed, onMounted, watchEffect } from 'vue'
import useBaseTable from '@/composables/use-base-table'
- import type { TableColumnType } from 'ant-design-vue'
+ import SetSource from
'@/pages/cluster-manage/cluster/components/set-source.vue'
import { useI18n } from 'vue-i18n'
import { useStackStore } from '@/store/stack'
import { storeToRefs } from 'pinia'
- import { ServiceVO } from '@/api/service/types'
+ import type { ServiceVO } from '@/api/service/types'
+ import type { TableColumnType } from 'ant-design-vue'
const { t } = useI18n()
const stackStore = useStackStore()
@@ -34,10 +35,13 @@
stackSelected: 'Bigtop',
stackGroup: ['Bigtop', 'Infra', 'Extra']
})
+
+ const data = ref<ServiceVO[]>([])
+ const setSourceRef = ref<InstanceType<typeof SetSource>>()
+
const currentStack = computed(() =>
stacks.value.find((stack) => stack.stackName.toUpperCase() ===
store.stackSelected.toUpperCase())
)
- const data = ref<ServiceVO[]>([])
const columns = computed((): TableColumnType[] => [
{
title: '#',
@@ -84,7 +88,7 @@
})
const handleSetSource = () => {
- // setSourceRef.value?.handleOpen()
+ setSourceRef.value?.handleOpen()
}
onMounted(() => {
@@ -95,7 +99,7 @@
<template>
<div class="cluster-components">
<div>
- <div class="menu-title">{{ $t('menu.component') }}</div>
+ <div class="menu-title">{{ $t('menu.stacks') }}</div>
</div>
<div class="cluster-components-header">
<a-radio-group v-model:value="store.stackSelected" button-style="solid">
@@ -118,6 +122,7 @@
</template>
</a-table>
</div>
+ <set-source ref="setSourceRef" />
</div>
</template>
diff --git
a/bigtop-manager-ui/src/pages/cluster-manage/infrastructures/service.vue
b/bigtop-manager-ui/src/pages/cluster-manage/infrastructures/service.vue
index 107b0694..18a0d459 100644
--- a/bigtop-manager-ui/src/pages/cluster-manage/infrastructures/service.vue
+++ b/bigtop-manager-ui/src/pages/cluster-manage/infrastructures/service.vue
@@ -162,7 +162,7 @@
</div>
<div class="header-restart-status">
<span class="small-gray">{{ `${$t('common.restart')}` }}</span>
- <status-dot :color="CommonStatus[statusColors[item.status]]" />
+ <status-dot :color="item.restartFlag ? 'error' : 'success'" />
<span class="small">{{ `${item.restartFlag ?
$t('common.required') : $t('common.not_required')}` }}</span>
</div>
</div>
diff --git a/bigtop-manager-ui/src/pages/login/index.vue
b/bigtop-manager-ui/src/pages/login/index.vue
index 4065f9e4..ab0fc41f 100644
--- a/bigtop-manager-ui/src/pages/login/index.vue
+++ b/bigtop-manager-ui/src/pages/login/index.vue
@@ -18,14 +18,17 @@
-->
<script setup lang="ts">
+ import { useRouter } from 'vue-router'
import { reactive, shallowRef } from 'vue'
- import SelectLang from '@/components/select-lang/index.vue'
import { UserOutlined, LockOutlined } from '@ant-design/icons-vue'
import { login } from '@/api/login'
- import router from '@/router'
- import md5 from 'md5'
import { message } from 'ant-design-vue'
import { useI18n } from 'vue-i18n'
+ import md5 from 'md5'
+ import SelectLang from '@/components/select-lang/index.vue'
+
+ const i18n = useI18n()
+ const router = useRouter()
const formRef = shallowRef()
const submitLoading = shallowRef(false)
@@ -36,7 +39,6 @@
remember: true
})
- const i18n = useI18n()
const submit = async () => {
submitLoading.value = true
const hide = message.loading(i18n.t('login.logging_in'), 0)
@@ -52,9 +54,8 @@
} else {
sessionStorage.setItem('Token', res.token)
}
-
message.success(i18n.t('login.login_success'))
- await router.push('/')
+ router.push('/')
} catch (e) {
console.warn(e)
} finally {
diff --git a/bigtop-manager-ui/src/plugins/index.ts
b/bigtop-manager-ui/src/plugins/index.ts
index 7ece92ec..b81d6464 100644
--- a/bigtop-manager-ui/src/plugins/index.ts
+++ b/bigtop-manager-ui/src/plugins/index.ts
@@ -25,15 +25,16 @@ import Antd, { message } from 'ant-design-vue'
import components from '@/components/common'
import directives from '@/directives'
import VueDOMPurifyHTML from 'vue-dompurify-html'
+
interface PluginOptions {
antdMessageMaxCount: number
}
export default {
install(app: App, options: PluginOptions) {
+ app.use(pinia)
app.use(Antd)
app.use(router)
- app.use(pinia)
app.use(i18n)
app.use(directives)
app.use(components)
diff --git a/bigtop-manager-ui/src/router/guard.ts
b/bigtop-manager-ui/src/router/guard.ts
index 60639814..6f7030f9 100644
--- a/bigtop-manager-ui/src/router/guard.ts
+++ b/bigtop-manager-ui/src/router/guard.ts
@@ -17,14 +17,24 @@
* under the License.
*/
-import type { Router } from 'vue-router'
-
+import type { NavigationGuardNext, Router } from 'vue-router'
+import { useClusterStore } from '@/store/cluster'
function setCommonGuard(router: Router) {
- router.beforeEach(async (_to, _from, next) => {
- next()
+ router.beforeEach(async (to, from, next) => {
+ if (to.name === 'Clusters' && from.name !== 'Login') {
+ checkClusterSelect(next)
+ } else {
+ next()
+ }
})
}
+function checkClusterSelect(next: NavigationGuardNext) {
+ const clusterStore = useClusterStore()
+ clusterStore.clusterCount === 0 && clusterStore.loadClusters()
+ clusterStore.clusterCount === 0 && next({ name: 'Default' })
+}
+
function createRouterGuard(router: Router) {
/** common guard */
setCommonGuard(router)
diff --git a/bigtop-manager-ui/src/router/routes/index.ts
b/bigtop-manager-ui/src/router/routes/index.ts
index 2b1e70df..a68de3ed 100644
--- a/bigtop-manager-ui/src/router/routes/index.ts
+++ b/bigtop-manager-ui/src/router/routes/index.ts
@@ -28,6 +28,7 @@ export const dynamicRoutes: RouteRecordRaw[] =
mergeRouteModules(dynamicRoutesFi
const routes: RouteRecordRaw[] = [
{
+ name: 'Login',
path: '/login',
component: () => import('@/pages/login/index.vue')
},
diff --git a/bigtop-manager-ui/src/router/routes/modules/clusters.ts
b/bigtop-manager-ui/src/router/routes/modules/clusters.ts
index c5ab3450..7e5139b9 100644
--- a/bigtop-manager-ui/src/router/routes/modules/clusters.ts
+++ b/bigtop-manager-ui/src/router/routes/modules/clusters.ts
@@ -24,22 +24,15 @@ import pageView from '@/layouts/index.vue'
const routes: RouteRecordRaw[] = [
{
path: '/cluster-manage',
+ name: 'ClusterManage',
component: pageView,
- redirect: RouteExceptions.SPECIAL_ROUTE_PATH,
+ redirect: '/cluster-manage/clusters',
meta: {
title: 'menu.cluster'
},
children: [
{
- name: RouteExceptions.DEFAULT_ROUTE_NAME,
- path: 'default',
- component: () => import('@/layouts/default.vue'),
- meta: {
- hidden: true
- }
- },
- {
- name: RouteExceptions.SPECIAL_ROUTE_NAME,
+ name: 'Clusters',
path: 'clusters',
redirect: '',
meta: {
@@ -47,9 +40,17 @@ const routes: RouteRecordRaw[] = [
title: 'menu.cluster'
},
children: [
+ {
+ name: 'Default',
+ path: 'default',
+ component: () => import('@/layouts/default.vue'),
+ meta: {
+ hidden: true
+ }
+ },
{
name: 'ClusterDetail',
- path: RouteExceptions.DYNAMIC_ROUTE_MATCH,
+ path: ':cluster/:id',
component: () =>
import('@/pages/cluster-manage/cluster/index.vue'),
meta: {
hidden: true
@@ -65,7 +66,7 @@ const routes: RouteRecordRaw[] = [
},
{
name: 'CreateService',
- path:
`${RouteExceptions.DYNAMIC_ROUTE_MATCH}/create-service/:creationMode?`,
+ path: ':cluster/:id/create-service/:creationMode?',
component: () => import('@/components/create-service/create.vue'),
meta: {
hidden: true
@@ -73,7 +74,7 @@ const routes: RouteRecordRaw[] = [
},
{
name: 'ServiceDetail',
- path:
`${RouteExceptions.DYNAMIC_ROUTE_MATCH}/service-detail/:service/:serviceId`,
+ path: ':cluster/:id/service-detail/:service/:serviceId',
component: () =>
import('@/components/service-management/index.vue'),
meta: {
hidden: true
@@ -81,15 +82,7 @@ const routes: RouteRecordRaw[] = [
},
{
name: 'CreateComponent',
- path:
`${RouteExceptions.DYNAMIC_ROUTE_MATCH}/create-component/:service/:serviceId/:creationMode?/:type`,
- component: () => import('@/components/create-service/create.vue'),
- meta: {
- hidden: true
- }
- },
- {
- name: 'CreateComponent',
- path:
`${RouteExceptions.DYNAMIC_ROUTE_MATCH}/create-component/:service/:serviceId/:creationMode?/:type`,
+ path:
':cluster/:id/create-component/:service/:serviceId/:creationMode?/:type',
component: () => import('@/components/create-service/create.vue'),
meta: {
hidden: true
@@ -112,7 +105,7 @@ const routes: RouteRecordRaw[] = [
component: () =>
import('@/pages/cluster-manage/infrastructures/index.vue'),
meta: {
hidden: true,
- activeMenu: '/cluster-manage/infrastructures'
+ activeMenu: '/cluster-manage/infrastructures/list'
}
},
{
@@ -121,7 +114,7 @@ const routes: RouteRecordRaw[] = [
component: () => import('@/components/create-service/create.vue'),
meta: {
hidden: true,
- activeMenu: '/cluster-manage/infrastructures'
+ activeMenu: '/cluster-manage/infrastructures/list'
}
},
{
@@ -130,16 +123,7 @@ const routes: RouteRecordRaw[] = [
component: () =>
import('@/components/service-management/index.vue'),
meta: {
hidden: true,
- activeMenu: '/cluster-manage/infrastructures'
- }
- },
- {
- name: 'CreateInfraComponent',
- path:
'/create-infra-service/create-infra-component/:id/:cluster/:service/:serviceId/:creationMode/:type',
- component: () => import('@/components/create-service/create.vue'),
- meta: {
- hidden: true,
- activeMenu: '/cluster-manage/infrastructures'
+ activeMenu: '/cluster-manage/infrastructures/list'
}
},
{
@@ -148,7 +132,7 @@ const routes: RouteRecordRaw[] = [
component: () => import('@/components/create-service/create.vue'),
meta: {
hidden: true,
- activeMenu: '/cluster-manage/infrastructures'
+ activeMenu: '/cluster-manage/infrastructures/list'
}
}
]
@@ -156,11 +140,22 @@ const routes: RouteRecordRaw[] = [
{
name: 'Components',
path: 'components',
- component: () => import('@/pages/cluster-manage/components/index.vue'),
+ redirect: '/cluster-manage/components/list',
meta: {
icon: 'components',
- title: 'menu.component'
- }
+ title: 'menu.stacks'
+ },
+ children: [
+ {
+ name: 'ComponentList',
+ path: 'list',
+ component: () =>
import('@/pages/cluster-manage/components/index.vue'),
+ meta: {
+ hidden: true,
+ activeMenu: '/cluster-manage/components/list'
+ }
+ }
+ ]
},
{
name: 'Hosts',
@@ -177,7 +172,7 @@ const routes: RouteRecordRaw[] = [
component: () => import('@/pages/cluster-manage/hosts/index.vue'),
meta: {
hidden: true,
- activeMenu: '/cluster-manage/hosts'
+ activeMenu: '/cluster-manage/hosts/list'
}
},
{
@@ -186,7 +181,7 @@ const routes: RouteRecordRaw[] = [
component: () => import('@/pages/cluster-manage/hosts/create.vue'),
meta: {
hidden: true,
- activeMenu: '/cluster-manage/hosts'
+ activeMenu: '/cluster-manage/hosts/list'
}
},
{
@@ -195,7 +190,7 @@ const routes: RouteRecordRaw[] = [
component: () => import('@/pages/cluster-manage/hosts/detail.vue'),
meta: {
hidden: true,
- activeMenu: '/cluster-manage/hosts'
+ activeMenu: '/cluster-manage/hosts/list'
}
}
]
diff --git a/bigtop-manager-ui/src/router/routes/modules/system.ts
b/bigtop-manager-ui/src/router/routes/modules/system.ts
index 0bfaf729..5a591a13 100644
--- a/bigtop-manager-ui/src/router/routes/modules/system.ts
+++ b/bigtop-manager-ui/src/router/routes/modules/system.ts
@@ -22,7 +22,8 @@ import pageView from '@/layouts/index.vue'
const routes: RouteRecordRaw[] = [
{
- path: '/system-manage/',
+ name: 'SystemManage',
+ path: '/system-manage',
component: pageView,
redirect: '/system-manage/llm-config',
meta: {
@@ -32,11 +33,22 @@ const routes: RouteRecordRaw[] = [
{
name: 'LlmConfig',
path: 'llm-config',
- component: () => import('@/pages/system-manage/llm-config/index.vue'),
+ redirect: '/system-manage/llm-config/list',
meta: {
icon: 'llm_config',
title: 'menu.llm_config'
- }
+ },
+ children: [
+ {
+ name: 'LlmConfigList',
+ path: 'list',
+ component: () =>
import('@/pages/system-manage/llm-config/index.vue'),
+ meta: {
+ hidden: true,
+ activeMenu: '/system-manage/llm-config/list'
+ }
+ }
+ ]
}
]
}
diff --git a/bigtop-manager-ui/src/store/cluster/index.ts
b/bigtop-manager-ui/src/store/cluster/index.ts
index 4380c728..b9a77030 100644
--- a/bigtop-manager-ui/src/store/cluster/index.ts
+++ b/bigtop-manager-ui/src/store/cluster/index.ts
@@ -35,6 +35,7 @@ export const useClusterStore = defineStore(
const loading = ref(false)
const currCluster = ref<ClusterVO>({})
const clusterId = computed(() => (route.params.id as string) || undefined)
+ const clusterCount = computed(() => clusters.value.length)
watch(
() => clusters.value,
@@ -60,10 +61,9 @@ export const useClusterStore = defineStore(
try {
loading.value = true
currCluster.value = await getCluster(parseInt(clusterId.value))
- currCluster.value.id != undefined && (await
serviceStore.getServices(currCluster.value.id))
+ await serviceStore.getServices(currCluster.value.id!)
} catch (error) {
currCluster.value = {}
- clusters.value = []
console.log('error :>> ', error)
} finally {
loading.value = false
@@ -71,13 +71,19 @@ export const useClusterStore = defineStore(
}
const loadClusters = async () => {
- clusters.value = await getClusterList()
+ try {
+ clusters.value = await getClusterList()
+ } catch (error) {
+ clusters.value.length = 0
+ console.log('error :>> ', error)
+ }
}
return {
clusters,
loading,
currCluster,
+ clusterCount,
addCluster,
delCluster,
loadClusters,
diff --git a/bigtop-manager-ui/src/store/menu/index.ts
b/bigtop-manager-ui/src/store/menu/index.ts
index eec8d342..ab265c16 100644
--- a/bigtop-manager-ui/src/store/menu/index.ts
+++ b/bigtop-manager-ui/src/store/menu/index.ts
@@ -17,15 +17,11 @@
* under the License.
*/
-import { computed, ref, watchEffect } from 'vue'
-import { useRoute, useRouter } from 'vue-router'
+import { nextTick, ref, shallowRef } from 'vue'
+import { RouteRecordRaw, useRoute, useRouter } from 'vue-router'
import { dynamicRoutes as dr } from '@/router/routes/index'
-import { defineStore, storeToRefs } from 'pinia'
-import { useClusterStore } from '@/store/cluster/index'
-import { RouteExceptions } from '@/enums'
-import { findActivePath } from './helper'
-import type { MenuItem } from './types'
-import cloneDeep from 'lodash/cloneDeep'
+import { defineStore } from 'pinia'
+import { useClusterStore } from '../cluster'
export const useMenuStore = defineStore(
'menu',
@@ -33,136 +29,61 @@ export const useMenuStore = defineStore(
const router = useRouter()
const route = useRoute()
const clusterStore = useClusterStore()
- const { clusters } = storeToRefs(clusterStore)
-
- const baseRoutesMap = ref<Map<string, MenuItem[]>>(new Map())
- const headerMenus = ref(dr.filter((v) => v.meta?.title && !v.meta.hidden))
- const headerSelectedKey = ref(headerMenus.value[0].path)
-
- const hasCluster = computed(() => clusters.value.length > 0)
- const isCreateClusterVisible = computed(() =>
RouteExceptions.SPECIAL_ROUTE_PATH.includes(route.matched[0].path))
- const isDynamicRouteMatched = computed(() => {
- const path = route.matched.at(-1)?.path
- return path?.includes(RouteExceptions.DYNAMIC_ROUTE_MATCH)
- })
-
- const updateSiderItemByClusters = (formatSider: MenuItem[]) => {
- formatSider.forEach((item) => {
- if (item.name == RouteExceptions.SPECIAL_ROUTE_NAME) {
- item.children = clusters.value.map((v) => {
- return {
- icon: '',
- key: `${item.key}/${v.displayName}/${v.id}`,
- label: v.displayName || '',
- title: v.displayName || '',
- activeMenu: item.key,
- status: v.status || 3
- }
- })
- }
- })
+ const baseRoutesMap = ref<Record<string, RouteRecordRaw>>({})
+ const headerMenus = ref<RouteRecordRaw[]>([])
+ const siderMenus = ref<RouteRecordRaw[]>([])
+ const headerSelectedKey = ref()
+ const siderMenuSelectedKey = ref()
+ const routePathFromClusters = shallowRef('/cluster-manage/clusters')
+
+ const buildMenuMap = () => {
+ baseRoutesMap.value = dr.reduce((buildRes, { path, name, meta, children
}) => {
+ !meta?.hidden && (buildRes[path] = { path, name, meta, children })
+ return buildRes
+ }, {})
}
- const siderMenus = computed((): MenuItem[] => {
- const siderMenuTemplate =
baseRoutesMap.value.get(headerSelectedKey.value) || []
- const formatSider = cloneDeep(siderMenuTemplate)
- if (hasCluster.value) {
- updateSiderItemByClusters(formatSider as MenuItem[])
- }
- return formatSider
- })
-
- const siderMenuSelectedKey = ref(findActivePath(siderMenus.value[0]))
-
- const redirectRouterToDefault = () => {
- siderMenuSelectedKey.value = ''
- router.replace({ name: RouteExceptions.DEFAULT_ROUTE_NAME })
+ const setupHeader = () => {
+ headerSelectedKey.value = route.matched[0].path ?? '/cluster-manage'
+ headerMenus.value = Object.values(baseRoutesMap.value)
+ siderMenus.value = baseRoutesMap.value[headerSelectedKey.value].children
|| []
}
- watchEffect(() => {
- // resolve highlight menu
- let activeMenu = route.meta.activeMenu || route.path
- if (route.name === 'CreateService') {
- activeMenu = route.path.split('/').slice(0, -2).join('/')
- }
- if (route.name === 'ServiceDetail') {
- activeMenu = route.path.split('/').slice(0, -3).join('/')
- }
- if (route.name === 'CreateComponent') {
- activeMenu = route.path.split('/').slice(0, -5).join('/')
- }
- const matchedNames = [RouteExceptions.SPECIAL_ROUTE_NAME,
RouteExceptions.DEFAULT_ROUTE_NAME] as string[]
- headerSelectedKey.value = route.matched[0].path
-
- if (matchedNames.includes(route.name as string)) {
- if (hasCluster.value && isDynamicRouteMatched.value) {
- siderMenuSelectedKey.value = findActivePath(siderMenus.value[0])
- } else {
- siderMenuSelectedKey.value = activeMenu
- redirectRouterToDefault()
- }
+ const setupSider = () => {
+ siderMenus.value = baseRoutesMap.value[headerSelectedKey.value].children
|| []
+ if (siderMenus.value[0].redirect) {
+ siderMenuSelectedKey.value = siderMenus.value[0].redirect
} else {
- if (!activeMenu || (isDynamicRouteMatched.value && !hasCluster.value))
{
- redirectRouterToDefault()
- return
+ if (clusterStore.clusters[0]) {
+ const { id, name } = clusterStore.clusters[0]
+ onSiderClick(`${routePathFromClusters.value}/${name}/${id}`)
+ } else {
+ onSiderClick(`${routePathFromClusters.value}/default`)
}
- siderMenuSelectedKey.value = activeMenu
}
- })
-
- const formatRouteToMenu = (tree: any[], upPath = ''): MenuItem[] => {
- return tree
- .filter(({ meta }) => !meta?.hidden)
- .map(({ path, name, meta, children }) => {
- const fullPath = `${upPath}${path}`
- return {
- icon: meta.icon,
- key: fullPath,
- label: meta.title || '',
- title: meta.title || '',
- name: name || '',
- children: children && children.length > 0 ?
formatRouteToMenu(children, fullPath) : []
- }
- })
- }
-
- const setBaseRoutesMap = () => {
- dr.forEach((route) => {
- if (!route.meta?.hidden) {
- const exist = baseRoutesMap.value.get(route.path) || []
- baseRoutesMap.value.set(route.path, [...exist,
...formatRouteToMenu(route.children || [], route.path)])
- }
- })
}
const onHeaderClick = (key: string) => {
headerSelectedKey.value = key
- if (!hasCluster.value && route.name ==
RouteExceptions.SPECIAL_ROUTE_NAME) {
- return
- }
- siderMenuSelectedKey.value = findActivePath(siderMenus.value[0])
- siderMenuSelectedKey.value && router.push(siderMenuSelectedKey.value)
+ router.push({ path: key })
+ setupSider()
}
const onSiderClick = (key: string) => {
- siderMenuSelectedKey.value = key
- router.push(key)
- }
-
- const updateSiderMenu = async (isDelete = false) => {
- isDelete ? await clusterStore.delCluster() : await
clusterStore.addCluster()
- siderMenuSelectedKey.value = siderMenus.value[0].children?.at(-1)?.key
|| RouteExceptions.SPECIAL_ROUTE_PATH
- router.push(siderMenuSelectedKey.value)
+ router.push({ path: key })
}
- const setUpMenu = async () => {
- setBaseRoutesMap()
+ const updateSider = async () => {
await clusterStore.loadClusters()
- updateSiderMenu()
+ const { id, name } = clusterStore.clusters[clusterStore.clusterCount - 1]
+ await nextTick()
+ onSiderClick(`${routePathFromClusters.value}/${name}/${id}`)
}
- const cleanUpMenu = () => {
- baseRoutesMap.value.clear()
+ const setupMenu = async () => {
+ buildMenuMap()
+ setupHeader()
+ setupSider()
}
return {
@@ -170,20 +91,17 @@ export const useMenuStore = defineStore(
siderMenus,
headerSelectedKey,
siderMenuSelectedKey,
- isCreateClusterVisible,
- isDynamicRouteMatched,
- setUpMenu,
- cleanUpMenu,
- setBaseRoutesMap,
+ routePathFromClusters,
+ setupMenu,
+ updateSider,
onHeaderClick,
- onSiderClick,
- updateSiderMenu
+ onSiderClick
}
},
{
persist: {
- storage: localStorage,
- paths: ['siderMenus']
+ storage: sessionStorage,
+ paths: ['headerMenus', 'siderMenus']
}
}
)
diff --git a/bigtop-manager-ui/src/utils/router-util.ts
b/bigtop-manager-ui/src/utils/router-util.ts
index 150cfcd1..661332ef 100644
--- a/bigtop-manager-ui/src/utils/router-util.ts
+++ b/bigtop-manager-ui/src/utils/router-util.ts
@@ -29,30 +29,5 @@ export const mergeRouteModules = (routeModules:
Record<string, unknown>): RouteR
mergedRoutes.push(...moduleRoutes)
}
- return getMergeRoutes(mergedRoutes)
-}
-
-const getMergeRoutes = <T extends RouteRecordRaw>(routes: T[]): T[] => {
- const mergedMap = new Map()
- routes.forEach((route: T) => {
- const firstLevelPath = route.path.split('/')[1]
- if (!mergedMap.has(firstLevelPath)) {
- mergedMap.set(firstLevelPath, {
- path: `/${firstLevelPath}/`,
- component: route.component,
- meta: route.meta,
- children: [],
- redirect: route.redirect || undefined
- })
- }
- if (route.children) {
- const existingRoute = mergedMap.get(firstLevelPath)
- route.children.forEach((child) => {
- if (!existingRoute.children.some((c: T) => c.path === child.path)) {
- existingRoute.children.push(child)
- }
- })
- }
- })
- return Array.from(mergedMap.values())
+ return mergedRoutes
}