diff --git a/bigtop-manager-ui/src/api/cluster/index.ts b/bigtop-manager-ui/src/api/cluster/index.ts index 8d74653b2..ed38562f4 100644 --- a/bigtop-manager-ui/src/api/cluster/index.ts +++ b/bigtop-manager-ui/src/api/cluster/index.ts @@ -18,9 +18,24 @@ */ import request from '@/api/request.ts' -import { ClusterVO } from '@/api/cluster/types.ts' +import type { ClusterVO, UpdateClusterParam } from './types' -export const getClusters = (): Promise => { +export const getCluster = (id: number): Promise => { + return request({ + method: 'get', + url: `/clusters/${id}` + }) +} + +export const updateCluster = (id: number, data: UpdateClusterParam) => { + return request({ + method: 'put', + url: `/clusters/${id}`, + data + }) +} + +export const getClusterList = (): Promise => { return request({ method: 'get', url: '/clusters' diff --git a/bigtop-manager-ui/src/api/cluster/types.ts b/bigtop-manager-ui/src/api/cluster/types.ts index 1af5c674c..b9f8beb53 100644 --- a/bigtop-manager-ui/src/api/cluster/types.ts +++ b/bigtop-manager-ui/src/api/cluster/types.ts @@ -17,28 +17,21 @@ * under the License. */ -export interface ClusterReq { - clusterName: string - clusterType: number - stackName: string - stackVersion: string - repoInfoList: RepoReq[] - hostnames: string[] -} +export type UpdateClusterParam = { name: string; desc: string } export interface ClusterVO { - id: number - clusterName: string - clusterType: number - stackName: string - stackVersion: string - selected: boolean -} - -export interface RepoReq { - repoId: string - repoName: string - baseUrl: string - os: string - arch: string + createUser?: string + desc?: string + displayName?: string + id?: number + name?: string + rootDir?: string + status?: number + totalDisk?: number + totalHost?: number + totalMemory?: number + totalProcessor?: number + totalService?: number + type?: number + userGroup?: string } diff --git a/bigtop-manager-ui/src/api/command/index.ts b/bigtop-manager-ui/src/api/command/index.ts index 197fad134..8e84df0d7 100644 --- a/bigtop-manager-ui/src/api/command/index.ts +++ b/bigtop-manager-ui/src/api/command/index.ts @@ -18,9 +18,9 @@ */ import request from '@/api/request.ts' -import { CommandVO } from '@/api/command/types.ts' +import { CommandRequest, CommandVO } from '@/api/command/types.ts' -export const execCommand = (data: any): Promise => { +export const execCommand = (data: CommandRequest): Promise => { return request({ method: 'post', url: '/command', diff --git a/bigtop-manager-ui/src/api/command/types.ts b/bigtop-manager-ui/src/api/command/types.ts index a1d66922d..30f599906 100644 --- a/bigtop-manager-ui/src/api/command/types.ts +++ b/bigtop-manager-ui/src/api/command/types.ts @@ -17,7 +17,123 @@ * under the License. */ +export interface CommandRequest { + clusterCommand?: ClusterCommandReq + clusterId?: number + command: Command + commandLevel: CommandLevel + componentCommands?: ComponentCommandReq[] + customCommand?: string + hostCommands?: HostCommandReq[] + serviceCommands?: ServiceCommandReq[] + [property: string]: any +} + +export interface ClusterCommandReq { + desc?: string + displayName: string + hosts: HostReq[] + name: string + rootDir?: string + type: number + userGroup?: string + [property: string]: any +} + +export interface HostReq { + agentDir?: string + authType?: number | string + clusterId?: number + desc?: string + grpcPort?: number + hostnames?: string[] + sshKeyFilename?: string + sshKeyPassword?: string + sshKeyString?: string + sshPassword?: string + sshPort?: number + sshUser?: string + [property: string]: any +} + +export enum Command { + Add = 'Add', + Check = 'Check', + Configure = 'Configure', + Custom = 'Custom', + Init = 'Init', + Prepare = 'Prepare', + Restart = 'Restart', + Start = 'Start', + Status = 'Status', + Stop = 'Stop' +} + +export enum CommandLevel { + Cluster = 'cluster', + Component = 'component', + Host = 'host', + Service = 'service' +} + +export interface ComponentCommandReq { + componentName: string + hostnames: string[] + [property: string]: any +} + +export interface HostCommandReq { + agentDir?: string + authType?: number + clusterId?: number + desc?: string + grpcPort?: number + hostnames?: string[] + sshKeyFilename?: string + sshKeyPassword?: string + sshKeyString?: string + sshPassword?: string + sshPort?: number + sshUser?: string + [property: string]: any +} + +export interface ServiceCommandReq { + componentHosts: ComponentHostReq[] + configs: ServiceConfigReq[] + serviceName: string + [property: string]: any +} + +export interface ComponentHostReq { + componentName: string + hostnames: string[] + [property: string]: any +} + +export interface ServiceConfigReq { + id?: number + name?: string + properties?: PropertyReq[] + [property: string]: any +} + +export interface PropertyReq { + attrs?: AttrsReq + desc?: string + displayName?: string + name: string + value?: string + [property: string]: any +} + +export interface AttrsReq { + type?: string + [property: string]: any +} + export interface CommandVO { - id: number - state: string + id?: number + state?: string + [property: string]: any } diff --git a/bigtop-manager-ui/src/api/component/index.ts b/bigtop-manager-ui/src/api/component/index.ts index 8a0d4fba4..60cba9a84 100644 --- a/bigtop-manager-ui/src/api/component/index.ts +++ b/bigtop-manager-ui/src/api/component/index.ts @@ -16,13 +16,3 @@ * specific language governing permissions and limitations * under the License. */ - -import { HostComponentVO } from '@/api/component/types.ts' -import request from '@/api/request.ts' - -export const getHostComponents = (clusterId: number): Promise => { - return request({ - method: 'get', - url: '/clusters/' + clusterId + '/host-components' - }) -} diff --git a/bigtop-manager-ui/src/api/component/types.ts b/bigtop-manager-ui/src/api/component/types.ts index a7238170e..86e619dcb 100644 --- a/bigtop-manager-ui/src/api/component/types.ts +++ b/bigtop-manager-ui/src/api/component/types.ts @@ -17,30 +17,30 @@ * under the License. */ -import { MaintainState } from '@/enums/state' - +/** + * ComponentVO + */ export interface ComponentVO { - id: number - componentName: string - displayName: string - category: string - serviceName: string - clusterName: string - cardinality: string + cardinality?: string + category?: string + displayName?: string + hostname?: string + id?: number + name?: string + quickLink?: QuickLinkVO + serviceDisplayName?: string + serviceId?: number + serviceName?: string + stack?: string + status?: number + [property: string]: any } -export interface ServiceComponentVO { - serviceName: string - components: ComponentVO[] -} - -export interface HostComponentVO { - id: number - componentName: string - displayName: string - category: string - serviceName: string - clusterName: string - hostname: string - state: MaintainState +/** + * QuickLinkVO + */ +export interface QuickLinkVO { + displayName?: string + url?: string + [property: string]: any } diff --git a/bigtop-manager-ui/src/api/hosts/index.ts b/bigtop-manager-ui/src/api/hosts/index.ts index ba5bb533f..f970167ea 100644 --- a/bigtop-manager-ui/src/api/hosts/index.ts +++ b/bigtop-manager-ui/src/api/hosts/index.ts @@ -18,11 +18,34 @@ */ import request from '@/api/request.ts' -import { HostVO } from '@/api/hosts/types.ts' +import { HostParams, HostVO, HostVOList, InstalledStatusVO } from '@/api/hosts/types.ts' -export const getHosts = (clusterId: number): Promise => { +export const getHosts = (): Promise => { return request({ method: 'get', - url: '/clusters/' + clusterId + '/hosts' + url: '/hosts' + }) +} + +export const addHost = (data: HostParams): Promise => { + return request({ + method: 'post', + url: '/hosts', + data + }) +} + +export const installDependencies = (data: HostParams) => { + return request({ + method: 'post', + url: '/hosts/install-dependencies', + data + }) +} + +export const getInstalledStatus = (): Promise => { + return request({ + method: 'get', + url: '/hosts/installed-status' }) } diff --git a/bigtop-manager-ui/src/api/hosts/types.ts b/bigtop-manager-ui/src/api/hosts/types.ts index b1280eb0d..519a3c29c 100644 --- a/bigtop-manager-ui/src/api/hosts/types.ts +++ b/bigtop-manager-ui/src/api/hosts/types.ts @@ -17,17 +17,68 @@ * under the License. */ +import type { PageVO } from '@/api/types' + +export type HostVOList = PageVO + +/** + * HostVO + */ export interface HostVO { - id: number - clusterName: string - hostname: string - ipv4: string - arch: string - os: string - availableProcessors: string - freeMemorySize: string - totalMemorySize: string - state: string - freeDisk: string - totalDisk: string + agentDir?: string + arch?: string + authType?: number + availableProcessors?: number + clusterDisplayName?: string + clusterName?: string + componentNum?: number + desc?: string + errInfo?: string + freeDisk?: number + freeMemorySize?: number + grpcPort?: number + hostname?: string + id?: number + ipv4?: string + ipv6?: string + os?: string + sshKeyFilename?: string + sshKeyPassword?: string + sshKeyString?: string + sshPassword?: string + sshPort?: number + sshUser?: string + status?: number + totalDisk?: number + totalMemorySize?: number + [property: string]: any +} + +export interface HostParams { + agentDir?: string + authType?: number | string // '1-password,2-key,3-no_auth', + clusterId?: number + desc?: string + grpcPort?: number + hostnames?: string[] + sshKeyFilename?: string + sshKeyPassword?: string + sshKeyString?: string + sshPassword?: string + sshPort?: number + sshUser?: string + [property: string]: any +} + +export interface InstalledStatusVO { + hostname?: string + message?: string + status?: Status +} + +export enum Status { + Failed = 'FAILED', + Installing = 'INSTALLING', + Success = 'SUCCESS', + Unknown = 'UNKNOW' } diff --git a/bigtop-manager-ui/src/api/job/index.ts b/bigtop-manager-ui/src/api/job/index.ts index 14f8e2aaa..c7aaa0520 100644 --- a/bigtop-manager-ui/src/api/job/index.ts +++ b/bigtop-manager-ui/src/api/job/index.ts @@ -16,28 +16,47 @@ * specific language governing permissions and limitations * under the License. */ - import request from '@/api/request.ts' -import { JobVO, Pagination } from '@/api/job/types.ts' +import type { JobParams, JobList, TaskLogParams, TaskParams, JobVO, StageVO, TaskVO } from './types' -export const getJob = (id: number, clusterId: number): Promise => { +export const retryJob = (pathParams: JobParams): Promise => { + return request({ + method: 'post', + url: `/clusters/${pathParams.clusterId}/jobs/${pathParams.jobId}/retry` + }) +} + +export const getJobList = (clusterId: number): Promise => { return request({ method: 'get', - url: '/clusters/' + clusterId + '/jobs/' + id + url: `/clusters/${clusterId}/jobs` }) } -export const retryJob = (id: number, clusterId: number): Promise => { +export const getJobDetails = (pathParams: JobParams): Promise => { return request({ - method: 'post', - url: '/clusters/' + clusterId + '/jobs/' + id + '/retry' + method: 'get', + url: `/clusters/${pathParams.clusterId}/jobs/${pathParams.jobId}` + }) +} + +export const getStageList = (pathParams: JobParams): Promise => { + return request({ + method: 'get', + url: `/clusters/${pathParams.clusterId}/jobs/${pathParams.jobId}/stages` + }) +} + +export const getTaskList = (pathParams: TaskParams): Promise => { + return request({ + method: 'get', + url: `/clusters/${pathParams.clusterId}/jobs/${pathParams.jobId}/stages/${pathParams.stageId}/tasks` }) } -export const getJobs = (clusterId: number, pagination: Pagination): Promise<{ content: JobVO[]; total: number }> => { +export const getTaskLog = (pathParams: TaskLogParams): Promise => { return request({ method: 'get', - url: `/clusters/${clusterId}/jobs`, - params: pagination + url: `/clusters/${pathParams.clusterId}/jobs/${pathParams.jobId}/stages/${pathParams.stageId}/tasks/${pathParams.taskId}/log` }) } diff --git a/bigtop-manager-ui/src/api/job/types.ts b/bigtop-manager-ui/src/api/job/types.ts index 81aaf643a..86e545554 100644 --- a/bigtop-manager-ui/src/api/job/types.ts +++ b/bigtop-manager-ui/src/api/job/types.ts @@ -17,40 +17,51 @@ * under the License. */ -import { State } from '@/enums/state' +import type { PageVO } from '@/api/types' -export type StateType = keyof typeof State +export type JobList = PageVO +export type StageList = PageVO +export type JobParams = { clusterId: number; jobId: number } +export type TaskParams = JobParams & { stageId: number } +export type TaskLogParams = TaskParams & { taskId: number } -interface BaseVO { - id: number - name: string - state: StateType - createTime?: string - updateTime?: string - progress?: number -} - -export interface JobVO extends BaseVO { - stages: StageVO[] -} +export type StateType = keyof typeof State -export interface StageVO extends BaseVO { - order: number - tasks: TaskVO[] +export enum State { + 'Pending' = 'pending', + 'Processing' = 'processing', + 'Successful' = 'successful', + 'Failed' = 'failed', + 'Canceled' = 'canceled' } -export interface TaskVO extends BaseVO { - hostname: string +export interface JobVO { + createTime?: string + id?: number + name?: string + stages?: StageVO[] + state?: StateType + updateTime?: string + [property: string]: any } -export interface Pagination { - pageNum: number - pageSize: number - sort?: 'asc' | 'desc' - orderBy?: string +export interface StageVO { + createTime?: string + id?: number + name?: string + order?: number + state?: StateType + tasks?: TaskVO[] + updateTime?: string + [property: string]: any } -export interface OuterData { - meta: JobVO[] - currItem: StageVO | TaskVO | undefined +export interface TaskVO { + createTime?: string + hostname?: string + id?: number + name?: string + state?: StateType + updateTime?: string + [property: string]: any } diff --git a/bigtop-manager-ui/src/api/llm-config/types.ts b/bigtop-manager-ui/src/api/llm-config/types.ts index f1ef52129..2dacbe326 100644 --- a/bigtop-manager-ui/src/api/llm-config/types.ts +++ b/bigtop-manager-ui/src/api/llm-config/types.ts @@ -26,7 +26,8 @@ export enum AuthPlatformStatus { export enum LlmLogo { 'openai' = 1, 'dashscope' = 2, - 'qianfan' = 3 + 'qianfan' = 3, + 'deepseek' = 4 } export type LlmLogoFlag = `${LlmLogo}` diff --git a/bigtop-manager-ui/src/api/repo/index.ts b/bigtop-manager-ui/src/api/repo/index.ts new file mode 100644 index 000000000..94108d6c6 --- /dev/null +++ b/bigtop-manager-ui/src/api/repo/index.ts @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { RepoUpdate, RepoVO } from './types' +import request from '@/api/request.ts' + +export const getRepoList = (): Promise => { + return request({ + method: 'get', + url: 'repos' + }) +} + +export const updateRepo = (data: RepoUpdate[]) => { + return request({ + method: 'put', + url: 'repos', + data + }) +} diff --git a/bigtop-manager-ui/src/api/repo/types.ts b/bigtop-manager-ui/src/api/repo/types.ts index ade427565..597adce4c 100644 --- a/bigtop-manager-ui/src/api/repo/types.ts +++ b/bigtop-manager-ui/src/api/repo/types.ts @@ -16,12 +16,16 @@ * specific language governing permissions and limitations * under the License. */ - export interface RepoVO { - repoId: string - repoName: string - repoType: string - baseUrl: string - os: string - arch: string + arch?: string + baseUrl?: string + id?: number + name?: string + [property: string]: any +} + +export interface RepoUpdate { + baseUrl?: string + id?: number + [property: string]: any } diff --git a/bigtop-manager-ui/src/api/request-util.ts b/bigtop-manager-ui/src/api/request-util.ts new file mode 100644 index 000000000..7a2da40e3 --- /dev/null +++ b/bigtop-manager-ui/src/api/request-util.ts @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import type { ResponseEntity } from './types' +import request from './request' +import { AxiosRequestConfig } from 'axios' + +const get = (url: string, config?: AxiosRequestConfig): Promise> => { + return request.get(url, config) +} + +const post = (url: string, data?: U, config?: AxiosRequestConfig): Promise> => { + return request.post(url, data, config) +} + +const put = (url: string, data: U, config?: AxiosRequestConfig): Promise> => { + return request.put(url, data, config) +} + +const del = (url: string, config?: AxiosRequestConfig): Promise> => { + return request.delete(url, config) +} + +export { get, post, put, del } diff --git a/bigtop-manager-ui/src/api/request.ts b/bigtop-manager-ui/src/api/request.ts index b1c7771b3..2578fd50f 100644 --- a/bigtop-manager-ui/src/api/request.ts +++ b/bigtop-manager-ui/src/api/request.ts @@ -17,7 +17,8 @@ * under the License. */ -import axios, { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'axios' +import type { AxiosInstance, AxiosResponse, InternalAxiosRequestConfig } from 'axios' +import axios, { AxiosError } from 'axios' import { message } from 'ant-design-vue' import { ResponseEntity } from '@/api/types' import router from '@/router' @@ -25,13 +26,17 @@ import i18n from '@/locales' import { API_EXPIRE_TIME } from '@/utils/constant.ts' import { Locale } from '@/store/locale/types.ts' -const request = axios.create({ +const baseConfig = { baseURL: import.meta.env.VITE_APP_BASE_API, withCredentials: true, timeout: API_EXPIRE_TIME -}) +} + +const axiosInstance: AxiosInstance = axios.create(baseConfig) +const request = axiosInstance.interceptors.request +const response = axiosInstance.interceptors.response -request.interceptors.request.use((config: InternalAxiosRequestConfig): InternalAxiosRequestConfig => { +request.use((config: InternalAxiosRequestConfig): InternalAxiosRequestConfig => { config.headers = config.headers || {} const locale = i18n.global.locale.value as Locale @@ -45,7 +50,7 @@ request.interceptors.request.use((config: InternalAxiosRequestConfig): Inte return config }) -request.interceptors.response.use( +response.use( async (res: AxiosResponse) => { if (res.config.responseType === 'stream') { // Skip SSE api check @@ -80,4 +85,4 @@ request.interceptors.response.use( } ) -export default request +export default axiosInstance diff --git a/bigtop-manager-ui/src/api/service/index.ts b/bigtop-manager-ui/src/api/service/index.ts index 9b61a3845..6642f0948 100644 --- a/bigtop-manager-ui/src/api/service/index.ts +++ b/bigtop-manager-ui/src/api/service/index.ts @@ -17,12 +17,73 @@ * under the License. */ +import type { + ServiceParams, + ServiceVO, + ServiceConfig, + ServiceConfigSnapshot, + ServiceList, + SnapshotData, + SnapshotRecovery +} from './types' import request from '@/api/request.ts' -import { ServiceVO } from '@/api/service/types.ts' -export const getService = (clusterId: number): Promise => { +export const getServiceList = (clusterId: number): Promise => { return request({ method: 'get', - url: '/clusters/' + clusterId + '/services' + url: `/clusters/${clusterId}/services` + }) +} + +export const getService = (params: ServiceParams): Promise => { + return request({ + method: 'get', + url: `/clusters/${params.clusterId}/services/${params.id}` + }) +} + +export const getServiceConfigs = (params: ServiceParams): Promise => { + return request({ + method: 'get', + url: `/clusters/${params.clusterId}/services/${params.id}/configs` + }) +} + +export const updateServiceConfigs = (params: ServiceParams, data: ServiceConfig): Promise => { + return request({ + method: 'post', + url: `/clusters/${params.clusterId}/services/${params.id}/configs`, + data + }) +} + +export const getServiceConfigSnapshotsList = (params: ServiceParams): Promise => { + return request({ + method: 'get', + url: `/clusters/${params.clusterId}/services/${params.id}/config-snapshots` + }) +} + +export const takeServiceConfigSnapshot = ( + params: ServiceParams, + data: SnapshotData +): Promise => { + return request({ + method: 'post', + url: `/clusters/${params.clusterId}/services/${params.id}/config-snapshots`, + data + }) +} + +export const recoveryServiceConfigSnapshot = (params: SnapshotRecovery): Promise => { + return request({ + method: 'post', + url: `/clusters/${params.clusterId}/services/${params.id}/config-snapshots/${params.snapshotId}` + }) +} +export const deleteServiceConfigSnapshot = (params: SnapshotRecovery): Promise => { + return request({ + method: 'delete', + url: `/clusters/${params.clusterId}/services/${params.id}/config-snapshots/${params.snapshotId}` }) } diff --git a/bigtop-manager-ui/src/api/service/types.ts b/bigtop-manager-ui/src/api/service/types.ts index d6a5d0d24..2afefea75 100644 --- a/bigtop-manager-ui/src/api/service/types.ts +++ b/bigtop-manager-ui/src/api/service/types.ts @@ -17,21 +17,51 @@ * under the License. */ +import type { ComponentVO } from '@/api/component/types' +import type { PageVO } from '@/api/types' + +export type ServiceList = PageVO +export type ServiceParams = { clusterId: number; id: number } +export type SnapshotData = { desc?: string; name?: string } +export type SnapshotRecovery = ServiceParams & { snapshotId: string } + export interface ServiceVO { + components?: ComponentVO[] + configs?: ServiceConfig[] + desc?: string + displayName?: string + id?: number + name?: string + requiredServices?: string[] + restartFlag?: boolean + stack?: string + status?: number + user?: string + version?: string +} + +export interface ServiceConfig { id?: number - serviceName: string - displayName: string - serviceDesc: string - serviceVersion: string - clusterName?: string - serviceUser?: string - serviceGroup?: string - isClient?: boolean - isHealthy?: boolean - quickLinks?: QuickLinkVO[] + name?: string + properties?: Property[] } -export interface QuickLinkVO { - displayName: string - url: string +export interface Property { + attrs?: Attr + desc?: string + displayName?: string + name: string + value?: string +} + +export interface Attr { + type?: string +} + +export interface ServiceConfigSnapshot { + configJson?: string + desc?: string + id?: number + name?: string + [property: string]: any } diff --git a/bigtop-manager-ui/src/api/stack/index.ts b/bigtop-manager-ui/src/api/stack/index.ts index f7d400429..cbd1825c2 100644 --- a/bigtop-manager-ui/src/api/stack/index.ts +++ b/bigtop-manager-ui/src/api/stack/index.ts @@ -19,8 +19,6 @@ import request from '@/api/request.ts' import { StackVO } from '@/api/stack/types.ts' -import { ServiceComponentVO } from '@/api/component/types.ts' -import { ServiceConfigVO } from '@/api/config/types.ts' export const getStacks = (): Promise => { return request({ @@ -28,17 +26,3 @@ export const getStacks = (): Promise => { url: '/stacks' }) } - -export const getStackComponents = (stackName: string, stackVersion: string): Promise => { - return request({ - method: 'get', - url: '/stacks/' + stackName + '/' + stackVersion + '/components' - }) -} - -export const getStackConfigs = (stackName: string, stackVersion: string): Promise => { - return request({ - method: 'get', - url: '/stacks/' + stackName + '/' + stackVersion + '/configurations' - }) -} diff --git a/bigtop-manager-ui/src/api/stack/types.ts b/bigtop-manager-ui/src/api/stack/types.ts index 3b7440123..67f655372 100644 --- a/bigtop-manager-ui/src/api/stack/types.ts +++ b/bigtop-manager-ui/src/api/stack/types.ts @@ -17,8 +17,8 @@ * under the License. */ -import { ServiceVO } from '@/api/service/types.ts' import { RepoVO } from '@/api/repo/types.ts' +import { ServiceVO } from '../service/types' export interface StackVO { stackName: string diff --git a/bigtop-manager-ui/src/api/upload-file/index.ts b/bigtop-manager-ui/src/api/upload-file/index.ts new file mode 100644 index 000000000..8b5644e9e --- /dev/null +++ b/bigtop-manager-ui/src/api/upload-file/index.ts @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import request from '@/api/request.ts' + +export const uploadFile = (data: FormData): Promise => { + return request({ + method: 'post', + url: '/files/upload-key', + data, + headers: { + 'Content-Type': 'multipart/form-data' + } + }) +} diff --git a/bigtop-manager-ui/src/assets/images/cluster.png b/bigtop-manager-ui/src/assets/images/cluster.png new file mode 100644 index 000000000..142077657 Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/cluster.png differ diff --git a/bigtop-manager-ui/src/assets/images/deepseek.png b/bigtop-manager-ui/src/assets/images/deepseek.png new file mode 100644 index 000000000..161d03e29 Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/deepseek.png differ diff --git a/bigtop-manager-ui/src/assets/images/default.png b/bigtop-manager-ui/src/assets/images/default.png new file mode 100644 index 000000000..40849b5a3 Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/default.png differ diff --git a/bigtop-manager-ui/src/assets/images/flink.png b/bigtop-manager-ui/src/assets/images/flink.png new file mode 100644 index 000000000..c508e1e77 Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/flink.png differ diff --git a/bigtop-manager-ui/src/assets/images/grafana.png b/bigtop-manager-ui/src/assets/images/grafana.png new file mode 100644 index 000000000..307d392d0 Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/grafana.png differ diff --git a/bigtop-manager-ui/src/assets/images/hadoop.png b/bigtop-manager-ui/src/assets/images/hadoop.png new file mode 100644 index 000000000..176856a96 Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/hadoop.png differ diff --git a/bigtop-manager-ui/src/assets/images/hbase.png b/bigtop-manager-ui/src/assets/images/hbase.png new file mode 100644 index 000000000..c975a8d68 Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/hbase.png differ diff --git a/bigtop-manager-ui/src/assets/images/hive.png b/bigtop-manager-ui/src/assets/images/hive.png new file mode 100644 index 000000000..095282218 Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/hive.png differ diff --git a/bigtop-manager-ui/src/assets/images/host.png b/bigtop-manager-ui/src/assets/images/host.png new file mode 100644 index 000000000..1e7040303 Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/host.png differ diff --git a/bigtop-manager-ui/src/assets/images/kafka.png b/bigtop-manager-ui/src/assets/images/kafka.png new file mode 100644 index 000000000..3f18c3dd9 Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/kafka.png differ diff --git a/bigtop-manager-ui/src/assets/images/mysql.png b/bigtop-manager-ui/src/assets/images/mysql.png new file mode 100644 index 000000000..a37ef476e Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/mysql.png differ diff --git a/bigtop-manager-ui/src/assets/images/prometheus.png b/bigtop-manager-ui/src/assets/images/prometheus.png new file mode 100644 index 000000000..1b87345f9 Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/prometheus.png differ diff --git a/bigtop-manager-ui/src/assets/images/seatunnel.png b/bigtop-manager-ui/src/assets/images/seatunnel.png new file mode 100644 index 000000000..0e859ebea Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/seatunnel.png differ diff --git a/bigtop-manager-ui/src/assets/images/solr.png b/bigtop-manager-ui/src/assets/images/solr.png new file mode 100644 index 000000000..6d0d02daa Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/solr.png differ diff --git a/bigtop-manager-ui/src/assets/images/spark.png b/bigtop-manager-ui/src/assets/images/spark.png new file mode 100644 index 000000000..3a3cede97 Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/spark.png differ diff --git a/bigtop-manager-ui/src/assets/images/svg/bottom.svg b/bigtop-manager-ui/src/assets/images/svg/bottom.svg new file mode 100644 index 000000000..edc1e747f --- /dev/null +++ b/bigtop-manager-ui/src/assets/images/svg/bottom.svg @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/bigtop-manager-ui/src/assets/images/svg/canceled.svg b/bigtop-manager-ui/src/assets/images/svg/canceled.svg new file mode 100644 index 000000000..1adf2461c --- /dev/null +++ b/bigtop-manager-ui/src/assets/images/svg/canceled.svg @@ -0,0 +1,29 @@ + + + + + + + + \ No newline at end of file diff --git a/bigtop-manager-ui/src/assets/images/svg/error.svg b/bigtop-manager-ui/src/assets/images/svg/error.svg new file mode 100644 index 000000000..44d3bf63c --- /dev/null +++ b/bigtop-manager-ui/src/assets/images/svg/error.svg @@ -0,0 +1,32 @@ + + + + + + + + + + \ No newline at end of file diff --git a/bigtop-manager-ui/src/assets/images/svg/failed.svg b/bigtop-manager-ui/src/assets/images/svg/failed.svg new file mode 100644 index 000000000..44d3bf63c --- /dev/null +++ b/bigtop-manager-ui/src/assets/images/svg/failed.svg @@ -0,0 +1,32 @@ + + + + + + + + + + \ No newline at end of file diff --git a/bigtop-manager-ui/src/pages/cluster-manage/cluster/detail.vue b/bigtop-manager-ui/src/assets/images/svg/filter.svg similarity index 69% rename from bigtop-manager-ui/src/pages/cluster-manage/cluster/detail.vue rename to bigtop-manager-ui/src/assets/images/svg/filter.svg index d76126734..22f0cceff 100644 --- a/bigtop-manager-ui/src/pages/cluster-manage/cluster/detail.vue +++ b/bigtop-manager-ui/src/assets/images/svg/filter.svg @@ -1,3 +1,4 @@ + - - - - - - + + + + \ No newline at end of file diff --git a/bigtop-manager-ui/src/assets/images/svg/filter_activated.svg b/bigtop-manager-ui/src/assets/images/svg/filter_activated.svg new file mode 100644 index 000000000..af28467f9 --- /dev/null +++ b/bigtop-manager-ui/src/assets/images/svg/filter_activated.svg @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/bigtop-manager-ui/src/assets/images/svg/installing.svg b/bigtop-manager-ui/src/assets/images/svg/installing.svg new file mode 100644 index 000000000..a51ec2056 --- /dev/null +++ b/bigtop-manager-ui/src/assets/images/svg/installing.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bigtop-manager-ui/src/assets/images/svg/more_line.svg b/bigtop-manager-ui/src/assets/images/svg/more_line.svg new file mode 100644 index 000000000..0fa0cca82 --- /dev/null +++ b/bigtop-manager-ui/src/assets/images/svg/more_line.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/bigtop-manager-ui/src/assets/images/svg/processing.svg b/bigtop-manager-ui/src/assets/images/svg/processing.svg new file mode 100644 index 000000000..015797f81 --- /dev/null +++ b/bigtop-manager-ui/src/assets/images/svg/processing.svg @@ -0,0 +1,28 @@ + + + + + + + + \ No newline at end of file diff --git a/bigtop-manager-ui/src/assets/images/svg/question.svg b/bigtop-manager-ui/src/assets/images/svg/question.svg new file mode 100644 index 000000000..79a6923cb --- /dev/null +++ b/bigtop-manager-ui/src/assets/images/svg/question.svg @@ -0,0 +1,29 @@ + + + + + + + + + \ No newline at end of file diff --git a/bigtop-manager-ui/src/assets/images/svg/restart.svg b/bigtop-manager-ui/src/assets/images/svg/restart.svg new file mode 100644 index 000000000..4d6466755 --- /dev/null +++ b/bigtop-manager-ui/src/assets/images/svg/restart.svg @@ -0,0 +1,31 @@ + + + + + + + + + + \ No newline at end of file diff --git a/bigtop-manager-ui/src/assets/images/svg/search.svg b/bigtop-manager-ui/src/assets/images/svg/search.svg new file mode 100644 index 000000000..cbaaf37f2 --- /dev/null +++ b/bigtop-manager-ui/src/assets/images/svg/search.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bigtop-manager-ui/src/assets/images/svg/search_activated.svg b/bigtop-manager-ui/src/assets/images/svg/search_activated.svg new file mode 100644 index 000000000..4f830254a --- /dev/null +++ b/bigtop-manager-ui/src/assets/images/svg/search_activated.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bigtop-manager-ui/src/assets/images/svg/start.svg b/bigtop-manager-ui/src/assets/images/svg/start.svg new file mode 100644 index 000000000..e24b7ae02 --- /dev/null +++ b/bigtop-manager-ui/src/assets/images/svg/start.svg @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file diff --git a/bigtop-manager-ui/src/assets/images/svg/stop.svg b/bigtop-manager-ui/src/assets/images/svg/stop.svg new file mode 100644 index 000000000..48249fa5d --- /dev/null +++ b/bigtop-manager-ui/src/assets/images/svg/stop.svg @@ -0,0 +1,32 @@ + + + + + + + + + + \ No newline at end of file diff --git a/bigtop-manager-ui/src/assets/images/svg/success.svg b/bigtop-manager-ui/src/assets/images/svg/success.svg new file mode 100644 index 000000000..4b1e36274 --- /dev/null +++ b/bigtop-manager-ui/src/assets/images/svg/success.svg @@ -0,0 +1,29 @@ + + + + + + + + \ No newline at end of file diff --git a/bigtop-manager-ui/src/assets/images/svg/unknow.svg b/bigtop-manager-ui/src/assets/images/svg/unknow.svg new file mode 100644 index 000000000..2bb5e7912 --- /dev/null +++ b/bigtop-manager-ui/src/assets/images/svg/unknow.svg @@ -0,0 +1,33 @@ + + + + + + + + + + \ No newline at end of file diff --git a/bigtop-manager-ui/src/assets/images/tez.png b/bigtop-manager-ui/src/assets/images/tez.png new file mode 100644 index 000000000..bcceea0ee Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/tez.png differ diff --git a/bigtop-manager-ui/src/assets/images/zookeeper.png b/bigtop-manager-ui/src/assets/images/zookeeper.png new file mode 100644 index 000000000..080dd55ed Binary files /dev/null and b/bigtop-manager-ui/src/assets/images/zookeeper.png differ diff --git a/bigtop-manager-ui/src/components/ai-assistant/index.vue b/bigtop-manager-ui/src/components/ai-assistant/index.vue index 871d5c13e..7b0e04963 100644 --- a/bigtop-manager-ui/src/components/ai-assistant/index.vue +++ b/bigtop-manager-ui/src/components/ai-assistant/index.vue @@ -170,7 +170,7 @@ diff --git a/bigtop-manager-ui/src/components/common/auto-form/index.vue b/bigtop-manager-ui/src/components/common/auto-form/index.vue index 9d924006c..0022d9508 100644 --- a/bigtop-manager-ui/src/components/common/auto-form/index.vue +++ b/bigtop-manager-ui/src/components/common/auto-form/index.vue @@ -20,13 +20,15 @@ - + 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 ae481660d..7f2d17d43 100644 --- a/bigtop-manager-ui/src/components/common/button-group/types.ts +++ b/bigtop-manager-ui/src/components/common/button-group/types.ts @@ -17,9 +17,15 @@ * under the License. */ +import { MenuItemProps, MenuProps } from 'ant-design-vue' + type BtnType = 'primary' | 'ghost' | 'dashed' | 'link' | 'text' | 'default' type ShapeType = 'default' | 'circle' | 'round' +export interface DropdownMenu extends MenuItemProps { + action: string + text: string +} export interface GroupItem { icon?: string tip?: string @@ -28,12 +34,19 @@ export interface GroupItem { type?: BtnType shape?: ShapeType disabled?: boolean + danger?: boolean + dropdownMenu?: DropdownMenu[] clickEvent?: (item?: GroupItem, ...args: any[]) => void + dropdownMenuClickEvent?: MenuProps['onClick'] } export interface Props { - i18n: string + i18n?: string + textCompact?: boolean groups: GroupItem[] groupType?: BtnType groupShape?: ShapeType + space?: number + args?: any + auto?: boolean } diff --git a/bigtop-manager-ui/src/components/common/filter-form/index.vue b/bigtop-manager-ui/src/components/common/filter-form/index.vue new file mode 100644 index 000000000..7562ea370 --- /dev/null +++ b/bigtop-manager-ui/src/components/common/filter-form/index.vue @@ -0,0 +1,153 @@ + + + + + + + diff --git a/bigtop-manager-ui/src/components/common/filter-form/types.ts b/bigtop-manager-ui/src/components/common/filter-form/types.ts new file mode 100644 index 000000000..c2d1e3b52 --- /dev/null +++ b/bigtop-manager-ui/src/components/common/filter-form/types.ts @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export interface FilterFormItemOptionItem { + value: string | number | boolean + label: string + [propkey: string]: any +} + +export interface FilterFormItem { + type: string + key: string + label: string + options?: FilterFormItemOptionItem[] +} diff --git a/bigtop-manager-ui/src/components/common/header-card/index.vue b/bigtop-manager-ui/src/components/common/header-card/index.vue new file mode 100644 index 000000000..d11d81bb3 --- /dev/null +++ b/bigtop-manager-ui/src/components/common/header-card/index.vue @@ -0,0 +1,109 @@ + + + + + + + diff --git a/bigtop-manager-ui/src/components/common/main-card/index.vue b/bigtop-manager-ui/src/components/common/main-card/index.vue new file mode 100644 index 000000000..f5efb7a78 --- /dev/null +++ b/bigtop-manager-ui/src/components/common/main-card/index.vue @@ -0,0 +1,68 @@ + + + + + + + diff --git a/bigtop-manager-ui/src/components/common/main-card/types.ts b/bigtop-manager-ui/src/components/common/main-card/types.ts new file mode 100644 index 000000000..abc7c4dae --- /dev/null +++ b/bigtop-manager-ui/src/components/common/main-card/types.ts @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export interface TabItem { + key: string + title: string +} diff --git a/bigtop-manager-ui/src/components/common/status-dot/index.vue b/bigtop-manager-ui/src/components/common/status-dot/index.vue new file mode 100644 index 000000000..96c401a34 --- /dev/null +++ b/bigtop-manager-ui/src/components/common/status-dot/index.vue @@ -0,0 +1,65 @@ + + + + + + + diff --git a/bigtop-manager-ui/src/composables/use-base-table.ts b/bigtop-manager-ui/src/composables/use-base-table.ts index f1010693d..2d359b4b9 100644 --- a/bigtop-manager-ui/src/composables/use-base-table.ts +++ b/bigtop-manager-ui/src/composables/use-base-table.ts @@ -19,31 +19,41 @@ import { ref, onUnmounted } from 'vue' import type { TablePaginationConfig, TableColumnType } from 'ant-design-vue' -export interface UseBaseTableProps { +import { useI18n } from 'vue-i18n' + +type PaginationProps = TablePaginationConfig | false | undefined +export interface UseBaseTableProps { columns: TableColumnType[] rows?: T[] - pagination?: TablePaginationConfig | false | undefined + pagination?: PaginationProps } const useBaseTable = (props: UseBaseTableProps) => { const { columns, rows, pagination } = props + const { t } = useI18n() const loading = ref(false) const dataSource = ref(rows || []) const columnsProp = ref(columns) - const paginationProps = ref({ + const paginationProps = ref({ current: 1, pageSize: 10, total: dataSource.value.length, size: 'small', showSizeChanger: true, - pageSizeOptions: ['10', '20', '30', '40', '50'] + pageSizeOptions: ['10', '20', '30', '40', '50'], + showTotal: (total) => `${t('common.total', [total])}` }) // merge pagination config - if (pagination) { + if (pagination === undefined && paginationProps.value) { paginationProps.value = Object.assign(paginationProps.value, pagination) + } else { + paginationProps.value = false } const onChange = (pagination: TablePaginationConfig) => { + if (!paginationProps.value) { + return + } paginationProps.value = Object.assign(paginationProps.value, pagination) } @@ -56,7 +66,8 @@ const useBaseTable = (props: UseBaseTableProps) => { total: dataSource.value.length || 0, size: 'small', showSizeChanger: true, - pageSizeOptions: ['10', '20', '30', '40', '50'] + pageSizeOptions: ['10', '20', '30', '40', '50'], + showTotal: (total) => `${t('common.total', [total])}` } } diff --git a/bigtop-manager-ui/src/layouts/default.vue b/bigtop-manager-ui/src/layouts/default.vue index 1f109f211..a135f333d 100644 --- a/bigtop-manager-ui/src/layouts/default.vue +++ b/bigtop-manager-ui/src/layouts/default.vue @@ -17,10 +17,33 @@ ~ under the License. --> - + - + diff --git a/bigtop-manager-ui/src/layouts/index.vue b/bigtop-manager-ui/src/layouts/index.vue index 7c70c6dc5..c48ab595d 100644 --- a/bigtop-manager-ui/src/layouts/index.vue +++ b/bigtop-manager-ui/src/layouts/index.vue @@ -23,22 +23,21 @@ import LayoutHeader from '@/layouts/header.vue' import LayoutSider from '@/layouts/sider.vue' import { useUserStore } from '@/store/user' - import { useClusterStore } from '@/store/cluster' + // import { useClusterStore } from '@/store/cluster' import { useMenuStore } from '@/store/menu/index' + import { useStackStore } from '@/store/stack' import { storeToRefs } from 'pinia' const userStore = useUserStore() const menuStore = useMenuStore() - const clusterStore = useClusterStore() + // const clusterStore = useClusterStore() + const stackStore = useStackStore() const { headerSelectedKey, headerMenus, siderMenuSelectedKey, siderMenus } = storeToRefs(menuStore) onMounted(async () => { userStore.getUserInfo() - clusterStore.loadClusters() - // setInterval(() => { - // clusterStore.addCluster() - // }, 5000) menuStore.setUpMenu() + stackStore.loadStacks() }) diff --git a/bigtop-manager-ui/src/layouts/sider.vue b/bigtop-manager-ui/src/layouts/sider.vue index 9ace43381..530d126f6 100644 --- a/bigtop-manager-ui/src/layouts/sider.vue +++ b/bigtop-manager-ui/src/layouts/sider.vue @@ -18,7 +18,7 @@ --> + + + + 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 new file mode 100644 index 000000000..847ef1208 --- /dev/null +++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/check-workflow.vue @@ -0,0 +1,170 @@ + + + + + + + diff --git a/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/cluster-base.vue b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/cluster-base.vue new file mode 100644 index 000000000..82a9d1e21 --- /dev/null +++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/cluster-base.vue @@ -0,0 +1,212 @@ + + + + + + + diff --git a/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/component-info.vue b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/component-info.vue new file mode 100644 index 000000000..0f8fe394c --- /dev/null +++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/component-info.vue @@ -0,0 +1,117 @@ + + + + + + + diff --git a/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/gauge-chart.vue b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/gauge-chart.vue new file mode 100644 index 000000000..d2d2dcaae --- /dev/null +++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/gauge-chart.vue @@ -0,0 +1,148 @@ + + + + + + + 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 new file mode 100644 index 000000000..a222bc431 --- /dev/null +++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/host-config.vue @@ -0,0 +1,270 @@ + + + + + + + diff --git a/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/mock.ts b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/mock.ts new file mode 100644 index 000000000..4ccb391ac --- /dev/null +++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/mock.ts @@ -0,0 +1,187 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export function generateTestData(count = 100) { + const names = ['componentA', 'componentB', 'componentC', 'componentD', 'componentE'] + const versions = ['1.0.0', '2.3.1', '3.2.4', '4.0.0', '5.1.2'] + const compStacks = [ + 'React, Redux, Webpack', + 'Vue, Vuex, Vite', + 'Angular, RxJS, NgRx', + 'Node.js, Express, MongoDB', + 'Svelte, Rollup, Firebase' + ] + const descriptions = [ + '这是一个用于状态管理的组件', + '这是一个用于数据展示的组件', + '这是一个用于实时数据处理的组件', + '这是一个后端服务组件', + '这是一个前端开发框架' + ] + + const testData = Array.from({ length: count }, (_, i) => ({ + key: (i + 1).toString(), + name: names[Math.floor(Math.random() * names.length)], + version: versions[Math.floor(Math.random() * versions.length)], + compStack: compStacks[Math.floor(Math.random() * compStacks.length)], + descrip: descriptions[Math.floor(Math.random() * descriptions.length)] + })) + + return testData +} + +export function generateTableHostData(numRows = 100) { + const hostnames = ['Server-A', 'Server-B', 'Server-C', 'Server-D', 'Server-E'] + const nodeNames = ['host-A', 'host-B', 'host-C', 'host-D'] + const ipAddresses = ['192.168.1.1', '192.168.1.2', '192.168.1.3', '192.168.1.4', '192.168.1.5'] + const systems = 'Rocky Linux 8.8' + const architecture = 'x86_64' + const remarks = ['Main server', 'Backup server', 'Database server', 'Web server', 'Test server'] + const statuses = ['installing', 'success', 'error', 'unknow'] + + const tableData = [] + + for (let i = 0; i < numRows; i++) { + tableData.push({ + key: i + 1, + name: hostnames[Math.floor(Math.random() * hostnames.length)], + system: `${systems}-${i}`, + architecture: `${architecture}-${i}`, + componentCount: `${i} components`, + nodeName: nodeNames[Math.floor(Math.random() * nodeNames.length)], + address: ipAddresses[Math.floor(Math.random() * ipAddresses.length)], + remark: remarks[Math.floor(Math.random() * remarks.length)], + status: statuses[Math.floor(Math.random() * statuses.length)] + }) + } + + return tableData +} + +export function getCheckWorkflows(stageCount: number, maxTasksPerStage: number, maxStatus: number): Array { + const data = [] + + for (let i = 0; i < stageCount; i++) { + const taskCount = Math.floor(Math.random() * maxTasksPerStage) + 1 + const tasks = [] + + for (let j = 0; j < taskCount; j++) { + tasks.push({ + id: j, + name: `task${j + 1}`, + status: Math.floor(Math.random() * maxStatus) + 1 + }) + } + + data.push({ + id: i, + name: `stage${i + 1}`, + status: Math.floor(Math.random() * maxStatus) + 1, + tasks + }) + } + + return data +} + +export enum StatusColors { + success = 'success', + error = 'error', + unknow = 'warning' +} + +export enum StatusTexts { + success = 'healthy', + error = 'unhealthy', + unknow = 'unknown' +} + +export type ServiceStatus = keyof typeof StatusColors + +export interface ServiceItem { + key: string | number + serviceName: string + version: string + restart: boolean + status: ServiceStatus +} + +export function getServices(): ServiceItem[] { + const statusList = ['success', 'error', 'unknow'] + const serviceNames = [ + 'GraFana', + 'Flink', + 'Kafka', + 'ZooKeeper', + 'Hadoop', + 'Hbase', + 'Hive', + 'MySQL', + 'Spark', + 'Solr', + 'Seatunnel', + 'Tez', + 'Prometheus' + ] + return Array.from({ length: serviceNames.length }, (_, i) => ({ + key: i, + serviceName: serviceNames[i], + version: `${serviceNames[i].toLowerCase()}1.0.${i}`, + restart: Math.floor(Math.random() * 2) == 0, + status: statusList[Math.floor(Math.random() * statusList.length)] as ServiceStatus + })) +} + +export interface UserListItem { + serviceName: string + userName: string + userGroup: string + descrip: string +} + +export function getUserList(count: number = 20): UserListItem[] { + return Array.from({ length: count }, (_, i) => ({ + key: i, + serviceName: `serviceName-${i}`, + userName: `user-${i}`, + userGroup: `userGroup-${i}`, + descrip: 'descrip-descrip-descrip' + })) +} + +type JobStatus = 'success' | 'exception' | 'normal' | 'active' +export interface JobListItem { + name: string + status: JobStatus + progress: number + createTime: string + updateTime: string +} + +export function getJobList(count: number = 20): JobListItem[] { + const status = ['success', 'exception', 'normal', 'active'] + return Array.from({ length: count }, (_, i) => ({ + key: i, + name: `name-${i}`, + progress: Math.floor(Math.random() * 100), + status: status[Math.floor(Math.random() * status.length)] as JobStatus, + createTime: '2024-09-19 11:11:11', + updateTime: '2024-09-19 11:11:11' + })) +} diff --git a/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/set-source.vue b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/set-source.vue new file mode 100644 index 000000000..4c8d996a6 --- /dev/null +++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/components/set-source.vue @@ -0,0 +1,151 @@ + + + + + + + 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 a1f074d6b..3fbee40d4 100644 --- a/bigtop-manager-ui/src/pages/cluster-manage/cluster/create.vue +++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/create.vue @@ -19,23 +19,259 @@ - + diff --git a/bigtop-manager-ui/src/pages/cluster-manage/cluster/host.vue b/bigtop-manager-ui/src/pages/cluster-manage/cluster/host.vue new file mode 100644 index 000000000..f39243de4 --- /dev/null +++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/host.vue @@ -0,0 +1,245 @@ + + + + + + + diff --git a/bigtop-manager-ui/src/pages/cluster-manage/cluster/index.vue b/bigtop-manager-ui/src/pages/cluster-manage/cluster/index.vue index d78ec09f2..6017e998d 100644 --- a/bigtop-manager-ui/src/pages/cluster-manage/cluster/index.vue +++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/index.vue @@ -17,12 +17,93 @@ ~ under the License. --> - + - + diff --git a/bigtop-manager-ui/src/pages/cluster-manage/cluster/job.vue b/bigtop-manager-ui/src/pages/cluster-manage/cluster/job.vue new file mode 100644 index 000000000..90a1eb21b --- /dev/null +++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/job.vue @@ -0,0 +1,94 @@ + + + + + + + diff --git a/bigtop-manager-ui/src/pages/cluster-manage/cluster/overview.vue b/bigtop-manager-ui/src/pages/cluster-manage/cluster/overview.vue new file mode 100644 index 000000000..c7daf8346 --- /dev/null +++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/overview.vue @@ -0,0 +1,341 @@ + + + + + + + diff --git a/bigtop-manager-ui/src/pages/cluster-manage/cluster/service.vue b/bigtop-manager-ui/src/pages/cluster-manage/cluster/service.vue new file mode 100644 index 000000000..007a9cb21 --- /dev/null +++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/service.vue @@ -0,0 +1,226 @@ + + + + + + + diff --git a/bigtop-manager-ui/src/pages/cluster-manage/cluster/user.vue b/bigtop-manager-ui/src/pages/cluster-manage/cluster/user.vue new file mode 100644 index 000000000..2955093de --- /dev/null +++ b/bigtop-manager-ui/src/pages/cluster-manage/cluster/user.vue @@ -0,0 +1,87 @@ + + + + + + + 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 c4e831863..85ed4a0a7 100644 --- a/bigtop-manager-ui/src/pages/cluster-manage/hosts/create.vue +++ b/bigtop-manager-ui/src/pages/cluster-manage/hosts/create.vue @@ -17,10 +17,545 @@ ~ under the License. --> - + - + diff --git a/bigtop-manager-ui/src/store/cluster/index.ts b/bigtop-manager-ui/src/store/cluster/index.ts index 397b49bb1..5c8459c6d 100644 --- a/bigtop-manager-ui/src/store/cluster/index.ts +++ b/bigtop-manager-ui/src/store/cluster/index.ts @@ -20,7 +20,7 @@ import { defineStore } from 'pinia' import { ClusterVO } from '@/api/cluster/types.ts' import { ref } from 'vue' -// import { getClusters } from '@/api/cluster' +import { getClusterList } from '@/api/cluster' export const useClusterStore = defineStore( 'cluster', @@ -28,21 +28,6 @@ export const useClusterStore = defineStore( const clusters = ref([]) const count = ref(0) - const generateRandomDataArray = () => { - const dataArray = [] - for (let i = 0; i < count.value; i++) { - dataArray.push({ - id: i, - clusterName: `Cluster-${i}`, - clusterType: Math.floor(Math.random() * 10), - stackName: `Stack-${i}`, - stackVersion: `Version-${i}`, - selected: Math.random() < 0.5 - }) - } - return dataArray - } - const addCluster = async () => { count.value = count.value + 1 await loadClusters() @@ -58,12 +43,8 @@ export const useClusterStore = defineStore( } const loadClusters = async () => { - // clusters.value = await getClusters() - clusters.value = (await new Promise((resolve) => { - setTimeout(() => { - resolve(generateRandomDataArray()) - }, 1000) - })) as ClusterVO[] + const data = await getClusterList() + clusters.value = data as ClusterVO[] } return { diff --git a/bigtop-manager-ui/src/store/llm-config/config.ts b/bigtop-manager-ui/src/store/llm-config/config.ts index 7aa767d5a..e2e735d3b 100644 --- a/bigtop-manager-ui/src/store/llm-config/config.ts +++ b/bigtop-manager-ui/src/store/llm-config/config.ts @@ -92,13 +92,13 @@ export function useFormItemConfig() { rules: [ { required: true, - message: t('common.enter_error', [t('llmConfig.desc')]), + message: t('common.enter_error', [t('llmConfig.desc').toLowerCase()]), trigger: 'blur' } ] }, controlProps: { - placeholder: t('common.enter_error', [t('llmConfig.desc')]) + placeholder: t('common.enter_error', [t('llmConfig.desc').toLowerCase()]) } } ]) diff --git a/bigtop-manager-ui/src/store/menu/index.ts b/bigtop-manager-ui/src/store/menu/index.ts index 887bd24d8..72df905e9 100644 --- a/bigtop-manager-ui/src/store/menu/index.ts +++ b/bigtop-manager-ui/src/store/menu/index.ts @@ -89,10 +89,11 @@ export const useMenuStore = defineStore( item.children = clusters.value.map((v) => { return { icon: '', - key: `${item.key}/${v.clusterName}/${v.id}`, - label: v.clusterName, - title: v.clusterName, - activeMenu: item.key + key: `${item.key}/${v.displayName}/${v.id}`, + label: v.displayName || '', + title: v.displayName || '', + activeMenu: item.key, + status: v.status || 3 } }) } @@ -144,8 +145,10 @@ export const useMenuStore = defineStore( router.push(siderMenuSelectedKey.value) } - const setUpMenu = () => { + const setUpMenu = async () => { setBaseRoutesMap() + await clusterStore.loadClusters() + updateSiderMenu() } const cleanUpMenu = () => { @@ -168,6 +171,9 @@ export const useMenuStore = defineStore( } }, { - persist: false + persist: { + storage: localStorage, + paths: ['siderMenus'] + } } ) diff --git a/bigtop-manager-ui/src/store/menu/types.ts b/bigtop-manager-ui/src/store/menu/types.ts index fa5c94906..bf995ef30 100644 --- a/bigtop-manager-ui/src/store/menu/types.ts +++ b/bigtop-manager-ui/src/store/menu/types.ts @@ -23,5 +23,6 @@ export interface MenuItem { title: string name?: string activeMenu?: string + status?: number children?: MenuItem[] } diff --git a/bigtop-manager-ui/src/store/stack/index.ts b/bigtop-manager-ui/src/store/stack/index.ts new file mode 100644 index 000000000..02d7884c6 --- /dev/null +++ b/bigtop-manager-ui/src/store/stack/index.ts @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { getStacks } from '@/api/stack' +import { StackVO } from '@/api/stack/types' +import { defineStore } from 'pinia' +import { ref } from 'vue' + +export const useStackStore = defineStore( + 'stack', + () => { + const stacks = ref([]) + const loadStacks = async () => { + const data = await getStacks() + stacks.value = data + } + + return { + stacks, + loadStacks + } + }, + { + persist: { + storage: sessionStorage + } + } +) diff --git a/bigtop-manager-ui/src/styles/ant-design-vue.scss b/bigtop-manager-ui/src/styles/ant-design-vue.scss index a23e7d2f9..dda4a10c5 100644 --- a/bigtop-manager-ui/src/styles/ant-design-vue.scss +++ b/bigtop-manager-ui/src/styles/ant-design-vue.scss @@ -381,3 +381,5 @@ $box-shadow-tabs-overflow-top: var(--box-shadow-tabs-overflow-top); $box-shadow-tabs-overflow-bottom: var(--box-shadow-tabs-overflow-bottom); $_token-key: var(--_token-key); $_hash-id: var(--_hash-id); + + diff --git a/bigtop-manager-ui/src/styles/index.scss b/bigtop-manager-ui/src/styles/index.scss index 7e114fdfa..f2bf2d1f5 100644 --- a/bigtop-manager-ui/src/styles/index.scss +++ b/bigtop-manager-ui/src/styles/index.scss @@ -45,3 +45,12 @@ height: 20px; } } + +// temp resolve error on console +.ant-modal div[aria-hidden='true'] { + display: none !important; +} + +:where(.ant-modal-header) { + margin-bottom: 16px !important; +} diff --git a/bigtop-manager-ui/src/styles/variables.scss b/bigtop-manager-ui/src/styles/variables.scss index ee3ab848e..57c3aadb4 100644 --- a/bigtop-manager-ui/src/styles/variables.scss +++ b/bigtop-manager-ui/src/styles/variables.scss @@ -41,3 +41,13 @@ $layout-sider-bg-color: $color-bg-base; align-items: $align; gap: $gap; } + +@mixin status-dot($background: $color-success, $width: 8px, $height: 8px, $margin: 0 6px 0 0) { + content: ''; + display: inline-block; + background-color: $background; + width: $width; + height: $height; + border-radius: 50%; + margin: $margin; +} diff --git a/bigtop-manager-ui/src/types/components.d.ts b/bigtop-manager-ui/src/types/components.d.ts new file mode 100644 index 000000000..f9673d004 --- /dev/null +++ b/bigtop-manager-ui/src/types/components.d.ts @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +export {} + +declare module 'vue' { + export interface GlobalComponents { + HeaderCard: (typeof import('@/components/common/header-card/index.vue'))['default'] + MainCard: (typeof import('@/components/common/main-card/index.vue'))['default'] + AutoForm: (typeof import('@/components/common/auto-form/index.vue'))['default'] + ButtonGroup: (typeof import('@/components/common/button-group/index.vue'))['default'] + MarkdownView: (typeof import('@/components/common/markdown-view/index.vue'))['default'] + StatusDot: (typeof import('@/components/common/status-dot/index.vue'))['default'] + } +} diff --git a/bigtop-manager-ui/src/utils/tools.ts b/bigtop-manager-ui/src/utils/tools.ts index 3be3f4d38..9092937ae 100644 --- a/bigtop-manager-ui/src/utils/tools.ts +++ b/bigtop-manager-ui/src/utils/tools.ts @@ -75,3 +75,21 @@ export const getRandomFromTimestamp = (len: number = 6) => { export const formatTime = (time: string | undefined, formatRule: string = 'YYYY-MM-DD HH:mm:ss') => { return typeof time === 'string' && dayjs(time).tz(dayjs.tz.guess(), true).format(formatRule) } + +export const generateRandomId = (length = 8) => { + return Math.random() + .toString(36) + .substring(2, length + 2) +} + +export const pick = (obj: T, keys: K[]): Pick => { + return keys.reduce( + (acc, key) => { + if (obj.hasOwnProperty(key)) { + acc[key] = obj[key] + } + return acc + }, + {} as Pick + ) +} diff --git a/bigtop-manager-ui/tests/__composables__/use-table.test.ts b/bigtop-manager-ui/tests/__composables__/use-table.test.ts index ec424d601..006a537f9 100644 --- a/bigtop-manager-ui/tests/__composables__/use-table.test.ts +++ b/bigtop-manager-ui/tests/__composables__/use-table.test.ts @@ -16,11 +16,22 @@ * specific language governing permissions and limitations * under the License. */ - import { describe, it, expect, vi } from 'vitest' import useBaseTable from '../../src/composables/use-base-table' import { withSetup } from '../test-util' +// Mock useI18n +vi.mock('vue-i18n', () => ({ + useI18n: () => ({ + t: (key: string, args?: any[]) => { + if (key === 'common.total') { + return `Total: ${args?.[0] || 0}` + } + return key + } + }) +})) + describe('useBaseTable', () => { const columns = [{ title: 'Column 1' }] const rows = [{ id: 1, name: 'Item 1' }] @@ -30,27 +41,38 @@ describe('useBaseTable', () => { expect(result.columnsProp.value).toEqual(columns) expect(result.dataSource.value).toEqual(rows) expect(result.loading.value).toBe(false) - expect(result.paginationProps.value).toEqual({ + + // Compare paginationProps excluding the showTotal function + const expectedPaginationProps = { current: 1, pageSize: 10, total: rows.length, size: 'small', showSizeChanger: true, pageSizeOptions: ['10', '20', '30', '40', '50'] - }) + } + expect(result.paginationProps.value).toEqual(expect.objectContaining(expectedPaginationProps)) + // Test showTotal function separately + expect(result.paginationProps.value.showTotal(5)).toBe('Total: 5') }) it('should update paginationProps when onChange is called', () => { const [result] = withSetup(useBaseTable, { columns, rows }) result.onChange({ current: 2, pageSize: 20 }) - expect(result.paginationProps.value).toEqual({ + + // Compare paginationProps excluding the showTotal function + const expectedPaginationProps = { current: 2, pageSize: 20, total: rows.length, size: 'small', showSizeChanger: true, pageSizeOptions: ['10', '20', '30', '40', '50'] - }) + } + expect(result.paginationProps.value).toEqual(expect.objectContaining(expectedPaginationProps)) + // Test showTotal function separately + console.log('result.paginationProps.value.showTotal(10) :>> ', result.paginationProps.value.showTotal(10)) + expect(result.paginationProps.value.showTotal(10)).toBe('Total: 10') }) it('should reset state when resetState is called', () => { @@ -59,14 +81,19 @@ describe('useBaseTable', () => { expect(result.columnsProp.value).toEqual(columns) expect(result.dataSource.value).toEqual([]) expect(result.loading.value).toBe(false) - expect(result.paginationProps.value).toEqual({ + + // Compare paginationProps excluding the showTotal function + const expectedPaginationProps = { current: 1, pageSize: 10, total: 0, size: 'small', showSizeChanger: true, pageSizeOptions: ['10', '20', '30', '40', '50'] - }) + } + expect(result.paginationProps.value).toEqual(expect.objectContaining(expectedPaginationProps)) + // Test showTotal function separately + expect(result.paginationProps.value.showTotal(0)).toBe('Total: 0') }) it('should update columnsProp when columns change', () => { @@ -78,12 +105,12 @@ describe('useBaseTable', () => { it('should call resetState when component unmounts', () => { const [result, app] = withSetup(useBaseTable, { columns, rows }) - const restStateSpy = vi.fn() - result.resetState = restStateSpy + const resetStateSpy = vi.fn() + result.resetState = resetStateSpy app.unmount = vi.fn().mockImplementation(() => { - restStateSpy() + resetStateSpy() }) app.unmount() - expect(restStateSpy).toHaveBeenCalled() + expect(resetStateSpy).toHaveBeenCalled() }) })