Integrate Chat and Copilot into chat-sdk, and add SQL parse display (#166)

This commit is contained in:
williamhliu
2023-10-02 18:05:12 +08:00
committed by GitHub
parent 741ed4191b
commit 71cb20eb4f
68 changed files with 1353 additions and 882 deletions

View File

@@ -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;