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 21739ef3 BIGTOP-4401: Supports adding/deleting components (#201)
21739ef3 is described below
commit 21739ef37ebafe06a8e57b41a8e2a8beba1fb2e3
Author: Fdefined <[email protected]>
AuthorDate: Wed Apr 9 14:50:06 2025 +0800
BIGTOP-4401: Supports adding/deleting components (#201)
---
.../src/components/common/button-group/index.vue | 6 +-
.../src/components/common/button-group/types.ts | 4 +-
.../components/component-assigner.vue | 44 ++++++++---
.../components/component-installer.vue | 13 ++--
.../components/service-configurator.vue | 16 +++-
.../create-service/components/service-selector.vue | 48 +++++++++---
.../components/use-create-service.ts | 88 ++++++++++++++++++----
.../src/components/create-service/create.vue | 41 +++++++---
bigtop-manager-ui/src/components/job/index.vue | 2 +-
.../cluster/components/check-workflow.vue | 1 -
.../cluster/components/host-config.vue | 2 +-
.../src/pages/cluster-manage/cluster/host.vue | 67 ++++++++++++----
.../cluster/service-management/components.vue | 23 ++++--
.../components/snapshot-management.vue | 2 +-
.../cluster/service-management/index.vue | 2 +-
.../src/pages/cluster-manage/cluster/service.vue | 2 +-
.../src/pages/cluster-manage/hosts/create.vue | 3 +-
.../src/pages/cluster-manage/hosts/index.vue | 4 +-
.../cluster-manage/hosts/install-dependencies.vue | 2 +-
.../pages/cluster-manage/infrastructures/index.vue | 14 +++-
.../src/router/routes/modules/clusters.ts | 21 +++++-
bigtop-manager-ui/src/store/menu/index.ts | 3 +
bigtop-manager-ui/src/store/stack/index.ts | 2 +-
bigtop-manager-ui/src/styles/index.scss | 2 +-
24 files changed, 312 insertions(+), 100 deletions(-)
diff --git a/bigtop-manager-ui/src/components/common/button-group/index.vue
b/bigtop-manager-ui/src/components/common/button-group/index.vue
index 43ee306a..7d475c5c 100644
--- a/bigtop-manager-ui/src/components/common/button-group/index.vue
+++ b/bigtop-manager-ui/src/components/common/button-group/index.vue
@@ -34,7 +34,7 @@
})
const { t } = useI18n()
- const { groups, groupShape, groupType, space, args } = toRefs(props)
+ const { groups, groupShape, groupType, space, payload } = toRefs(props)
const checkTitle = (item: GroupItem) => {
if (props.i18n) {
@@ -52,7 +52,7 @@
<template>
<a-space :size="space" :wrap="true" :class="{ 'text-compact':
$props.textCompact, 'btn-auto': $props.auto }">
<template v-for="(item, _index) in groups" :key="_index">
- <template v-if="!item.hidden">
+ <template v-if="!(typeof item.hidden === 'function' ? item.hidden(item,
payload) : item.hidden ?? false)">
<a-dropdown v-if="item.dropdownMenu">
<a-button
:disabled="item.disabled"
@@ -83,7 +83,7 @@
:shape="item.shape || groupShape || 'default'"
:type="item.type || groupType || 'default'"
:title="checkTitle(item)"
- @click="item.clickEvent ? item.clickEvent(item, args) : () => {}"
+ @click="item.clickEvent ? item.clickEvent(item, payload) : () => {}"
>
<template #icon>
<slot name="icon" :item="item" />
diff --git a/bigtop-manager-ui/src/components/common/button-group/types.ts
b/bigtop-manager-ui/src/components/common/button-group/types.ts
index 4125e867..b309a171 100644
--- a/bigtop-manager-ui/src/components/common/button-group/types.ts
+++ b/bigtop-manager-ui/src/components/common/button-group/types.ts
@@ -31,7 +31,7 @@ export interface GroupItem<T = any> {
tip?: string
text?: string
action?: T
- hidden?: boolean
+ hidden?: boolean | ((item?: GroupItem<T>, ...args: any[]) => boolean)
type?: BtnType
shape?: ShapeType
disabled?: boolean
@@ -48,6 +48,6 @@ export interface Props {
groupType?: BtnType
groupShape?: ShapeType
space?: number
- args?: any
+ payload?: any
auto?: boolean
}
diff --git
a/bigtop-manager-ui/src/components/create-service/components/component-assigner.vue
b/bigtop-manager-ui/src/components/create-service/components/component-assigner.vue
index df9574b1..231d354a 100644
---
a/bigtop-manager-ui/src/components/create-service/components/component-assigner.vue
+++
b/bigtop-manager-ui/src/components/create-service/components/component-assigner.vue
@@ -48,7 +48,16 @@
searchedColumn: '',
selectedRowKeys: []
})
- const { clusterId, installedStore, allComps, selectedServices,
updateHostsForComponent } = useCreateService()
+ const {
+ clusterId,
+ installedStore,
+ allComps,
+ allCompsMeta,
+ creationModeType,
+ selectedServices,
+ updateHostsForComponent
+ } = useCreateService()
+
const serviceList = computed(() =>
selectedServices.value.map((v) => ({
...v,
@@ -56,10 +65,14 @@
}))
)
+ const currCompInfo = computed(() =>
allComps.value.get(currComp.value.split('/')[1]))
+ const currCompInfoMeta = computed(() =>
allCompsMeta.value.get(currComp.value.split('/')[1]))
+ const installedServices = computed(() =>
installedStore.getInstalledNamesOrIdsOfServiceByKey(`${clusterId.value}`))
const hostsOfCurrComp = computed((): HostVO[] => {
const temp = currComp.value.split('/').at(-1)
- return allComps.value.has(temp) ? allComps.value.get(temp)?.hosts : []
+ return allComps.value.has(temp!) ? allComps.value.get(temp!)?.hosts ?? []
: []
})
+
const columns = computed((): TableColumnType<HostVO>[] => [
{
title: t('host.hostname'),
@@ -119,20 +132,31 @@
onChangeCallback: getHostList
})
- const getCheckboxProps: TableRowSelection['getCheckboxProps'] = (record) =>
({
- disabled: installedStore
- .getInstalledNamesOrIdsOfServiceByKey(`${clusterId.value}`)
- .includes(currComp.value.split('/')[0]),
- name: record.hostname
- })
+ const validateHostIsCheck = (host: HostVO) => {
+ const notAdd = currCompInfoMeta.value?.hosts.findIndex((v) => v.hostname
=== host.hostname) == -1
+ if (creationModeType.value === 'component') {
+ return !currCompInfo.value?.uninstall && !notAdd
+ } else {
+ return installedServices.value.includes(currComp.value.split('/')[0]) &&
!notAdd
+ }
+ }
+
+ const getCheckboxProps: TableRowSelection['getCheckboxProps'] = (record) => {
+ return {
+ disabled: validateHostIsCheck(record),
+ name: record.hostname
+ }
+ }
const onSelectChange: TableRowSelection['onChange'] = (selectedRowKeys,
selectedRows) => {
- allComps.value.has(currComp.value.split('/').at(-1)) &&
updateHostsForComponent(currComp.value, selectedRows)
+ allComps.value.has(currComp.value.split('/').at(-1)!) &&
updateHostsForComponent(currComp.value, selectedRows)
state.selectedRowKeys = selectedRowKeys
}
const resetSelectedRowKeys = (key: string) => {
- state.selectedRowKeys = allComps.value.has(key) ?
allComps.value.get(key)?.hosts.map((v: HostVO) => v.hostname) : []
+ state.selectedRowKeys = allComps.value.has(key)
+ ? (allComps.value.get(key)?.hosts.map((v: HostVO) => v.hostname) as
Key[]) ?? ([] as Key[])
+ : []
}
const treeSelectedChange = (keyPath: string) => {
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 825533af..af08100d 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
@@ -48,14 +48,13 @@
})
const getJobInstanceDetails = async () => {
- const { id: jobId } = stepData.value
+ const { id: jobId, clusterId } = stepData.value
if (jobId === undefined) {
return true
}
try {
- const data = await getJobDetails({ jobId, clusterId: 0 })
+ const data = await getJobDetails({ jobId, clusterId })
jobDetail.value = data
- activeKey.value = data.stages ? data.stages?.map((v) => v.id!) : []
return ['Successful', 'Failed'].includes(data.state as StateType)
} catch (error) {
console.log('error :>> ', error)
@@ -64,12 +63,12 @@
}
const handleRetryJob = async () => {
- const { id: jobId } = stepData.value
+ const { id: jobId, clusterId } = stepData.value
if (jobId === undefined) {
return true
}
try {
- await retryJob({ jobId, clusterId: 0 })
+ await retryJob({ jobId, clusterId })
pollJobDetails(getJobInstanceDetails)
} catch (error) {
console.log('error :>> ', error)
@@ -96,14 +95,14 @@
}
const viewLogs = (stage: StageVO, task: TaskVO) => {
- const { id: jobId } = stepData.value
+ const { id: jobId, clusterId } = stepData.value
const { id: stageId } = stage
const { id: taskId } = task
if (jobId === undefined || stageId === undefined || taskId === undefined) {
return
}
logsViewState.payLoad = {
- clusterId: 0,
+ clusterId,
jobId,
stageId,
taskId
diff --git
a/bigtop-manager-ui/src/components/create-service/components/service-configurator.vue
b/bigtop-manager-ui/src/components/create-service/components/service-configurator.vue
index 37073c1d..0fb1aa07 100644
---
a/bigtop-manager-ui/src/components/create-service/components/service-configurator.vue
+++
b/bigtop-manager-ui/src/components/create-service/components/service-configurator.vue
@@ -62,13 +62,21 @@
lg: { span: 17 }
}
})
- const serviceList = computed(() => selectedServices.value)
- const disabled = computed(() =>
- installedStore
+ const serviceList = computed(() => selectedServices.value)
+ const disabled = computed(() => {
+ return installedStore
.getInstalledNamesOrIdsOfServiceByKey(`${clusterId.value}`)
.includes(currService.value.toString().split('/').at(-1)!)
- )
+ })
+
+ // const disabled = computed(() => {
+ // return creationModeType.value === 'component'
+ // ? false
+ // : installedStore
+ // .getInstalledNamesOrIdsOfServiceByKey(`${clusterId.value}`)
+ // .includes(currService.value.toString().split('/').at(-1)!)
+ // })
watch(
() => props.isView,
diff --git
a/bigtop-manager-ui/src/components/create-service/components/service-selector.vue
b/bigtop-manager-ui/src/components/create-service/components/service-selector.vue
index f8b47788..464242b6 100644
---
a/bigtop-manager-ui/src/components/create-service/components/service-selector.vue
+++
b/bigtop-manager-ui/src/components/create-service/components/service-selector.vue
@@ -18,18 +18,18 @@
-->
<script setup lang="ts">
- import { computed, onActivated, reactive, ref, toRefs, useAttrs } from 'vue'
+ import { computed, onActivated, reactive, ref, toRefs } from 'vue'
import { usePngImage } from '@/utils/tools'
import useCreateService from './use-create-service'
import type { ExpandServiceVO } from '@/store/stack'
- import { ComponentVO } from '@/api/component/types.ts'
+ import type { ComponentVO } from '@/api/component/types.ts'
+ import type { ServiceVO } from '@/api/service/types'
interface State {
isAddableData: ExpandServiceVO[]
selectedData: ExpandServiceVO[]
}
- const { creationMode } = useAttrs()
const searchStr = ref('')
const state = reactive<State>({
isAddableData: [],
@@ -37,10 +37,13 @@
})
const {
clusterId,
+ routeParams,
selectedServices,
servicesOfInfra,
servicesOfExcludeInfra,
installedStore,
+ creationMode,
+ creationModeType,
confirmServiceDependencies,
setDataByCurrent
} = useCreateService()
@@ -142,20 +145,41 @@
}
}
+ const mergeInherentServiceAndInstalledService = (
+ installedServiceMap: Map<string, ExpandServiceVO>,
+ inherentServices: ServiceVO[]
+ ) => {
+ const inherentService = inherentServices.filter((v) => v.name ===
routeParams.value.service)[0]
+ const installedService = {
...installedServiceMap.get(routeParams.value.service)! }
+ const map = new Map(installedService.components!.map((item) => [item.name,
item]))
+ inherentService.components!.forEach((item) => {
+ !map.has(item.name) && map.set(item.name, { ...item, hosts: [],
uninstall: true })
+ })
+ installedService.components = [...map.values()]
+ return installedService
+ }
+
const addInstalledSymbolForSelectedServices = async (onlyInstalled: boolean)
=> {
if (onlyInstalled) {
const installedServiceMap = await initInstalledServicesDetail()
const installedServiceNames =
installedStore.getInstalledNamesOrIdsOfServiceByKey(`${clusterId.value}`)
- const data = creationMode === 'internal' ? servicesOfExcludeInfra.value
: servicesOfInfra.value
- data.forEach((v) => {
- if (installedServiceNames.includes(v.name || '')) {
- Object.assign(v, installedServiceMap.get(v.name!))
- v.isInstalled = true
- state.selectedData.push(v as ExpandServiceVO)
- } else {
- state.isAddableData.push(v as ExpandServiceVO)
+ const inherentServices = creationMode.value === 'internal' ?
servicesOfExcludeInfra.value : servicesOfInfra.value
+
+ if (creationModeType.value === 'component' &&
installedServiceMap.has(routeParams.value.service)) {
+ state.selectedData[0] =
mergeInherentServiceAndInstalledService(installedServiceMap, inherentServices)
+ state.selectedData[0].isInstalled = true
+ state.isAddableData = []
+ } else {
+ for (const service of inherentServices) {
+ if (installedServiceNames.includes(service.name || '')) {
+ Object.assign(service, installedServiceMap.get(service.name!))
+ service.isInstalled = true
+ state.selectedData.push(service as ExpandServiceVO)
+ } else {
+ state.isAddableData.push(service as ExpandServiceVO)
+ }
}
- })
+ }
setDataByCurrent(state.selectedData)
} else {
state.selectedData = [...selectedServices.value]
diff --git
a/bigtop-manager-ui/src/components/create-service/components/use-create-service.ts
b/bigtop-manager-ui/src/components/create-service/components/use-create-service.ts
index 021c8fd5..aaaeb25c 100644
---
a/bigtop-manager-ui/src/components/create-service/components/use-create-service.ts
+++
b/bigtop-manager-ui/src/components/create-service/components/use-create-service.ts
@@ -29,15 +29,28 @@ import SvgIcon from '@/components/common/svg-icon/index.vue'
import type { HostVO } from '@/api/hosts/types'
import type { CommandRequest, CommandVO, ServiceCommandReq } from
'@/api/command/types'
import type { ServiceVO } from '@/api/service/types'
+import type { ComponentVO } from '@/api/component/types'
interface ProcessResult {
success: boolean
conflictService?: ExpandServiceVO
}
+interface RouteParams {
+ service: string
+ serviceId: number
+ id: number
+ cluster: string
+}
+
+interface CompItem extends ComponentVO {
+ hosts: HostVO[]
+}
+
const scope = effectScope()
let isChange = false
let selectedServices: Ref<ExpandServiceVO[]>
+let selectedServicesMeta: Ref<ExpandServiceVO[]>
let afterCreateRes: Ref<CommandVO>
let servicesOfInfra: ComputedRef<ExpandServiceVO[]>
let servicesOfExcludeInfra: ComputedRef<ExpandServiceVO[] | ServiceVO[]>
@@ -46,7 +59,8 @@ let steps: ComputedRef<string[]>
const setupStore = () => {
scope.run(() => {
selectedServices = ref<ExpandServiceVO[]>([])
- afterCreateRes = ref<CommandVO>({ id: undefined })
+ selectedServicesMeta = ref<ExpandServiceVO[]>([])
+ afterCreateRes = ref<{ clusterId: number } & CommandVO>({ id: undefined,
clusterId: 0 })
servicesOfInfra = computed(() =>
useStackStore().getServicesByExclude(['bigtop', 'extra']) as ExpandServiceVO[])
servicesOfExcludeInfra = computed(() =>
useStackStore().getServicesByExclude(['infra']))
steps = computed(() => [
@@ -71,6 +85,36 @@ const useCreateService = () => {
const { current, stepsLimit, previousStep, nextStep } = useSteps(steps.value)
const clusterId = computed(() => Number(route.params.id))
const creationMode = computed(() => route.params.creationMode as 'internal'
| 'public')
+ const creationModeType = computed(() => route.params.type)
+ const routeParams = computed(() => route.params as unknown as RouteParams)
+
+ const commandRequest = ref<CommandRequest>({
+ command: 'Add',
+ commandLevel: 'service',
+ clusterId: clusterId.value
+ })
+
+ const allComps = computed(() => {
+ return new Map(
+ selectedServices.value.flatMap((s) =>
+ s.components!.map((comp) => [
+ comp.name,
+ { serviceName: s.name, serviceDisplayName: s.displayName, serviceId:
s.id, ...comp }
+ ])
+ )
+ ) as Map<string, CompItem>
+ })
+
+ const allCompsMeta = computed(() => {
+ return new Map(
+ selectedServicesMeta.value.flatMap((s) =>
+ s.components!.map((comp) => [
+ comp.name,
+ { serviceName: s.name, serviceDisplayName: s.displayName, serviceId:
s.id, ...comp }
+ ])
+ )
+ ) as Map<string, CompItem>
+ })
watch(
() => selectedServices.value,
@@ -82,18 +126,9 @@ const useCreateService = () => {
}
)
- const commandRequest = ref<CommandRequest>({
- command: 'Add',
- commandLevel: 'service',
- clusterId: clusterId.value
- })
-
- const allComps = computed(() => {
- return new Map(selectedServices.value.flatMap((s) =>
s.components!.map((comp) => [comp.name, comp])))
- })
-
const setDataByCurrent = (val: ExpandServiceVO[]) => {
selectedServices.value = val
+ selectedServicesMeta.value = JSON.parse(JSON.stringify(val))
}
const updateHostsForComponent = (compName: string, hosts: HostVO[]) => {
@@ -220,6 +255,26 @@ const useCreateService = () => {
try {
commandRequest.value.serviceCommands =
transformServiceData(selectedServices.value)
afterCreateRes.value = await execCommand(commandRequest.value)
+ Object.assign(afterCreateRes.value, { clusterId })
+ return true
+ } catch (error) {
+ console.log('error :>> ', error)
+ return false
+ }
+ }
+
+ const addComponentForService = async () => {
+ try {
+ commandRequest.value.commandLevel = 'component'
+ commandRequest.value.componentCommands = []
+ for (const [compName, comp] of allComps.value) {
+ commandRequest.value.componentCommands?.push({
+ componentName: compName!,
+ hostnames: comp.hosts.map((v) => v.hostname!)
+ })
+ }
+ afterCreateRes.value = await execCommand(commandRequest.value)
+ Object.assign(afterCreateRes.value, { clusterId })
return true
} catch (error) {
console.log('error :>> ', error)
@@ -233,19 +288,24 @@ const useCreateService = () => {
current,
stepsLimit,
selectedServices,
+ selectedServicesMeta,
servicesOfExcludeInfra,
servicesOfInfra,
installedStore,
allComps,
afterCreateRes,
+ scope,
+ creationMode,
+ creationModeType,
+ routeParams,
+ allCompsMeta,
setDataByCurrent,
+ addComponentForService,
updateHostsForComponent,
confirmServiceDependencies,
createService,
previousStep,
- nextStep,
- scope,
- creationMode
+ nextStep
}
}
diff --git a/bigtop-manager-ui/src/components/create-service/create.vue
b/bigtop-manager-ui/src/components/create-service/create.vue
index 48f7e7cb..e687373b 100644
--- a/bigtop-manager-ui/src/components/create-service/create.vue
+++ b/bigtop-manager-ui/src/components/create-service/create.vue
@@ -35,18 +35,34 @@
stepsLimit,
steps,
allComps,
+ allCompsMeta,
+ creationModeType,
afterCreateRes,
selectedServices,
setDataByCurrent,
previousStep,
nextStep,
createService,
- confirmServiceDependencies
+ confirmServiceDependencies,
+ addComponentForService
} = useCreateService()
const compRef = ref<any>()
const currComp = computed(() => components.value[current.value])
+ const noUninstallComponent = computed(() => {
+ return (
+ current.value === 1 &&
+ creationModeType.value === 'component' &&
+ Array.from(allComps.value).every(
+ ([compName, { hosts }]) => hosts.length ===
allCompsMeta.value.get(compName)?.hosts?.length
+ )
+ )
+ })
const validateServiceSelection = async () => {
+ if (creationModeType.value === 'component') {
+ return true
+ }
+
if (selectedServices.value.filter((v) => !v.isInstalled).length === 0) {
message.error(t('service.service_selection'))
return false
@@ -57,16 +73,17 @@
const validateDependenciesOfServiceSelection = async () => {
let selectedServiceNames = new Set(selectedServices.value.map((service) =>
service.name))
- for (const service of selectedServices.value) {
- const res = await confirmServiceDependencies(service)
- if (res.length === 0) {
+ for (const selectedService of selectedServices.value) {
+ const serviceDependencies = await
confirmServiceDependencies(selectedService)
+ if (serviceDependencies.length === 0) {
return false
}
- const filter = res.filter((service) =>
!selectedServiceNames.has(service.name))
- filter.forEach((service) => {
- compRef.value.addInstallItem(service)
- selectedServiceNames.add(service.name)
- })
+ for (const service of serviceDependencies) {
+ if (!selectedServiceNames.has(service.name)) {
+ compRef.value.addInstallItem(service)
+ selectedServiceNames.add(service.name)
+ }
+ }
}
return true
}
@@ -86,7 +103,7 @@
if (current.value < 3) {
;(await stepValidators[current.value]()) && nextStep()
} else if (current.value === 3) {
- const state = await createService()
+ const state = creationModeType.value === 'component' ? await
addComponentForService() : await createService()
if (state) {
nextStep()
}
@@ -124,7 +141,7 @@
:is="currComp"
ref="compRef"
:is-view="current === 3"
- v-bind="{ creationMode: $route.params.creationMode || 'internal' }"
+ v-bind="{ ...$route.params, creationMode: $route.params.creationMode
|| 'internal' }"
/>
</keep-alive>
<component-installer v-if="current == stepsLimit"
:step-data="afterCreateRes" />
@@ -135,7 +152,7 @@
{{ $t('common.prev') }}
</a-button>
<template v-if="current >= 0 && current <= stepsLimit - 1">
- <a-button type="primary" @click="proceedToNextStep">
+ <a-button :disabled="noUninstallComponent" type="primary"
@click="proceedToNextStep">
{{ $t('common.next') }}
</a-button>
</template>
diff --git a/bigtop-manager-ui/src/components/job/index.vue
b/bigtop-manager-ui/src/components/job/index.vue
index dd849522..2bdb7f88 100644
--- a/bigtop-manager-ui/src/components/job/index.vue
+++ b/bigtop-manager-ui/src/components/job/index.vue
@@ -152,7 +152,7 @@
loading.value = true
}
const { api } = apiMap.value[breadcrumbs.value.length - 1]
- const res = await api(apiParams.value, { ...filtersParams.value, order:
'desc' })
+ const res = await api(apiParams.value, { ...filtersParams.value, sort:
'desc' })
dataSource.value = res.content
paginationProps.value.total = res.total
} catch (error) {
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 c10c0920..7e3e4974 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
@@ -56,7 +56,6 @@
try {
const data = await getJobDetails({ jobId, clusterId: 0 })
jobDetail.value = data
- activeKey.value = data.stages ? data.stages?.map((v) => v.id!) : []
emits('updateData', { ...stepData.value, ...data })
return ['Successful', 'Failed'].includes(data.state as StateType)
} catch (error) {
diff --git
a/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/host-config.vue
b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/host-config.vue
index 7c0f7266..98b0d0a5 100644
---
a/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/host-config.vue
+++
b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/host-config.vue
@@ -239,7 +239,7 @@
:text-compact="true"
:space="24"
:groups="operations"
- :args="record"
+ :payload="record"
group-shape="default"
group-type="link"
></button-group>
diff --git a/bigtop-manager-ui/src/pages/cluster-manage/cluster/host.vue
b/bigtop-manager-ui/src/pages/cluster-manage/cluster/host.vue
index e0e2ba9f..495becf0 100644
--- a/bigtop-manager-ui/src/pages/cluster-manage/cluster/host.vue
+++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/host.vue
@@ -18,15 +18,20 @@
-->
<script setup lang="ts">
- import { TableColumnType, TableProps } from 'ant-design-vue'
+ import { message, Modal, TableColumnType, TableProps } from 'ant-design-vue'
import { computed, onActivated, reactive, ref, useAttrs } from 'vue'
import { useI18n } from 'vue-i18n'
import { getHosts } from '@/api/hosts'
+ import * as hostApi from '@/api/hosts'
+ import { useRouter } from 'vue-router'
import useBaseTable from '@/composables/use-base-table'
+ import HostCreate from '@/pages/cluster-manage/hosts/create.vue'
+ import InstallDependencies from
'@/pages/cluster-manage/hosts/install-dependencies.vue'
import type { FilterConfirmProps, FilterResetProps } from
'ant-design-vue/es/table/interface'
import type { GroupItem } from '@/components/common/button-group/types'
import type { HostVO } from '@/api/hosts/types'
import type { ClusterVO } from '@/api/cluster/types'
+ import type { HostReq } from '@/api/command/types'
type Key = string | number
interface TableState {
@@ -36,8 +41,11 @@
}
const { t } = useI18n()
+ const router = useRouter()
const attrs = useAttrs() as ClusterVO
const searchInputRef = ref()
+ const hostCreateRef = ref<InstanceType<typeof HostCreate> | null>(null)
+ const installRef = ref<InstanceType<typeof InstallDependencies> | null>(null)
const hostStatus = ref(['INSTALLING', 'SUCCESS', 'FAILED', 'UNKNOWN'])
const state = reactive<TableState>({
searchText: '',
@@ -120,7 +128,7 @@
{
text: 'remove',
danger: true,
- clickEvent: (_item, args) => handleDelete(args)
+ clickEvent: (_item, args) => deleteHost([args.id])
}
])
@@ -147,16 +155,47 @@
state.searchText = ''
}
- const handleEdit = (row: any) => {
- console.log('row :>> ', row)
+ const handleEdit = (row: HostVO) => {
+ const formatHost = { ...row, displayName: row.clusterDisplayName,
clusterId: attrs?.id }
+ hostCreateRef.value?.handleOpen('EDIT', formatHost)
}
- const handleDelete = (row?: any) => {
- if (!row) {
- console.log('selectedRowKeys :>> ', state.selectedRowKeys)
- } else {
- console.log('row :>> ', row)
+ const bulkRemove = () => {
+ if (state.selectedRowKeys.length === 0) {
+ message.error(t('common.delete_empty'))
+ return
}
+ deleteHost(state.selectedRowKeys as number[])
+ }
+
+ const deleteHost = (ids: number[]) => {
+ Modal.confirm({
+ title: ids.length > 1 ? t('common.delete_msgs') : t('common.delete_msg'),
+ async onOk() {
+ try {
+ const data = await hostApi.removeHost({ ids })
+ if (data) {
+ message.success(t('common.delete_success'))
+ await getHostList(true)
+ }
+ } catch (error) {
+ console.log('error :>> ', error)
+ }
+ }
+ })
+ }
+
+ const viewHostDetail = (row: HostVO) => {
+ const { id: hostId } = row
+ router.push({ name: 'HostDetail', query: { hostId, clusterId: attrs.id } })
+ }
+
+ const addHost = () => {
+ hostCreateRef.value?.handleOpen('ADD', { clusterId: attrs.id })
+ }
+
+ const afterSetupHostConfig = async (type: 'ADD' | 'EDIT', item: HostReq) => {
+ type === 'ADD' ? installRef.value?.handleOpen(item) : await
getHostList(true)
}
const getHostList = async (isReset = false) => {
@@ -195,8 +234,8 @@
<header>
<div class="header-title">{{ $t('host.host_list') }}</div>
<a-space :size="16">
- <a-button type="primary" danger @click="handleDelete">{{
$t('common.bulk_remove') }}</a-button>
- <a-button type="primary">{{ $t('cluster.add_host') }}</a-button>
+ <a-button type="primary" danger @click="bulkRemove">{{
$t('common.bulk_remove') }}</a-button>
+ <a-button type="primary" @click="addHost">{{ $t('cluster.add_host')
}}</a-button>
</a-space>
</header>
<a-table
@@ -232,7 +271,7 @@
</template>
<template #bodyCell="{ record, column }">
<template v-if="column.key === 'hostname'">
- <a-typography-link underline> {{ record.hostname }}
</a-typography-link>
+ <a-typography-link underline @click="viewHostDetail(record)"> {{
record.hostname }} </a-typography-link>
</template>
<template v-if="column.key === 'status'">
<svg-icon style="margin-left: 0"
:name="hostStatus[record.status].toLowerCase()" />
@@ -244,13 +283,15 @@
:text-compact="true"
:space="24"
:groups="operations"
- :args="record"
+ :payload="record"
group-shape="default"
group-type="link"
/>
</template>
</template>
</a-table>
+ <host-create ref="hostCreateRef" :api-edit-caller="true"
@on-ok="afterSetupHostConfig" />
+ <install-dependencies ref="installRef"
@on-install-success="getHostList(true)" />
</div>
</template>
diff --git
a/bigtop-manager-ui/src/pages/cluster-manage/cluster/service-management/components.vue
b/bigtop-manager-ui/src/pages/cluster-manage/cluster/service-management/components.vue
index 35505783..2d852806 100644
---
a/bigtop-manager-ui/src/pages/cluster-manage/cluster/service-management/components.vue
+++
b/bigtop-manager-ui/src/pages/cluster-manage/cluster/service-management/components.vue
@@ -21,7 +21,7 @@
import { computed, onActivated, onDeactivated, reactive, ref, shallowRef,
useAttrs } from 'vue'
import { storeToRefs } from 'pinia'
import { useI18n } from 'vue-i18n'
- import { useRoute } from 'vue-router'
+ import { useRoute, useRouter } from 'vue-router'
import { deleteComponent, getComponents } from '@/api/component'
import { useStackStore } from '@/store/stack'
import { useJobProgress } from '@/store/job-progress'
@@ -52,8 +52,9 @@
const jobProgressStore = useJobProgress()
const stackStore = useStackStore()
const route = useRoute()
+ const router = useRouter()
const attrs = useAttrs()
- const { stacks } = storeToRefs(stackStore)
+ const { stacks, stackRelationMap } = storeToRefs(stackStore)
const searchInputRef = ref()
const pollingIntervalId = ref<any>(null)
const componentStatus = ref(['INSTALLING', 'SUCCESS', 'FAILED', 'UNKNOWN'])
@@ -146,21 +147,23 @@
{
text: 'start',
action: 'Start',
+ hidden: (_, args) =>
stackRelationMap.value?.components[`${args.name}`].category === 'client',
clickEvent: (item, args) => handleTableOperation(item!, args)
},
{
text: 'stop',
action: 'Stop',
+ hidden: (_, args) =>
stackRelationMap.value?.components[`${args.name}`].category === 'client',
clickEvent: (item, args) => handleTableOperation(item!, args)
},
{
text: 'restart',
action: 'Restart',
+ hidden: (_, args) =>
stackRelationMap.value?.components[`${args.name}`].category === 'client',
clickEvent: (item, args) => handleTableOperation(item!, args)
},
{
text: 'remove',
- disabled: true,
danger: true,
clickEvent: (_, args) => handleDelete(args)
}
@@ -312,6 +315,16 @@
}
}
+ const addComponent = () => {
+ const { cluster: clusterId } = route.params
+ const creationMode = clusterId == '0' ? 'public' : 'internal'
+ const routerName = clusterId == '0' ? 'CreateInfraComponent' :
'CreateComponent'
+ router.push({
+ name: routerName,
+ params: { ...route.params, creationMode, type: 'component' }
+ })
+ }
+
onActivated(() => {
startPolling()
})
@@ -326,7 +339,7 @@
<header>
<div class="header-title">{{ $t('common.component') }}</div>
<div class="list-operation">
- <a-button type="primary" :disabled="true">{{ $t('common.add',
[`${$t('common.component')}`]) }}</a-button>
+ <a-button type="primary" @click="addComponent">{{ $t('common.add',
[`${$t('common.component')}`]) }}</a-button>
<button-group :groups="batchOperations" group-shape="default" />
</div>
</header>
@@ -380,7 +393,7 @@
:text-compact="true"
:space="24"
:groups="operations"
- :args="record"
+ :payload="record"
group-shape="default"
group-type="link"
/>
diff --git
a/bigtop-manager-ui/src/pages/cluster-manage/cluster/service-management/components/snapshot-management.vue
b/bigtop-manager-ui/src/pages/cluster-manage/cluster/service-management/components/snapshot-management.vue
index 3e220a38..3def8642 100644
---
a/bigtop-manager-ui/src/pages/cluster-manage/cluster/service-management/components/snapshot-management.vue
+++
b/bigtop-manager-ui/src/pages/cluster-manage/cluster/service-management/components/snapshot-management.vue
@@ -170,7 +170,7 @@
:text-compact="true"
:space="24"
:groups="operations"
- :args="record"
+ :payload="record"
group-shape="default"
group-type="link"
/>
diff --git
a/bigtop-manager-ui/src/pages/cluster-manage/cluster/service-management/index.vue
b/bigtop-manager-ui/src/pages/cluster-manage/cluster/service-management/index.vue
index 144904cb..d02c5f12 100644
---
a/bigtop-manager-ui/src/pages/cluster-manage/cluster/service-management/index.vue
+++
b/bigtop-manager-ui/src/pages/cluster-manage/cluster/service-management/index.vue
@@ -24,10 +24,10 @@
import { useServiceStore } from '@/store/service'
import { useJobProgress } from '@/store/job-progress'
import { useRoute } from 'vue-router'
+ import { Command } from '@/api/command/types'
import Overview from './overview.vue'
import Components from './components.vue'
import Configs from './configs.vue'
- import { Command } from '@/api/command/types'
import type { TabItem } from '@/components/common/main-card/types'
import type { GroupItem } from '@/components/common/button-group/types'
import type { ServiceVO } from '@/api/service/types'
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 03534884..be4e1a71 100644
--- a/bigtop-manager-ui/src/pages/cluster-manage/cluster/service.vue
+++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/service.vue
@@ -183,7 +183,7 @@
</div>
</div>
<div class="item-content" @click.stop>
- <button-group :auto="true" :space="0" :args="item"
:groups="actionGroups">
+ <button-group :auto="true" :space="0" :payload="item"
:groups="actionGroups">
<template #icon="{ item: groupItem }">
<svg-icon :name="groupItem.icon || ''" />
</template>
diff --git a/bigtop-manager-ui/src/pages/cluster-manage/hosts/create.vue
b/bigtop-manager-ui/src/pages/cluster-manage/hosts/create.vue
index a1e3d01a..45d67fb2 100644
--- a/bigtop-manager-ui/src/pages/cluster-manage/hosts/create.vue
+++ b/bigtop-manager-ui/src/pages/cluster-manage/hosts/create.vue
@@ -365,7 +365,8 @@
if (payload) {
formValue.value = Object.assign(formValue.value, {
...payload,
- authType: `${payload.authType}`
+ authType: `${payload?.authType ?? 1}`,
+ inputType: `${payload?.inputType ?? 1}`
})
} else {
Object.assign(formValue.value, {
diff --git a/bigtop-manager-ui/src/pages/cluster-manage/hosts/index.vue
b/bigtop-manager-ui/src/pages/cluster-manage/hosts/index.vue
index 942ee00a..233cccfb 100644
--- a/bigtop-manager-ui/src/pages/cluster-manage/hosts/index.vue
+++ b/bigtop-manager-ui/src/pages/cluster-manage/hosts/index.vue
@@ -26,7 +26,7 @@
import * as hostApi from '@/api/hosts'
import useBaseTable from '@/composables/use-base-table'
import HostCreate from '@/pages/cluster-manage/hosts/create.vue'
- import InstallDependencies from './install-dependencies.vue'
+ import InstallDependencies from
'@/pages/cluster-manage/hosts/install-dependencies.vue'
import type { FilterConfirmProps, FilterResetProps, TableRowSelection } from
'ant-design-vue/es/table/interface'
import type { HostReq } from '@/api/command/types'
import type { GroupItem } from '@/components/common/button-group/types'
@@ -339,7 +339,7 @@
:text-compact="true"
:space="24"
:groups="operations"
- :args="record"
+ :payload="record"
group-shape="default"
group-type="link"
></button-group>
diff --git
a/bigtop-manager-ui/src/pages/cluster-manage/hosts/install-dependencies.vue
b/bigtop-manager-ui/src/pages/cluster-manage/hosts/install-dependencies.vue
index 7b161954..559bdbbf 100644
--- a/bigtop-manager-ui/src/pages/cluster-manage/hosts/install-dependencies.vue
+++ b/bigtop-manager-ui/src/pages/cluster-manage/hosts/install-dependencies.vue
@@ -329,7 +329,7 @@
:text-compact="true"
:space="24"
:groups="operations"
- :args="record"
+ :payload="record"
group-shape="default"
group-type="link"
></button-group>
diff --git
a/bigtop-manager-ui/src/pages/cluster-manage/infrastructures/index.vue
b/bigtop-manager-ui/src/pages/cluster-manage/infrastructures/index.vue
index cd257dfc..c4f7b4f3 100644
--- a/bigtop-manager-ui/src/pages/cluster-manage/infrastructures/index.vue
+++ b/bigtop-manager-ui/src/pages/cluster-manage/infrastructures/index.vue
@@ -116,7 +116,7 @@
const viewServiceDetail = (payload: ServiceVO) => {
router.push({
name: 'InfraServiceDetail',
- params: { id: 0, service: payload.name, serviceId: payload.id }
+ params: { id: 0, service: payload.name, cluster: 0, serviceId:
payload.id }
})
}
@@ -144,7 +144,7 @@
<div class="infra-body">
<filter-form :filter-items="filterFormItems" @filter="getServices" />
<a-empty v-if="services.length == 0" style="width: 100%"
:image="Empty.PRESENTED_IMAGE_SIMPLE" />
- <template v-else>
+ <div v-else class="service-item-wrp">
<a-card
v-for="item in services"
:key="item.name"
@@ -175,14 +175,14 @@
</div>
</div>
<div class="item-content" @click.stop>
- <button-group :auto="true" :space="0" :args="item"
:groups="actionGroups">
+ <button-group :auto="true" :space="0" :payload="item"
:groups="actionGroups">
<template #icon="{ item: groupItem }">
<svg-icon :name="groupItem.icon || ''" />
</template>
</button-group>
</div>
</a-card>
- </template>
+ </div>
</div>
</a-spin>
</template>
@@ -280,4 +280,10 @@
:deep(.ant-dropdown-link) {
margin-right: 10px;
}
+
+ .service-item-wrp {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 19px;
+ }
</style>
diff --git a/bigtop-manager-ui/src/router/routes/modules/clusters.ts
b/bigtop-manager-ui/src/router/routes/modules/clusters.ts
index d226b313..45a443e2 100644
--- a/bigtop-manager-ui/src/router/routes/modules/clusters.ts
+++ b/bigtop-manager-ui/src/router/routes/modules/clusters.ts
@@ -65,7 +65,7 @@ const routes: RouteRecordRaw[] = [
},
{
name: 'CreateService',
- path:
`${RouteExceptions.DYNAMIC_ROUTE_MATCH}/create-service/:creationMode`,
+ path:
`${RouteExceptions.DYNAMIC_ROUTE_MATCH}/create-service/:creationMode?`,
component: () => import('@/components/create-service/create.vue'),
meta: {
hidden: true
@@ -78,6 +78,14 @@ const routes: RouteRecordRaw[] = [
meta: {
hidden: true
}
+ },
+ {
+ name: 'CreateComponent',
+ path:
`${RouteExceptions.DYNAMIC_ROUTE_MATCH}/create-component/:service/:serviceId/:creationMode?/:type`,
+ component: () => import('@/components/create-service/create.vue'),
+ meta: {
+ hidden: true
+ }
}
]
},
@@ -110,12 +118,21 @@ const routes: RouteRecordRaw[] = [
},
{
name: 'InfraServiceDetail',
- path:
'create-infra-service/service-detail/:id/:service/:serviceId',
+ path:
'create-infra-service/service-detail/:id/:cluster/:service/:serviceId',
component: () =>
import('@/pages/cluster-manage/cluster/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'
+ }
}
]
},
diff --git a/bigtop-manager-ui/src/store/menu/index.ts
b/bigtop-manager-ui/src/store/menu/index.ts
index 6a31508d..eec8d342 100644
--- a/bigtop-manager-ui/src/store/menu/index.ts
+++ b/bigtop-manager-ui/src/store/menu/index.ts
@@ -88,6 +88,9 @@ export const useMenuStore = defineStore(
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
diff --git a/bigtop-manager-ui/src/store/stack/index.ts
b/bigtop-manager-ui/src/store/stack/index.ts
index 358f74ab..99acbaa5 100644
--- a/bigtop-manager-ui/src/store/stack/index.ts
+++ b/bigtop-manager-ui/src/store/stack/index.ts
@@ -25,7 +25,7 @@ import type { ServiceConfig, ServiceVO } from
'@/api/service/types'
import type { StackVO } from '@/api/stack/types'
export type ExpandServiceVO = ServiceVO & { order: number }
-interface StackRelationMap {
+export interface StackRelationMap {
services: {
displayName: string
stack: string
diff --git a/bigtop-manager-ui/src/styles/index.scss
b/bigtop-manager-ui/src/styles/index.scss
index fe88f1d9..12dd0203 100644
--- a/bigtop-manager-ui/src/styles/index.scss
+++ b/bigtop-manager-ui/src/styles/index.scss
@@ -74,7 +74,7 @@
.job-progress-notification{
&:hover{
- background-color: $color-bg-text-hover;
+ background-color: $color-bg-layout;
cursor: pointer;
}
.ant-notification-notice-close{