diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/OverviewContainer.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/OverviewContainer.tsx index c7ac04f95..4b67d1360 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/OverviewContainer.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/OverviewContainer.tsx @@ -164,7 +164,7 @@ const OverviewContainer: React.FC = ({ mode, domainManger, dispatch }) => }; const handleModelChange = (model?: ISemantic.IModelItem) => { - queryModelList(); + // queryModelList(); if (!model) { return; } @@ -180,10 +180,10 @@ const OverviewContainer: React.FC = ({ mode, domainManger, dispatch }) => }); }; - const cleanModelInfo = (domainId: number) => { + const cleanModelInfo = (domainId) => { setIsModel(false); - pushUrlMenu(domainId, 0, 'overview'); setActiveKey('overview'); + pushUrlMenu(domainId, 0, 'overview'); dispatch({ type: 'domainManger/setSelectModel', selectModelId: 0, @@ -203,7 +203,7 @@ const OverviewContainer: React.FC = ({ mode, domainManger, dispatch }) =>
{ + onTreeSelected={(domainData: ISemantic.IDomainItem) => { const { id, name } = domainData; cleanModelInfo(id); dispatch({ @@ -212,6 +212,12 @@ const OverviewContainer: React.FC = ({ mode, domainManger, dispatch }) => selectDomainName: name, domainData, }); + dispatch({ + type: 'domainManger/setModelTableHistoryParams', + payload: { + [id]: {}, + }, + }); }} onTreeDataUpdate={() => { initProjectTree(); diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/SemanticGraph/components/ModelRelationFormDrawer.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/SemanticGraph/components/ModelRelationFormDrawer.tsx index 038d9e386..0daa662f5 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/SemanticGraph/components/ModelRelationFormDrawer.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/SemanticGraph/components/ModelRelationFormDrawer.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from 'react'; import { Form, Button, Drawer, Space, Input, Select, message, Popconfirm } from 'antd'; import { formLayout } from '@/components/FormHelper/utils'; -import { createOrUpdateModelRela, deleteModelRela } from '../../service'; +import { createOrUpdateModelRela, deleteModelRela, getModelDetail } from '../../service'; export type ModelRelationFormDrawerProps = { domainId: number; @@ -46,27 +46,30 @@ const ModelRelationFormDrawer: React.FC = ({ form.setFieldsValue(formData); }, [relationData]); + const queryModelDetail = async (modelId: number, isSource: boolean) => { + const { code, data } = await getModelDetail({ modelId }); + if (code === 200) { + if (Array.isArray(data?.modelDetail?.identifiers)) { + const dataSourceIdentifiers = data.modelDetail.identifiers; + const options = dataSourceIdentifiers.map((item: any) => { + return { + label: `${item.bizName}${item.name ? `(${item.name})` : ''}`, + value: item.bizName, + }; + }); + if (isSource) { + setSourcePrimaryOptions(options); + } else { + setTargetPrimaryOptions(options); + } + } + } + }; + useEffect(() => { const { sourceData, targetData } = nodeModel; - const dataSourceFromIdentifiers = sourceData?.modelDetail?.identifiers || []; - const dataSourceToIdentifiers = targetData?.modelDetail?.identifiers || []; - - const sourceOptions = dataSourceFromIdentifiers.map((item: any) => { - return { - label: `${item.bizName}${item.name ? `(${item.name})` : ''}`, - value: item.bizName, - }; - }); - - const targetOptions = dataSourceToIdentifiers.map((item: any) => { - return { - label: `${item.bizName}${item.name ? `(${item.name})` : ''}`, - value: item.bizName, - }; - }); - - setSourcePrimaryOptions(sourceOptions); - setTargetPrimaryOptions(targetOptions); + queryModelDetail(sourceData.uid, true); + queryModelDetail(targetData.uid, false); }, [nodeModel]); const renderContent = () => { diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/View/components/ViewSearchFormModal_tag.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/View/components/ViewSearchFormModal_tag.tsx index a0527074b..7e79f053d 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/View/components/ViewSearchFormModal_tag.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/View/components/ViewSearchFormModal_tag.tsx @@ -8,7 +8,7 @@ import { ISemantic } from '../../data'; import DefaultSettingForm from './DefaultSettingForm'; import { isArrayOfValues } from '@/utils/utils'; import ProCard from '@ant-design/pro-card'; -import { TransType } from '../../enum'; +import { TransType, ChatConfigType } from '../../enum'; import { number } from 'echarts'; export type ModelCreateFormModalProps = { @@ -135,14 +135,14 @@ const ViewSearchFormModal: React.FC = ({ form={form} dimensionList={dimensionList} metricList={metricList} - chatConfigType={TransType.METRIC} + chatConfigType={ChatConfigType.METRIC} /> )} {viewItem?.queryType === TransType.TAG && ( - + )}
diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/DomainManagerTab.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/DomainManagerTab.tsx index db5274683..94d7e0c6e 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/DomainManagerTab.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/DomainManagerTab.tsx @@ -14,8 +14,8 @@ import type { StateType } from '../model'; import { HomeOutlined, FundViewOutlined } from '@ant-design/icons'; import { ISemantic } from '../data'; import SemanticGraphCanvas from '../SemanticGraphCanvas'; -import HeadlessFlows from '../HeadlessFlows'; -import SemanticFlows from '../SemanticFlows'; +// import HeadlessFlows from '../HeadlessFlows'; +// import SemanticFlows from '../SemanticFlows'; import RecommendedQuestionsSection from '../components/Entity/RecommendedQuestionsSection'; import View from '../View'; // import DatabaseTable from '../components/Database/DatabaseTable'; @@ -56,6 +56,7 @@ const DomainManagerTab: React.FC = ({ key: 'overview', children: ( { handleModelChange(model); @@ -96,11 +97,6 @@ const DomainManagerTab: React.FC = ({ key: 'permissonSetting', children: , }, - // { - // label: '数据库管理', - // key: 'database', - // children: , - // }, ].filter((item) => { if (item.hidden) { return false; @@ -131,22 +127,11 @@ const DomainManagerTab: React.FC = ({ key: 'dimenstion', children: , }, - // { - // label: '标签管理', - // key: 'tag', - // children: , - // }, - { label: '权限管理', key: 'permissonSetting', children: , }, - // { - // label: '问答设置', - // key: 'chatSetting', - // children: , - // }, { label: '推荐问题', key: 'recommendedQuestions', @@ -166,13 +151,14 @@ const DomainManagerTab: React.FC = ({ separator="" items={[ { - path: `/webapp/model/${selectDomainId}/0/overview`, title: ( { onBackDomainBtnClick?.(); }} - style={selectModelName ? {} : { color: '#296df3', fontWeight: 'bold' }} + style={ + selectModelName ? { cursor: 'pointer' } : { color: '#296df3', fontWeight: 'bold' } + } > {selectDomainName} diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/Entity/DimensionValueSettingForm.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/Entity/DimensionValueSettingForm.tsx index faae5a066..5a4ac98ae 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/Entity/DimensionValueSettingForm.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/Entity/DimensionValueSettingForm.tsx @@ -3,7 +3,10 @@ import type { ForwardRefRenderFunction } from 'react'; import { Form, Switch, Space, Button, Tooltip, message, Select } from 'antd'; import FormItemTitle from '@/components/FormHelper/FormItemTitle'; import { RedoOutlined, InfoCircleOutlined } from '@ant-design/icons'; +import DisabledWheelNumberInput from '@/components/DisabledWheelNumberInput'; import { formLayout } from '@/components/FormHelper/utils'; +import ProCard from '@ant-design/pro-card'; +import { connect } from 'umi'; import { DictTaskState, KnowledgeConfigTypeEnum, @@ -17,8 +20,12 @@ import { editDictConfig, createDictConfig, deleteDictTask, + queryMetric, + getModelList, + getMetricData, } from '../../service'; import type { ISemantic } from '../../data'; +import type { StateType } from '../../model'; import { isString } from 'lodash'; import styles from '../style.less'; import CommonEditList from '../../components/CommonEditList'; @@ -27,26 +34,28 @@ type Props = { dataItem: ISemantic.IDimensionItem | ISemantic.ITagItem; type?: KnowledgeConfigTypeEnum; onSubmit?: () => void; + domainManger: StateType; }; const FormItem = Form.Item; -const DimensionValueSettingForm: ForwardRefRenderFunction = ( - { dataItem, type = KnowledgeConfigTypeEnum.DIMENSION }, - ref, -) => { +const DimensionValueSettingForm: React.FC = ({ + dataItem, + type = KnowledgeConfigTypeEnum.DIMENSION, + domainManger, +}) => { const [form] = Form.useForm(); - + const { selectDomainId } = domainManger; const exchangeFields = ['blackList', 'whiteList']; const [dimensionVisible, setDimensionVisible] = useState(false); const [taskItemState, setTaskItemState] = useState(); const [saveLoading, setSaveLoading] = useState(false); const [refreshLoading, setRefreshLoading] = useState(false); const [knowledgeConfig, setKnowledgeConfig] = useState(); - + const [modelList, setModelList] = useState([]); const [deleteLoading, setDeleteLoading] = useState(false); const [importDictState, setImportDictState] = useState(false); - + const [metricList, setMetricList] = useState(); const defaultKnowledgeConfig: ISemantic.IDictKnowledgeConfigItemConfig = { blackList: [], whiteList: [], @@ -58,11 +67,44 @@ const DimensionValueSettingForm: ForwardRefRenderFunction = ( queryDictLatestTaskList(); }, []); + // useEffect(() => { + // const modelId = dataItem?.modelId; + // if (modelId) { + // queryMetricList(modelId); + // form.setFieldValue('modelId', modelId); + // } + // }, [dataItem]); + + useEffect(() => { + if (!selectDomainId) { + return; + } + queryModelList(selectDomainId); + }, [selectDomainId]); + + const queryModelList = async (domainId: number) => { + const { code, data } = await getModelList(domainId); + if (code === 200) { + setModelList(data); + } else { + message.error('获取模型列表失败!'); + } + }; + + const queryMetricList = async (modelId: number) => { + const { code, data, msg } = await queryMetric({ modelId }); + if (code === 200 && Array.isArray(data?.list)) { + setMetricList(data.list); + } else { + message.error(msg); + } + }; + const taskRender = () => { if (taskItemState?.taskStatus) { return ( - {DictTaskState[taskItemState?.taskStatus || 'unknown']} + {DictTaskState[`${taskItemState?.taskStatus || 'unknown'}`]} ); } @@ -93,6 +135,10 @@ const DimensionValueSettingForm: ForwardRefRenderFunction = ( ...config, }); setKnowledgeConfig(configItem); + const { metricId } = config; + if (metricId) { + queryMetricData(metricId); + } } else { form.setFieldsValue({ ...defaultKnowledgeConfig, @@ -121,30 +167,17 @@ const DimensionValueSettingForm: ForwardRefRenderFunction = ( } }; - const getFormValidateFields = async () => { - const fields = await form.validateFields(); - const fieldValue = Object.keys(fields).reduce((formField: any, key: string) => { - const targetValue = fields[key]; - if (exchangeFields.includes(key)) { - if (isString(targetValue)) { - formField[key] = targetValue.split(','); - } else { - formField[key] = []; - } - } else { - formField[key] = targetValue; - } - return formField; - }, {}); - return { - ...fieldValue, - }; + const queryMetricData = async (metricId: string) => { + const { code, data, msg } = await getMetricData(metricId); + if (code === 200) { + const { modelId } = data; + queryMetricList(modelId); + form.setFieldValue('modelId', modelId); + return; + } + message.error(msg); }; - useImperativeHandle(ref, () => ({ - getFormValidateFields, - })); - const createDictConfigQuery = async ( dimension: ISemantic.IDimensionItem, config: ISemantic.IDictKnowledgeConfigItemConfig, @@ -196,10 +229,11 @@ const DimensionValueSettingForm: ForwardRefRenderFunction = ( status, }); setSaveLoading(false); - if (code !== 200) { - message.error('字典导入配置保存失败!'); + if (code === 200) { + message.success('字典导入配置保存成功!'); return; } + message.error('字典导入配置保存失败!'); }; const deleteDictTaskQuery = async (dimension: ISemantic.IDimensionItem) => { @@ -223,6 +257,17 @@ const DimensionValueSettingForm: ForwardRefRenderFunction = ( style={{ margin: '0 30px 30px 30px' }} layout="vertical" className={styles.form} + onValuesChange={(value, values) => { + if (value.modelId === undefined && values.modelId == undefined) { + setMetricList([]); + form.setFieldValue('metricId', undefined); + return; + } + if (value.modelId) { + form.setFieldValue('metricId', undefined); + queryMetricList(value.modelId); + } + }} > = ( {dimensionVisible && ( <> - {/* */} -
-
- {KnowledgeConfigTypeWordingMap[type]}值过滤 - - + + 指标设置 + } + bordered + extra={ + + } + style={{ marginBottom: 20 }} + > + + } + > + + + { + return { + value: item.id, + label: item.name, + }; + })} + /> + + + + + } + > + + +
+
+ {KnowledgeConfigTypeWordingMap[type]}值过滤 +
+ + + + + + + +
- - - - - - - - -
+ )} @@ -379,4 +484,6 @@ const DimensionValueSettingForm: ForwardRefRenderFunction = ( ); }; -export default forwardRef(DimensionValueSettingForm); +export default connect(({ domainManger }: { domainManger: StateType }) => ({ + domainManger, +}))(DimensionValueSettingForm); diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ModelTable.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ModelTable.tsx index cacbb7693..f1813443a 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ModelTable.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ModelTable.tsx @@ -4,7 +4,7 @@ import { message, Button, Space, Popconfirm, Input } from 'antd'; import React, { useRef, useState, useEffect } from 'react'; import { StatusEnum } from '../enum'; import type { Dispatch } from 'umi'; -import { connect } from 'umi'; +import { connect, history } from 'umi'; import type { StateType } from '../model'; import { deleteModel, updateModel } from '../service'; import ClassModelTypeModal from './ClassModelTypeModal'; @@ -22,30 +22,64 @@ type Props = { domainManger: StateType; }; -const ModelTable: React.FC = ({ modelList, disabledEdit = false, onModelChange }) => { +const ModelTable: React.FC = ({ + modelList, + disabledEdit = false, + onModelChange, + dispatch, + domainManger, +}) => { + const { selectDomainId, modelTableHistoryParams } = domainManger; const [modelItem, setModelItem] = useState(); const [saveLoading, setSaveLoading] = useState(false); const [filterParams, setFilterParams] = useState>({}); const [createDataSourceModalOpen, setCreateDataSourceModalOpen] = useState(false); + const [currentPageNumber, setCurrentPageNumber] = useState(1); const actionRef = useRef(); const [tableData, setTableData] = useState([]); + const params = modelTableHistoryParams?.[selectDomainId]; useEffect(() => { if (!Array.isArray(modelList)) { return; } - setTableData(modelList); - }, [modelList]); + const { key } = filterParams; + getTableData(key); + }, [modelList, filterParams]); useEffect(() => { - const { key } = filterParams; + if (!params) { + return; + } + const { pageNumber, key } = params; + setFilterParams((preState) => { + return { + ...preState, + key, + }; + }); + setCurrentPageNumber(pageNumber); + }, []); + + const dipatchParams = (params: Record) => { + dispatch({ + type: 'domainManger/setModelTableHistoryParams', + payload: { + [selectDomainId]: { + ...params, + }, + }, + }); + }; + + const getTableData = (key: string) => { if (key) { setTableData(modelList.filter((item) => item.name.includes(key))); } else { setTableData(modelList); } - }, [filterParams]); + }; const updateModelStatus = async (modelData: ISemantic.IModelItem) => { setSaveLoading(true); @@ -89,7 +123,6 @@ const ModelTable: React.FC = ({ modelList, disabledEdit = false, onModelC dataIndex: 'key', title: '模型搜索', hideInTable: true, - renderFormItem: () => , }, { dataIndex: 'bizName', @@ -200,6 +233,16 @@ const ModelTable: React.FC = ({ modelList, disabledEdit = false, onModelC tableAlertRender={() => { return false; }} + pagination={{ + current: currentPageNumber, + onChange: (pageNumber) => { + setCurrentPageNumber(pageNumber); + dipatchParams({ + ...filterParams, + pageNumber: `${pageNumber}`, + }); + }, + }} headerTitle={ = ({ modelList, disabledEdit = false, onModelC { + setCurrentPageNumber(1); + dipatchParams({ + ...filterParams, + key: value, + pageNumber: `1`, + }); setFilterParams((preState) => { return { ...preState, diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/model.ts b/webapp/packages/supersonic-fe/src/pages/SemanticModel/model.ts index 5b752d14c..802ed6365 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/model.ts +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/model.ts @@ -18,6 +18,7 @@ export type StateType = { domainData?: ISemantic.IDomainItem; modelData?: ISemantic.IDomainItem; domainList: ISemantic.IDomainItem[]; + modelTableHistoryParams?: Record; }; export type ModelType = { @@ -38,6 +39,7 @@ export type ModelType = { setDataBaseScriptColumn: Reducer; setDatabaseConfigList: Reducer; setMetricList: Reducer; + setModelTableHistoryParams: Reducer; reset: Reducer; }; }; @@ -56,8 +58,8 @@ export const defaultState: StateType = { domainData: undefined, dataBaseResultColsMap: {}, databaseConfigList: [], - // dataBaseConfig: {}, domainList: [], + modelTableHistoryParams: {}, }; const Model: ModelType = { @@ -177,6 +179,15 @@ const Model: ModelType = { ...action.payload, }; }, + setModelTableHistoryParams(state = defaultState, action) { + return { + ...state, + modelTableHistoryParams: { + ...state.modelTableHistoryParams, + ...action.payload, + }, + }; + }, reset() { return defaultState; },