[improvement][semantic-fe] Added an editing component to set filtering rules for Q&A. Now, the SQL editor will be accompanied by a list for display and control, to resolve ambiguity when using comma-separated values.

[improvement][semantic-fe] Improved validation logic and prompt copywriting for data source/dimension/metric editing and creation.
[improvement][semantic-fe] Improved user experience for visual modeling. Now, when using the legend to control the display/hide of data sources and their associated metric dimensions, the canvas will be re-layout based on the activated data source in the legend.

Co-authored-by: tristanliu <tristanliu@tencent.com>
This commit is contained in:
tristanliu
2023-07-21 15:30:38 +08:00
committed by GitHub
parent 6492316e23
commit 078a81038f
39 changed files with 1541 additions and 1161 deletions

View File

@@ -1,18 +1,33 @@
import React, { useEffect, useRef, useState } from 'react';
import { Form, Button, Modal, Steps, Input, Select, Switch, InputNumber } from 'antd';
import {
Form,
Button,
Modal,
Steps,
Input,
Select,
Switch,
InputNumber,
message,
Result,
} from 'antd';
import MetricMeasuresFormTable from './MetricMeasuresFormTable';
import { SENSITIVE_LEVEL_OPTIONS } from '../constant';
import { formLayout } from '@/components/FormHelper/utils';
import FormItemTitle from '@/components/FormHelper/FormItemTitle';
import styles from './style.less';
import { getMeasureListByDomainId } from '../service';
import { creatExprMetric, updateExprMetric } from '../service';
import { ISemantic } from '../data';
import { history } from 'umi';
export type CreateFormProps = {
datasourceId?: number;
domainId: number;
createModalVisible: boolean;
metricItem: any;
onCancel?: () => void;
onSubmit: (values: any) => void;
onSubmit?: (values: any) => void;
};
const { Step } = Steps;
@@ -21,6 +36,7 @@ const { TextArea } = Input;
const { Option } = Select;
const MetricInfoCreateForm: React.FC<CreateFormProps> = ({
datasourceId,
domainId,
onCancel,
createModalVisible,
@@ -31,17 +47,18 @@ const MetricInfoCreateForm: React.FC<CreateFormProps> = ({
const [currentStep, setCurrentStep] = useState(0);
const formValRef = useRef({} as any);
const [form] = Form.useForm();
const updateFormVal = (val: SaveDataSetForm) => {
const updateFormVal = (val: any) => {
formValRef.current = val;
};
const [classMeasureList, setClassMeasureList] = useState<any[]>([]);
const [classMeasureList, setClassMeasureList] = useState<ISemantic.IMeasure[]>([]);
const [exprTypeParamsState, setExprTypeParamsState] = useState<any>([]);
const [exprTypeParamsState, setExprTypeParamsState] = useState<ISemantic.IMeasure[]>([]);
const [exprSql, setExprSql] = useState<string>('');
const [isPercentState, setIsPercentState] = useState<boolean>(false);
const [hasMeasuresState, setHasMeasuresState] = useState<boolean>(true);
const forward = () => setCurrentStep(currentStep + 1);
const backward = () => setCurrentStep(currentStep - 1);
@@ -50,6 +67,12 @@ const MetricInfoCreateForm: React.FC<CreateFormProps> = ({
const { code, data } = await getMeasureListByDomainId(domainId);
if (code === 200) {
setClassMeasureList(data);
if (datasourceId) {
const hasMeasures = data.some(
(item: ISemantic.IMeasure) => item.datasourceId === datasourceId,
);
setHasMeasuresState(hasMeasures);
}
return;
}
setClassMeasureList([]);
@@ -74,7 +97,8 @@ const MetricInfoCreateForm: React.FC<CreateFormProps> = ({
if (currentStep < 1) {
forward();
} else {
onSubmit?.(submitForm);
// onSubmit?.(submitForm);
await saveMetric(submitForm);
}
};
@@ -118,15 +142,41 @@ const MetricInfoCreateForm: React.FC<CreateFormProps> = ({
useEffect(() => {
if (isEdit) {
initData();
} else {
// initFields([]);
}
}, [metricItem]);
const saveMetric = async (fieldsValue: any) => {
const queryParams = {
domainId,
...fieldsValue,
};
const { typeParams } = queryParams;
if (!typeParams?.expr) {
message.error('请输入度量表达式');
return;
}
if (!(Array.isArray(typeParams?.measures) && typeParams.measures.length > 0)) {
message.error('请添加一个度量');
return;
}
let saveMetricQuery = creatExprMetric;
if (queryParams.id) {
saveMetricQuery = updateExprMetric;
}
const { code, msg } = await saveMetricQuery(queryParams);
if (code === 200) {
message.success('编辑指标成功');
onSubmit?.(queryParams);
return;
}
message.error(msg);
};
const renderContent = () => {
if (currentStep === 1) {
return (
<MetricMeasuresFormTable
datasourceId={datasourceId}
typeParams={{
measures: exprTypeParamsState,
expr: exprSql,
@@ -231,6 +281,9 @@ const MetricInfoCreateForm: React.FC<CreateFormProps> = ({
);
};
const renderFooter = () => {
if (!hasMeasuresState) {
return <Button onClick={onCancel}></Button>;
}
if (currentStep === 1) {
return (
<>
@@ -266,26 +319,47 @@ const MetricInfoCreateForm: React.FC<CreateFormProps> = ({
footer={renderFooter()}
onCancel={onCancel}
>
<Steps style={{ marginBottom: 28 }} size="small" current={currentStep}>
<Step title="基本信息" />
<Step title="度量信息" />
</Steps>
<Form
{...formLayout}
form={form}
initialValues={{
...formValRef.current,
}}
onValuesChange={(value) => {
const { isPercent } = value;
if (isPercent !== undefined) {
setIsPercentState(isPercent);
{hasMeasuresState ? (
<>
<Steps style={{ marginBottom: 28 }} size="small" current={currentStep}>
<Step title="基本信息" />
<Step title="度量信息" />
</Steps>
<Form
{...formLayout}
form={form}
initialValues={{
...formValRef.current,
}}
onValuesChange={(value) => {
const { isPercent } = value;
if (isPercent !== undefined) {
setIsPercentState(isPercent);
}
}}
className={styles.form}
>
{renderContent()}
</Form>
</>
) : (
<Result
status="warning"
subTitle="当前数据源缺少度量,无法创建指标。请前往数据源配置中,将字段设置为度量"
extra={
<Button
type="primary"
key="console"
onClick={() => {
history.replace(`/semanticModel/${domainId}/dataSource`);
onCancel?.();
}}
>
</Button>
}
}}
className={styles.form}
>
{renderContent()}
</Form>
/>
)}
</Modal>
);
};