Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: [feat/sql-languages][taier-ui] add custom parameters #1138

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions taier-ui/src/components/customParameter/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.dtc-custom-parameter {
&__item {
margin-bottom: 24px;
}

&__gap {
margin-left: 2px;
margin-right: 6px;
}

&__add {
color: #3f87ff;
cursor: pointer;
}

&__delete {
margin-left: 8px;
color: #3f87ff;
font-size: 0;
cursor: pointer;
}

&__exist {
font-size: 12px;
color: #ff4d4f;
}
}
191 changes: 191 additions & 0 deletions taier-ui/src/components/customParameter/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
import React, { useEffect, useState } from 'react';
import { DeleteOutlined, PlusSquareOutlined } from '@ant-design/icons';
import { Col, Input, Row, Space } from 'antd';

import './index.scss';

interface IComponentType {
/**
* 自定义组件类型
*/
type: string;
/**
* 组件
*/
Component: React.ComponentClass<any, any> | React.FC<any>;
}

interface ICustomItem extends IComponentType {
/**
* 自定义参数名
*/
label: string;
/**
* 自定义参数值
*/
value: string;
/**
* 自定义参数是否合法
*/
status: boolean;
}

export type ICustomValue = Omit<ICustomItem, 'Component'>;

interface ICustomParameterProps {
/**
* 自定义参数名-value对应的key名
*/
labelKey?: string;
/**
* 自定义参数值-value对应的key名
*/
valueKey?: string;
/**
* 已存在的keys
*/
existingKeys: string[];
/**
* 自定义参数列表
*/
value?: Record<string, string>[];
/**
* 自定义参数改变触发函数
* @param value
* @returns
*/
onChange?: (value: ICustomValue[]) => void;
}

const DEFAULT_FORM_ITEM: IComponentType = {
type: 'INPUT',
Component: Input,
};

export default function CustomParameter({
labelKey = 'label',
valueKey = 'value',
existingKeys,
value,
onChange,
}: ICustomParameterProps) {
const [customParamRows, setCustomParamRows] = useState<ICustomItem[]>([]);

const handleCustomParameterAdd = () => {
const customItem: ICustomItem = {
type: DEFAULT_FORM_ITEM.type,
Component: DEFAULT_FORM_ITEM.Component,
label: '',
value: '',
status: false,
};

setCustomParamRows([...customParamRows, customItem]);
};

const handleCustomParameterDelete = (index: number) => {
const paramRows = customParamRows.filter((_, i) => i !== index);
setCustomParamRows(paramRows);
onChange?.(
paramRows?.map((item) => ({
label: item.label,
value: item.value,
type: item.type,
status: item.status,
}))
);
};

const handleIsSame = (item: ICustomItem) =>
existingKeys.includes(item.label) || customParamRows.filter((cIt) => cIt.label === item.label).length > 1;

console.log(existingKeys);

useEffect(() => {
setCustomParamRows(
value?.map((item) => {
return {
type: item.type || DEFAULT_FORM_ITEM.type,
label: item[labelKey],
value: item[valueKey],
Component: DEFAULT_FORM_ITEM.Component,
status: false,
};
}) || []
);
}, []);

return (
<div className="dtc-custom-parameter">
{customParamRows.map((item, index) => (
<Row className="dtc-custom-parameter__item" align={'middle'} key={index}>
<Col span={8}>
<Input
value={item.label}
style={{
width: 'calc(100% - 18px)',
}}
status={!item.label ? 'error' : ''}
onChange={(e: any) => {
const params = customParamRows.map((item, i) => {
if (i === index) item.label = e.target.value;
return item;
});
setCustomParamRows(params);
onChange?.(
params?.map((item) => ({
label: item.label,
value: item.value,
type: item.type,
status: Boolean(item.label && item.value && !handleIsSame(item)),
}))
);
}}
/>
<span className="dtc-custom-parameter__gap">:</span>
</Col>
<Col span={12}>
<item.Component
value={item.value}
status={!item.value ? 'error' : ''}
onChange={(e: any) => {
const params = customParamRows.map((item, i) => {
if (i === index) item.value = e.target.value;
return item;
});
setCustomParamRows(params);
onChange?.(
params?.map((item) => ({
label: item.label,
value: item.value,
type: item.type,
status: Boolean(item.label && item.value && !handleIsSame(item)),
}))
);
}}
/>
</Col>
<Col span={4}>
<div className="dtc-custom-parameter__delete">
<Space>
<DeleteOutlined
style={{ fontSize: 18 }}
onClick={() => handleCustomParameterDelete(index)}
/>
{handleIsSame(item) ? (
<span className="dtc-custom-parameter__exist">已存在</span>
) : null}
</Space>
</div>
</Col>
</Row>
))}
<Col span={16} offset={8}>
<Space className="dtc-custom-parameter__add" onClick={handleCustomParameterAdd}>
<PlusSquareOutlined />
<span>{'添加自定义参数'}</span>
</Space>
</Col>
</div>
);
}
22 changes: 21 additions & 1 deletion taier-ui/src/pages/console/cluster/detail/detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
import type { RcFile } from 'antd/lib/upload';

