[improvement][headless-fe] route rebuild stash

This commit is contained in:
tristanliu
2024-11-23 17:23:16 +08:00
parent 46d64d78f3
commit 0edadd01eb
19 changed files with 735 additions and 183 deletions

View File

@@ -57,24 +57,81 @@ const ROUTES = [
}, },
{ {
path: '/model/', path: '/model/',
component: './SemanticModel/DomainManager', component: './SemanticModel/',
name: 'semanticModel', name: 'semanticModel',
envEnableList: [ENV_KEY.SEMANTIC], envEnableList: [ENV_KEY.SEMANTIC],
routes: [ routes: [
{ {
path: '/model/:domainId/:modelId', path: '/model/:domainId',
component: './SemanticModel/DomainManager', component: './SemanticModel/DomainManager',
// name: 'semanticModel',
envEnableList: [ENV_KEY.SEMANTIC], envEnableList: [ENV_KEY.SEMANTIC],
}, routes: [
{ {
path: '/model/:domainId/:modelId/:menuKey', path: '/model/:domainId/:menuKey',
component: './SemanticModel/DomainManager', component: './SemanticModel/DomainManager',
// name: 'semanticModel',
envEnableList: [ENV_KEY.SEMANTIC],
}, },
], ],
}, },
{
path: '/model/manager/:domainId/:modelId',
component: './SemanticModel/ModelManager',
envEnableList: [ENV_KEY.SEMANTIC],
routes: [
{
path: '/model/manager/:domainId/:modelId/:menuKey',
component: './SemanticModel/ModelManager',
},
],
},
// {
// path: '/model/:domainId/:modelId/:menuKey',
// component: './SemanticModel/DomainManager',
// envEnableList: [ENV_KEY.SEMANTIC],
// },
// {
// path: '/model/:domainId/:modelId/metric',
// component: './SemanticModel/components/ModelMetric',
// envEnableList: [ENV_KEY.SEMANTIC],
// routes: [
// {
// path: '/model/:domainId/:modelId/metric/list',
// component: './SemanticModel/components/ClassMetricTable',
// envEnableList: [ENV_KEY.SEMANTIC],
// },
// ],
// },
],
},
// {
// path: '/model/',
// component: './SemanticModel/DomainManager',
// name: 'semanticModel',
// envEnableList: [ENV_KEY.SEMANTIC],
// routes: [
// {
// path: '/model/:domainId/:modelId',
// component: './SemanticModel/DomainManager',
// envEnableList: [ENV_KEY.SEMANTIC],
// },
// {
// path: '/model/:domainId/:modelId/:menuKey',
// component: './SemanticModel/DomainManager',
// envEnableList: [ENV_KEY.SEMANTIC],
// },
// {
// path: '/model/:domainId/:modelId/metric',
// component: './SemanticModel/components/ModelMetric',
// envEnableList: [ENV_KEY.SEMANTIC],
// routes: [
// {
// path: '/model/:domainId/:modelId/metric/list',
// component: './SemanticModel/components/ClassMetricTable',
// envEnableList: [ENV_KEY.SEMANTIC],
// },
// ],
// },
// ],
// },
// { // {
// path: '/model/:domainId/:modelId/:menuKey', // path: '/model/:domainId/:modelId/:menuKey',

View File

@@ -0,0 +1,12 @@
import React from 'react';
import { Outlet } from '@umijs/max';
const Dimension: React.FC = () => {
return (
<>
<Outlet />
</>
);
};
export default Dimension;

View File

