[improvement][headless-fe] Enhanced dataset creation to support the tag mode. (#808)

* [improvement][semantic-fe] Add model alias setting & Add view permission restrictions to the model permission management tab.
[improvement][semantic-fe] Add permission control to the action buttons for the main domain; apply high sensitivity filtering to the authorization of metrics/dimensions.
[improvement][semantic-fe] Optimize the editing mode in the dimension/metric/datasource components to use the modelId stored in the database for data, instead of relying on the data from the state manager.

* [improvement][semantic-fe] Add time granularity setting in the data source configuration.

* [improvement][semantic-fe] Dictionary import for dimension values supported in Q&A visibility

* [improvement][semantic-fe] Modification of data source creation prompt wording"

* [improvement][semantic-fe] metric market experience optimization

* [improvement][semantic-fe] enhance the analysis of metric trends

* [improvement][semantic-fe] optimize the presentation of metric trend permissions

* [improvement][semantic-fe] add metric trend download functionality

* [improvement][semantic-fe] fix the dimension initialization issue in metric correlation

* [improvement][semantic-fe] Fix the issue of database changes not taking effect when creating based on an SQL data source.

* [improvement][semantic-fe] Optimizing pagination logic and some CSS styles

* [improvement][semantic-fe] Fixing the API for the indicator list by changing "current" to "pageNum"

* [improvement][semantic-fe] Fixing the default value setting for the indicator list

* [improvement][semantic-fe] Adding batch operations for indicators/dimensions/models

* [improvement][semantic-fe] Replacing the single status update API for indicators/dimensions with a batch update API

* [improvement][semantic-fe] Redesigning the indicator homepage to incorporate trend charts and table functionality for indicators

* [improvement][semantic-fe] Optimizing the logic for setting dimension values and editing data sources, and adding system settings functionality

* [improvement][semantic-fe] Upgrading antd version to 5.x, extracting the batch operation button component, optimizing the interaction for system settings, and expanding the configuration generation types for list-to-select component.

* [improvement][semantic-fe] Adding the ability to filter dimensions based on whether they are tags or not.

* [improvement][semantic-fe] Adding the ability to edit relationships between models in the canvas.

* [improvement][semantic-fe] Updating the datePicker component to use dayjs instead.

* [improvement][semantic-fe] Fixing the issue with passing the model ID for dimensions in the indicator market.

* [improvement][semantic-fe] Fixing the abnormal state of the popup when creating a model.

* [improvement][semantic-fe] Adding permission logic for bulk operations in the indicator market.

* [improvement][semantic-fe] Adding the ability to download and transpose data.

* [improvement][semantic-fe] Fixing the initialization issue with the date selection component in the indicator details page when switching time granularity.

* [improvement][semantic-fe] Fixing the logic error in the dimension value setting.

* [improvement][semantic-fe] Fixing the synchronization issue with the question and answer settings information.

* [improvement][semantic-fe] Optimizing the canvas functionality for better performance and user experience.

* [improvement][semantic-fe] Optimizing the update process for drawing model relationship edges in the canvas.

* [improvement][semantic-fe] Changing the line type for canvas connections.

* [improvement][semantic-fe] Replacing the initialization variable from "semantic" to "headless".

* [improvement][semantic-fe] Fixing the missing migration issue for default drill-down dimension configuration in model editing. Additionally, optimizing the data retrieval method for initializing fields in the model.

* [improvement][semantic-fe] Updating the logic for the fieldName.

* [improvement][semantic-fe] Adjusting the position of the metrics tab.

* [improvement][semantic-fe] Changing the 字段名称 to 英文名称.

* [improvement][semantic-fe] Fix metric measurement deletion.

* [improvement][semantic-fe] UI optimization for metric details page.

* [improvement][semantic-fe] UI optimization for metric details page.

* [improvement][semantic-fe] UI adjustment for metric details page.

* [improvement][semantic-fe] The granularity field in the time type of model editing now supports setting it as empty.

* [improvement][semantic-fe] Added field type and metric type to the metric creation options.

* [improvement][semantic-fe] The organization structure selection feature has been added to the permission management.

* [improvement][semantic-fe] Improved user experience for the metric list.

* [improvement][semantic-fe] fix update the metric list.

* [improvement][headless-fe] Added view management functionality.

* [improvement][headless-fe] The view management functionality has been added. This feature allows users to create, edit, and manage different views within the system.

* [improvement][headless-fe] Added model editing side effect detection.

* [improvement][headless-fe] Fixed the logic error in view editing.

* [improvement][headless-fe] Fixed the issue with initializing dimension associations in metric settings.

* [improvement][headless-fe] Added the ability to hide the Q&A settings entry point.

* [improvement][headless-fe] Fixed the issue with selecting search results in metric field creation.

* [improvement][headless-fe] Added search functionality to the field list in model editing.

* [improvement][headless-fe] fix the field list in model editing

* [improvement][headless-fe] Restructured the data for the dimension value settings interface.

* [improvement][headless-fe] Added dynamic variable functionality to model creation based on SQL scripts.

* [improvement][headless-fe] Added support for passing dynamic variables as parameters in the executeSql function.

* [improvement][headless-fe] Resolved the issue where users were unable to select all options for dimensions, metrics, and fields in the metric generation process.

* [improvement][headless-fe] Replaced the term "view" with "dataset"

* [improvement][headless-fe] Added the ability to export metrics and dimensions to a specific target.

* [improvement][headless-fe] Enhanced dataset creation to support the tag mode.
This commit is contained in:
tristanliu
2024-03-12 22:02:03 +08:00
committed by GitHub
parent 26bef3d472
commit f152deeb81
9 changed files with 331 additions and 99 deletions

View File

@@ -11,7 +11,7 @@ export type ModelCreateFormModalProps = {
metricList?: ISemantic.IMetricItem[]; metricList?: ISemantic.IMetricItem[];
modelId?: number; modelId?: number;
selectedTransferKeys: React.Key[]; selectedTransferKeys: React.Key[];
toolbarSolt?: ReactNode; toolbarSolt?: React.ReactNode;
onCancel: () => void; onCancel: () => void;
onSubmit: (values: any, selectedKeys: React.Key[]) => void; onSubmit: (values: any, selectedKeys: React.Key[]) => void;
}; };

