Skip to content
Permalink
Browse files
[feature] can set agent port in frontend when creating a new cluster (#…
…32)

can set agent port in frontend when creating a new cluster
  • Loading branch information
zhengbowen01 committed Apr 7, 2022
1 parent 8e71f37 commit 9aec45819405bfcc8f7a1eef3a2022b41ddb9409
Showing 12 changed files with 118 additions and 38 deletions.
@@ -341,5 +341,8 @@
"TableDescription": "Table Description",
"CreateTime": "Create Time",
"UpdateTime": "Update Time",
"UpdateTimeHelper": "Records the time when the last table structure change occurred"
"UpdateTimeHelper": "Records the time when the last table structure change occurred",

"Sync successfully, please refresh the page": "Sync successfully, please refresh the page",
"Sync failed": "Sync failed"
}
@@ -354,6 +354,9 @@
"TableDescription": "数据表描述信息",
"CreateTime": "创建时间",
"UpdateTime": "最近修改时间",
"UpdateTimeHelper": "记录该表最近发生表结构变更的时间"
"UpdateTimeHelper": "记录该表最近发生表结构变更的时间",

"Sync successfully, please refresh the page": "同步成功,请刷新页面" ,
"Sync failed": "同步失败"
}

@@ -44,15 +44,15 @@ export function Header(props: HeaderProps) {
<span styleName="common-header-icon">{props.icon}</span>
<span styleName="common-header-name">{props.title}</span>
</div>
<div styleName="common-header-refresh">
{/* <div styleName="common-header-refresh">
<SyncOutlined
spin={loading}
onClick={() => {
refresh();
setLoading(true);
}}
/>
</div>
</div> */}
</div>
);
}
@@ -18,7 +18,6 @@
import ProCard from '@ant-design/pro-card';
import { Button, message, Row, Space, Steps } from 'antd';
import React, { useEffect, useState } from 'react';
import { pathToRegexp } from 'path-to-regexp';
import { NewSpaceInfoContext } from '@src/common/common.context';
import { useForm } from 'antd/lib/form/Form';
import { AccessClusterStepsEnum } from './access-cluster.data';
@@ -120,11 +119,13 @@ export function AccessCluster() {
sshUser: value.sshUser,
};
params.installInfo = value.installInfo;
params.agentPort = value.agentPort ? parseInt(value.agentPort) : value.agentPort;
isParamsValid =
checkParam(params.authInfo.sshUser, '请填写SSH用户') &&
checkParam(params.authInfo.sshPort, '请填写SSH端口') &&
checkParam(params.authInfo.sshKey, '请填写SSH私钥') &&
checkParam(params.installInfo, '请填写安装路径');
checkParam(params.installInfo, '请填写安装路径') &&
checkParam(params.agentPort, '请填写Agent启动端口');
}
if (!isParamsValid) return;
setLoading(true);
@@ -0,0 +1,20 @@
// 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
//
// http://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.

.input {
width: 400px;
}
@@ -20,11 +20,12 @@ import React, { useContext, useEffect } from 'react';
import ProCard from '@ant-design/pro-card';
import { NewSpaceInfoContext } from '@src/common/common.context';
import TextArea from 'antd/lib/input/TextArea';
import styles from './index.module.less';

