mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-18 08:17:18 +00:00
[improvement][project] global refactor , code format , support llm , support fuzzy detect ,support query filter and so on.
This commit is contained in:
@@ -1,23 +1,31 @@
|
||||
import type { ActionType, ProColumns } from '@ant-design/pro-table';
|
||||
import ProTable from '@ant-design/pro-table';
|
||||
import { message, Button, Drawer, Space, Popconfirm } from 'antd';
|
||||
import React, { useRef, useState } from 'react';
|
||||
import { message, Button, Drawer, Space, Popconfirm, Modal, Card, Row, Col } from 'antd';
|
||||
import { ConsoleSqlOutlined, CoffeeOutlined } from '@ant-design/icons';
|
||||
import React, { useRef, useState, useEffect } from 'react';
|
||||
import type { Dispatch } from 'umi';
|
||||
import { connect } from 'umi';
|
||||
import DataSourceCreateForm from '../Datasource/components/DataSourceCreateForm';
|
||||
import ClassDataSourceTypeModal from './ClassDataSourceTypeModal';
|
||||
import type { StateType } from '../model';
|
||||
import { getDatasourceList, deleteDatasource } from '../service';
|
||||
import DataSource from '../Datasource';
|
||||
import moment from 'moment';
|
||||
|
||||
const { Meta } = Card;
|
||||
type Props = {
|
||||
dispatch: Dispatch;
|
||||
domainManger: StateType;
|
||||
};
|
||||
|
||||
const ClassDataSourceTable: React.FC<Props> = ({ dispatch, domainManger }) => {
|
||||
const { selectDomainId } = domainManger;
|
||||
const { selectDomainId, dataBaseResultColsMap, dataBaseConfig } = domainManger;
|
||||
const [createModalVisible, setCreateModalVisible] = useState<boolean>(false);
|
||||
const [dataSourceItem, setDataSourceItem] = useState<any>();
|
||||
const [createDataSourceModalOpen, setCreateDataSourceModalOpen] = useState(false);
|
||||
const [dataSourceModalVisible, setDataSourceModalVisible] = useState(false);
|
||||
const [fastModeSql, setFastModeSql] = useState<string>('');
|
||||
const [fastModeTableName, setFastModeTableName] = useState<string>('');
|
||||
|
||||
const actionRef = useRef<ActionType>();
|
||||
|
||||
@@ -62,6 +70,10 @@ const ClassDataSourceTable: React.FC<Props> = ({ dispatch, domainManger }) => {
|
||||
key="classEditBtn"
|
||||
onClick={() => {
|
||||
setDataSourceItem(record);
|
||||
if (record.datasourceDetail.queryType === 'table_query') {
|
||||
setDataSourceModalVisible(true);
|
||||
return;
|
||||
}
|
||||
setCreateModalVisible(true);
|
||||
}}
|
||||
>
|
||||
@@ -72,12 +84,12 @@ const ClassDataSourceTable: React.FC<Props> = ({ dispatch, domainManger }) => {
|
||||
okText="是"
|
||||
cancelText="否"
|
||||
onConfirm={async () => {
|
||||
const { code } = await deleteDatasource(record.id);
|
||||
const { code, msg } = await deleteDatasource(record.id);
|
||||
if (code === 200) {
|
||||
setDataSourceItem(undefined);
|
||||
actionRef.current?.reload();
|
||||
} else {
|
||||
message.error('删除失败');
|
||||
message.error(msg);
|
||||
}
|
||||
}}
|
||||
>
|
||||
@@ -121,6 +133,20 @@ const ClassDataSourceTable: React.FC<Props> = ({ dispatch, domainManger }) => {
|
||||
return resData;
|
||||
};
|
||||
|
||||
const queryDataBaseExcuteSql = (tableName: string) => {
|
||||
const sql = `select * from ${tableName}`;
|
||||
setFastModeSql(sql);
|
||||
setFastModeTableName(tableName);
|
||||
dispatch({
|
||||
type: 'domainManger/queryDataBaseExcuteSql',
|
||||
payload: {
|
||||
sql,
|
||||
domainId: selectDomainId,
|
||||
tableName,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ProTable
|
||||
@@ -140,13 +166,46 @@ const ClassDataSourceTable: React.FC<Props> = ({ dispatch, domainManger }) => {
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
setDataSourceItem(undefined);
|
||||
setCreateModalVisible(true);
|
||||
setCreateDataSourceModalOpen(true);
|
||||
}}
|
||||
>
|
||||
创建数据源
|
||||
</Button>,
|
||||
]}
|
||||
/>
|
||||
{
|
||||
<ClassDataSourceTypeModal
|
||||
open={createDataSourceModalOpen}
|
||||
onTypeChange={(type) => {
|
||||
if (type === 'fast') {
|
||||
setDataSourceModalVisible(true);
|
||||
} else {
|
||||
setCreateModalVisible(true);
|
||||
}
|
||||
setCreateDataSourceModalOpen(false);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
{dataSourceModalVisible && (
|
||||
<DataSourceCreateForm
|
||||
sql={fastModeSql}
|
||||
basicInfoFormMode="fast"
|
||||
domainId={Number(selectDomainId)}
|
||||
dataSourceItem={dataSourceItem}
|
||||
onCancel={() => {
|
||||
setDataSourceModalVisible(false);
|
||||
}}
|
||||
onDataBaseTableChange={(tableName: string) => {
|
||||
queryDataBaseExcuteSql(tableName);
|
||||
}}
|
||||
onSubmit={() => {
|
||||
setDataSourceModalVisible(false);
|
||||
setDataSourceItem(undefined);
|
||||
actionRef.current?.reload();
|
||||
}}
|
||||
createModalVisible={dataSourceModalVisible}
|
||||
/>
|
||||
)}
|
||||
{createModalVisible && (
|
||||
<Drawer
|
||||
width={'100%'}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
import { Modal, Card, Row, Col } from 'antd';
|
||||
import { ConsoleSqlOutlined, CoffeeOutlined } from '@ant-design/icons';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
const { Meta } = Card;
|
||||
type Props = {
|
||||
open: boolean;
|
||||
onTypeChange: (type: 'fast' | 'normal') => void;
|
||||
};
|
||||
|
||||
const ClassDataSourceTypeModal: React.FC<Props> = ({ open, onTypeChange }) => {
|
||||
const [createDataSourceModalOpen, setCreateDataSourceModalOpen] = useState(false);
|
||||
useEffect(() => {
|
||||
setCreateDataSourceModalOpen(open);
|
||||
}, [open]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
open={createDataSourceModalOpen}
|
||||
onCancel={() => {
|
||||
setCreateDataSourceModalOpen(false);
|
||||
}}
|
||||
footer={null}
|
||||
centered
|
||||
closable={false}
|
||||
>
|
||||
<Row gutter={16} style={{ marginTop: '0px' }}>
|
||||
<Col span={12}>
|
||||
<Card
|
||||
hoverable
|
||||
style={{ height: 220 }}
|
||||
onClick={() => {
|
||||
onTypeChange('fast');
|
||||
setCreateDataSourceModalOpen(false);
|
||||
}}
|
||||
cover={
|
||||
<CoffeeOutlined
|
||||
width={240}
|
||||
style={{ paddingTop: '45px', height: 120, fontSize: '48px', color: '#1890ff' }}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Meta title="快速创建" description="自动进行数据源可视化创建" />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Card
|
||||
onClick={() => {
|
||||
onTypeChange('normal');
|
||||
setCreateDataSourceModalOpen(false);
|
||||
}}
|
||||
hoverable
|
||||
style={{ height: 220 }}
|
||||
cover={
|
||||
<ConsoleSqlOutlined
|
||||
style={{ paddingTop: '45px', height: 120, fontSize: '48px', color: '#1890ff' }}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Meta title="SQL脚本" description="自定义SQL脚本创建数据源" />
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default ClassDataSourceTypeModal;
|
||||
@@ -88,6 +88,10 @@ const ClassDimensionTable: React.FC<Props> = ({ domainManger, dispatch }) => {
|
||||
dataIndex: 'name',
|
||||
title: '维度名称',
|
||||
},
|
||||
{
|
||||
dataIndex: 'alias',
|
||||
title: '别名',
|
||||
},
|
||||
{
|
||||
dataIndex: 'bizName',
|
||||
title: '字段名称',
|
||||
@@ -146,12 +150,12 @@ const ClassDimensionTable: React.FC<Props> = ({ domainManger, dispatch }) => {
|
||||
okText="是"
|
||||
cancelText="否"
|
||||
onConfirm={async () => {
|
||||
const { code } = await deleteDimension(record.id);
|
||||
const { code, msg } = await deleteDimension(record.id);
|
||||
if (code === 200) {
|
||||
setDimensionItem(undefined);
|
||||
actionRef.current?.reload();
|
||||
} else {
|
||||
message.error('删除失败');
|
||||
message.error(msg);
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -68,6 +68,10 @@ const ClassMetricTable: React.FC<Props> = ({ domainManger, dispatch }) => {
|
||||
dataIndex: 'name',
|
||||
title: '指标名称',
|
||||
},
|
||||
{
|
||||
dataIndex: 'alias',
|
||||
title: '别名',
|
||||
},
|
||||
{
|
||||
dataIndex: 'bizName',
|
||||
title: '字段名称',
|
||||
@@ -118,12 +122,12 @@ const ClassMetricTable: React.FC<Props> = ({ domainManger, dispatch }) => {
|
||||
okText="是"
|
||||
cancelText="否"
|
||||
onConfirm={async () => {
|
||||
const { code } = await deleteMetric(record.id);
|
||||
const { code, msg } = await deleteMetric(record.id);
|
||||
if (code === 200) {
|
||||
setMetricItem(undefined);
|
||||
actionRef.current?.reload();
|
||||
} else {
|
||||
message.error('删除失败');
|
||||
message.error(msg);
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -7,29 +7,39 @@ import { formLayout } from '@/components/FormHelper/utils';
|
||||
import styles from '../style.less';
|
||||
type Props = {
|
||||
domainId: number;
|
||||
dataBaseConfig: any;
|
||||
onSubmit: (params?: any) => void;
|
||||
};
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const TextArea = Input.TextArea;
|
||||
|
||||
const DatabaseCreateForm: ForwardRefRenderFunction<any, Props> = ({ domainId }, ref) => {
|
||||
const DatabaseCreateForm: ForwardRefRenderFunction<any, Props> = (
|
||||
{ domainId, dataBaseConfig, onSubmit },
|
||||
ref,
|
||||
) => {
|
||||
const [form] = Form.useForm();
|
||||
const [selectedDbType, setSelectedDbType] = useState<string>('h2');
|
||||
const queryDatabaseConfig = async () => {
|
||||
const { code, data } = await getDatabaseByDomainId(domainId);
|
||||
if (code === 200) {
|
||||
form.setFieldsValue({ ...data });
|
||||
setSelectedDbType(data?.type);
|
||||
return;
|
||||
}
|
||||
message.error('数据库配置获取错误');
|
||||
};
|
||||
// const queryDatabaseConfig = async () => {
|
||||
// const { code, data } = await getDatabaseByDomainId(domainId);
|
||||
// if (code === 200) {
|
||||
// form.setFieldsValue({ ...data });
|
||||
// setSelectedDbType(data?.type);
|
||||
// return;
|
||||
// }
|
||||
// message.error('数据库配置获取错误');
|
||||
// };
|
||||
|
||||
useEffect(() => {
|
||||
form.resetFields();
|
||||
queryDatabaseConfig();
|
||||
}, [domainId]);
|
||||
form.setFieldsValue({ ...dataBaseConfig });
|
||||
setSelectedDbType(dataBaseConfig?.type);
|
||||
}, [dataBaseConfig]);
|
||||
|
||||
// useEffect(() => {
|
||||
// form.resetFields();
|
||||
// // queryDatabaseConfig();
|
||||
// }, [domainId]);
|
||||
|
||||
const getFormValidateFields = async () => {
|
||||
return await form.validateFields();
|
||||
@@ -48,6 +58,7 @@ const DatabaseCreateForm: ForwardRefRenderFunction<any, Props> = ({ domainId },
|
||||
|
||||
if (code === 200) {
|
||||
message.success('保存成功');
|
||||
onSubmit?.();
|
||||
return;
|
||||
}
|
||||
message.error(msg);
|
||||
|
||||
@@ -11,8 +11,8 @@ type Props = {
|
||||
domainManger: StateType;
|
||||
};
|
||||
|
||||
const DatabaseSection: React.FC<Props> = ({ domainManger }) => {
|
||||
const { selectDomainId } = domainManger;
|
||||
const DatabaseSection: React.FC<Props> = ({ domainManger, dispatch }) => {
|
||||
const { selectDomainId, dataBaseConfig } = domainManger;
|
||||
|
||||
const entityCreateRef = useRef<any>({});
|
||||
|
||||
@@ -22,8 +22,16 @@ const DatabaseSection: React.FC<Props> = ({ domainManger }) => {
|
||||
<ProCard title="数据库设置" bordered>
|
||||
<DatabaseCreateForm
|
||||
ref={entityCreateRef}
|
||||
dataBaseConfig={dataBaseConfig}
|
||||
domainId={Number(selectDomainId)}
|
||||
onSubmit={() => {}}
|
||||
onSubmit={() => {
|
||||
dispatch({
|
||||
type: 'domainManger/queryDatabaseByDomainId',
|
||||
payload: {
|
||||
domainId: selectDomainId,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</ProCard>
|
||||
</Space>
|
||||
|
||||
@@ -85,6 +85,7 @@ const DimensionInfoModal: React.FC<CreateFormProps> = ({
|
||||
>
|
||||
<Input placeholder="名称不可重复" disabled={isEdit} />
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
name="datasourceId"
|
||||
label="所属数据源"
|
||||
@@ -98,6 +99,9 @@ const DimensionInfoModal: React.FC<CreateFormProps> = ({
|
||||
))}
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem name="alias" label="别名">
|
||||
<Input placeholder="多个别名用英文逗号隔开" />
|
||||
</FormItem>
|
||||
<FormItem
|
||||
name="semanticType"
|
||||
label="类型"
|
||||
|
||||
@@ -2,6 +2,8 @@ import React, { useEffect, useState } from 'react';
|
||||
import { Button, Modal, message } from 'antd';
|
||||
import { addDomainExtend, editDomainExtend, getDomainExtendDetailConfig } from '../../service';
|
||||
import DimensionMetricVisibleTransfer from './DimensionMetricVisibleTransfer';
|
||||
import { exChangeRichEntityListToIds } from './utils';
|
||||
|
||||
type Props = {
|
||||
domainId: number;
|
||||
themeData: any;
|
||||
@@ -36,7 +38,6 @@ const DimensionMetricVisibleModal: React.FC<Props> = ({
|
||||
onSubmit,
|
||||
}) => {
|
||||
const [sourceList, setSourceList] = useState<any[]>([]);
|
||||
const [visibilityData, setVisibilityData] = useState<any>({});
|
||||
const [selectedKeyList, setSelectedKeyList] = useState<string[]>([]);
|
||||
const settingTypeConfig = settingType === 'dimension' ? dimensionConfig : metricConfig;
|
||||
useEffect(() => {
|
||||
@@ -47,27 +48,12 @@ const DimensionMetricVisibleModal: React.FC<Props> = ({
|
||||
setSourceList(list);
|
||||
}, [settingSourceList]);
|
||||
|
||||
const queryThemeListData: any = async () => {
|
||||
const { code, data } = await getDomainExtendDetailConfig({
|
||||
domainId,
|
||||
});
|
||||
if (code === 200) {
|
||||
setVisibilityData(data.visibility);
|
||||
return;
|
||||
}
|
||||
message.error('获取可见信息失败');
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
queryThemeListData();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedKeyList(visibilityData?.[settingTypeConfig.visibleIdListKey] || []);
|
||||
}, [visibilityData]);
|
||||
setSelectedKeyList(themeData.visibility?.[settingTypeConfig.visibleIdListKey] || []);
|
||||
}, [themeData]);
|
||||
|
||||
const saveEntity = async () => {
|
||||
const { id } = themeData;
|
||||
const { id, entity } = themeData;
|
||||
let saveDomainExtendQuery = addDomainExtend;
|
||||
if (id) {
|
||||
saveDomainExtendQuery = editDomainExtend;
|
||||
@@ -79,6 +65,8 @@ const DimensionMetricVisibleModal: React.FC<Props> = ({
|
||||
}
|
||||
return list;
|
||||
}, []);
|
||||
const entityParams = exChangeRichEntityListToIds(entity);
|
||||
themeData.entity = entityParams;
|
||||
const params = {
|
||||
...themeData,
|
||||
visibility: themeData.visibility || {},
|
||||
|
||||
@@ -2,15 +2,17 @@ import { useEffect, useState, forwardRef, useImperativeHandle } from 'react';
|
||||
import type { ForwardRefRenderFunction } from 'react';
|
||||
import { message, Form, Input, Select, Button } from 'antd';
|
||||
import { addDomainExtend, editDomainExtend } from '../../service';
|
||||
import type { ISemantic, IChatConfig } from '../../data';
|
||||
import { formLayout } from '@/components/FormHelper/utils';
|
||||
|
||||
import { exChangeRichEntityListToIds } from './utils';
|
||||
import styles from '../style.less';
|
||||
|
||||
type Props = {
|
||||
entityData: any;
|
||||
metricList: any[];
|
||||
dimensionList: any[];
|
||||
entityData: IChatConfig.IEntity;
|
||||
metricList: ISemantic.IMetricList;
|
||||
dimensionList: ISemantic.IDimensionList;
|
||||
domainId: number;
|
||||
onSubmit: (params?: any) => void;
|
||||
onSubmit: () => void;
|
||||
};
|
||||
|
||||
const FormItem = Form.Item;
|
||||
@@ -34,33 +36,19 @@ const EntityCreateForm: ForwardRefRenderFunction<any, Props> = (
|
||||
if (Object.keys(entityData).length === 0) {
|
||||
return;
|
||||
}
|
||||
const { detailData = {}, names = [] } = entityData;
|
||||
if (!detailData.dimensionIds) {
|
||||
entityData = {
|
||||
...entityData,
|
||||
detailData: {
|
||||
...detailData,
|
||||
dimensionIds: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
if (!detailData.metricIds) {
|
||||
entityData = {
|
||||
...entityData,
|
||||
detailData: {
|
||||
...detailData,
|
||||
metricIds: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
form.setFieldsValue({ ...entityData, name: names.join(',') });
|
||||
const names = entityData.names || [];
|
||||
const formatEntityData = exChangeRichEntityListToIds(entityData);
|
||||
form.setFieldsValue({
|
||||
...formatEntityData,
|
||||
name: names.join(','),
|
||||
});
|
||||
}, [entityData]);
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
getFormValidateFields,
|
||||
}));
|
||||
useEffect(() => {
|
||||
const metricOption = metricList.map((item: any) => {
|
||||
const metricOption = metricList.map((item: ISemantic.IMetricItem) => {
|
||||
return {
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
@@ -70,7 +58,7 @@ const EntityCreateForm: ForwardRefRenderFunction<any, Props> = (
|
||||
}, [metricList]);
|
||||
|
||||
useEffect(() => {
|
||||
const dimensionEnum = dimensionList.map((item: any) => {
|
||||
const dimensionEnum = dimensionList.map((item: ISemantic.IDimensionItem) => {
|
||||
return {
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
@@ -128,6 +116,13 @@ const EntityCreateForm: ForwardRefRenderFunction<any, Props> = (
|
||||
mode="multiple"
|
||||
allowClear
|
||||
style={{ width: '100%' }}
|
||||
filterOption={(inputValue: string, item: any) => {
|
||||
const { label } = item;
|
||||
if (label.includes(inputValue)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}}
|
||||
placeholder="请选择主体标识"
|
||||
options={dimensionListOptions}
|
||||
/>
|
||||
@@ -137,6 +132,13 @@ const EntityCreateForm: ForwardRefRenderFunction<any, Props> = (
|
||||
mode="multiple"
|
||||
allowClear
|
||||
style={{ width: '100%' }}
|
||||
filterOption={(inputValue: string, item: any) => {
|
||||
const { label } = item;
|
||||
if (label.includes(inputValue)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}}
|
||||
placeholder="请选择展示维度信息"
|
||||
options={dimensionListOptions}
|
||||
/>
|
||||
@@ -146,6 +148,13 @@ const EntityCreateForm: ForwardRefRenderFunction<any, Props> = (
|
||||
mode="multiple"
|
||||
allowClear
|
||||
style={{ width: '100%' }}
|
||||
filterOption={(inputValue: string, item: any) => {
|
||||
const { label } = item;
|
||||
if (label.includes(inputValue)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}}
|
||||
placeholder="请选择展示指标信息"
|
||||
options={metricListOptions}
|
||||
/>
|
||||
|
||||
@@ -3,10 +3,11 @@ import React, { useState, useEffect, useRef } from 'react';
|
||||
import type { Dispatch } from 'umi';
|
||||
import { connect } from 'umi';
|
||||
import type { StateType } from '../../model';
|
||||
import { getDomainExtendConfig } from '../../service';
|
||||
import { getDomainExtendConfig, getDomainExtendDetailConfig } from '../../service';
|
||||
import ProCard from '@ant-design/pro-card';
|
||||
import EntityCreateForm from './EntityCreateForm';
|
||||
import MetricSettingForm from './MetricSettingForm';
|
||||
import type { IChatConfig } from '../../data';
|
||||
import DimensionMetricVisibleForm from './DimensionMetricVisibleForm';
|
||||
|
||||
type Props = {
|
||||
@@ -17,18 +18,21 @@ type Props = {
|
||||
const EntitySection: React.FC<Props> = ({ domainManger, dispatch }) => {
|
||||
const { selectDomainId, dimensionList, metricList } = domainManger;
|
||||
|
||||
const [entityData, setEntityData] = useState<any>({});
|
||||
const [entityData, setEntityData] = useState<IChatConfig.IEntity>({} as IChatConfig.IEntity);
|
||||
|
||||
const [themeData, setThemeData] = useState<any>({});
|
||||
|
||||
const entityCreateRef = useRef<any>({});
|
||||
|
||||
const queryThemeListData: any = async () => {
|
||||
const { code, data } = await getDomainExtendConfig({
|
||||
const { code, data } = await getDomainExtendDetailConfig({
|
||||
domainId: selectDomainId,
|
||||
});
|
||||
// getDomainExtendConfig({
|
||||
// domainId: selectDomainId,
|
||||
// });
|
||||
if (code === 200) {
|
||||
const target = data?.[0] || {};
|
||||
const target = data;
|
||||
if (target) {
|
||||
setThemeData(target);
|
||||
setEntityData({
|
||||
@@ -75,7 +79,14 @@ const EntitySection: React.FC<Props> = ({ domainManger, dispatch }) => {
|
||||
<MetricSettingForm
|
||||
domainId={Number(selectDomainId)}
|
||||
themeData={themeData}
|
||||
metricList={metricList}
|
||||
// metricList={metricList}
|
||||
metricList={metricList.filter((item) => {
|
||||
const blackMetricIdList = themeData.visibility?.blackMetricIdList;
|
||||
if (Array.isArray(blackMetricIdList)) {
|
||||
return !blackMetricIdList.includes(item.id);
|
||||
}
|
||||
return false;
|
||||
})}
|
||||
onSubmit={() => {
|
||||
queryThemeListData();
|
||||
}}
|
||||
@@ -86,8 +97,22 @@ const EntitySection: React.FC<Props> = ({ domainManger, dispatch }) => {
|
||||
ref={entityCreateRef}
|
||||
domainId={Number(selectDomainId)}
|
||||
entityData={entityData}
|
||||
metricList={metricList}
|
||||
dimensionList={dimensionList}
|
||||
// metricList={metricList}
|
||||
metricList={metricList.filter((item) => {
|
||||
const blackMetricIdList = themeData.visibility?.blackMetricIdList;
|
||||
if (Array.isArray(blackMetricIdList)) {
|
||||
return !blackMetricIdList.includes(item.id);
|
||||
}
|
||||
return false;
|
||||
})}
|
||||
// dimensionList={dimensionList}
|
||||
dimensionList={dimensionList.filter((item) => {
|
||||
const blackDimensionList = themeData.visibility?.blackDimIdList;
|
||||
if (Array.isArray(blackDimensionList)) {
|
||||
return !blackDimensionList.includes(item.id);
|
||||
}
|
||||
return false;
|
||||
})}
|
||||
onSubmit={() => {
|
||||
queryThemeListData();
|
||||
}}
|
||||
|
||||
@@ -17,7 +17,7 @@ const FormItem = Form.Item;
|
||||
const Option = Select.Option;
|
||||
|
||||
const MetricSettingForm: ForwardRefRenderFunction<any, Props> = (
|
||||
{ metricList, domainId, themeData: uniqueMetricData },
|
||||
{ metricList, domainId, themeData: uniqueMetricData, onSubmit },
|
||||
ref,
|
||||
) => {
|
||||
const [form] = Form.useForm();
|
||||
@@ -82,6 +82,7 @@ const MetricSettingForm: ForwardRefRenderFunction<any, Props> = (
|
||||
|
||||
if (code === 200) {
|
||||
form.setFieldValue('id', data);
|
||||
onSubmit?.();
|
||||
message.success('保存成功');
|
||||
return;
|
||||
}
|
||||
@@ -116,6 +117,13 @@ const MetricSettingForm: ForwardRefRenderFunction<any, Props> = (
|
||||
allowClear
|
||||
showSearch
|
||||
style={{ width: '100%' }}
|
||||
filterOption={(inputValue: string, item: any) => {
|
||||
const { label } = item;
|
||||
if (label.includes(inputValue)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}}
|
||||
placeholder="请选择展示指标信息"
|
||||
options={metricListOptions}
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { IChatConfig, ISemantic } from '../../data';
|
||||
|
||||
export const exChangeRichEntityListToIds = (entityData: IChatConfig.IEntity) => {
|
||||
const entityList = entityData.entityIds || [];
|
||||
const detailData: {
|
||||
dimensionIds: number[];
|
||||
metricIds: number[];
|
||||
} = { dimensionIds: [], metricIds: [] };
|
||||
const { dimensionList, metricList } = entityData.entityInternalDetailDesc || {};
|
||||
if (Array.isArray(dimensionList)) {
|
||||
detailData.dimensionIds = dimensionList.map((item: ISemantic.IDimensionItem) => {
|
||||
return item.id;
|
||||
});
|
||||
}
|
||||
if (Array.isArray(metricList)) {
|
||||
detailData.metricIds = metricList.map((item: ISemantic.IMetricItem) => {
|
||||
return item.id;
|
||||
});
|
||||
}
|
||||
const entityIds = entityList.map((item) => {
|
||||
return item.id;
|
||||
});
|
||||
return {
|
||||
...entityData,
|
||||
entityIds,
|
||||
detailData,
|
||||
};
|
||||
};
|
||||
@@ -159,6 +159,9 @@ const MetricInfoCreateForm: React.FC<CreateFormProps> = ({
|
||||
>
|
||||
<Input placeholder="名称不可重复" disabled={isEdit} />
|
||||
</FormItem>
|
||||
<FormItem name="alias" label="别名">
|
||||
<Input placeholder="多个别名用英文逗号隔开" />
|
||||
</FormItem>
|
||||
<FormItem
|
||||
name="sensitiveLevel"
|
||||
label="敏感度"
|
||||
|
||||
@@ -215,7 +215,7 @@ const PermissionTable: React.FC<Props> = ({ domainManger }) => {
|
||||
okText="是"
|
||||
cancelText="否"
|
||||
onConfirm={async () => {
|
||||
const { code } = await removeGroupAuth({
|
||||
const { code, msg } = await removeGroupAuth({
|
||||
domainId: record.domainId,
|
||||
groupId: record.groupId,
|
||||
});
|
||||
@@ -223,7 +223,7 @@ const PermissionTable: React.FC<Props> = ({ domainManger }) => {
|
||||
setPermissonData({});
|
||||
queryListData();
|
||||
} else {
|
||||
message.error('删除失败');
|
||||
message.error(msg);
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { DownOutlined, PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons';
|
||||
import { Input, message, Tree, Popconfirm, Space, Tooltip } from 'antd';
|
||||
import { Input, message, Tree, Popconfirm, Space, Tooltip, Row, Col } from 'antd';
|
||||
import type { DataNode } from 'antd/lib/tree';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import type { FC, Key } from 'react';
|
||||
import { connect } from 'umi';
|
||||
import type { Dispatch } from 'umi';
|
||||
@@ -21,6 +21,8 @@ type ProjectListProps = {
|
||||
selectDomainName: string;
|
||||
createDomainBtnVisible?: boolean;
|
||||
dispatch: Dispatch;
|
||||
onCreateDomainBtnClick?: () => void;
|
||||
onTreeSelected?: () => void;
|
||||
};
|
||||
|
||||
const projectTreeFlat = (projectTree: DataNode[], filterValue: string): DataNode[] => {
|
||||
@@ -41,6 +43,8 @@ const projectTreeFlat = (projectTree: DataNode[], filterValue: string): DataNode
|
||||
const ProjectListTree: FC<ProjectListProps> = ({
|
||||
selectDomainId,
|
||||
createDomainBtnVisible = true,
|
||||
onCreateDomainBtnClick,
|
||||
onTreeSelected,
|
||||
dispatch,
|
||||
}) => {
|
||||
const [projectTree, setProjectTree] = useState<DataNode[]>([]);
|
||||
@@ -89,6 +93,7 @@ const ProjectListTree: FC<ProjectListProps> = ({
|
||||
const targetNodeData = classList.filter((item: any) => {
|
||||
return item.id === selectedKeys;
|
||||
})[0];
|
||||
onTreeSelected?.();
|
||||
dispatch({
|
||||
type: 'domainManger/setSelectDomain',
|
||||
selectDomainId: selectedKeys,
|
||||
@@ -196,28 +201,29 @@ const ProjectListTree: FC<ProjectListProps> = ({
|
||||
|
||||
return (
|
||||
<div className={styles.projectList}>
|
||||
<h2 className={styles.treeTitle}>
|
||||
<span className={styles.title}>主题域</span>
|
||||
<Space>
|
||||
{createDomainBtnVisible && (
|
||||
<Tooltip title="新增顶级域">
|
||||
<PlusCircleOutlined
|
||||
onClick={() => {
|
||||
setProjectInfoParams({ type: 'top', modelType: 'add' });
|
||||
setProjectInfoModalVisible(true);
|
||||
}}
|
||||
className={styles.addBtn}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Space>
|
||||
</h2>
|
||||
<Search
|
||||
allowClear
|
||||
className={styles.search}
|
||||
placeholder="请输入主题域名称进行查询"
|
||||
onSearch={onSearch}
|
||||
/>
|
||||
<Row>
|
||||
<Col flex="1 1 200px">
|
||||
<Search
|
||||
allowClear
|
||||
className={styles.search}
|
||||
placeholder="请输入主题域名称进行查询"
|
||||
onSearch={onSearch}
|
||||
/>
|
||||
</Col>
|
||||
<Col flex="0 1 50px">
|
||||
<Tooltip title="新增顶级域">
|
||||
<PlusCircleOutlined
|
||||
onClick={() => {
|
||||
setProjectInfoParams({ type: 'top', modelType: 'add' });
|
||||
setProjectInfoModalVisible(true);
|
||||
onCreateDomainBtnClick?.();
|
||||
}}
|
||||
className={styles.addBtn}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Tree
|
||||
expandedKeys={expandedKeys}
|
||||
onExpand={handleExpand}
|
||||
|
||||
@@ -3,62 +3,7 @@
|
||||
flex-direction: row;
|
||||
background-color: #fff;
|
||||
height: calc(100vh - 48px);
|
||||
.projectList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// width: 400px;
|
||||
overflow: hidden;
|
||||
// min-height: calc(100vh - 48px);
|
||||
border-right: 1px solid #d9d9d9;
|
||||
|
||||
.treeTitle {
|
||||
margin-bottom: 0;
|
||||
padding: 20px;
|
||||
line-height: 34px;
|
||||
text-align: right;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #d9d9d9;
|
||||
|
||||
.title {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.addBtn {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: #296DF3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search {
|
||||
width: calc(100% - 20px);
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.tree {
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
|
||||
.projectItem {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
cursor: auto;
|
||||
|
||||
.title {
|
||||
flex: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.operation {
|
||||
.icon {
|
||||
margin-left: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.projectManger {
|
||||
width: 100%;
|
||||
@@ -139,6 +84,65 @@
|
||||
}
|
||||
}
|
||||
|
||||
.projectList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 400px;
|
||||
overflow: hidden;
|
||||
// min-height: calc(100vh - 48px);
|
||||
.addBtn {
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
font-size: 18px;
|
||||
margin-top: 18px;
|
||||
&:hover {
|
||||
color: #296DF3;
|
||||
}
|
||||
}
|
||||
.treeTitle {
|
||||
margin-bottom: 0;
|
||||
padding: 20px;
|
||||
line-height: 34px;
|
||||
text-align: right;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #d9d9d9;
|
||||
|
||||
.title {
|
||||
float: left;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.search {
|
||||
width: calc(100% - 20px);
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.tree {
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
|
||||
.projectItem {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
cursor: auto;
|
||||
|
||||
.title {
|
||||
flex: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.operation {
|
||||
.icon {
|
||||
margin-left: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user {
|
||||
display: grid;
|
||||
}
|
||||
@@ -221,4 +225,25 @@
|
||||
background: #f8f9fb;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.domainSelector {
|
||||
display: flex;
|
||||
width: max-content;
|
||||
padding: 0 11px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
// background-color: #fff;
|
||||
// border: 1px solid #d9d9d9;
|
||||
border-radius: 4px;
|
||||
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
color: #000a24d9;
|
||||
.downIcon {
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
&:hover {
|
||||
color:#296DF3;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user