View File

@@ -0,0 +1,114 @@
import React, { useState, useEffect } from 'react';
import { ISemantic } from '../../data';
import { TransType } from '../../enum';
import DimensionMetricVisibleTransfer from '../../components/Entity/DimensionMetricVisibleTransfer';
import { wrapperTransTypeAndId } from '../../utils';
export type ModelCreateFormModalProps = {
tagList?: ISemantic.ITagItem[];
modelId?: number;
selectedTransferKeys: React.Key[];
toolbarSolt?: React.ReactNode;
onCancel: () => void;
onSubmit: (values: any, selectedKeys: React.Key[]) => void;
};
const TagTransferModal: React.FC<ModelCreateFormModalProps> = ({
modelId,
toolbarSolt,
selectedTransferKeys,
tagList,
onSubmit,
}) => {
const [sourceList, setSourceList] = useState<any[]>([]);
const [selectedItemList, setSelectedItemList] = useState<any[]>([]);
const addItemKey = (item: any, transType: TransType) => {
const { id } = item;
const key = wrapperTransTypeAndId(transType, id);
return {
...item,
transType,
key,
};
};
useEffect(() => {
if (!tagList) {
return;
}
const sourceTagList = tagList.reduce((mergeList: any[], item) => {
mergeList.push(addItemKey(item, TransType.TAG));
return mergeList;
}, []);
const hasTagList = selectedItemList.reduce((modelTagList: ISemantic.ITagItem[], item) => {
const hasItem = sourceTagList.find((dataListItem: ISemantic.ITagItem) => {
return dataListItem.id === item.id;
});
if (!hasItem) {
modelTagList.push(addItemKey(item, TransType.TAG));
}
return modelTagList;
}, []);
setSourceList([...sourceTagList, ...hasTagList]);
}, [tagList]);
return (
<DimensionMetricVisibleTransfer
titles={[<>{toolbarSolt}</>, '已加入标签']}
listStyle={{
width: 520,
height: 600,
}}
targetList={selectedTransferKeys}
sourceList={sourceList}
onChange={(newTargetKeys: string[]) => {
const removeTagList: ISemantic.ITagItem[] = [];
const tagItemChangeList = Array.isArray(tagList)
? tagList.reduce((tagChangeList: any[], item: any) => {
if (newTargetKeys.includes(wrapperTransTypeAndId(TransType.TAG, item.id))) {
tagChangeList.push(item);
} else {
removeTagList.push(item.id);
}
return tagChangeList;
}, [])
: [];
setSelectedItemList([...tagItemChangeList]);
// 如果不是当前选中model中的指标或者维度则先从本地数据中删除避免后续请求数据更新时产生视觉上的界面闪烁
const preUpdateSourceData = sourceList.filter((item) => {
const { id } = item;
if (modelId !== item.modelId && removeTagList.includes(id)) {
return false;
}
return true;
});
setSourceList([...preUpdateSourceData]);
const dataSetModelConfigs = [...tagItemChangeList].reduce((config, item) => {
const { modelId, id } = item;
if (config[modelId]) {
config[modelId].tagIds.push(id);
} else {
config[modelId] = {
id: modelId,
tagIds: [id],
};
}
return config;
}, {});
onSubmit?.(dataSetModelConfigs, newTargetKeys);
}}
/>
);
};
export default TagTransferModal;

