mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-15 06:27:21 +00:00
Integrate Chat and Copilot into chat-sdk, and add SQL parse display (#166)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import { AGG_TYPE_MAP, PREFIX_CLS } from '../../common/constants';
|
||||
import { ChatContextType, FilterItemType } from '../../common/type';
|
||||
import { CheckCircleFilled, InfoCircleOutlined } from '@ant-design/icons';
|
||||
import { CheckCircleFilled } from '@ant-design/icons';
|
||||
import classNames from 'classnames';
|
||||
import SwicthEntity from './SwitchEntity';
|
||||
import Loading from './Loading';
|
||||
@@ -30,7 +30,7 @@ const ParseTip: React.FC<Props> = ({
|
||||
}) => {
|
||||
const prefixCls = `${PREFIX_CLS}-item`;
|
||||
|
||||
const getNode = (tipTitle: string, tipNode?: ReactNode, parseSucceed?: boolean) => {
|
||||
const getNode = (tipTitle: ReactNode, tipNode?: ReactNode, parseSucceed?: boolean) => {
|
||||
const contentContainerClass = classNames(`${prefixCls}-content-container`, {
|
||||
[`${prefixCls}-content-container-succeed`]: parseSucceed,
|
||||
});
|
||||
@@ -62,7 +62,6 @@ const ParseTip: React.FC<Props> = ({
|
||||
|
||||
const getTipNode = (parseInfo: ChatContextType, isOptions?: boolean, index?: number) => {
|
||||
const {
|
||||
modelId,
|
||||
modelName,
|
||||
dateInfo,
|
||||
dimensionFilters,
|
||||
@@ -76,8 +75,6 @@ const ParseTip: React.FC<Props> = ({
|
||||
nativeQuery,
|
||||
} = parseInfo || {};
|
||||
|
||||
const maxOptionCount = queryMode === 'DSL' ? 10 : MAX_OPTION_VALUES_COUNT;
|
||||
|
||||
const { startDate, endDate } = dateInfo || {};
|
||||
const dimensionItems = dimensions?.filter(item => item.type === 'DIMENSION');
|
||||
const metric = metrics?.[0];
|
||||
@@ -92,44 +89,6 @@ const ParseTip: React.FC<Props> = ({
|
||||
const fields =
|
||||
queryMode === 'ENTITY_DETAIL' ? dimensionItems?.concat(metrics || []) : dimensionItems;
|
||||
|
||||
const getFilterContent = (filters: any) => {
|
||||
return (
|
||||
<div className={`${prefixCls}-tip-item-filter-content`}>
|
||||
{filters.map((filter: any) => (
|
||||
<div className={`${prefixCls}-tip-item-option`}>
|
||||
<span>
|
||||
<span className={`${prefixCls}-tip-item-filter-name`}>{filter.name}</span>
|
||||
{filter.operator !== '=' && filter.operator !== 'IN'
|
||||
? ` ${filter.operator} `
|
||||
: ':'}
|
||||
</span>
|
||||
{queryMode !== 'DSL' && !filter.bizName?.includes('_id') ? (
|
||||
<FilterItem
|
||||
modelId={modelId}
|
||||
filters={dimensionFilters}
|
||||
filter={filter}
|
||||
onFiltersChange={onFiltersChange}
|
||||
/>
|
||||
) : (
|
||||
<span className={itemValueClass}>{filter.value}</span>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const getFiltersNode = () => {
|
||||
return (
|
||||
<div className={`${prefixCls}-tip-item`}>
|
||||
<div className={`${prefixCls}-tip-item-name`}>筛选条件:</div>
|
||||
<div className={`${prefixCls}-tip-item-content`}>
|
||||
{getFilterContent(dimensionFilters)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`${prefixCls}-tip-content`}
|
||||
@@ -147,7 +106,7 @@ const ParseTip: React.FC<Props> = ({
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{(queryMode.includes('ENTITY') || queryMode === 'DSL') &&
|
||||
{(queryMode?.includes('ENTITY') || queryMode === 'DSL') &&
|
||||
typeof entityId === 'string' &&
|
||||
!!entityAlias &&
|
||||
!!entityName ? (
|
||||
@@ -165,11 +124,11 @@ const ParseTip: React.FC<Props> = ({
|
||||
</div>
|
||||
) : (
|
||||
<div className={`${prefixCls}-tip-item`}>
|
||||
<div className={`${prefixCls}-tip-item-name`}>数据模型:</div>
|
||||
<div className={`${prefixCls}-tip-item-name`}>数据来源:</div>
|
||||
<div className={itemValueClass}>{modelName}</div>
|
||||
</div>
|
||||
)}
|
||||
{!queryMode.includes('ENTITY') && metric && (
|
||||
{!queryMode?.includes('ENTITY') && metric && (
|
||||
<div className={`${prefixCls}-tip-item`}>
|
||||
<div className={`${prefixCls}-tip-item-name`}>指标:</div>
|
||||
<div className={itemValueClass}>{metric.name}</div>
|
||||
@@ -199,24 +158,21 @@ const ParseTip: React.FC<Props> = ({
|
||||
</div>
|
||||
<div className={itemValueClass}>
|
||||
{fields
|
||||
.slice(0, maxOptionCount)
|
||||
.slice(0, MAX_OPTION_VALUES_COUNT)
|
||||
.map(field => field.name)
|
||||
.join('、')}
|
||||
{fields.length > maxOptionCount && '...'}
|
||||
{fields.length > MAX_OPTION_VALUES_COUNT && '...'}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{[
|
||||
'METRIC_FILTER',
|
||||
'METRIC_ENTITY',
|
||||
'ENTITY_DETAIL',
|
||||
'ENTITY_LIST_FILTER',
|
||||
'ENTITY_ID',
|
||||
'DSL',
|
||||
].includes(queryMode) &&
|
||||
dimensionFilters &&
|
||||
dimensionFilters?.length > 0 &&
|
||||
getFiltersNode()}
|
||||
{queryMode !== 'ENTITY_ID' &&
|
||||
entityDimensions?.length > 0 &&
|
||||
entityDimensions.map(dimension => (
|
||||
<div className={`${prefixCls}-tip-item`} key={dimension.itemId}>
|
||||
<div className={`${prefixCls}-tip-item-name`}>{dimension.name}:</div>
|
||||
<div className={itemValueClass}>{dimension.value}</div>
|
||||
</div>
|
||||
))}
|
||||
{queryMode === 'METRIC_ORDERBY' && aggType && aggType !== 'NONE' && (
|
||||
<div className={`${prefixCls}-tip-item`}>
|
||||
<div className={`${prefixCls}-tip-item-name`}>聚合方式:</div>
|
||||
@@ -230,7 +186,8 @@ const ParseTip: React.FC<Props> = ({
|
||||
};
|
||||
|
||||
const parseInfo = parseInfoOptions[0] || {};
|
||||
const { properties, entity, entityInfo, elementMatches, queryMode } = parseInfo || {};
|
||||
const { modelId, properties, entity, entityInfo, elementMatches, queryMode, dimensionFilters } =
|
||||
parseInfo || {};
|
||||
|
||||
const { type } = properties || {};
|
||||
const entityAlias = entity?.alias?.[0]?.split('.')?.[0];
|
||||
@@ -249,31 +206,71 @@ const ParseTip: React.FC<Props> = ({
|
||||
)
|
||||
);
|
||||
|
||||
const getFilterContent = (filters: any) => {
|
||||
const itemValueClass = `${prefixCls}-tip-item-value`;
|
||||
return (
|
||||
<div className={`${prefixCls}-tip-item-filter-content`}>
|
||||
{filters.map((filter: any) => (
|
||||
<div className={`${prefixCls}-tip-item-option`} key={filter.name}>
|
||||
<span>
|
||||
<span className={`${prefixCls}-tip-item-filter-name`}>{filter.name}</span>
|
||||
{filter.operator !== '=' && filter.operator !== 'IN' ? ` ${filter.operator} ` : ':'}
|
||||
</span>
|
||||
{/* {queryMode !== 'DSL' && !filter.bizName?.includes('_id') ? ( */}
|
||||
{!filter.bizName?.includes('_id') ? (
|
||||
<FilterItem
|
||||
modelId={modelId}
|
||||
filters={dimensionFilters}
|
||||
filter={filter}
|
||||
onFiltersChange={onFiltersChange}
|
||||
/>
|
||||
) : (
|
||||
<span className={itemValueClass}>{filter.value}</span>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const getFiltersNode = () => {
|
||||
return (
|
||||
<div className={`${prefixCls}-tip-item`}>
|
||||
<div className={`${prefixCls}-tip-item-name`}>筛选条件:</div>
|
||||
<div className={`${prefixCls}-tip-item-content`}>{getFilterContent(dimensionFilters)}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const tipNode = (
|
||||
<div className={`${prefixCls}-tip`}>
|
||||
{getTipNode(parseInfo)}
|
||||
{queryMode !== 'ENTITY_ID' && entityDimensions?.length > 0 && (
|
||||
<div className={`${prefixCls}-entity-info`}>
|
||||
{entityDimensions.map(dimension => (
|
||||
<div className={`${prefixCls}-dimension-item`} key={dimension.itemId}>
|
||||
<div className={`${prefixCls}-dimension-name`}>{dimension.name}:</div>
|
||||
<div className={`${prefixCls}-dimension-value`}>{dimension.value}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{(!type || queryMode === 'DSL') && entityAlias && entityName && (
|
||||
<div className={`${prefixCls}-switch-entity-tip`}>
|
||||
<InfoCircleOutlined />
|
||||
<div>
|
||||
如果未匹配到您查询的{entityAlias},可点击上面的{entityAlias}名切换
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{[
|
||||
'METRIC_FILTER',
|
||||
'METRIC_ENTITY',
|
||||
'ENTITY_DETAIL',
|
||||
'ENTITY_LIST_FILTER',
|
||||
'ENTITY_ID',
|
||||
'DSL',
|
||||
].includes(queryMode) &&
|
||||
dimensionFilters &&
|
||||
dimensionFilters?.length > 0 &&
|
||||
getFiltersNode()}
|
||||
</div>
|
||||
);
|
||||
|
||||
return getNode('意图解析结果', tipNode, true);
|
||||
return getNode(
|
||||
<div className={`${prefixCls}-title-bar`}>
|
||||
意图解析
|
||||
{(!type || queryMode === 'DSL') && entityAlias && entityAlias !== '厂牌' && entityName && (
|
||||
<div className={`${prefixCls}-switch-entity-tip`}>
|
||||
(如果未匹配到您查询的{entityAlias},可点击{entityAlias}名切换)
|
||||
</div>
|
||||
)}
|
||||
</div>,
|
||||
tipNode,
|
||||
true
|
||||
);
|
||||
};
|
||||
|
||||
export default ParseTip;
|
||||
|
||||
Reference in New Issue
Block a user