@@ -1,12 +1,108 @@
import React from 'react'; import { message } from 'antd';
import OverviewContainer from './OverviewContainer'; import React, { useEffect, useState } from 'react';
import { history, useParams, useModel } from '@umijs/max';
import { ISemantic } from './data';
import { getDomainList, getDataSetList } from './service';
import DomainManagerTab from './components/DomainManagerTab';
import { isArrayOfValues } from '@/utils/utils';
type Props = {}; type Props = {};
const DomainManager: React.FC<Props> = () => {
const DomainManager: React.FC<Props> = ({}) => {
const defaultTabKey = 'overview';
const params: any = useParams();
const domainId = params.domainId;
const domainModel = useModel('SemanticModel.domainData');
const modelModel = useModel('SemanticModel.modelData');
const databaseModel = useModel('SemanticModel.databaseData');
const { selectDomainId, domainList, setSelectDomain, setDomainList } = domainModel;
const { selectModelId } = modelModel;
const { MrefreshDatabaseList } = databaseModel;
const menuKey = params.menuKey ? params.menuKey : defaultTabKey;
const [collapsedState, setCollapsedState] = useState(true);
const [activeKey, setActiveKey] = useState<string>(menuKey);
const [dataSetList, setDataSetList] = useState<ISemantic.IDatasetItem[]>([]);
// const initSelectedDomain = (domainList: ISemantic.IDomainItem[]) => {
// const targetNode = domainList.filter((item: any) => {
// return `${item.id}` === domainId;
// })[0];
// if (!targetNode) {
// const firstRootNode = domainList.filter((item: any) => {
// return item.parentId === 0;
// })[0];
// if (firstRootNode) {
// const { id } = firstRootNode;
// setSelectDomain(firstRootNode);
// setActiveKey(menuKey);
// pushUrlMenu(id, 0, menuKey);
// }
// } else {
// setSelectDomain(targetNode);
// }
// };
// const initProjectTree = async () => {
// const { code, data, msg } = await getDomainList();
// if (code === 200) {
// initSelectedDomain(data);
// setDomainList(data);
// } else {
// message.error(msg);
// }
// };
// useEffect(() => {
// initProjectTree();
// MrefreshDatabaseList();
// }, []);
// useEffect(() => {
// if (!selectDomainId) {
// return;
// }
// // queryModelList();
// queryDataSetList();
// }, [selectDomainId]);
// const queryDataSetList = async () => {
// const { code, data, msg } = await getDataSetList(selectDomainId);
// if (code === 200) {
// setDataSetList(data);
// if (!isArrayOfValues(data)) {
// setActiveKey(defaultTabKey);
// }
// } else {
// message.error(msg);
// }
// };
const pushUrlMenu = (domainId: number, menuKey: string) => {
history.push(`/model/${domainId}/${menuKey}`);
};
const cleanModelInfo = (domainId) => {
setActiveKey(defaultTabKey);
pushUrlMenu(domainId, defaultTabKey);
// setSelectModel(undefined);
};
// const handleCollapsedBtn = () => {
// setCollapsedState(!collapsedState);
// };
return ( return (
<> <DomainManagerTab
<OverviewContainer mode={'domain'} /> activeKey={activeKey}
</> dataSetList={dataSetList}
onBackDomainBtnClick={() => {
cleanModelInfo(selectDomainId);
}}
onMenuChange={(menuKey) => {
setActiveKey(menuKey);
pushUrlMenu(selectDomainId, menuKey);
}}
/>
); );
}; };

View File