View File

@@ -1,9 +1,9 @@
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import { Form, Button, Modal, Input, Select, Steps, Tabs, Space } from 'antd'; import { Form, Button, Modal, Input, Select, Steps, Radio, Space } from 'antd';
import styles from '../../components/style.less'; import styles from '../../components/style.less';
import { message } from 'antd'; import { message } from 'antd';
import { formLayout } from '@/components/FormHelper/utils'; import { formLayout } from '@/components/FormHelper/utils';
import { createView, updateView, getDimensionList, queryMetric } from '../../service'; import { createView, updateView, getDimensionList, queryMetric, getTagList } from '../../service';
import { ISemantic } from '../../data'; import { ISemantic } from '../../data';
import { isString } from 'lodash'; import { isString } from 'lodash';
import FormItemTitle from '@/components/FormHelper/FormItemTitle'; import FormItemTitle from '@/components/FormHelper/FormItemTitle';
@@ -34,6 +34,8 @@ const ViewCreateFormModal: React.FC<ModelCreateFormModalProps> = ({
currentModel: modelList[0]?.id, currentModel: modelList[0]?.id,
}); });
const [queryType, setQueryType] = useState<string>('METRIC');
const [saveLoading, setSaveLoading] = useState<boolean>(false); const [saveLoading, setSaveLoading] = useState<boolean>(false);
const [modalWidth, setModalWidth] = useState<number>(800); const [modalWidth, setModalWidth] = useState<number>(800);
const [selectedModelItem, setSelectedModelItem] = useState<ISemantic.IModelItem | undefined>( const [selectedModelItem, setSelectedModelItem] = useState<ISemantic.IModelItem | undefined>(
@@ -46,19 +48,22 @@ const ViewCreateFormModal: React.FC<ModelCreateFormModalProps> = ({
form.setFieldsValue({ form.setFieldsValue({
...viewItem, ...viewItem,
}); });
setQueryType(viewItem?.queryType);
}, [viewItem]); }, [viewItem]);
const [dimensionList, setDimensionList] = useState<ISemantic.IDimensionItem[]>(); const [dimensionList, setDimensionList] = useState<ISemantic.IDimensionItem[]>();
const [metricList, setMetricList] = useState<ISemantic.IMetricItem[]>(); const [metricList, setMetricList] = useState<ISemantic.IMetricItem[]>();
const [tagList, setTagList] = useState<ISemantic.ITagItem[]>();
useEffect(() => { useEffect(() => {
if (selectedModelItem?.id) { if (selectedModelItem?.id) {
queryDimensionList(selectedModelItem.id); queryDimensionList(selectedModelItem.id);
queryMetricList(selectedModelItem.id); queryMetricList(selectedModelItem.id);
queryTagList(selectedModelItem.id);
} }
}, [selectedModelItem]); }, [selectedModelItem]);
const queryDimensionList = async (modelId) => { const queryDimensionList = async (modelId: number) => {
const { code, data, msg } = await getDimensionList({ modelId }); const { code, data, msg } = await getDimensionList({ modelId });
if (code === 200 && Array.isArray(data?.list)) { if (code === 200 && Array.isArray(data?.list)) {
setDimensionList(data.list); setDimensionList(data.list);
@@ -67,7 +72,7 @@ const ViewCreateFormModal: React.FC<ModelCreateFormModalProps> = ({
} }
}; };
const queryMetricList = async (modelId) => { const queryMetricList = async (modelId: number) => {
const { code, data, msg } = await queryMetric({ modelId }); const { code, data, msg } = await queryMetric({ modelId });
if (code === 200 && Array.isArray(data?.list)) { if (code === 200 && Array.isArray(data?.list)) {
setMetricList(data.list); setMetricList(data.list);
@@ -76,6 +81,20 @@ const ViewCreateFormModal: React.FC<ModelCreateFormModalProps> = ({
} }
}; };
const queryTagList = async (modelId: number) => {
const { code, data, msg } = await getTagList({
modelIds: [modelId],
});
const { list } = data || {};
if (code === 200) {
setTagList(list);
} else {
message.error(msg);
setTagList([]);
}
};
const handleConfirm = async () => { const handleConfirm = async () => {
const fieldsValue = await form.validateFields(); const fieldsValue = await form.validateFields();
const viewModelConfigsMap = configTableRef?.current.getViewModelConfigs() || {}; const viewModelConfigsMap = configTableRef?.current.getViewModelConfigs() || {};
@@ -83,6 +102,7 @@ const ViewCreateFormModal: React.FC<ModelCreateFormModalProps> = ({
const queryData: ISemantic.IModelItem = { const queryData: ISemantic.IModelItem = {
...formVals, ...formVals,
...fieldsValue, ...fieldsValue,
queryType,
dataSetDetail: { dataSetDetail: {
dataSetModelConfigs: Object.values(viewModelConfigsMap), dataSetModelConfigs: Object.values(viewModelConfigsMap),
}, },
@@ -99,7 +119,7 @@ const ViewCreateFormModal: React.FC<ModelCreateFormModalProps> = ({
} }
}; };
const stepWidth = { const stepWidth: any = {
'0': 800, '0': 800,
'1': 1200, '1': 1200,
'2': 800, '2': 800,
@@ -140,23 +160,6 @@ const ViewCreateFormModal: React.FC<ModelCreateFormModalProps> = ({
</> </>
); );
} }
// if (currentStep === 2) {
// return (
// <>
// <Button style={{ float: 'left' }} onClick={backward}>
// 上一步
// </Button>
// <Button
// type="primary"
// onClick={() => {
// handleConfirm();
// }}
// >
// 保 存
// </Button>
// </>
// );
// }
return ( return (
<> <>
<Button onClick={onCancel}></Button> <Button onClick={onCancel}></Button>
@@ -179,27 +182,29 @@ const ViewCreateFormModal: React.FC<ModelCreateFormModalProps> = ({
return ( return (
<> <>
<div style={{ display: currentStep === 1 ? 'block' : 'none' }}> <div style={{ display: currentStep === 1 ? 'block' : 'none' }}>
{/* <FormItem <div style={{ marginBottom: 10, paddingLeft: 12 }}>
name="currentModel" <Radio.Group
label="选择模型" buttonStyle="solid"
rules={[{ required: true, message: '请选择模型!' }]} value={queryType}
> onChange={(e) => {
<Select setQueryType(e.target.value);
placeholder="请选择模型,获取当前模型下指标维度信息"
onChange={(val) => {
const modelItem = modelList.find((item) => item.id === val);
setSelectedModelItem(modelItem);
}} }}
options={modelList.map((item) => { >
return { label: item.name, value: item.id }; <Radio.Button value="METRIC"></Radio.Button>
})} <Radio.Button value="TAG"></Radio.Button>
/> </Radio.Group>
</FormItem> */} </div>
<ViewModelConfigTransfer <ViewModelConfigTransfer
key={queryType}
queryType={queryType}
toolbarSolt={ toolbarSolt={
<Space> <Space>
<span>: </span> <span>: </span>
<Select <Select
style={{
minWidth: 100,
}}
value={selectedModelItem?.id} value={selectedModelItem?.id}
placeholder="请选择模型,获取当前模型下指标维度信息" placeholder="请选择模型,获取当前模型下指标维度信息"
onChange={(val) => { onChange={(val) => {
@@ -216,6 +221,7 @@ const ViewCreateFormModal: React.FC<ModelCreateFormModalProps> = ({
} }
dimensionList={dimensionList} dimensionList={dimensionList}
metricList={metricList} metricList={metricList}
tagList={tagList}
modelItem={selectedModelItem} modelItem={selectedModelItem}
viewItem={viewItem} viewItem={viewItem}
ref={configTableRef} ref={configTableRef}

View File

@@ -2,27 +2,42 @@ import { message } from 'antd';
import React, { forwardRef, useImperativeHandle, useState, useEffect } from 'react'; import React, { forwardRef, useImperativeHandle, useState, useEffect } from 'react';
import type { ReactNode, Ref } from 'react'; import type { ReactNode, Ref } from 'react';
import DimensionMetricTransferModal from './DimensionMetricTransferModal'; import DimensionMetricTransferModal from './DimensionMetricTransferModal';
import TagTransferModal from './TagTransferModal';
import { TransType } from '../../enum'; import { TransType } from '../../enum';
import { getDimensionList, queryMetric } from '../../service'; import { getDimensionList, queryMetric, getTagList } from '../../service';
import { wrapperTransTypeAndId } from '../../utils'; import { wrapperTransTypeAndId } from '../../utils';
import { ISemantic } from '../../data'; import { ISemantic } from '../../data';
import { isArrayOfValues } from '@/utils/utils'; import { isArrayOfValues } from '@/utils/utils';
type Props = { type Props = {
queryType?: string;
viewItem: ISemantic.IViewItem; viewItem: ISemantic.IViewItem;
modelItem?: ISemantic.IModelItem; modelItem?: ISemantic.IModelItem;
dimensionList?: ISemantic.IDimensionItem[]; dimensionList?: ISemantic.IDimensionItem[];
metricList?: ISemantic.IMetricItem[]; metricList?: ISemantic.IMetricItem[];
tagList?: ISemantic.ITagItem[];
toolbarSolt?: ReactNode; toolbarSolt?: ReactNode;
}; };
const ViewModelConfigTransfer: React.FC<Props> = forwardRef( const ViewModelConfigTransfer: React.FC<Props> = forwardRef(
({ viewItem, modelItem, dimensionList, metricList, toolbarSolt }: Props, ref: Ref<any>) => { (
{
queryType = 'METRIC',
viewItem,
modelItem,
dimensionList,
metricList,
tagList,
toolbarSolt,
}: Props,
ref: Ref<any>,
) => {
const [selectedTransferKeys, setSelectedTransferKeys] = useState<React.Key[]>([]); const [selectedTransferKeys, setSelectedTransferKeys] = useState<React.Key[]>([]);
const [viewModelConfigsMap, setViewModelConfigsMap] = useState({}); const [viewModelConfigsMap, setViewModelConfigsMap] = useState({});
const [mergeDimensionList, setDimensionList] = useState<ISemantic.IDimensionItem[]>(); const [mergeDimensionList, setDimensionList] = useState<ISemantic.IDimensionItem[]>();
const [mergeMetricList, setMetricList] = useState<ISemantic.IMetricItem[]>(); const [mergeMetricList, setMetricList] = useState<ISemantic.IMetricItem[]>();
const [mergeTagList, setTagList] = useState<ISemantic.ITagItem[]>();
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
getViewModelConfigs: () => { getViewModelConfigs: () => {
@@ -30,6 +45,33 @@ const ViewModelConfigTransfer: React.FC<Props> = forwardRef(
}, },
})); }));
const queryTagListByIds = async (ids: number[]) => {
if (!isArrayOfValues(ids)) {
setTagList(tagList);
return;
}
const { code, data, msg } = await getTagList({ ids });
if (code === 200 && Array.isArray(data?.list)) {
const mergeList = data?.list.reduce(
(modelTagList: ISemantic.ITagItem[], item: ISemantic.ITagItem) => {
const hasItem = Array.isArray(tagList)
? tagList.find((dataListItem: ISemantic.ITagItem) => {
return dataListItem.id === item.id;
})
: [];
if (!hasItem) {
return [item, ...modelTagList];
}
return modelTagList;
},
tagList,
);
setTagList(mergeList);
} else {
message.error(msg);
}
};
const queryDimensionListByIds = async (ids: number[]) => { const queryDimensionListByIds = async (ids: number[]) => {
if (!isArrayOfValues(ids)) { if (!isArrayOfValues(ids)) {
setDimensionList(dimensionList); setDimensionList(dimensionList);
@@ -38,7 +80,7 @@ const ViewModelConfigTransfer: React.FC<Props> = forwardRef(
const { code, data, msg } = await getDimensionList({ ids }); const { code, data, msg } = await getDimensionList({ ids });
if (code === 200 && Array.isArray(data?.list)) { if (code === 200 && Array.isArray(data?.list)) {
const mergeList = data?.list.reduce( const mergeList = data?.list.reduce(
(modelDimensionList: ISemantic.IDimensionItem[], item) => { (modelDimensionList: ISemantic.IDimensionItem[], item: ISemantic.IDimensionItem) => {
const hasItem = Array.isArray(dimensionList) const hasItem = Array.isArray(dimensionList)
? dimensionList.find((dataListItem: ISemantic.IDimensionItem) => { ? dimensionList.find((dataListItem: ISemantic.IDimensionItem) => {
return dataListItem.id === item.id; return dataListItem.id === item.id;
@@ -64,7 +106,8 @@ const ViewModelConfigTransfer: React.FC<Props> = forwardRef(
} }
const { code, data, msg } = await queryMetric({ ids }); const { code, data, msg } = await queryMetric({ ids });
if (code === 200 && Array.isArray(data?.list)) { if (code === 200 && Array.isArray(data?.list)) {
const mergeList = data.list.reduce((modelMetricList: ISemantic.IMetricItem[], item) => { const mergeList = data.list.reduce(
(modelMetricList: ISemantic.IMetricItem[], item: ISemantic.IMetricItem) => {
const hasItem = Array.isArray(metricList) const hasItem = Array.isArray(metricList)
? metricList.find((dataListItem: ISemantic.IMetricItem) => { ? metricList.find((dataListItem: ISemantic.IMetricItem) => {
return dataListItem.id === item.id; return dataListItem.id === item.id;
@@ -74,7 +117,9 @@ const ViewModelConfigTransfer: React.FC<Props> = forwardRef(
return [item, ...modelMetricList]; return [item, ...modelMetricList];
} }
return modelMetricList; return modelMetricList;
}, metricList); },
metricList,
);
setMetricList(mergeList); setMetricList(mergeList);
} else { } else {
message.error(msg); message.error(msg);
@@ -83,18 +128,17 @@ const ViewModelConfigTransfer: React.FC<Props> = forwardRef(
useEffect(() => { useEffect(() => {
const dataSetModelConfigs = viewItem?.dataSetDetail?.dataSetModelConfigs; const dataSetModelConfigs = viewItem?.dataSetDetail?.dataSetModelConfigs;
if (Array.isArray(dataSetModelConfigs)) { if (Array.isArray(dataSetModelConfigs)) {
const idList: number[] = []; const idList: number[] = [];
const transferKeys: React.Key[] = []; const transferKeys: React.Key[] = [];
const viewConfigMap = {}; const viewConfigMap: any = {};
const allMetrics: number[] = [];
const allDimensions: number[] = [];
dataSetModelConfigs.forEach((item: ISemantic.IViewModelConfigItem) => { dataSetModelConfigs.forEach((item: ISemantic.IViewModelConfigItem) => {
const { id, metrics, dimensions } = item; const { id, metrics, dimensions, tagIds } = item;
idList.push(id); idList.push(id);
allMetrics.push(...metrics);
allDimensions.push(...dimensions);
viewConfigMap[id] = { ...item }; viewConfigMap[id] = { ...item };
if (queryType === 'METRIC') {
if (Array.isArray(metrics)) { if (Array.isArray(metrics)) {
metrics.forEach((metricId: number) => { metrics.forEach((metricId: number) => {
transferKeys.push(wrapperTransTypeAndId(TransType.METRIC, metricId)); transferKeys.push(wrapperTransTypeAndId(TransType.METRIC, metricId));
@@ -105,13 +149,24 @@ const ViewModelConfigTransfer: React.FC<Props> = forwardRef(
transferKeys.push(wrapperTransTypeAndId(TransType.DIMENSION, dimensionId)); transferKeys.push(wrapperTransTypeAndId(TransType.DIMENSION, dimensionId));
}); });
} }
}
if (queryType === 'TAG') {
if (Array.isArray(tagIds)) {
tagIds.forEach((tagId: number) => {
transferKeys.push(wrapperTransTypeAndId(TransType.TAG, tagId));
});
}
}
}); });
setSelectedTransferKeys(transferKeys); setSelectedTransferKeys(transferKeys);
setViewModelConfigsMap(viewConfigMap); setViewModelConfigsMap(viewConfigMap);
} }
}, []); }, [queryType]);
useEffect(() => { useEffect(() => {
if (queryType !== 'METRIC') {
return;
}
if (!dimensionList || !metricList) { if (!dimensionList || !metricList) {
return; return;
} }
@@ -132,10 +187,33 @@ const ViewModelConfigTransfer: React.FC<Props> = forwardRef(
setDimensionList(dimensionList); setDimensionList(dimensionList);
setMetricList(metricList); setMetricList(metricList);
} }
}, [modelItem, dimensionList, metricList]); }, [queryType, modelItem, dimensionList, metricList]);
useEffect(() => {
if (queryType !== 'TAG') {
return;
}
if (!tagList) {
return;
}
const dataSetModelConfigs = isArrayOfValues(Object.values(viewModelConfigsMap))
? (Object.values(viewModelConfigsMap) as ISemantic.IViewModelConfigItem[])
: viewItem?.dataSetDetail?.dataSetModelConfigs;
if (isArrayOfValues(dataSetModelConfigs)) {
const allTags: number[] = [];
dataSetModelConfigs.forEach((item: ISemantic.IViewModelConfigItem) => {
const { tagIds } = item;
allTags.push(...tagIds);
});
queryTagListByIds(allTags);
} else {
setTagList(tagList);
}
}, [queryType, modelItem, tagList]);
return ( return (
<> <>
<div style={{ display: queryType === 'TAG' ? 'none' : 'block' }}>
<DimensionMetricTransferModal <DimensionMetricTransferModal
toolbarSolt={toolbarSolt} toolbarSolt={toolbarSolt}
modelId={modelItem?.id} modelId={modelItem?.id}
@@ -166,6 +244,35 @@ const ViewModelConfigTransfer: React.FC<Props> = forwardRef(
}} }}
onCancel={() => {}} onCancel={() => {}}
/> />
</div>
<div style={{ display: queryType !== 'TAG' ? 'none' : 'block' }}>
<TagTransferModal
toolbarSolt={toolbarSolt}
modelId={modelItem?.id}
tagList={mergeTagList}
selectedTransferKeys={selectedTransferKeys}
onSubmit={(
submitData: Record<string, ISemantic.IViewModelConfigItem>,
selectedKeys: React.Key[],
) => {
const dataSetModelConfigs = Object.values(
submitData,
) as ISemantic.IViewModelConfigItem[];
if (isArrayOfValues(dataSetModelConfigs)) {
const allTags: number[] = [];
dataSetModelConfigs.forEach((item: ISemantic.IViewModelConfigItem) => {
const { tagIds } = item;
allTags.push(...tagIds);
});
queryTagListByIds(allTags);
}
setViewModelConfigsMap(submitData);
setSelectedTransferKeys(selectedKeys);
}}
onCancel={() => {}}
/>
</div>
</> </>
); );
}, },

View File

@@ -135,7 +135,7 @@ const ViewSearchFormModal: React.FC<ModelCreateFormModalProps> = ({
<Modal <Modal
width={800} width={800}
destroyOnClose destroyOnClose
title={'数据集信息'} title={'查询设置'}
open={true} open={true}
maskClosable={false} maskClosable={false}
footer={renderFooter()} footer={renderFooter()}

View File

@@ -12,7 +12,7 @@ type Props = {
knowledgeInfosMap?: IChatConfig.IKnowledgeInfosItemMap; knowledgeInfosMap?: IChatConfig.IKnowledgeInfosItemMap;
sourceList: any[]; sourceList: any[];
targetList: React.Key[]; targetList: React.Key[];
titles?: string[]; titles?: (React.ReactNode | string)[];
onKnowledgeInfosMapChange?: (knowledgeInfosMap: IChatConfig.IKnowledgeInfosItemMap) => void; onKnowledgeInfosMapChange?: (knowledgeInfosMap: IChatConfig.IKnowledgeInfosItemMap) => void;
onChange?: (params?: any) => void; onChange?: (params?: any) => void;
[key: string]: any; [key: string]: any;

View File

@@ -16,6 +16,8 @@ const TransTypeTag: React.FC<Props> = ({ type }) => {
<Tag color="orange">{'指标'}</Tag> <Tag color="orange">{'指标'}</Tag>
) : type === SemanticNodeType.DATASOURCE ? ( ) : type === SemanticNodeType.DATASOURCE ? (
<Tag color="green">{'模型'}</Tag> <Tag color="green">{'模型'}</Tag>
) : type === SemanticNodeType.TAG ? (
<Tag color="green">{'标签'}</Tag>
) : ( ) : (
<></> <></>
)} )}

View File

@@ -157,6 +157,7 @@ export declare namespace ISemantic {
includesAll: boolean; includesAll: boolean;
metrics: number[]; metrics: number[];
dimensions: number[]; dimensions: number[];
tagIds: number[];
} }
interface IViewItem { interface IViewItem {

View File

@@ -6,12 +6,14 @@ export enum ChatConfigType {
export enum TransType { export enum TransType {
DIMENSION = 'DIMENSION', DIMENSION = 'DIMENSION',
METRIC = 'METRIC', METRIC = 'METRIC',
TAG = 'TAG',
} }
export enum SemanticNodeType { export enum SemanticNodeType {
DATASOURCE = 'DATASOURCE', DATASOURCE = 'DATASOURCE',
DIMENSION = 'DIMENSION', DIMENSION = 'DIMENSION',
METRIC = 'METRIC', METRIC = 'METRIC',
TAG = 'TAG',
} }
export enum MetricTypeWording { export enum MetricTypeWording {