mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-11 03:58:14 +00:00
[improvement][semantic-fe] Adding the ability to filter dimensions based on whether they are tags or not. (#417)
* [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.
This commit is contained in:
@@ -1,15 +1,43 @@
|
|||||||
import { Space } from 'antd';
|
import { Space, Typography } from 'antd';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
import styles from './index.less';
|
||||||
export interface IProps {
|
export interface IProps {
|
||||||
title: string | ReactNode;
|
title: string | ReactNode;
|
||||||
subTitle?: string;
|
subTitle?: string;
|
||||||
|
subTitleEditable?: boolean;
|
||||||
|
onSubTitleChange?: (title: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FormItemTitle: React.FC<IProps> = ({ title, subTitle }) => {
|
const { Paragraph } = Typography;
|
||||||
|
|
||||||
|
const FormItemTitle: React.FC<IProps> = ({
|
||||||
|
title,
|
||||||
|
subTitle,
|
||||||
|
subTitleEditable = false,
|
||||||
|
onSubTitleChange,
|
||||||
|
}) => {
|
||||||
return (
|
return (
|
||||||
<Space direction="vertical" size={2}>
|
// <div style={{ display: 'block' }}>
|
||||||
<span>{title}</span>
|
|
||||||
{subTitle && <span style={{ fontSize: '12px', color: '#6a6a6a' }}>{subTitle}</span>}
|
// </div>
|
||||||
|
<Space direction="vertical" size={2} style={{ width: '100%' }}>
|
||||||
|
<div>{title}</div>
|
||||||
|
<div className={styles.subTitleContainer}>
|
||||||
|
{subTitleEditable ? (
|
||||||
|
<Paragraph
|
||||||
|
editable={{
|
||||||
|
// editing: true,
|
||||||
|
onChange: (title: string) => {
|
||||||
|
onSubTitleChange?.(title);
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{subTitle || '添加描述'}
|
||||||
|
</Paragraph>
|
||||||
|
) : (
|
||||||
|
subTitle && <span style={{ fontSize: '12px', color: '#6a6a6a' }}>{subTitle}</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</Space>
|
</Space>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,39 +1,13 @@
|
|||||||
.normalState {
|
.subTitleContainer {
|
||||||
position: static;
|
width: 500px;
|
||||||
height: 100%;
|
:global {
|
||||||
|
.ant-typography{
|
||||||
.backNormal {
|
font-size: 12px;
|
||||||
display: none;
|
color: #6a6a6a;
|
||||||
}
|
}
|
||||||
}
|
.ant-typography-edit-content {
|
||||||
|
margin-left: 12px;
|
||||||
.maxState {
|
margin-top: 8px;
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 999;
|
|
||||||
|
|
||||||
.innerWrap {
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.backNormal {
|
|
||||||
display: block;
|
|
||||||
height: 30px;
|
|
||||||
padding-right: 20px;
|
|
||||||
color: #02a7f0;
|
|
||||||
font-size: 22px;
|
|
||||||
line-height: 30px;
|
|
||||||
text-align: right;
|
|
||||||
|
|
||||||
.fullscreenExitIcon {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,6 +88,10 @@ ol {
|
|||||||
padding: 24px !important;
|
padding: 24px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ant-modal-body {
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
.ant-pro-page-container-children-content {
|
.ant-pro-page-container-children-content {
|
||||||
margin: 12px 12px 0 !important;
|
margin: 12px 12px 0 !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ const ForgetPwdForm: React.FC<RegisterFormProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
width={600}
|
width={600}
|
||||||
bodyStyle={{ padding: '32px 40px 48px' }}
|
styles={{ padding: '32px 40px 48px' }}
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
title="忘记密码"
|
title="忘记密码"
|
||||||
open={createModalVisible}
|
open={createModalVisible}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ const RegisterForm: React.FC<RegisterFormProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
width={600}
|
width={600}
|
||||||
bodyStyle={{ padding: '32px 40px 48px' }}
|
styles={{ padding: '32px 40px 48px' }}
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
title="用户注册"
|
title="用户注册"
|
||||||
open={createModalVisible}
|
open={createModalVisible}
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
// import { Tabs } from 'antd';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'umi';
|
import { connect } from 'umi';
|
||||||
|
|
||||||
// import styles from '../components/style.less';
|
|
||||||
import type { StateType } from '../model';
|
import type { StateType } from '../model';
|
||||||
import ProCard from '@ant-design/pro-card';
|
import ProCard from '@ant-design/pro-card';
|
||||||
import EntitySection from '../components/Entity/EntitySection';
|
import EntitySection from '../components/Entity/EntitySection';
|
||||||
// import RecommendedQuestionsSection from '../components/Entity/RecommendedQuestionsSection';
|
|
||||||
import { ChatConfigType } from '../enum';
|
import { ChatConfigType } from '../enum';
|
||||||
import type { Dispatch } from 'umi';
|
import type { Dispatch } from 'umi';
|
||||||
|
|
||||||
@@ -16,36 +12,12 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ChatSettingSection: React.FC<Props> = () => {
|
const ChatSettingSection: React.FC<Props> = () => {
|
||||||
// const isModelItem = [
|
|
||||||
// {
|
|
||||||
// label: '指标模式',
|
|
||||||
// key: 'metric',
|
|
||||||
// children: <EntitySection chatConfigType={ChatConfigType.AGG} />,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// label: '实体模式',
|
|
||||||
// key: 'dimenstion',
|
|
||||||
// children: <EntitySection chatConfigType={ChatConfigType.DETAIL} />,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// label: '推荐问题',
|
|
||||||
// key: 'recommendedQuestions',
|
|
||||||
// children: <RecommendedQuestionsSection />,
|
|
||||||
// },
|
|
||||||
// ];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ width: 900, margin: '20px auto' }}>
|
<div style={{ width: 900, margin: '20px auto' }}>
|
||||||
{/* <Tabs
|
|
||||||
className={styles.chatSettingSectionTab}
|
|
||||||
items={isModelItem}
|
|
||||||
destroyInactiveTabPane
|
|
||||||
tabPosition="left"
|
|
||||||
/> */}
|
|
||||||
<ProCard bordered title="指标模式" style={{ marginBottom: 20 }}>
|
<ProCard bordered title="指标模式" style={{ marginBottom: 20 }}>
|
||||||
<EntitySection chatConfigType={ChatConfigType.AGG} />
|
<EntitySection chatConfigType={ChatConfigType.AGG} />
|
||||||
</ProCard>
|
</ProCard>
|
||||||
<ProCard bordered title="实体模式" style={{ marginBottom: 20 }}>
|
<ProCard bordered title="标签模式" style={{ marginBottom: 20 }}>
|
||||||
<EntitySection chatConfigType={ChatConfigType.DETAIL} />
|
<EntitySection chatConfigType={ChatConfigType.DETAIL} />
|
||||||
</ProCard>
|
</ProCard>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ const ChatSetting: React.FC<Props> = ({
|
|||||||
children: <EntitySection chatConfigType={ChatConfigType.AGG} />,
|
children: <EntitySection chatConfigType={ChatConfigType.AGG} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '实体模式',
|
label: '标签模式',
|
||||||
key: 'dimenstion',
|
key: 'dimenstion',
|
||||||
children: <EntitySection chatConfigType={ChatConfigType.DETAIL} />,
|
children: <EntitySection chatConfigType={ChatConfigType.DETAIL} />,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { ReactNode, useEffect, useRef, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import { Form, Button, Modal, Steps, message } from 'antd';
|
import { Form, Button, Modal, Steps, message } from 'antd';
|
||||||
import DataSourceBasicForm from './DataSourceBasicForm';
|
import DataSourceBasicForm from './DataSourceBasicForm';
|
||||||
import FieldForm from './DataSourceFieldForm';
|
import DataSourceFieldForm from './DataSourceFieldForm';
|
||||||
import { formLayout } from '@/components/FormHelper/utils';
|
import { formLayout } from '@/components/FormHelper/utils';
|
||||||
import { EnumDataSourceType } from '../constants';
|
import { EnumDataSourceType } from '../constants';
|
||||||
import styles from '../style.less';
|
import styles from '../style.less';
|
||||||
@@ -94,6 +94,8 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
|||||||
name,
|
name,
|
||||||
isCreateMetric: createMetric,
|
isCreateMetric: createMetric,
|
||||||
dateFormat,
|
dateFormat,
|
||||||
|
entityNames,
|
||||||
|
isTag,
|
||||||
} = item;
|
} = item;
|
||||||
const isCreateDimension = createDimension ? 1 : 0;
|
const isCreateDimension = createDimension ? 1 : 0;
|
||||||
const isCreateMetric = createMetric ? 1 : 0;
|
const isCreateMetric = createMetric ? 1 : 0;
|
||||||
@@ -104,6 +106,7 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
|||||||
type,
|
type,
|
||||||
isCreateDimension,
|
isCreateDimension,
|
||||||
name,
|
name,
|
||||||
|
isTag: isTag ? 1 : 0,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case EnumDataSourceType.TIME:
|
case EnumDataSourceType.TIME:
|
||||||
@@ -125,6 +128,7 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
|||||||
bizName,
|
bizName,
|
||||||
name,
|
name,
|
||||||
type,
|
type,
|
||||||
|
entityNames,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case EnumDataSourceType.MEASURES:
|
case EnumDataSourceType.MEASURES:
|
||||||
@@ -325,7 +329,7 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div style={{ display: currentStep === 1 ? 'block' : 'none' }}>
|
<div style={{ display: currentStep === 1 ? 'block' : 'none' }}>
|
||||||
<FieldForm
|
<DataSourceFieldForm
|
||||||
fields={fields}
|
fields={fields}
|
||||||
onFieldChange={handleFieldChange}
|
onFieldChange={handleFieldChange}
|
||||||
onSqlChange={(sql) => {
|
onSqlChange={(sql) => {
|
||||||
@@ -410,7 +414,7 @@ const DataSourceCreateForm: React.FC<CreateFormProps> = ({
|
|||||||
<Modal
|
<Modal
|
||||||
forceRender
|
forceRender
|
||||||
width={1300}
|
width={1300}
|
||||||
styles={{ padding: '32px 40px 48px' }}
|
// styles={{ padding: '32px 40px 48px' }}
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
title={`${isEdit ? '编辑' : '新建'}数据源`}
|
title={`${isEdit ? '编辑' : '新建'}数据源`}
|
||||||
maskClosable={false}
|
maskClosable={false}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Table, Select, Checkbox, Input, Alert, Space, Tooltip, Form } from 'antd';
|
import { Table, Select, Checkbox, Input, Alert, Space, Tooltip, Form, Switch } from 'antd';
|
||||||
import TableTitleTooltips from '../../components/TableTitleTooltips';
|
import TableTitleTooltips from '../../components/TableTitleTooltips';
|
||||||
import { isUndefined } from 'lodash';
|
import { isUndefined } from 'lodash';
|
||||||
import { ExclamationCircleOutlined } from '@ant-design/icons';
|
import { ExclamationCircleOutlined } from '@ant-design/icons';
|
||||||
@@ -22,6 +22,8 @@ type FieldItem = {
|
|||||||
checked?: number;
|
checked?: number;
|
||||||
dateFormat?: string;
|
dateFormat?: string;
|
||||||
timeGranularity?: string;
|
timeGranularity?: string;
|
||||||
|
entityNames?: string[];
|
||||||
|
isTag?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
@@ -42,7 +44,6 @@ const getCreateFieldName = (type: EnumDataSourceType) => {
|
|||||||
? 'isCreateDimension'
|
? 'isCreateDimension'
|
||||||
: 'isCreateMetric';
|
: 'isCreateMetric';
|
||||||
return isCreateName;
|
return isCreateName;
|
||||||
// const editState = !isUndefined(record[isCreateName]) ? !!record[isCreateName] : true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const FieldForm: React.FC<Props> = ({ fields, sql, onFieldChange, onSqlChange }) => {
|
const FieldForm: React.FC<Props> = ({ fields, sql, onFieldChange, onSqlChange }) => {
|
||||||
@@ -117,9 +118,31 @@ const FieldForm: React.FC<Props> = ({ fields, sql, onFieldChange, onSqlChange })
|
|||||||
{
|
{
|
||||||
title: '扩展配置',
|
title: '扩展配置',
|
||||||
dataIndex: 'extender',
|
dataIndex: 'extender',
|
||||||
width: 180,
|
width: 185,
|
||||||
render: (_: any, record: FieldItem) => {
|
render: (_: any, record: FieldItem) => {
|
||||||
const { type } = record;
|
const { type } = record;
|
||||||
|
if (type === EnumDataSourceType.PRIMARY) {
|
||||||
|
const entityNames =
|
||||||
|
fields.find((field) => field.bizName === record.bizName)?.entityNames || [];
|
||||||
|
return (
|
||||||
|
<Space>
|
||||||
|
<Select
|
||||||
|
style={{ minWidth: 345 }}
|
||||||
|
mode="tags"
|
||||||
|
value={entityNames}
|
||||||
|
placeholder="输入实体名称后回车确认,支持英文逗号自动分隔"
|
||||||
|
tokenSeparators={[',']}
|
||||||
|
onChange={(value) => {
|
||||||
|
handleFieldChange(record, 'entityNames', value);
|
||||||
|
}}
|
||||||
|
maxTagCount={9}
|
||||||
|
/>
|
||||||
|
<Tooltip title="主键可以作为一个实体,在此设置一个或多个实体名称">
|
||||||
|
<ExclamationCircleOutlined />
|
||||||
|
</Tooltip>
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
}
|
||||||
if (type === EnumDataSourceType.MEASURES) {
|
if (type === EnumDataSourceType.MEASURES) {
|
||||||
const agg = fields.find((field) => field.bizName === record.bizName)?.agg;
|
const agg = fields.find((field) => field.bizName === record.bizName)?.agg;
|
||||||
return (
|
return (
|
||||||
@@ -140,6 +163,25 @@ const FieldForm: React.FC<Props> = ({ fields, sql, onFieldChange, onSqlChange })
|
|||||||
</Select>
|
</Select>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (type === EnumDataSourceType.CATEGORICAL) {
|
||||||
|
const isTag = fields.find((field) => field.bizName === record.bizName)?.isTag;
|
||||||
|
return (
|
||||||
|
<Space>
|
||||||
|
<span>设为标签</span>
|
||||||
|
<Switch
|
||||||
|
defaultChecked
|
||||||
|
size="small"
|
||||||
|
checked={!!isTag}
|
||||||
|
onChange={(value) => {
|
||||||
|
handleFieldChange(record, 'isTag', value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tooltip title="如果勾选,代表维度的取值都是一种“标签”,可用作对实体的圈选">
|
||||||
|
<ExclamationCircleOutlined />
|
||||||
|
</Tooltip>
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
}
|
||||||
if (type === EnumDataSourceType.TIME) {
|
if (type === EnumDataSourceType.TIME) {
|
||||||
const dateFormat = fields.find((field) => field.bizName === record.bizName)?.dateFormat;
|
const dateFormat = fields.find((field) => field.bizName === record.bizName)?.dateFormat;
|
||||||
const timeGranularity = fields.find(
|
const timeGranularity = fields.find(
|
||||||
@@ -222,7 +264,6 @@ const FieldForm: React.FC<Props> = ({ fields, sql, onFieldChange, onSqlChange })
|
|||||||
[isCreateName]: value,
|
[isCreateName]: value,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// handleFieldChange(record, isCreateName, value);
|
|
||||||
onFieldChange(record.bizName, {
|
onFieldChange(record.bizName, {
|
||||||
...record,
|
...record,
|
||||||
checked: value,
|
checked: value,
|
||||||
@@ -237,7 +278,6 @@ const FieldForm: React.FC<Props> = ({ fields, sql, onFieldChange, onSqlChange })
|
|||||||
disabled={!editState}
|
disabled={!editState}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const value = e.target.value;
|
const value = e.target.value;
|
||||||
// handleFieldChange(record, 'name', value);
|
|
||||||
onFieldChange(record.bizName, {
|
onFieldChange(record.bizName, {
|
||||||
...record,
|
...record,
|
||||||
name: value,
|
name: value,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import DomainListTree from './components/DomainList';
|
|||||||
|
|
||||||
import styles from './components/style.less';
|
import styles from './components/style.less';
|
||||||
import type { StateType } from './model';
|
import type { StateType } from './model';
|
||||||
import { DownOutlined, LeftOutlined } from '@ant-design/icons';
|
import { LeftOutlined, RightOutlined } from '@ant-design/icons';
|
||||||
import { ISemantic } from './data';
|
import { ISemantic } from './data';
|
||||||
import { getDomainList, getModelList } from './service';
|
import { getDomainList, getModelList } from './service';
|
||||||
import ChatSettingTab from './ChatSetting/ChatSettingTab';
|
import ChatSettingTab from './ChatSetting/ChatSettingTab';
|
||||||
@@ -24,17 +24,12 @@ const OverviewContainer: React.FC<Props> = ({ mode, domainManger, dispatch }) =>
|
|||||||
const modelId = params.modelId;
|
const modelId = params.modelId;
|
||||||
|
|
||||||
const menuKey = params.menuKey ? params.menuKey : !Number(modelId) ? 'overview' : '';
|
const menuKey = params.menuKey ? params.menuKey : !Number(modelId) ? 'overview' : '';
|
||||||
const { selectDomainId, selectModelId, selectDomainName, selectModelName, domainList } =
|
const { selectDomainId, selectModelId, domainList } = domainManger;
|
||||||
domainManger;
|
|
||||||
const [modelList, setModelList] = useState<ISemantic.IModelItem[]>([]);
|
const [modelList, setModelList] = useState<ISemantic.IModelItem[]>([]);
|
||||||
const [isModel, setIsModel] = useState<boolean>(false);
|
const [isModel, setIsModel] = useState<boolean>(false);
|
||||||
const [open, setOpen] = useState(false);
|
const [collapsedState, setCollapsedState] = useState(true);
|
||||||
const [activeKey, setActiveKey] = useState<string>(menuKey);
|
const [activeKey, setActiveKey] = useState<string>(menuKey);
|
||||||
|
|
||||||
const handleOpenChange = (newOpen: boolean) => {
|
|
||||||
setOpen(newOpen);
|
|
||||||
};
|
|
||||||
|
|
||||||
const initSelectedDomain = (domainList: ISemantic.IDomainItem[]) => {
|
const initSelectedDomain = (domainList: ISemantic.IDomainItem[]) => {
|
||||||
const targetNode = domainList.filter((item: any) => {
|
const targetNode = domainList.filter((item: any) => {
|
||||||
return `${item.id}` === domainId;
|
return `${item.id}` === domainId;
|
||||||
@@ -198,39 +193,43 @@ const OverviewContainer: React.FC<Props> = ({ mode, domainManger, dispatch }) =>
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleCollapsedBtn = () => {
|
||||||
|
setCollapsedState(!collapsedState);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.projectBody}>
|
<div className={styles.projectBody}>
|
||||||
<Helmet title={'语义模型-超音数'} />
|
<Helmet title={'语义模型-超音数'} />
|
||||||
<div className={styles.projectManger}>
|
<div className={styles.projectManger}>
|
||||||
<div className={styles.sider}>
|
<div className={`${styles.sider} ${!collapsedState ? styles.siderCollapsed : ''}`}>
|
||||||
{/* <div className={styles.domainTitle}>
|
<div className={styles.treeContainer}>
|
||||||
<Space>
|
<DomainListTree
|
||||||
{selectDomainName ? `${selectDomainName}` : '主题域信息'}
|
createDomainBtnVisible={mode === 'domain' ? true : false}
|
||||||
{selectModelName && (
|
onTreeSelected={(domainData) => {
|
||||||
<>
|
const { id, name } = domainData;
|
||||||
<span style={{ position: 'relative' }}> | </span>
|
cleanModelInfo(id);
|
||||||
<span style={{ fontSize: 16, color: '#296DF3' }}>{selectModelName}</span>
|
dispatch({
|
||||||
</>
|
type: 'domainManger/setSelectDomain',
|
||||||
)}
|
selectDomainId: id,
|
||||||
</Space>
|
selectDomainName: name,
|
||||||
</div> */}
|
domainData,
|
||||||
<DomainListTree
|
});
|
||||||
createDomainBtnVisible={mode === 'domain' ? true : false}
|
}}
|
||||||
onTreeSelected={(domainData) => {
|
onTreeDataUpdate={() => {
|
||||||
setOpen(false);
|
initProjectTree();
|
||||||
const { id, name } = domainData;
|
}}
|
||||||
cleanModelInfo(id);
|
/>
|
||||||
dispatch({
|
</div>
|
||||||
type: 'domainManger/setSelectDomain',
|
|
||||||
selectDomainId: id,
|
<div
|
||||||
selectDomainName: name,
|
className={styles.siderCollapsedButton}
|
||||||
domainData,
|
onClick={() => {
|
||||||
});
|
handleCollapsedBtn();
|
||||||
}}
|
}}
|
||||||
onTreeDataUpdate={() => {
|
>
|
||||||
initProjectTree();
|
{collapsedState ? <LeftOutlined /> : <RightOutlined />}
|
||||||
}}
|
</div>
|
||||||
/>
|
{/* <RightOutlined /> */}
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
{selectDomainId ? (
|
{selectDomainId ? (
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ const ClassDataSourceTable: React.FC<Props> = ({ dispatch, domainManger }) => {
|
|||||||
title: '操作',
|
title: '操作',
|
||||||
dataIndex: 'x',
|
dataIndex: 'x',
|
||||||
valueType: 'option',
|
valueType: 'option',
|
||||||
|
width: 100,
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
return (
|
return (
|
||||||
<Space>
|
<Space>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { excuteSql } from '../service';
|
|||||||
import type { StateType } from '../model';
|
import type { StateType } from '../model';
|
||||||
import DataSource from '../Datasource';
|
import DataSource from '../Datasource';
|
||||||
import { IDataSource } from '../data';
|
import { IDataSource } from '../data';
|
||||||
|
import styles from './style.less';
|
||||||
|
|
||||||
const { Meta } = Card;
|
const { Meta } = Card;
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -95,6 +96,7 @@ const ClassDataSourceTypeModal: React.FC<Props> = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Modal
|
<Modal
|
||||||
|
className={styles.classDataSourceTypeModal}
|
||||||
open={createDataSourceModalOpen}
|
open={createDataSourceModalOpen}
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
setCreateDataSourceModalOpen(false);
|
setCreateDataSourceModalOpen(false);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { ActionType, ProColumns } from '@ant-design/pro-table';
|
import type { ActionType, ProColumns } from '@ant-design/pro-table';
|
||||||
import ProTable from '@ant-design/pro-table';
|
import ProTable from '@ant-design/pro-table';
|
||||||
import { message, Button, Space, Popconfirm, Input, Tag, Dropdown } from 'antd';
|
import { message, Button, Space, Popconfirm, Input, Tag, Select } from 'antd';
|
||||||
import React, { useRef, useState, useEffect } from 'react';
|
import React, { useRef, useState, useEffect } from 'react';
|
||||||
import type { Dispatch } from 'umi';
|
import type { Dispatch } from 'umi';
|
||||||
import { connect } from 'umi';
|
import { connect } from 'umi';
|
||||||
@@ -168,6 +168,31 @@ const ClassDimensionTable: React.FC<Props> = ({ domainManger, dispatch }) => {
|
|||||||
width: 80,
|
width: 80,
|
||||||
valueEnum: SENSITIVE_LEVEL_ENUM,
|
valueEnum: SENSITIVE_LEVEL_ENUM,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'isTag',
|
||||||
|
title: '是否为标签',
|
||||||
|
// search: false,
|
||||||
|
renderFormItem: () => (
|
||||||
|
<Select
|
||||||
|
placeholder="请选择标签状态"
|
||||||
|
allowClear
|
||||||
|
options={[
|
||||||
|
{ value: 1, label: '是' },
|
||||||
|
{ value: 0, label: '否' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
render: (isTag) => {
|
||||||
|
switch (isTag) {
|
||||||
|
case 0:
|
||||||
|
return '否';
|
||||||
|
case 1:
|
||||||
|
return <span style={{ color: '#1677ff' }}>是</span>;
|
||||||
|
default:
|
||||||
|
return <Tag color="default">未知</Tag>;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
title: '状态',
|
title: '状态',
|
||||||
@@ -220,6 +245,7 @@ const ClassDimensionTable: React.FC<Props> = ({ domainManger, dispatch }) => {
|
|||||||
title: '操作',
|
title: '操作',
|
||||||
dataIndex: 'x',
|
dataIndex: 'x',
|
||||||
valueType: 'option',
|
valueType: 'option',
|
||||||
|
width: 200,
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
return (
|
return (
|
||||||
<Space className={styles.ctrlBtnContainer}>
|
<Space className={styles.ctrlBtnContainer}>
|
||||||
|
|||||||
@@ -190,6 +190,7 @@ const ClassMetricTable: React.FC<Props> = ({ domainManger, dispatch }) => {
|
|||||||
title: '操作',
|
title: '操作',
|
||||||
dataIndex: 'x',
|
dataIndex: 'x',
|
||||||
valueType: 'option',
|
valueType: 'option',
|
||||||
|
width: 150,
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
return (
|
return (
|
||||||
<Space className={styles.ctrlBtnContainer}>
|
<Space className={styles.ctrlBtnContainer}>
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ const DatabaseTable: React.FC<Props> = ({}) => {
|
|||||||
title: '操作',
|
title: '操作',
|
||||||
dataIndex: 'x',
|
dataIndex: 'x',
|
||||||
valueType: 'option',
|
valueType: 'option',
|
||||||
|
width: 100,
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
if (!record.hasEditPermission) {
|
if (!record.hasEditPermission) {
|
||||||
return <></>;
|
return <></>;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Button, Form, Input, Modal, Select, Row, Col, Space, Tooltip } from 'antd';
|
import { Button, Form, Input, Modal, Select, Row, Col, Space, Tooltip, Switch } from 'antd';
|
||||||
import { SENSITIVE_LEVEL_OPTIONS } from '../constant';
|
import { SENSITIVE_LEVEL_OPTIONS } from '../constant';
|
||||||
import { formLayout } from '@/components/FormHelper/utils';
|
import { formLayout } from '@/components/FormHelper/utils';
|
||||||
import SqlEditor from '@/components/SqlEditor';
|
import SqlEditor from '@/components/SqlEditor';
|
||||||
@@ -7,6 +7,7 @@ import InfoTagList from './InfoTagList';
|
|||||||
import { ISemantic } from '../data';
|
import { ISemantic } from '../data';
|
||||||
import { InfoCircleOutlined } from '@ant-design/icons';
|
import { InfoCircleOutlined } from '@ant-design/icons';
|
||||||
import { createDimension, updateDimension, mockDimensionAlias } from '../service';
|
import { createDimension, updateDimension, mockDimensionAlias } from '../service';
|
||||||
|
import FormItemTitle from '@/components/FormHelper/FormItemTitle';
|
||||||
|
|
||||||
import { message } from 'antd';
|
import { message } from 'antd';
|
||||||
|
|
||||||
@@ -231,6 +232,26 @@ const DimensionInfoModal: React.FC<CreateFormProps> = ({
|
|||||||
<FormItem name="defaultValues" label="默认值">
|
<FormItem name="defaultValues" label="默认值">
|
||||||
<InfoTagList />
|
<InfoTagList />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
<Form.Item
|
||||||
|
label={
|
||||||
|
<FormItemTitle
|
||||||
|
title={`设为标签`}
|
||||||
|
subTitle={`如果勾选,代表维度的取值都是一种'标签',可用作对实体的圈选`}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
name="isTag"
|
||||||
|
valuePropName="checked"
|
||||||
|
getValueFromEvent={(value) => {
|
||||||
|
return value === true ? 1 : 0;
|
||||||
|
}}
|
||||||
|
getValueProps={(value) => {
|
||||||
|
return {
|
||||||
|
checked: value === 1,
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
<FormItem
|
<FormItem
|
||||||
name="description"
|
name="description"
|
||||||
label="维度描述"
|
label="维度描述"
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import { createDomain, updateDomain, deleteDomain } from '../service';
|
|||||||
import { treeParentKeyLists } from '../utils';
|
import { treeParentKeyLists } from '../utils';
|
||||||
import ProjectInfoFormProps from './ProjectInfoForm';
|
import ProjectInfoFormProps from './ProjectInfoForm';
|
||||||
import { constructorClassTreeFromList, addPathInTreeData } from '../utils';
|
import { constructorClassTreeFromList, addPathInTreeData } from '../utils';
|
||||||
import { PlusCircleOutlined } from '@ant-design/icons';
|
|
||||||
|
|
||||||
import styles from './style.less';
|
import styles from './style.less';
|
||||||
import { ISemantic } from '../data';
|
import { ISemantic } from '../data';
|
||||||
@@ -180,19 +179,17 @@ const DomainListTree: FC<DomainListProps> = ({
|
|||||||
return (
|
return (
|
||||||
<div className={styles.domainList}>
|
<div className={styles.domainList}>
|
||||||
<div className={styles.searchContainer}>
|
<div className={styles.searchContainer}>
|
||||||
<Row>
|
<Row style={{ gap: 20 }}>
|
||||||
<Col flex="1 1 auto">
|
<Col flex="1 1 215px">
|
||||||
{/* <Space> */}
|
|
||||||
<Search
|
<Search
|
||||||
allowClear
|
allowClear
|
||||||
className={styles.search}
|
className={styles.search}
|
||||||
placeholder="请输入主题域名称进行查询"
|
placeholder="请输入主题域名称"
|
||||||
onSearch={onSearch}
|
onSearch={onSearch}
|
||||||
/>
|
/>
|
||||||
{/* </Space> */}
|
|
||||||
</Col>
|
</Col>
|
||||||
{createDomainBtnVisible && (
|
{createDomainBtnVisible && (
|
||||||
<Col flex="0 0 40px" style={{ display: 'flex', alignItems: 'center' }}>
|
<Col flex="0 0 45px" style={{ display: 'flex', alignItems: 'center' }}>
|
||||||
<Tooltip title="新增顶级域">
|
<Tooltip title="新增顶级域">
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -205,16 +202,6 @@ const DomainListTree: FC<DomainListProps> = ({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{/* <Tooltip title="新增顶级域">
|
|
||||||
<PlusCircleOutlined
|
|
||||||
onClick={() => {
|
|
||||||
setProjectInfoParams({ type: 'top', modelType: 'add' });
|
|
||||||
setProjectInfoModalVisible(true);
|
|
||||||
onCreateDomainBtnClick?.();
|
|
||||||
}}
|
|
||||||
className={styles.addBtn}
|
|
||||||
/>
|
|
||||||
</Tooltip> */}
|
|
||||||
</Col>
|
</Col>
|
||||||
)}
|
)}
|
||||||
</Row>
|
</Row>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import ClassDataSourceTable from './ClassDataSourceTable';
|
|||||||
import ClassDimensionTable from './ClassDimensionTable';
|
import ClassDimensionTable from './ClassDimensionTable';
|
||||||
import ClassMetricTable from './ClassMetricTable';
|
import ClassMetricTable from './ClassMetricTable';
|
||||||
import PermissionSection from './Permission/PermissionSection';
|
import PermissionSection from './Permission/PermissionSection';
|
||||||
import EntitySettingSection from './Entity/EntitySettingSection';
|
// import EntitySettingSection from './Entity/EntitySettingSection';
|
||||||
import ChatSettingSection from '../ChatSetting/ChatSettingSection';
|
import ChatSettingSection from '../ChatSetting/ChatSettingSection';
|
||||||
import OverView from './OverView';
|
import OverView from './OverView';
|
||||||
import styles from './style.less';
|
import styles from './style.less';
|
||||||
@@ -99,11 +99,11 @@ const DomainManagerTab: React.FC<Props> = ({
|
|||||||
key: 'metric',
|
key: 'metric',
|
||||||
children: <ClassMetricTable />,
|
children: <ClassMetricTable />,
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
label: '实体',
|
// label: '实体',
|
||||||
key: 'entity',
|
// key: 'entity',
|
||||||
children: <EntitySettingSection />,
|
// children: <EntitySettingSection />,
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
label: '权限管理',
|
label: '权限管理',
|
||||||
key: 'permissonSetting',
|
key: 'permissonSetting',
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ const DefaultSettingForm: ForwardRefRenderFunction<any, Props> = (
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
{chatConfigType === ChatConfigType.DETAIL && (
|
{chatConfigType === ChatConfigType.DETAIL && (
|
||||||
<FormItem name="dataItemIds" label="展示维度/指标">
|
<FormItem name="dataItemIds" label="圈选结果展示字段">
|
||||||
<Select
|
<Select
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
allowClear
|
allowClear
|
||||||
@@ -176,63 +176,11 @@ const DefaultSettingForm: ForwardRefRenderFunction<any, Props> = (
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}}
|
}}
|
||||||
placeholder="请选择展示维度/指标信息"
|
placeholder="请选择圈选结果展示字段"
|
||||||
options={dataItemListOptions}
|
options={dataItemListOptions}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
{chatConfigType === ChatConfigType.AGG && (
|
|
||||||
<>
|
|
||||||
{/* <FormItem
|
|
||||||
name="metricIds"
|
|
||||||
label={
|
|
||||||
<FormItemTitle
|
|
||||||
title={'指标'}
|
|
||||||
subTitle={'问答搜索结果选择中,如果没有指定指标,将会采用默认指标进行展示'}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Select
|
|
||||||
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}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem
|
|
||||||
name="ratioMetricIds"
|
|
||||||
label={
|
|
||||||
<FormItemTitle
|
|
||||||
title={'同环比指标'}
|
|
||||||
subTitle={'问答搜索含有指定的指标,将会同时计算该指标最后一天的同环比'}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Select
|
|
||||||
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}
|
|
||||||
/>
|
|
||||||
</FormItem> */}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<FormItem
|
<FormItem
|
||||||
label={
|
label={
|
||||||
<FormItemTitle
|
<FormItemTitle
|
||||||
|
|||||||
@@ -1,19 +1,13 @@
|
|||||||
import { Table, Transfer, Checkbox, Button, Space, message, Tooltip } from 'antd';
|
import { Table, Transfer } from 'antd';
|
||||||
import type { ColumnsType, TableRowSelection } from 'antd/es/table/interface';
|
import type { ColumnsType, TableRowSelection } from 'antd/es/table/interface';
|
||||||
import type { TransferItem } from 'antd/es/transfer';
|
import type { TransferItem } from 'antd/es/transfer';
|
||||||
import type { CheckboxChangeEvent } from 'antd/es/checkbox';
|
|
||||||
import difference from 'lodash/difference';
|
import difference from 'lodash/difference';
|
||||||
import React, { useState, useEffect } from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'umi';
|
import { connect } from 'umi';
|
||||||
import type { StateType } from '../../model';
|
import type { StateType } from '../../model';
|
||||||
import type { IChatConfig } from '../../data';
|
import type { IChatConfig } from '../../data';
|
||||||
import DimensionValueSettingModal from './DimensionValueSettingModal';
|
|
||||||
import TransTypeTag from '../TransTypeTag';
|
import TransTypeTag from '../TransTypeTag';
|
||||||
import TableTitleTooltips from '../../components/TableTitleTooltips';
|
import { SemanticNodeType, TransType } from '../../enum';
|
||||||
import { RedoOutlined } from '@ant-design/icons';
|
|
||||||
import { SemanticNodeType, DictTaskState, TransType } from '../../enum';
|
|
||||||
import { createDictTask, searchDictLatestTaskList } from '@/pages/SemanticModel/service';
|
|
||||||
import styles from '../style.less';
|
|
||||||
interface RecordType {
|
interface RecordType {
|
||||||
id: number;
|
id: number;
|
||||||
key: string;
|
key: string;
|
||||||
@@ -29,105 +23,14 @@ type Props = {
|
|||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
type TaskStateMap = Record<string, DictTaskState>;
|
// type TaskStateMap = Record<string, DictTaskState>;
|
||||||
|
|
||||||
const DimensionMetricVisibleTableTransfer: React.FC<Props> = ({
|
const DimensionMetricVisibleTableTransfer: React.FC<Props> = ({
|
||||||
domainManger,
|
// domainManger,
|
||||||
knowledgeInfosMap,
|
knowledgeInfosMap,
|
||||||
onKnowledgeInfosMapChange,
|
// onKnowledgeInfosMapChange,
|
||||||
...restProps
|
...restProps
|
||||||
}) => {
|
}) => {
|
||||||
// const { selectModelId: modelId } = domainManger;
|
|
||||||
// const [dimensionValueSettingModalVisible, setDimensionValueSettingModalVisible] =
|
|
||||||
// useState<boolean>(false);
|
|
||||||
// const [currentRecord, setCurrentRecord] = useState<RecordType>({} as RecordType);
|
|
||||||
// const [currentDimensionSettingFormData, setCurrentDimensionSettingFormData] =
|
|
||||||
// useState<IChatConfig.IKnowledgeConfig>();
|
|
||||||
|
|
||||||
// const [recordLoadingMap, setRecordLoadingMap] = useState<Record<string, boolean>>({});
|
|
||||||
|
|
||||||
// const [taskStateMap, setTaskStateMap] = useState<TaskStateMap>({});
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// queryDictLatestTaskList();
|
|
||||||
// }, []);
|
|
||||||
|
|
||||||
// const updateKnowledgeInfosMap = (record: RecordType, updateData: Record<string, any>) => {
|
|
||||||
// const { bizName, id } = record;
|
|
||||||
// const knowledgeMap = {
|
|
||||||
// ...knowledgeInfosMap,
|
|
||||||
// };
|
|
||||||
// const target = knowledgeMap[bizName];
|
|
||||||
// if (target) {
|
|
||||||
// knowledgeMap[bizName] = {
|
|
||||||
// ...target,
|
|
||||||
// ...updateData,
|
|
||||||
// };
|
|
||||||
// } else {
|
|
||||||
// knowledgeMap[bizName] = {
|
|
||||||
// itemId: id,
|
|
||||||
// bizName,
|
|
||||||
// ...updateData,
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// onKnowledgeInfosMapChange?.(knowledgeMap);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// const queryDictLatestTaskList = async () => {
|
|
||||||
// const { code, data } = await searchDictLatestTaskList({
|
|
||||||
// modelId,
|
|
||||||
// });
|
|
||||||
// if (code !== 200) {
|
|
||||||
// message.error('获取字典导入任务失败!');
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// const tastMap = data.reduce(
|
|
||||||
// (stateMap: TaskStateMap, item: { dimId: number; status: DictTaskState }) => {
|
|
||||||
// const { dimId, status } = item;
|
|
||||||
// stateMap[dimId] = status;
|
|
||||||
// return stateMap;
|
|
||||||
// },
|
|
||||||
// {},
|
|
||||||
// );
|
|
||||||
// setTaskStateMap(tastMap);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// const createDictTaskQuery = async (recordData: RecordType) => {
|
|
||||||
// setRecordLoadingMap({
|
|
||||||
// ...recordLoadingMap,
|
|
||||||
// [recordData.id]: true,
|
|
||||||
// });
|
|
||||||
// const { code } = await createDictTask({
|
|
||||||
// updateMode: 'REALTIME_ADD',
|
|
||||||
// modelAndDimPair: {
|
|
||||||
// [modelId]: [recordData.id],
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
// setRecordLoadingMap({
|
|
||||||
// ...recordLoadingMap,
|
|
||||||
// [recordData.id]: false,
|
|
||||||
// });
|
|
||||||
// if (code !== 200) {
|
|
||||||
// message.error('字典导入任务创建失败!');
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// setTimeout(() => {
|
|
||||||
// queryDictLatestTaskList();
|
|
||||||
// }, 2000);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// const deleteDictTask = async (recordData: RecordType) => {
|
|
||||||
// const { code } = await createDictTask({
|
|
||||||
// updateMode: 'REALTIME_DELETE',
|
|
||||||
// modelAndDimPair: {
|
|
||||||
// [modelId]: [recordData.id],
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
// if (code !== 200) {
|
|
||||||
// message.error('删除字典导入任务创建失败!');
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
let rightColumns: ColumnsType<RecordType> = [
|
let rightColumns: ColumnsType<RecordType> = [
|
||||||
{
|
{
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
@@ -141,104 +44,6 @@ const DimensionMetricVisibleTableTransfer: React.FC<Props> = ({
|
|||||||
return <TransTypeTag type={type} />;
|
return <TransTypeTag type={type} />;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// dataIndex: 'y',
|
|
||||||
// title: (
|
|
||||||
// <TableTitleTooltips
|
|
||||||
// title="维度值可见"
|
|
||||||
// tooltips="勾选可见后,维度值将在搜索时可以被联想出来"
|
|
||||||
// />
|
|
||||||
// ),
|
|
||||||
// width: 120,
|
|
||||||
// render: (_: any, record: RecordType) => {
|
|
||||||
// const { type, bizName } = record;
|
|
||||||
// return type === TransType.DIMENSION ? (
|
|
||||||
// <Checkbox
|
|
||||||
// checked={knowledgeInfosMap?.[bizName]?.searchEnable}
|
|
||||||
// onChange={(e: CheckboxChangeEvent) => {
|
|
||||||
// updateKnowledgeInfosMap(record, { searchEnable: e.target.checked });
|
|
||||||
// if (!e.target.checked) {
|
|
||||||
// deleteDictTask(record);
|
|
||||||
// }
|
|
||||||
// }}
|
|
||||||
// onClick={(event) => {
|
|
||||||
// event.stopPropagation();
|
|
||||||
// }}
|
|
||||||
// />
|
|
||||||
// ) : (
|
|
||||||
// <></>
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// dataIndex: 'taskState',
|
|
||||||
// width: 130,
|
|
||||||
// title: (
|
|
||||||
// <Space>
|
|
||||||
// 导入字典状态
|
|
||||||
// <span
|
|
||||||
// className={styles.taskStateRefreshIcon}
|
|
||||||
// onClick={() => {
|
|
||||||
// queryDictLatestTaskList();
|
|
||||||
// }}
|
|
||||||
// >
|
|
||||||
// <Tooltip title="刷新字典任务状态">
|
|
||||||
// <RedoOutlined />
|
|
||||||
// </Tooltip>
|
|
||||||
// </span>
|
|
||||||
// </Space>
|
|
||||||
// ),
|
|
||||||
// render: (_, record) => {
|
|
||||||
// const { id, type } = record;
|
|
||||||
// const target = taskStateMap[id];
|
|
||||||
// if (type === TransType.DIMENSION && target) {
|
|
||||||
// return DictTaskState[target] || '未知状态';
|
|
||||||
// }
|
|
||||||
// return '--';
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: '操作',
|
|
||||||
// dataIndex: 'x',
|
|
||||||
// render: (_: any, record: RecordType) => {
|
|
||||||
// const { type, bizName, id } = record;
|
|
||||||
// return type === TransType.DIMENSION ? (
|
|
||||||
// <Space>
|
|
||||||
// <Button
|
|
||||||
// style={{ padding: 0 }}
|
|
||||||
// key="importDictBtn"
|
|
||||||
// type="link"
|
|
||||||
// disabled={!knowledgeInfosMap?.[bizName]?.searchEnable}
|
|
||||||
// loading={!!recordLoadingMap[id]}
|
|
||||||
// onClick={(event) => {
|
|
||||||
// createDictTaskQuery(record);
|
|
||||||
// event.stopPropagation();
|
|
||||||
// }}
|
|
||||||
// >
|
|
||||||
// 导入字典
|
|
||||||
// </Button>
|
|
||||||
// <Button
|
|
||||||
// style={{ padding: 0 }}
|
|
||||||
// key="editable"
|
|
||||||
// type="link"
|
|
||||||
// disabled={!knowledgeInfosMap?.[bizName]?.searchEnable}
|
|
||||||
// onClick={(event) => {
|
|
||||||
// setCurrentRecord(record);
|
|
||||||
// setCurrentDimensionSettingFormData(
|
|
||||||
// knowledgeInfosMap?.[bizName]?.knowledgeAdvancedConfig,
|
|
||||||
// );
|
|
||||||
// setDimensionValueSettingModalVisible(true);
|
|
||||||
// event.stopPropagation();
|
|
||||||
// }}
|
|
||||||
// >
|
|
||||||
// 可见维度值设置
|
|
||||||
// </Button>
|
|
||||||
// </Space>
|
|
||||||
// ) : (
|
|
||||||
// <></>
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const leftColumns: ColumnsType<RecordType> = [
|
const leftColumns: ColumnsType<RecordType> = [
|
||||||
@@ -299,17 +104,6 @@ const DimensionMetricVisibleTableTransfer: React.FC<Props> = ({
|
|||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</Transfer>
|
</Transfer>
|
||||||
{/* <DimensionValueSettingModal
|
|
||||||
visible={dimensionValueSettingModalVisible}
|
|
||||||
initialValues={currentDimensionSettingFormData}
|
|
||||||
onSubmit={(formValues) => {
|
|
||||||
updateKnowledgeInfosMap(currentRecord, { knowledgeAdvancedConfig: formValues });
|
|
||||||
setDimensionValueSettingModalVisible(false);
|
|
||||||
}}
|
|
||||||
onCancel={() => {
|
|
||||||
setDimensionValueSettingModalVisible(false);
|
|
||||||
}}
|
|
||||||
/> */}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ const DimensionValueSettingForm: ForwardRefRenderFunction<any, Props> = (
|
|||||||
className={styles.form}
|
className={styles.form}
|
||||||
>
|
>
|
||||||
<FormItem
|
<FormItem
|
||||||
style={{ marginTop: 15, marginBottom: -30 }}
|
style={{ marginTop: 15 }}
|
||||||
label={
|
label={
|
||||||
<FormItemTitle
|
<FormItemTitle
|
||||||
title={
|
title={
|
||||||
@@ -272,11 +272,11 @@ const DimensionValueSettingForm: ForwardRefRenderFunction<any, Props> = (
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
{dimensionVisible && (
|
{dimensionVisible && (
|
||||||
<>
|
<>
|
||||||
<Divider
|
{/* <Divider
|
||||||
style={{
|
style={{
|
||||||
marginBottom: 35,
|
marginBottom: 35,
|
||||||
}}
|
}}
|
||||||
/>
|
/> */}
|
||||||
<div style={{ padding: 20, border: '1px solid #eee', borderRadius: 10 }}>
|
<div style={{ padding: 20, border: '1px solid #eee', borderRadius: 10 }}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
@@ -1,115 +0,0 @@
|
|||||||
import { useEffect, useState, forwardRef, useImperativeHandle } from 'react';
|
|
||||||
import type { ForwardRefRenderFunction } from 'react';
|
|
||||||
import { message, Form, Input, Select, Button } from 'antd';
|
|
||||||
import { updateModel } from '../../service';
|
|
||||||
import type { ISemantic } from '../../data';
|
|
||||||
import { formLayout } from '@/components/FormHelper/utils';
|
|
||||||
import styles from '../style.less';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
modelData?: ISemantic.IModelItem;
|
|
||||||
dimensionList: ISemantic.IDimensionList;
|
|
||||||
modelId: number;
|
|
||||||
onSubmit: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
|
||||||
|
|
||||||
const EntityCreateForm: ForwardRefRenderFunction<any, Props> = (
|
|
||||||
{ modelData, dimensionList, modelId, onSubmit },
|
|
||||||
ref,
|
|
||||||
) => {
|
|
||||||
const [form] = Form.useForm();
|
|
||||||
const [dimensionListOptions, setDimensionListOptions] = useState<any>([]);
|
|
||||||
const getFormValidateFields = async () => {
|
|
||||||
return await form.validateFields();
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
form.resetFields();
|
|
||||||
if (!modelData?.entity) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { entity } = modelData;
|
|
||||||
form.setFieldsValue({
|
|
||||||
...entity,
|
|
||||||
name: entity.names.join(','),
|
|
||||||
});
|
|
||||||
}, [modelData]);
|
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
|
||||||
getFormValidateFields,
|
|
||||||
}));
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const dimensionEnum = dimensionList.map((item: ISemantic.IDimensionItem) => {
|
|
||||||
return {
|
|
||||||
label: item.name,
|
|
||||||
value: item.id,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
setDimensionListOptions(dimensionEnum);
|
|
||||||
}, [dimensionList]);
|
|
||||||
|
|
||||||
const saveEntity = async () => {
|
|
||||||
const values = await form.validateFields();
|
|
||||||
const { name = '' } = values;
|
|
||||||
const { code, msg, data } = await updateModel({
|
|
||||||
...modelData,
|
|
||||||
entity: {
|
|
||||||
...values,
|
|
||||||
names: name.split(','),
|
|
||||||
},
|
|
||||||
id: modelId,
|
|
||||||
modelId,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (code === 200) {
|
|
||||||
form.setFieldValue('id', data);
|
|
||||||
onSubmit?.();
|
|
||||||
message.success('保存成功');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
message.error(msg);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...formLayout} form={form} layout="vertical" className={styles.form}>
|
|
||||||
<FormItem hidden={true} name="id" label="ID">
|
|
||||||
<Input placeholder="id" />
|
|
||||||
</FormItem>
|
|
||||||
<FormItem name="name" label="实体别名">
|
|
||||||
<Input placeholder="请输入实体别名,多个名称以英文逗号分隔" />
|
|
||||||
</FormItem>
|
|
||||||
<FormItem name="entityId" label="唯一标识">
|
|
||||||
<Select
|
|
||||||
allowClear
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
// filterOption={(inputValue: string, item: any) => {
|
|
||||||
// const { label } = item;
|
|
||||||
// if (label.includes(inputValue)) {
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// return false;
|
|
||||||
// }}
|
|
||||||
placeholder="请选择主体标识"
|
|
||||||
options={dimensionListOptions}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem>
|
|
||||||
<Button
|
|
||||||
type="primary"
|
|
||||||
onClick={() => {
|
|
||||||
saveEntity();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
保 存
|
|
||||||
</Button>
|
|
||||||
</FormItem>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default forwardRef(EntityCreateForm);
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
import { message, Space } from 'antd';
|
|
||||||
import React, { useState, useEffect, useRef } from 'react';
|
|
||||||
import type { Dispatch } from 'umi';
|
|
||||||
import { connect } from 'umi';
|
|
||||||
import type { StateType } from '../../model';
|
|
||||||
import { getModelDetail } from '../../service';
|
|
||||||
import ProCard from '@ant-design/pro-card';
|
|
||||||
import EntityCreateForm from './EntityCreateForm';
|
|
||||||
import type { ISemantic } from '../../data';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
dispatch: Dispatch;
|
|
||||||
domainManger: StateType;
|
|
||||||
};
|
|
||||||
|
|
||||||
const EntitySettingSection: React.FC<Props> = ({ domainManger }) => {
|
|
||||||
const { dimensionList, selectModelId: modelId } = domainManger;
|
|
||||||
|
|
||||||
const [modelData, setModelData] = useState<ISemantic.IModelItem>();
|
|
||||||
|
|
||||||
const entityCreateRef = useRef<any>({});
|
|
||||||
|
|
||||||
const queryDomainData: any = async () => {
|
|
||||||
const { code, data } = await getModelDetail({
|
|
||||||
modelId,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (code === 200) {
|
|
||||||
setModelData(data);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
message.error('获取问答设置信息失败');
|
|
||||||
};
|
|
||||||
|
|
||||||
const initPage = async () => {
|
|
||||||
queryDomainData();
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
initPage();
|
|
||||||
}, [modelId]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ width: 800, margin: '20px auto' }}>
|
|
||||||
<Space direction="vertical" style={{ width: '100%' }} size={20}>
|
|
||||||
{
|
|
||||||
<ProCard title="实体" bordered>
|
|
||||||
<EntityCreateForm
|
|
||||||
ref={entityCreateRef}
|
|
||||||
modelId={Number(modelId)}
|
|
||||||
modelData={modelData}
|
|
||||||
dimensionList={dimensionList}
|
|
||||||
onSubmit={() => {
|
|
||||||
queryDomainData();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</ProCard>
|
|
||||||
}
|
|
||||||
</Space>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
export default connect(({ domainManger }: { domainManger: StateType }) => ({
|
|
||||||
domainManger,
|
|
||||||
}))(EntitySettingSection);
|
|
||||||
@@ -133,6 +133,7 @@ const ModelTable: React.FC<Props> = ({
|
|||||||
title: '操作',
|
title: '操作',
|
||||||
dataIndex: 'x',
|
dataIndex: 'x',
|
||||||
valueType: 'option',
|
valueType: 'option',
|
||||||
|
width: 150,
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
return (
|
return (
|
||||||
<Space className={styles.ctrlBtnContainer}>
|
<Space className={styles.ctrlBtnContainer}>
|
||||||
|
|||||||
@@ -12,9 +12,45 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
.sider {
|
.sider {
|
||||||
flex: 0 0 350px;
|
flex: 0 0 auto;
|
||||||
|
width: 285px;
|
||||||
border-right: 5px solid #eee;
|
border-right: 5px solid #eee;
|
||||||
|
position: relative;
|
||||||
|
transition: all 0.2s,background 0s;
|
||||||
|
.treeContainer {
|
||||||
|
width: 100%;
|
||||||
|
opacity: 1;
|
||||||
|
transition: all 0.2s,background 0s;
|
||||||
|
}
|
||||||
|
&.siderCollapsed {
|
||||||
|
width: 20px;
|
||||||
|
& .treeContainer{
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.siderCollapsedButton {
|
||||||
|
position: absolute;
|
||||||
|
inset-block-start: 17px;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 101;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 40px;
|
||||||
|
inset-inline-end: -13px;
|
||||||
|
transition: transform 0.3s;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
color: rgba(0, 0, 0, 0.25);
|
||||||
|
background-color: #ffffff;
|
||||||
|
box-shadow: 0 2px 8px -2px rgba(0,0,0,0.05), 0 1px 4px -1px rgba(25,15,15,0.07), 0 0 1px 0 rgba(0,0,0,0.08);
|
||||||
|
&:hover {
|
||||||
|
color: rgba(0, 0, 0, 0.75);
|
||||||
|
}
|
||||||
|
}
|
||||||
.domainTitle {
|
.domainTitle {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
@@ -49,8 +85,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.search {
|
.search {
|
||||||
width: calc(100% - 60px);
|
// width: calc(100% - 100px);
|
||||||
margin: 10px 0 10px 35px;
|
width: 100%;
|
||||||
|
margin: 10px 0 10px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tree {
|
.tree {
|
||||||
@@ -190,6 +227,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
.searchContainer {
|
.searchContainer {
|
||||||
|
width: 280px;
|
||||||
padding:3px 0;
|
padding:3px 0;
|
||||||
border-bottom: 1px solid #eee;
|
border-bottom: 1px solid #eee;
|
||||||
}
|
}
|
||||||
@@ -327,7 +365,8 @@
|
|||||||
|
|
||||||
.breadcrumb{
|
.breadcrumb{
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
margin: 20px 0 0 20px;
|
margin: 17px 0 0 20px;
|
||||||
|
padding-bottom: 3px;
|
||||||
:global {
|
:global {
|
||||||
.ant-breadcrumb-link {
|
.ant-breadcrumb-link {
|
||||||
height: 28px;
|
height: 28px;
|
||||||
@@ -336,4 +375,12 @@
|
|||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.classDataSourceTypeModal {
|
||||||
|
:global {
|
||||||
|
.ant-modal-body{
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -30,6 +30,11 @@ export const SENSITIVE_LEVEL_ENUM = SENSITIVE_LEVEL_OPTIONS.reduce(
|
|||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const IS_TAG_ENUM = {
|
||||||
|
1: '是',
|
||||||
|
0: '否',
|
||||||
|
};
|
||||||
|
|
||||||
export const SENSITIVE_LEVEL_COLOR = {
|
export const SENSITIVE_LEVEL_COLOR = {
|
||||||
[SENSITIVE_LEVEL.LOW]: 'lime',
|
[SENSITIVE_LEVEL.LOW]: 'lime',
|
||||||
[SENSITIVE_LEVEL.MID]: 'warning',
|
[SENSITIVE_LEVEL.MID]: 'warning',
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import { getSystemConfig, saveSystemConfig } from '@/services/user';
|
|||||||
import ProCard from '@ant-design/pro-card';
|
import ProCard from '@ant-design/pro-card';
|
||||||
import SelectTMEPerson from '@/components/SelectTMEPerson';
|
import SelectTMEPerson from '@/components/SelectTMEPerson';
|
||||||
import { SystemConfigParametersItem, SystemConfig } from './types';
|
import { SystemConfigParametersItem, SystemConfig } from './types';
|
||||||
|
import FormItemTitle from '@/components/FormHelper/FormItemTitle';
|
||||||
import { groupBy } from 'lodash';
|
import { groupBy } from 'lodash';
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
@@ -30,6 +31,7 @@ const System: React.FC = () => {
|
|||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
const [configSource, setConfigSource] = useState<SystemConfig>();
|
const [configSource, setConfigSource] = useState<SystemConfig>();
|
||||||
|
const [paramDescMap, setParamDescMap] = useState<Record<string, string>>({});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
querySystemConfig();
|
querySystemConfig();
|
||||||
@@ -37,8 +39,8 @@ const System: React.FC = () => {
|
|||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const querySystemConfig = async () => {
|
const querySystemConfig = async () => {
|
||||||
const { code, data, msg } = await getSystemConfig();
|
const { code, data, msg } = await getSystemConfig();
|
||||||
if (code === 200) {
|
if (code === 200 && data) {
|
||||||
const { parameters, admins } = data;
|
const { parameters = [], admins = [] } = data;
|
||||||
const groupByConfig = groupBy(parameters, 'module');
|
const groupByConfig = groupBy(parameters, 'module');
|
||||||
const anchor = Object.keys(groupByConfig).map((key: string) => {
|
const anchor = Object.keys(groupByConfig).map((key: string) => {
|
||||||
return {
|
return {
|
||||||
@@ -50,12 +52,24 @@ const System: React.FC = () => {
|
|||||||
setAnchorItems(anchor);
|
setAnchorItems(anchor);
|
||||||
setSystemConfig(groupByConfig);
|
setSystemConfig(groupByConfig);
|
||||||
setInitData(admins, parameters);
|
setInitData(admins, parameters);
|
||||||
|
initDescMap(parameters);
|
||||||
setConfigSource(data);
|
setConfigSource(data);
|
||||||
} else {
|
} else {
|
||||||
message.error(msg);
|
message.error(msg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const initDescMap = (systemConfigParameters: SystemConfigParametersItem[]) => {
|
||||||
|
const descData = systemConfigParameters.reduce(
|
||||||
|
(descMap: Record<string, string>, item: SystemConfigParametersItem) => {
|
||||||
|
descMap[item.name] = item.description;
|
||||||
|
return descMap;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
setParamDescMap(descData);
|
||||||
|
};
|
||||||
|
|
||||||
const setInitData = (admins: string[], systemConfigParameters: SystemConfigParametersItem[]) => {
|
const setInitData = (admins: string[], systemConfigParameters: SystemConfigParametersItem[]) => {
|
||||||
const fieldsValue = systemConfigParameters.reduce(
|
const fieldsValue = systemConfigParameters.reduce(
|
||||||
(fields, item) => {
|
(fields, item) => {
|
||||||
@@ -81,6 +95,7 @@ const System: React.FC = () => {
|
|||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
value: submitData[name],
|
value: submitData[name],
|
||||||
|
description: paramDescMap[name],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
@@ -158,7 +173,7 @@ const System: React.FC = () => {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
);
|
);
|
||||||
case 'list': {
|
case 'list': {
|
||||||
const { candidateValues } = item;
|
const { candidateValues = [] } = item;
|
||||||
const options = candidateValues.map((value) => {
|
const options = candidateValues.map((value) => {
|
||||||
return { label: value, value };
|
return { label: value, value };
|
||||||
});
|
});
|
||||||
@@ -170,7 +185,23 @@ const System: React.FC = () => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<FormItem name={name} label={comment} key={name}>
|
<FormItem
|
||||||
|
name={name}
|
||||||
|
key={name}
|
||||||
|
label={
|
||||||
|
<FormItemTitle
|
||||||
|
title={comment}
|
||||||
|
subTitle={paramDescMap[name]}
|
||||||
|
// subTitleEditable={true}
|
||||||
|
onSubTitleChange={(title) => {
|
||||||
|
setParamDescMap({
|
||||||
|
...paramDescMap,
|
||||||
|
[name]: title,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
{defaultItem}
|
{defaultItem}
|
||||||
</FormItem>
|
</FormItem>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ export type SystemConfigParametersItem = {
|
|||||||
comment: string;
|
comment: string;
|
||||||
value: string;
|
value: string;
|
||||||
candidateValues: string[];
|
candidateValues: string[];
|
||||||
|
description: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SystemConfig = {
|
export type SystemConfig = {
|
||||||
|
|||||||
Reference in New Issue
Block a user