@@ -904,7 +904,9 @@ const MetricInfoCreateForm: React.FC<CreateFormProps> = ({
type="primary" type="primary"
key="console" key="console"
onClick={() => { onClick={() => {
history.replace(`/model/${domainId}/${modelId || metricItem?.modelId}/dataSource`); history.replace(
`/model/manager/${domainId}/${modelId || metricItem?.modelId}/dataSource`,
);
onCancel?.(); onCancel?.();
}} }}
> >

View File

@@ -0,0 +1,71 @@
import React, { useEffect, useState } from 'react';
import { history, useParams, useModel } from '@umijs/max';
import ModelManagerTab from './components/ModelManagerTab';
type Props = {};
const OverviewContainer: React.FC<Props> = ({}) => {
const defaultTabKey = 'overview';
const params: any = useParams();
const domainId = params.domainId;
const modelId = params.modelId;
const domainModel = useModel('SemanticModel.domainData');
const modelModel = useModel('SemanticModel.modelData');
const dimensionModel = useModel('SemanticModel.dimensionData');
const metricModel = useModel('SemanticModel.metricData');
const databaseModel = useModel('SemanticModel.databaseData');
const { selectDomainId, domainList, setSelectDomain, setDomainList } = domainModel;
const {
selectModelId,
modelList,
MrefreshModelList,
setSelectModel,
setModelTableHistoryParams,
} = modelModel;
const { MrefreshDimensionList } = dimensionModel;
const { MrefreshMetricList } = metricModel;
const { MrefreshDatabaseList } = databaseModel;
const menuKey = params.menuKey ? params.menuKey : !Number(modelId) ? defaultTabKey : '';
const [activeKey, setActiveKey] = useState<string>(menuKey);
const initModelConfig = () => {
const currentMenuKey = menuKey === defaultTabKey ? '' : menuKey;
pushUrlMenu(selectDomainId, selectModelId, currentMenuKey);
setActiveKey(currentMenuKey);
};
useEffect(() => {
if (!selectModelId) {
return;
}
initModelConfig();
MrefreshDimensionList({ modelId: selectModelId });
MrefreshMetricList({ modelId: selectModelId });
}, [selectModelId]);
const pushUrlMenu = (domainId: number, modelId: number, menuKey: string) => {
history.push(`/model/manager/${domainId}/${modelId}/${menuKey}`);
};
const cleanModelInfo = (domainId) => {
setActiveKey(defaultTabKey);
pushUrlMenu(domainId, 0, defaultTabKey);
setSelectModel(undefined);
};
return (
<ModelManagerTab
activeKey={activeKey}
modelList={modelList}
onBackDomainBtnClick={() => {
cleanModelInfo(selectDomainId);
}}
onMenuChange={(menuKey) => {
setActiveKey(menuKey);
pushUrlMenu(selectDomainId, selectModelId, menuKey);
}}
/>
);
};
export default OverviewContainer;

View File

@@ -8,14 +8,14 @@ import { ISemantic } from './data';
import { getDomainList, getDataSetList } from './service'; import { getDomainList, getDataSetList } from './service';
import DomainManagerTab from './components/DomainManagerTab'; import DomainManagerTab from './components/DomainManagerTab';
import { isArrayOfValues } from '@/utils/utils'; import { isArrayOfValues } from '@/utils/utils';
import OverviewContainerRight from './components/OverviewContainerRight';
type Props = { type Props = {
mode: 'domain'; mode: 'domain';
}; };
const OverviewContainer: React.FC<Props> = ({ mode }) => { const OverviewContainer: React.FC<Props> = ({ mode = 'domain' }) => {
const defaultTabKey = 'overview'; const defaultTabKey = 'overview';
// 'overview' dataSetManage
const params: any = useParams(); const params: any = useParams();
const domainId = params.domainId; const domainId = params.domainId;
const modelId = params.modelId; const modelId = params.modelId;
@@ -184,6 +184,7 @@ const OverviewContainer: React.FC<Props> = ({ mode }) => {
<div className={styles.content}> <div className={styles.content}>
{selectDomainId ? ( {selectDomainId ? (
<> <>
<OverviewContainerRight />
<DomainManagerTab <DomainManagerTab
isModel={isModel} isModel={isModel}
activeKey={activeKey} activeKey={activeKey}

View File

@@ -0,0 +1,62 @@
import { Outlet } from '@umijs/max';
import { Tabs, Breadcrumb, Space, Radio } from 'antd';
import React, { useRef, useEffect, useState } from 'react';
import { history, useModel } from '@umijs/max';
import { HomeOutlined, FundViewOutlined } from '@ant-design/icons';
import styles from './components/style.less';
const OverviewContainerRight: React.FC = () => {
const domainModel = useModel('SemanticModel.domainData');
const modelModel = useModel('SemanticModel.modelData');
const { selectDomainId, selectDomainName, selectDomain: domainData } = domainModel;
const { selectModelId, selectModelName, setSelectModel } = modelModel;
return (
<>
<Breadcrumb
className={styles.breadcrumb}
separator=""
items={[
{
title: (
<Space
onClick={() => {
// onBackDomainBtnClick?.();
setSelectModel(undefined);
history.push(`/model/${selectDomainId}/overview`);
}}
style={
selectModelName ? { cursor: 'pointer' } : { color: '#296df3', fontWeight: 'bold' }
}
>
<HomeOutlined />
<span>{selectDomainName}</span>
</Space>
),
},
{
type: 'separator',
separator: selectModelName ? '/' : '',
},
{
title: selectModelName ? (
<Space
onClick={() => {
history.push(`/model/manager/${selectDomainId}/${selectModelId}/`);
}}
style={{ color: '#296df3' }}
>
<FundViewOutlined style={{ position: 'relative', top: '2px' }} />
<span>{selectModelName}</span>
</Space>
) : undefined,
},
]}
/>
<Outlet />
</>
);
};
export default OverviewContainerRight;

View File

@@ -13,11 +13,11 @@ import { ColumnsConfig } from '../../components/TableColumnRender';
import ViewSearchFormModal from './ViewSearchFormModal'; import ViewSearchFormModal from './ViewSearchFormModal';
type Props = { type Props = {
dataSetList: ISemantic.IDatasetItem[]; // dataSetList: ISemantic.IDatasetItem[];
disabledEdit?: boolean; disabledEdit?: boolean;
}; };
const DataSetTable: React.FC<Props> = ({ dataSetList, disabledEdit = false }) => { const DataSetTable: React.FC<Props> = ({ disabledEdit = false }) => {
const domainModel = useModel('SemanticModel.domainData'); const domainModel = useModel('SemanticModel.domainData');
const { selectDomainId } = domainModel; const { selectDomainId } = domainModel;
@@ -43,14 +43,14 @@ const DataSetTable: React.FC<Props> = ({ dataSetList, disabledEdit = false }) =>
} }
}; };
const [viewList, setViewList] = useState<ISemantic.IDatasetItem[]>(dataSetList); const [viewList, setViewList] = useState<ISemantic.IDatasetItem[]>();
// useEffect(() => {
// setViewList(dataSetList);
// }, [dataSetList]);
useEffect(() => { useEffect(() => {
setViewList(dataSetList); queryDataSetList();
}, [dataSetList]);
useEffect(() => {
// queryDataSetList();
queryDomainAllModel(); queryDomainAllModel();
}, [selectDomainId]); }, [selectDomainId]);

View File

@@ -4,13 +4,12 @@ import DataSetTable from './components/DataSetTable';
type Props = { type Props = {
disabledEdit?: boolean; disabledEdit?: boolean;
dataSetList: ISemantic.IDatasetItem[];
}; };
const View: React.FC<Props> = ({ dataSetList, disabledEdit = false }) => { const View: React.FC<Props> = ({ disabledEdit = false }) => {
return ( return (
<div style={{ padding: '15px 20px' }}> <div style={{ padding: '15px 20px' }}>
<DataSetTable disabledEdit={disabledEdit} dataSetList={dataSetList} /> <DataSetTable disabledEdit={disabledEdit} />
</div> </div>
); );
}; };

View File

@@ -142,7 +142,11 @@ const ClassMetricTable: React.FC<Props> = ({ onEmptyMetricData }) => {
} }
}; };
const columnsConfig = ColumnsConfig({ indicatorInfo: { url: '/model/metric/edit/' } }); const columnsConfig = ColumnsConfig({
indicatorInfo: {
url: '/model/metric/edit/',
},
});
const columns: ProColumns[] = [ const columns: ProColumns[] = [
{ {

View File

@@ -11,23 +11,24 @@ import styles from './style.less';
import { HomeOutlined, FundViewOutlined } from '@ant-design/icons'; import { HomeOutlined, FundViewOutlined } from '@ant-design/icons';
import { ISemantic } from '../data'; import { ISemantic } from '../data';
import SemanticGraphCanvas from '../SemanticGraphCanvas'; import SemanticGraphCanvas from '../SemanticGraphCanvas';
import Dimension from '../Dimension';
import ModelMetric from '../components/ModelMetric';
import View from '../View'; import View from '../View';
type Props = { type Props = {
isModel: boolean; // isModel: boolean;
activeKey: string; activeKey: string;
modelList: ISemantic.IModelItem[]; // modelList: ISemantic.IModelItem[];
dataSetList: ISemantic.IDatasetItem[]; dataSetList: ISemantic.IDatasetItem[];
handleModelChange: (model?: ISemantic.IModelItem) => void; // handleModelChange: (model?: ISemantic.IModelItem) => void;
onBackDomainBtnClick?: () => void; onBackDomainBtnClick?: () => void;
onMenuChange?: (menuKey: string) => void; onMenuChange?: (menuKey: string) => void;
}; };
const DomainManagerTab: React.FC<Props> = ({ const DomainManagerTab: React.FC<Props> = ({
isModel,
activeKey, activeKey,
modelList, // modelList,
dataSetList, dataSetList,
handleModelChange, // handleModelChange,
onBackDomainBtnClick, onBackDomainBtnClick,
onMenuChange, onMenuChange,
}) => { }) => {
@@ -38,7 +39,7 @@ const DomainManagerTab: React.FC<Props> = ({
const modelModel = useModel('SemanticModel.modelData'); const modelModel = useModel('SemanticModel.modelData');
const { selectDomainId, selectDomainName, selectDomain: domainData } = domainModel; const { selectDomainId, selectDomainName, selectDomain: domainData } = domainModel;
const { selectModelId, selectModelName } = modelModel; const { selectModelId, modelList, selectModelName } = modelModel;
useEffect(() => { useEffect(() => {
initState.current = false; initState.current = false;
@@ -50,7 +51,7 @@ const DomainManagerTab: React.FC<Props> = ({
label: '数据集管理', label: '数据集管理',
key: 'overview', key: 'overview',
hidden: !!domainData?.parentId, hidden: !!domainData?.parentId,
children: <View dataSetList={dataSetList} />, children: <View />,
}, },
{ {
label: '模型管理', label: '模型管理',
@@ -59,9 +60,9 @@ const DomainManagerTab: React.FC<Props> = ({
showModelType === 'list' ? ( showModelType === 'list' ? (
<OverView <OverView
modelList={modelList} modelList={modelList}
onModelChange={(model) => { // onModelChange={(model) => {
handleModelChange(model); // handleModelChange(model);
}} // }}
/> />
) : ( ) : (
<div style={{ width: '100%' }} key={selectDomainId}> <div style={{ width: '100%' }} key={selectDomainId}>
@@ -98,36 +99,9 @@ const DomainManagerTab: React.FC<Props> = ({
return item.key !== 'permissonSetting'; return item.key !== 'permissonSetting';
}); });
const isModelItem = [
{
label: '指标管理',
key: 'metric',
children: (
<ClassMetricTable
onEmptyMetricData={() => {
if (!initState.current) {
initState.current = true;
onMenuChange?.('dimenstion');
}
}}
/>
),
},
{
label: '维度管理',
key: 'dimenstion',
children: <ClassDimensionTable />,
},
{
label: '权限管理',
key: 'permissonSetting',
children: <PermissionSection permissionTarget={'model'} />,
},
];
const getActiveKey = () => { const getActiveKey = () => {
const key = activeKey || defaultTabKey; const key = activeKey || defaultTabKey;
const tabItems = !isModel ? tabItem : isModelItem; const tabItems = tabItem;
const tabItemsKeys = tabItems.map((item) => item.key); const tabItemsKeys = tabItems.map((item) => item.key);
if (!tabItemsKeys.includes(key)) { if (!tabItemsKeys.includes(key)) {
return tabItemsKeys[0]; return tabItemsKeys[0];
@@ -137,47 +111,9 @@ const DomainManagerTab: React.FC<Props> = ({
return ( return (
<div> <div>
<Breadcrumb
className={styles.breadcrumb}
separator=""
items={[
{
title: (
<Space
onClick={() => {
onBackDomainBtnClick?.();
}}
style={
selectModelName ? { cursor: 'pointer' } : { color: '#296df3', fontWeight: 'bold' }
}
>
<HomeOutlined />
<span>{selectDomainName}</span>
</Space>
),
},
{
type: 'separator',
separator: selectModelName ? '/' : '',
},
{
title: selectModelName ? (
<Space
onClick={() => {
history.push(`/model/${selectDomainId}/${selectModelId}/`);
}}
style={{ color: '#296df3' }}
>
<FundViewOutlined style={{ position: 'relative', top: '2px' }} />
<span>{selectModelName}</span>
</Space>
) : undefined,
},
]}
/>
<Tabs <Tabs
className={styles.tab} className={styles.tab}
items={!isModel ? tabItem : selectModelId ? isModelItem : []} items={tabItem}
activeKey={getActiveKey()} activeKey={getActiveKey()}
tabBarExtraContent={{ tabBarExtraContent={{
right: right:

View File

@@ -900,7 +900,9 @@ const MetricInfoCreateForm: React.FC<CreateFormProps> = ({
type="primary" type="primary"
key="console" key="console"
onClick={() => { onClick={() => {
history.replace(`/model/${domainId}/${modelId || metricItem?.modelId}/dataSource`); history.replace(
`/model/manager/${domainId}/${modelId || metricItem?.modelId}/dataSource`,
);
onCancel?.(); onCancel?.();
}} }}
> >

View File

@@ -0,0 +1,102 @@
import { Tabs, Breadcrumb, Space, Radio } from 'antd';
import React, { useRef, useEffect, useState } from 'react';
import { history, useModel } from '@umijs/max';
import ClassDimensionTable from './ClassDimensionTable';
import ClassMetricTable from './ClassMetricTable';
import PermissionSection from './Permission/PermissionSection';
import TagObjectTable from '../Insights/components/TagObjectTable';
import TermTable from '../components/Term/TermTable';
import OverView from './OverView';
import styles from './style.less';
import { HomeOutlined, FundViewOutlined } from '@ant-design/icons';
import { ISemantic } from '../data';
import SemanticGraphCanvas from '../SemanticGraphCanvas';
import Dimension from '../Dimension';
import ModelMetric from '../components/ModelMetric';
import View from '../View';
type Props = {
activeKey: string;
modelList: ISemantic.IModelItem[];
handleModelChange: (model?: ISemantic.IModelItem) => void;
onBackDomainBtnClick?: () => void;
onMenuChange?: (menuKey: string) => void;
};
const ModelManagerTab: React.FC<Props> = ({
activeKey,
modelList,
handleModelChange,
onBackDomainBtnClick,
onMenuChange,
}) => {
const initState = useRef<boolean>(false);
const defaultTabKey = 'metric';
const domainModel = useModel('SemanticModel.domainData');
const modelModel = useModel('SemanticModel.modelData');
const { selectDomainId, selectDomainName, selectDomain: domainData } = domainModel;
const { selectModelId, selectModelName } = modelModel;
useEffect(() => {
console.log(modelList, 'modelList');
}, [modelList]);
useEffect(() => {
initState.current = false;
}, [selectModelId]);
const isModelItem = [
{
label: '指标管理',
key: 'metric',
// children: <ModelMetric />,
children: (
<ClassMetricTable
onEmptyMetricData={() => {
if (!initState.current) {
initState.current = true;
onMenuChange?.('dimension');
}
}}
/>
),
},
{
label: '维度管理',
key: 'dimension',
children: <ClassDimensionTable />,
// children: <Dimension />,
},
{
label: '权限管理',
key: 'permissonSetting',
children: <PermissionSection permissionTarget={'model'} />,
},
];
const getActiveKey = () => {
const key = activeKey || defaultTabKey;
const tabItems = isModelItem;
const tabItemsKeys = tabItems.map((item) => item.key);
if (!tabItemsKeys.includes(key)) {
return tabItemsKeys[0];
}
return key;
};
return (
<div>
<Tabs
className={styles.tab}
items={isModelItem}
activeKey={getActiveKey()}
size="large"
onChange={(menuKey: string) => {
onMenuChange?.(menuKey);
}}
/>
</div>
);
};
export default ModelManagerTab;

View File

@@ -0,0 +1,12 @@
import React from 'react';
import { Outlet } from '@umijs/max';
const Dimension: React.FC = () => {
return (
<>
<Outlet />
</>
);
};
export default Dimension;

View File

@@ -3,7 +3,7 @@ import { ProTable } from '@ant-design/pro-components';
import { message, Button, Space, Popconfirm, Input } from 'antd'; import { message, Button, Space, Popconfirm, Input } from 'antd';
import React, { useRef, useState, useEffect } from 'react'; import React, { useRef, useState, useEffect } from 'react';
import { StatusEnum } from '../enum'; import { StatusEnum } from '../enum';
import { useModel } from '@umijs/max'; import { useModel, history } from '@umijs/max';
import { deleteModel, batchUpdateModelStatus } from '../service'; import { deleteModel, batchUpdateModelStatus } from '../service';
import ClassModelTypeModal from './ClassModelTypeModal'; import ClassModelTypeModal from './ClassModelTypeModal';
import { ColumnsConfig } from './TableColumnRender'; import { ColumnsConfig } from './TableColumnRender';
@@ -22,14 +22,14 @@ const ModelTable: React.FC<Props> = ({ modelList, disabledEdit = false, onModelC
const domainModel = useModel('SemanticModel.domainData'); const domainModel = useModel('SemanticModel.domainData');
const modelModel = useModel('SemanticModel.modelData'); const modelModel = useModel('SemanticModel.modelData');
const { selectDomainId } = domainModel; const { selectDomainId } = domainModel;
const { modelTableHistoryParams, setModelTableHistoryParams } = modelModel; const { modelTableHistoryParams, setModelTableHistoryParams, setSelectModel } = modelModel;
const [modelItem, setModelItem] = useState<ISemantic.IModelItem>(); const [modelItem, setModelItem] = useState<ISemantic.IModelItem>();
const [filterParams, setFilterParams] = useState<Record<string, any>>({}); const [filterParams, setFilterParams] = useState<Record<string, any>>({});
const [createDataSourceModalOpen, setCreateDataSourceModalOpen] = useState(false); const [createDataSourceModalOpen, setCreateDataSourceModalOpen] = useState(false);
const [currentPageNumber, setCurrentPageNumber] = useState<number>(1); const [currentPageNumber, setCurrentPageNumber] = useState<number>(1);
const actionRef = useRef<ActionType>(); const actionRef = useRef<ActionType>();
const [isEditing, setIsEditing] = useState<boolean>(false);
const [tableData, setTableData] = useState<ISemantic.IModelItem[]>([]); const [tableData, setTableData] = useState<ISemantic.IModelItem[]>([]);
const params = modelTableHistoryParams?.[selectDomainId]; const params = modelTableHistoryParams?.[selectDomainId];
@@ -100,10 +100,14 @@ const ModelTable: React.FC<Props> = ({ modelList, disabledEdit = false, onModelC
title: '模型名称', title: '模型名称',
search: false, search: false,
render: (_, record) => { render: (_, record) => {
const { domainId, id } = record;
return ( return (
<a <a
onClick={() => { onClick={() => {
onModelChange?.(record); setSelectModel(record);
history.push(`/model/manager/${domainId}/${id}`);
// onModelChange?.(record);
}} }}
> >
{_} {_}
@@ -161,6 +165,7 @@ const ModelTable: React.FC<Props> = ({ modelList, disabledEdit = false, onModelC
onClick={() => { onClick={() => {
setModelItem(record); setModelItem(record);
setCreateDataSourceModalOpen(true); setCreateDataSourceModalOpen(true);
setIsEditing(true);
}} }}
> >
@@ -209,6 +214,7 @@ const ModelTable: React.FC<Props> = ({ modelList, disabledEdit = false, onModelC
return ( return (
<> <>
<div style={{ display: isEditing ? 'none' : 'block' }}>
<ProTable <ProTable
className={`${styles.classTable} ${styles.classTableSelectColumnAlignLeft}`} className={`${styles.classTable} ${styles.classTableSelectColumnAlignLeft}`}
actionRef={actionRef} actionRef={actionRef}
@@ -278,15 +284,18 @@ const ModelTable: React.FC<Props> = ({ modelList, disabledEdit = false, onModelC
] ]
} }
/> />
</div>
{createDataSourceModalOpen && ( {createDataSourceModalOpen && (
<ClassModelTypeModal <ClassModelTypeModal
open={createDataSourceModalOpen} open={createDataSourceModalOpen}
modelItem={modelItem} modelItem={modelItem}
onSubmit={() => { onSubmit={() => {
onModelChange?.(); onModelChange?.();
setIsEditing(false);
setCreateDataSourceModalOpen(false); setCreateDataSourceModalOpen(false);
}} }}
onCancel={() => { onCancel={() => {
setIsEditing(false);
setCreateDataSourceModalOpen(false); setCreateDataSourceModalOpen(false);
}} }}
/> />

View File

@@ -16,6 +16,7 @@ export const ColumnsConfig: any = (params?: {
indicatorInfo?: { indicatorInfo?: {
url?: string; url?: string;
starType?: StarType; starType?: StarType;
onNameClick?: (record: ISemantic.IMetricItem) => void;
}; };
}) => { }) => {
return { return {
@@ -117,11 +118,15 @@ export const ColumnsConfig: any = (params?: {
className={styles.textLink} className={styles.textLink}
style={{ fontWeight: 500 }} style={{ fontWeight: 500 }}
onClick={(event: any) => { onClick={(event: any) => {
if (params?.indicatorInfo?.onNameClick) {
params?.indicatorInfo?.onNameClick(record);
} else {
history.push(`${url}${id}`); history.push(`${url}${id}`);
}
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
}} }}
href={`/webapp${url}${id}`} // href={`/webapp${url}${id}`}
> >
{name} {name}
</a> </a>

View File

@@ -1,7 +1,189 @@
import React from 'react'; import { message } from 'antd';
import React, { useEffect, useState } from 'react';
import { history, useParams, useModel } from '@umijs/max';
import DomainListTree from './components/DomainList';
import styles from './components/style.less';
import { LeftOutlined, RightOutlined } from '@ant-design/icons';
import { ISemantic } from './data';
import { getDomainList, getDataSetList } from './service';
import { isArrayOfValues } from '@/utils/utils';
import OverviewContainerRight from './OverviewContainerRight';
const classManager: React.FC = ({ children }) => { type Props = {
return <div>{children}</div>; mode: 'domain';
}; };
export default classManager; const OverviewContainer: React.FC<Props> = ({ mode = 'domain' }) => {
const defaultTabKey = 'overview';
const params: any = useParams();
const domainId = params.domainId;
const modelId = params.modelId;
const domainModel = useModel('SemanticModel.domainData');
const modelModel = useModel('SemanticModel.modelData');
const dimensionModel = useModel('SemanticModel.dimensionData');
const metricModel = useModel('SemanticModel.metricData');
const databaseModel = useModel('SemanticModel.databaseData');
const { selectDomainId, domainList, setSelectDomain, setDomainList } = domainModel;
const {
selectModelId,
modelList,
MrefreshModelList,
setSelectModel,
setModelTableHistoryParams,
} = modelModel;
const { MrefreshDimensionList } = dimensionModel;
const { MrefreshMetricList } = metricModel;
const { MrefreshDatabaseList } = databaseModel;
const menuKey = params.menuKey ? params.menuKey : !Number(modelId) ? defaultTabKey : '';
const [collapsedState, setCollapsedState] = useState(true);
const [activeKey, setActiveKey] = useState<string>(menuKey);
// const [dataSetList, setDataSetList] = useState<ISemantic.IDatasetItem[]>([]);
const initSelectedDomain = (domainList: ISemantic.IDomainItem[]) => {
const targetNode = domainList.filter((item: any) => {
return `${item.id}` === domainId;
})[0];
if (!targetNode) {
const firstRootNode = domainList.filter((item: any) => {
return item.parentId === 0;
})[0];
if (firstRootNode) {
const { id } = firstRootNode;
setSelectDomain(firstRootNode);
setActiveKey(menuKey);
pushUrlMenu(id, 0, menuKey);
}
} else {
setSelectDomain(targetNode);
}
};
const initProjectTree = async () => {
const { code, data, msg } = await getDomainList();
if (code === 200) {
initSelectedDomain(data);
setDomainList(data);
} else {
message.error(msg);
}
};
useEffect(() => {
initProjectTree();
MrefreshDatabaseList();
return () => {
setSelectDomain(undefined);
// setSelectModel(undefined);
};
}, []);
useEffect(() => {
if (!selectDomainId) {
return;
}
console.log(selectDomainId, 'selectDomainIdselectDomainId');
queryModelList();
// queryDataSetList();
}, [selectDomainId]);
// const queryDataSetList = async () => {
// const { code, data, msg } = await getDataSetList(selectDomainId);
// if (code === 200) {
// setDataSetList(data);
// if (!isArrayOfValues(data)) {
// setActiveKey(defaultTabKey);
// }
// } else {
// message.error(msg);
// }
// };
const queryModelList = async () => {
await MrefreshModelList(selectDomainId);
};
// const initModelConfig = () => {
// const currentMenuKey = menuKey === defaultTabKey ? '' : menuKey;
// pushUrlMenu(selectDomainId, selectModelId, currentMenuKey);
// setActiveKey(currentMenuKey);
// };
// useEffect(() => {
// if (!selectModelId) {
// return;
// }
// // initModelConfig();
// MrefreshDimensionList({ modelId: selectModelId });
// MrefreshMetricList({ modelId: selectModelId });
// }, [selectModelId]);
const pushUrlMenu = (domainId: number, modelId: number, menuKey: string) => {
history.push(`/model/${domainId}/${menuKey}`);
};
// // const handleModelChange = (model?: ISemantic.IModelItem) => {
// // if (!model) {
// // return;
// // }
// // if (`${model.id}` === `${selectModelId}`) {
// // initModelConfig();
// // }
// // setSelectModel(model);
// // };
const cleanModelInfo = (domainId) => {
setActiveKey(defaultTabKey);
pushUrlMenu(domainId, 0, defaultTabKey);
setSelectModel(undefined);
};
const handleCollapsedBtn = () => {
setCollapsedState(!collapsedState);
};
return (
<div className={styles.projectBody}>
<div className={styles.projectManger}>
<div className={`${styles.sider} ${!collapsedState ? styles.siderCollapsed : ''}`}>
<div className={styles.treeContainer}>
<DomainListTree
createDomainBtnVisible={mode === 'domain' ? true : false}
onTreeSelected={(domainData: ISemantic.IDomainItem) => {
const { id } = domainData;
cleanModelInfo(id);
setSelectDomain(domainData);
setModelTableHistoryParams({
[id]: {},
});
}}
onTreeDataUpdate={() => {
initProjectTree();
}}
/>
</div>
<div
className={styles.siderCollapsedButton}
onClick={() => {
handleCollapsedBtn();
}}
>
{collapsedState ? <LeftOutlined /> : <RightOutlined />}
</div>
</div>
<div className={styles.content}>
{selectDomainId ? (
<>
<OverviewContainerRight />
</>
) : (
<h2 className={styles.mainTip}></h2>
)}
</div>
</div>
</div>
);
};
export default OverviewContainer;