import api from '@/api';
import CustomParameter, { ICustomValue } from '@/components/customParameter';
import { COMPONENT_TYPE_VALUE } from '@/constant';
import context from '@/context/cluster';
import type { IComponentProps } from '.';
Expand All @@ -38,6 +39,7 @@ const { Sider, Content } = Layout;
const { Panel } = Collapse;

interface IDetailProps {
form: any;
templateData: ILayoutData[];
currentTreeNode?: IComponentProps;
loading?: boolean;
Expand Down Expand Up @@ -80,11 +82,12 @@ export interface ITemplateData {
/**
* XML 表示该值作为 config 渲染
*/
type: 'INPUT' | 'RADIO_LINKAGE' | 'CHECKBOX' | 'XML' | 'GROUP';
type: 'INPUT' | 'RADIO_LINKAGE' | 'CHECKBOX' | 'XML' | 'GROUP' | 'CUSTOM';
value: string;
}

export default function Detail({
form,
loading,
currentTreeNode,
templateData = [],
Expand Down Expand Up @@ -371,6 +374,23 @@ export default function Detail({
);
}
)}
<Form.Item
name={[template.groupName, 'customParameters'].join('$')}
noStyle
rules={[
{
validator(_, value: ICustomValue[]) {
return value.every((item) => item.status)
? Promise.resolve()
: Promise.reject('自定义字段名重复');
},
},
]}
>
<CustomParameter
existingKeys={Object.keys(form.getFieldValue(template.groupName) || {})}
/>
</Form.Item>
</Panel>
</Collapse>
);
Expand Down
22 changes: 20 additions & 2 deletions taier-ui/src/pages/console/cluster/detail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,24 @@ export default function ClusterDetail() {

// 上传配置文件所解析出来的配置项会放在 config 字段中,不存在于 values 里
const xmlConfig = form.getFieldValue('config');

const componentConfig = xmlConfig ? JSON.stringify(xmlConfig) : JSON.stringify(restValues);
let componentConfig: string;
const customParameters: Record<string, any> = {};
if (xmlConfig) {
componentConfig = JSON.stringify(xmlConfig);
} else {
const deploymode = restValues.deploymode;
deploymode?.forEach((item: string) => {
const key = [item, 'customParameters'].join('$');
customParameters[item] = restValues[key];
restValues[key]?.forEach((it: any) => {
restValues[item][it.key] = it.value;
});
return {};
});
console.log(customParameters);
console.log(restValues);
componentConfig = JSON.stringify(restValues);
}

try {
setDetailLoading(true);
Expand All @@ -416,6 +432,7 @@ export default function ClusterDetail() {
principals,
versionName: Array.isArray(versionName) ? versionName[versionName.length - 1] : versionName,
componentConfig,
customParameters,
deployType: currentComponent.deployType,
clusterId: currentComponent.clusterId,
componentCode: currentComponent.componentTypeCode,
Expand Down Expand Up @@ -630,6 +647,7 @@ export default function ClusterDetail() {
<Content className="h-full">
{selectedKey ? (
<Detail
form={form}
loading={detailLoading}
templateData={templateData}
currentTreeNode={currentTreeNode}
Expand Down
Loading