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 dd86f7d0 BIGTOP-4379: Add stack/infra page (#194)
dd86f7d0 is described below
commit dd86f7d0148db8e527a63122591118da824a5bd1
Author: pckinghao <[email protected]>
AuthorDate: Thu Mar 27 23:54:47 2025 +0800
BIGTOP-4379: Add stack/infra page (#194)
---
bigtop-manager-ui/src/api/command/types.ts | 7 +-
bigtop-manager-ui/src/locales/en_US/index.ts | 4 +-
.../src/locales/en_US/{index.ts => infra.ts} | 27 +--
bigtop-manager-ui/src/locales/zh_CN/index.ts | 4 +-
.../src/locales/{en_US/index.ts => zh_CN/infra.ts} | 27 +--
.../cluster/components/category-chart.vue | 2 +-
.../src/pages/cluster-manage/components/index.vue | 119 +++++++++-
.../pages/cluster-manage/infrastructures/index.vue | 255 ++++++++++++++++++++-
bigtop-manager-ui/src/utils/array.ts | 2 +-
bigtop-manager-ui/tsconfig.json | 3 +-
10 files changed, 379 insertions(+), 71 deletions(-)
diff --git a/bigtop-manager-ui/src/api/command/types.ts
b/bigtop-manager-ui/src/api/command/types.ts
index e5e876b4..97313362 100644
--- a/bigtop-manager-ui/src/api/command/types.ts
+++ b/bigtop-manager-ui/src/api/command/types.ts
@@ -66,7 +66,8 @@ export enum Command {
Restart = 'Restart',
Start = 'Start',
Status = 'Status',
- Stop = 'Stop'
+ Stop = 'Stop',
+ More = 'More'
}
export enum CommandLevel {
@@ -99,8 +100,8 @@ export interface HostCommandReq {
}
export interface ServiceCommandReq {
- componentHosts: ComponentHostReq[]
- configs: ServiceConfigReq[]
+ componentHosts?: ComponentHostReq[]
+ configs?: ServiceConfigReq[]
serviceName: string
[property: string]: any
}
diff --git a/bigtop-manager-ui/src/locales/en_US/index.ts
b/bigtop-manager-ui/src/locales/en_US/index.ts
index bc44b73b..e91a5f9f 100644
--- a/bigtop-manager-ui/src/locales/en_US/index.ts
+++ b/bigtop-manager-ui/src/locales/en_US/index.ts
@@ -28,6 +28,7 @@ import host from '@/locales/en_US/host.ts'
import job from '@/locales/en_US/job.ts'
import overview from '@/locales/en_US/overview'
import service from '@/locales/en_US/service'
+import infra from '@/locales/en_US/infra.ts'
export default {
common,
@@ -40,5 +41,6 @@ export default {
host,
job,
overview,
- service
+ service,
+ infra
}
diff --git a/bigtop-manager-ui/src/locales/en_US/index.ts
b/bigtop-manager-ui/src/locales/en_US/infra.ts
similarity index 56%
copy from bigtop-manager-ui/src/locales/en_US/index.ts
copy to bigtop-manager-ui/src/locales/en_US/infra.ts
index bc44b73b..6f9f7384 100644
--- a/bigtop-manager-ui/src/locales/en_US/index.ts
+++ b/bigtop-manager-ui/src/locales/en_US/infra.ts
@@ -16,29 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
-
-import common from '@/locales/en_US/common.ts'
-import menu from '@/locales/en_US/menu.ts'
-import login from '@/locales/en_US/login'
-import user from '@/locales/en_US/user.ts'
-import llmConfig from '@/locales/en_US/llm-config.ts'
-import aiAssistant from '@/locales/en_US/ai-assistant.ts'
-import cluster from '@/locales/en_US/cluster.ts'
-import host from '@/locales/en_US/host.ts'
-import job from '@/locales/en_US/job.ts'
-import overview from '@/locales/en_US/overview'
-import service from '@/locales/en_US/service'
-
export default {
- common,
- menu,
- login,
- user,
- llmConfig,
- aiAssistant,
- cluster,
- host,
- job,
- overview,
- service
+ info: 'Only one instance of a basic service shared across clusters can
exist',
+ action: 'Add service',
+ restart: 'Need to restart'
}
diff --git a/bigtop-manager-ui/src/locales/zh_CN/index.ts
b/bigtop-manager-ui/src/locales/zh_CN/index.ts
index 5aa15877..c2104cc2 100644
--- a/bigtop-manager-ui/src/locales/zh_CN/index.ts
+++ b/bigtop-manager-ui/src/locales/zh_CN/index.ts
@@ -28,6 +28,7 @@ import host from '@/locales/zh_CN/host.ts'
import job from '@/locales/zh_CN/job.ts'
import overview from '@/locales/zh_CN/overview.ts'
import service from '@/locales/zh_CN/service.ts'
+import infra from '@/locales/zh_CN/infra.ts'
export default {
common,
@@ -40,5 +41,6 @@ export default {
host,
job,
overview,
- service
+ service,
+ infra
}
diff --git a/bigtop-manager-ui/src/locales/en_US/index.ts
b/bigtop-manager-ui/src/locales/zh_CN/infra.ts
similarity index 56%
copy from bigtop-manager-ui/src/locales/en_US/index.ts
copy to bigtop-manager-ui/src/locales/zh_CN/infra.ts
index bc44b73b..3ea8333f 100644
--- a/bigtop-manager-ui/src/locales/en_US/index.ts
+++ b/bigtop-manager-ui/src/locales/zh_CN/infra.ts
@@ -16,29 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
-
-import common from '@/locales/en_US/common.ts'
-import menu from '@/locales/en_US/menu.ts'
-import login from '@/locales/en_US/login'
-import user from '@/locales/en_US/user.ts'
-import llmConfig from '@/locales/en_US/llm-config.ts'
-import aiAssistant from '@/locales/en_US/ai-assistant.ts'
-import cluster from '@/locales/en_US/cluster.ts'
-import host from '@/locales/en_US/host.ts'
-import job from '@/locales/en_US/job.ts'
-import overview from '@/locales/en_US/overview'
-import service from '@/locales/en_US/service'
-
export default {
- common,
- menu,
- login,
- user,
- llmConfig,
- aiAssistant,
- cluster,
- host,
- job,
- overview,
- service
+ info: '跨集群共享的基础服务,只能存在一个实例',
+ action: '添加服务',
+ restart: '需要重启'
}
diff --git
a/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/category-chart.vue
b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/category-chart.vue
index c9abfd99..6c07487f 100644
---
a/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/category-chart.vue
+++
b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/category-chart.vue
@@ -37,7 +37,7 @@
const myChart = shallowRef<echarts.ECharts | null>(null)
const generateTimeLabels = () => {
- const times = []
+ const times = [] as Array<string>
for (let h = 0; h < 24; h++) {
for (let m = 0; m < 60; m += 15) {
const hour = h.toString().padStart(2, '0')
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 4782fe83..07e54bd9 100644
--- a/bigtop-manager-ui/src/pages/cluster-manage/components/index.vue
+++ b/bigtop-manager-ui/src/pages/cluster-manage/components/index.vue
@@ -16,11 +16,124 @@
~ specific language governing permissions and limitations
~ under the License.
-->
+<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 { useI18n } from 'vue-i18n'
+ import { useStackStore } from '@/store/stack'
+ import { storeToRefs } from 'pinia'
+ import { ServiceVO } from '@/api/service/types'
-<script setup lang="ts"></script>
+ const { t } = useI18n()
+ const stackStore = useStackStore()
+ const { stacks } = storeToRefs(stackStore)
+
+ const store = reactive({
+ loading: false,
+ stackSelected: 'Bigtop',
+ stackGroup: ['Bigtop', 'Infra', 'Extra']
+ })
+ const currentStack = computed(() =>
+ stacks.value.find((stack) => stack.stackName.toUpperCase() ===
store.stackSelected.toUpperCase())
+ )
+ const data = ref<ServiceVO[]>([])
+ const columns = computed((): TableColumnType[] => [
+ {
+ title: '#',
+ width: '48px',
+ key: 'index',
+ customRender: ({ index }) => {
+ return `${index + 1}`
+ }
+ },
+ {
+ title: t('common.name'),
+ dataIndex: 'displayName',
+ width: '20%',
+ ellipsis: true
+ },
+ {
+ title: t('common.version'),
+ dataIndex: 'version',
+ width: '15%',
+ ellipsis: true
+ },
+ {
+ key: 'stack',
+ title: t('common.stack'),
+ dataIndex: 'stack',
+ width: '20%',
+ ellipsis: true
+ },
+ {
+ title: t('common.desc'),
+ dataIndex: 'desc',
+ ellipsis: true
+ }
+ ])
+
+ const { loading, paginationProps, onChange, resetState } = useBaseTable({
+ columns: columns.value,
+ rows: data.value
+ })
+
+ watchEffect(() => {
+ resetState()
+ data.value = currentStack.value?.services || []
+ })
+
+ const handleSetSource = () => {
+ // setSourceRef.value?.handleOpen()
+ }
+
+ onMounted(() => {
+ stackStore.loadStacks()
+ })
+</script>
<template>
- <div> components</div>
+ <div class="cluster-components">
+ <div>
+ <div class="menu-title">{{ $t('menu.component') }}</div>
+ </div>
+ <div class="cluster-components-header">
+ <a-radio-group v-model:value="store.stackSelected" button-style="solid">
+ <a-radio-button v-for="(stack, idx) in store.stackGroup" :key="idx"
:value="stack">{{ stack }}</a-radio-button>
+ </a-radio-group>
+ <a-button type="primary" @click="handleSetSource">{{
$t('cluster.config_source') }}</a-button>
+ </div>
+ <div>
+ <a-table
+ :loading="loading"
+ :data-source="data"
+ :columns="columns"
+ :pagination="paginationProps"
+ @change="onChange"
+ >
+ <template #bodyCell="{ column }">
+ <template v-if="column.key === 'stack'">
+ <span> {{ `${store.stackSelected}-${currentStack?.stackVersion}`
}} </span>
+ </template>
+ </template>
+ </a-table>
+ </div>
+ </div>
</template>
-<style scoped></style>
+<style lang="scss" scoped>
+ .cluster-components {
+ padding: 16px;
+ background-color: #fff;
+ .menu-title {
+ font-size: 16px;
+ font-weight: 500;
+ line-height: 24px;
+ }
+ .cluster-components-header {
+ display: flex;
+ justify-content: space-between;
+ margin: $space-md 0;
+ }
+ }
+</style>
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 2fc14d22..915374f4 100644
--- a/bigtop-manager-ui/src/pages/cluster-manage/infrastructures/index.vue
+++ b/bigtop-manager-ui/src/pages/cluster-manage/infrastructures/index.vue
@@ -17,19 +17,250 @@
~ under the License.
-->
-<script setup lang="ts"></script>
+<script setup lang="ts">
+ import { computed, shallowRef, onMounted, toRefs } from 'vue'
+ import { usePngImage } from '@/utils/tools'
+ import { useI18n } from 'vue-i18n'
+ import { CommonStatus, CommonStatusTexts } from '@/enums/state'
+ import { useServiceStore } from '@/store/service'
+ import type { ServiceListParams, ServiceStatusType } from
'@/api/service/types'
+ import type { GroupItem } from '@/components/common/button-group/types'
+ import type { FilterFormItem } from '@/components/common/filter-form/types'
+ // import { execCommand } from '@/api/command';
+ import type { Command } from '@/api/command/types'
+
+ const { t } = useI18n()
+ const serviceStore = useServiceStore()
+ const { services, loading } = toRefs(serviceStore)
+
+ const statusColors = shallowRef<Record<ServiceStatusType, keyof typeof
CommonStatusTexts>>({
+ 1: 'healthy',
+ 2: 'unhealthy',
+ 3: 'unknown'
+ })
+ const filterFormItems = computed((): FilterFormItem[] => [
+ { type: 'search', key: 'serviceName', label: t('service.name') },
+ {
+ type: 'status',
+ key: 'restartFlag',
+ label: t('service.required_restart'),
+ options: [
+ { label: t('common.required'), value: 1 },
+ { label: t('common.not_required'), value: 2 }
+ ]
+ },
+ {
+ type: 'status',
+ key: 'status',
+ label: t('common.status'),
+ options: [
+ { label: t(`common.${statusColors.value[1]}`), value: 1 },
+ { label: t(`common.${statusColors.value[2]}`), value: 2 },
+ { label: t(`common.${statusColors.value[3]}`), value: 3 }
+ ]
+ }
+ ])
+ const actionGroups = shallowRef<GroupItem[]>([
+ {
+ action: 'start',
+ icon: 'start',
+ clickEvent: (item, args) => {
+ console.log('item :>> ', item?.action)
+ infraAction('Start', args.name)
+ }
+ },
+ {
+ action: 'stop',
+ icon: 'stop',
+ clickEvent: (item, args) => {
+ console.log('item :>> ', item?.action)
+ infraAction('Stop', args.name)
+ }
+ },
+ {
+ action: 'restart',
+ icon: 'restart',
+ clickEvent: (item, args) => {
+ console.log('item :>> ', item?.action)
+ infraAction('Restart', args.name)
+ }
+ },
+ {
+ action: 'more',
+ icon: 'more_line',
+ clickEvent: (item, args) => {
+ console.log('item :>> ', item?.action)
+ infraAction('More', args.name)
+ }
+ }
+ ])
+
+ const infraAction = async (command: keyof typeof Command, serviceName:
string) => {
+ console.log(command, serviceName)
+ // await execCommand({
+ // command: command,
+ // clusterId: 0,
+ // commandLevel: "service",
+ // serviceCommands: [{ serviceName: serviceName }]
+ // })
+ }
+
+ const getServices = async (filters?: ServiceListParams) => {
+ await serviceStore.getServices(0, filters)
+ }
+
+ onMounted(async () => {
+ await getServices()
+ })
+</script>
<template>
- <div>
- <a-button
- @click="
- () => $router.push({ name: 'CreateInfraService', params: { id: 0,
cluster: '', creationMode: 'public' } })
- "
- >
- add Service
- </a-button>
- <span> infra list </span>
- </div>
+ <a-spin :spinning="loading" class="service">
+ <div class="infra-header">
+ <div>
+ <div class="menu-title">{{ $t('menu.infra') }}</div>
+ <div class="menu-info">{{ $t('infra.info') }}</div>
+ </div>
+ <a-button
+ type="primary"
+ @click="
+ () => $router.push({ name: 'CreateInfraService', params: { id: 0,
cluster: '', creationMode: 'public' } })
+ "
+ >
+ {{ $t('infra.action') }}
+ </a-button>
+ </div>
+ <div class="infra-body">
+ <filter-form :filter-items="filterFormItems" @filter="getServices" />
+ <a-empty v-if="services.length == 0" style="width: 100%" />
+ <template v-else>
+ <a-card v-for="item in services" :key="item.name" :hoverable="true"
class="service-item">
+ <div class="header">
+ <div class="header-base-wrp">
+ <a-avatar v-if="item.name"
:src="usePngImage(item.name.toLowerCase())" :size="42" class="header-icon" />
+ <div class="header-base-title">
+ <span>{{ `${item.displayName}` }}</span>
+ <span class="small-gray">{{ item.version }}</span>
+ </div>
+ <div class="header-base-status">
+ <a-tag :color="CommonStatus[statusColors[item.status]]">
+ <div class="header-base-status-inner">
+ <status-dot
:color="CommonStatus[statusColors[item.status]]" />
+ <span class="small">{{
$t(`common.${statusColors[item.status]}`) }}</span>
+ </div>
+ </a-tag>
+ </div>
+ </div>
+ <div class="header-restart-status">
+ <span class="small-gray">{{ `${$t('common.restart')}` }}</span>
+ <status-dot :color="CommonStatus[statusColors[item.status]]" />
+ <span class="small">{{ `${item.restartFlag ?
$t('common.required') : $t('common.not_required')}` }}</span>
+ </div>
+ </div>
+ <div class="item-content">
+ <button-group :auto="true" :space="0" :args="item"
:groups="actionGroups">
+ <template #icon="{ item: groupItem }">
+ <svg-icon :name="groupItem.icon || ''" />
+ </template>
+ </button-group>
+ </div>
+ </a-card>
+ </template>
+ </div>
+ </a-spin>
</template>
-<style scoped></style>
+<style scoped lang="scss">
+ .infra-header {
+ padding: 16px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ background-color: #fff;
+ .menu-title {
+ font-size: 16px;
+ font-weight: 500;
+ line-height: 24px;
+ }
+ .menu-info {
+ margin-top: 5px;
+ color: #00000072;
+ font-size: 14px;
+ font-weight: 400;
+ line-height: 22px;
+ }
+ }
+ .small {
+ font-size: 12px;
+ }
+ .small-gray {
+ line-height: 12px;
+ font-size: 12px;
+ color: rgba(0, 0, 0, 0.45);
+ }
+ .infra-body {
+ margin-top: 16px;
+ padding: 16px;
+ background-color: #fff;
+ .service {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 16px;
+ }
+ .service-item {
+ width: 280px;
+ height: 150px;
+ border-radius: 8px;
+ @include flexbox($direction: column);
+ :deep(.ant-card-body) {
+ padding: 0;
+ height: 100%;
+ @include flexbox($direction: column);
+ }
+ .header {
+ padding: $space-md;
+ border-bottom: 1px solid $color-border-secondary;
+ &-base-wrp {
+ @include flexbox($gap: $space-sm);
+ margin-bottom: 10px;
+ }
+ &-base-title {
+ @include flexbox($direction: column);
+ }
+ &-base-status {
+ flex: 1;
+ text-align: end;
+ &-inner {
+ @include flexbox($align: center, $gap: 4px);
+ }
+ .ant-tag {
+ margin-inline-end: 0;
+ }
+ }
+ &-restart-status {
+ @include flexbox($align: center, $gap: 6px);
+ .dot {
+ margin-top: 2px;
+ }
+ }
+ &-icon {
+ flex-shrink: 0;
+ border-radius: 0;
+ }
+ :deep(.ant-avatar) {
+ img {
+ object-fit: contain !important;
+ }
+ }
+ }
+ .item-content {
+ flex: 1;
+ @include flexbox($align: center);
+ padding-inline: 8px;
+ }
+ }
+ }
+ :deep(.ant-dropdown-link) {
+ margin-right: 10px;
+ }
+</style>
diff --git a/bigtop-manager-ui/src/utils/array.ts
b/bigtop-manager-ui/src/utils/array.ts
index 5f25684e..4cc0a1eb 100644
--- a/bigtop-manager-ui/src/utils/array.ts
+++ b/bigtop-manager-ui/src/utils/array.ts
@@ -33,7 +33,7 @@ const replacePatternInHosts = (rawHostNames: string[]):
string[] => {
extra: any,
allHostNames: any = []
rawHostNames.forEach(function (rawHostName) {
- const hostNames = []
+ const hostNames = [] as Array<string>
start = rawHostName.match(/\[\d*/)
end = rawHostName.match(/\-\d*]/)
extra = { 0: '' }
diff --git a/bigtop-manager-ui/tsconfig.json b/bigtop-manager-ui/tsconfig.json
index 741ccfd4..d33b1fa6 100644
--- a/bigtop-manager-ui/tsconfig.json
+++ b/bigtop-manager-ui/tsconfig.json
@@ -23,7 +23,8 @@
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true
+ "noFallthroughCasesInSwitch": true,
+ "noImplicitAny": false,
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue",
"src/types/**/*.d.ts"],
"references": [