export function ManagedOptions(props: any) {
const { form, reqInfo } = useContext(NewSpaceInfoContext);
useEffect(() => {
form.setFieldsValue({...reqInfo.authInfo});
form.setFieldsValue({ ...reqInfo.authInfo });
}, [reqInfo.cluster_id]);
return (
<ProCard title={<h2>托管选项</h2>} headerBordered>
@@ -62,15 +63,20 @@ export function ManagedOptions(props: any) {
<Form
form={form}
name="basic"
labelCol={{ span: 2 }}
wrapperCol={{ span: 10 }}
initialValues={{
installInfo: reqInfo.installInfo,
}}
autoComplete="off"
>
<Form.Item label="安装路径" name="installInfo" rules={[{ required: true, message: '请输入安装路径' }]}>
<Input />
<Input className={styles.input} />
</Form.Item>
<Form.Item
label="Agent启动端口"
name="agentPort"
rules={[{ required: true, message: '请输入Agent启动端口' }]}
>
<Input className={styles.input} />
</Form.Item>
</Form>
</ProCard>
@@ -115,8 +115,11 @@ export function NewCluster() {
if (value && step === NewClusterStepsEnum['install-options']) {
params.installInfo = value.installDir;
params.packageInfo = value.packageUrl;
params.agentPort = value.agentPort ? parseInt(value.agentPort) : value.agentPort;
isParamsValid =
checkParam(params.installInfo, '请填写代码包路径') && checkParam(params.packageInfo, '请填写安装路径');
checkParam(params.installInfo, '请填写代码包路径') &&
checkParam(params.packageInfo, '请填写安装路径') &&
checkParam(params.agentPort, '请填写Agent启动端口');
}
if (value && step === NewClusterStepsEnum['cluster-plan']) {
params.nodeConfig = value.nodeConfig;
@@ -0,0 +1,20 @@
// 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
//
// http://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.

.input {
width: 400px;
}
@@ -19,9 +19,10 @@ import { Form, Input, PageHeader } from 'antd';
import React, { useContext } from 'react';
import ProCard from '@ant-design/pro-card';
import { NewSpaceInfoContext } from '@src/common/common.context';
import styles from './index.module.less';

export function InstallOptions(props: any) {
const {form} = useContext(NewSpaceInfoContext);
const { form } = useContext(NewSpaceInfoContext);
return (
<ProCard title={<h2>安装选项</h2>} headerBordered>
<PageHeader className="site-page-header" title="获取安装包" style={{ paddingLeft: 0 }} />
@@ -31,30 +32,25 @@ export function InstallOptions(props: any) {
若Manager节点可访问公网,推荐直接使用预编译安装包地址;若Manager节点不可访问公网,推荐自行搭建http服务提供安装包。
</div>
</p>
<Form
form={form}
name="basic"
labelCol={{ span: 2 }}
wrapperCol={{ span: 10 }}
autoComplete="off"
>
<Form form={form} name="basic" autoComplete="off">
<Form.Item label="代码包路径" name="packageUrl" rules={[{ required: true, message: '请输入安装路径' }]}>
<Input />
<Input className={styles.input} />
</Form.Item>
</Form>
<PageHeader className="site-page-header" title="指定安装路径" style={{ paddingLeft: 0 }} />
<div>
<p>Doris与Doris Manager Agent将安装至该目录下。请确保该目录为Doris及相关组件专用。</p>
</div>
<Form
form={form}
name="basic"
labelCol={{ span: 2 }}
wrapperCol={{ span: 10 }}
autoComplete="off"
>
<Form form={form} name="basic" autoComplete="off">
<Form.Item label="安装路径" name="installDir" rules={[{ required: true, message: '请输入安装路径' }]}>
<Input />
<Input className={styles.input} />
</Form.Item>
<Form.Item
label="Agent启动端口"
name="agentPort"
rules={[{ required: true, message: '请输入Agent启动端口' }]}
>
<Input className={styles.input} />
</Form.Item>
</Form>
</ProCard>
@@ -40,12 +40,11 @@ export interface ISpaceParam {
spaceAdminUsers: number[];
}


export interface ISpaceUser {
name: string;
email: string;
id: number;
is_active: boolean
is_active: boolean;
}
export type IRequiredMark = boolean | 'optional';

@@ -88,4 +87,5 @@ export interface ClusterAccessParams {
clusterAccessInfo?: ClusterAccessInfo;
installInfo?: string;
spaceInfo?: SpaceInfo;
}
agentPort?: number;
}
@@ -19,22 +19,28 @@

import { useState, useEffect } from 'react';
import { Tree, message } from 'antd';
import { TableOutlined, HddOutlined, HomeOutlined } from '@ant-design/icons';
import { TableOutlined, HddOutlined, HomeOutlined, SyncOutlined } from '@ant-design/icons';
import { useTranslation } from 'react-i18next';
import { TreeAPI } from './tree.api';
import { DataNode } from './tree.interface';
import { updateTreeData } from './tree.service';
import { ContentRouteKeyEnum } from './tree.data';
import styles from './tree.module.less';
import EventEmitter from '@src/utils/event-emitter';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router';

import { HeaderAPI } from '@src/components/common-header/header.api';
import styles from './tree.module.less';
import { delay } from '@src/utils/utils';
import { isSuccess } from '@src/utils/http';

// import { LoadingWrapper } from '@src/components/loadingwrapper/loadingwrapper';
const initTreeDate: DataNode[] = [];
export function MetaBaseTree() {
const [treeData, setTreeData] = useState(initTreeDate);
const [loading, setLoading] = useState(true);
const { t } = useTranslation();
const navigate = useNavigate();
const [syncLoading, setSyncLoading] = useState(false);
useEffect(() => {
initTreeData();
EventEmitter.on('refreshData', initTreeData);
@@ -47,7 +53,7 @@ export function MetaBaseTree() {
const num = Math.random();
const database = res.data;
const treeData: Array<DataNode> = [];
database.forEach((item, index) => {
database.forEach(item => {
treeData.push({
title: `${item.name}`,
key: `1¥${num}¥name¥${item.id}¥${item.name}`,
@@ -116,19 +122,37 @@ export function MetaBaseTree() {
function goHome() {
navigate(`/meta`);
}

function syncData() {
setSyncLoading(true);
Promise.all([delay(500), HeaderAPI.refreshData()])
.then(res => {
if (isSuccess(res[1])) {
message.success(t`Sync successfully, please refresh the page`);
return;
}
message.error(res[1].msg);
})
.catch(() => {
message.error(t`Sync Failed`);
})
.finally(() => setSyncLoading(false));
}

return (
<div className={styles['palo-tree-container']}>
<h2 className={styles['palo-tree-title']}>
<HomeOutlined onClick={goHome} />
{t`DataTree`}
<span>{t`DataTree`}</span>
<SyncOutlined spin={syncLoading} style={{ color: '#1890ff', padding: 0 }} onClick={syncData} />
</h2>
<div className={styles['palo-tree-wrapper']}>
<Tree
showIcon={true}
loadData={onLoadData}
treeData={treeData}
className={styles['palo-side-tree']}
onSelect={(selectedKeys, info) => handleTreeSelect(selectedKeys, info)}
onSelect={selectedKeys => handleTreeSelect(selectedKeys)}
/>
</div>
</div>
@@ -75,4 +75,8 @@ export function showName(name: string): string {
return '空间成员';
}
return name;
}
}

export function delay(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}

0 comments on commit 9aec458

Please sign in to comment.