mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-14 05:43:51 +00:00
[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:
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user