mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-10 19:51:00 +00:00
[improvement] Enhanced date button, added shortcut TAB (#1387)
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import { AGG_TYPE_MAP, PREFIX_CLS } from '../../common/constants';
|
||||
import { ChatContextType, DateInfoType, EntityInfoType, FilterItemType } from '../../common/type';
|
||||
import { Button, DatePicker } from 'antd';
|
||||
import { Button, DatePicker, Row, Col } from 'antd';
|
||||
import { CheckCircleFilled, ReloadOutlined } from '@ant-design/icons';
|
||||
import Loading from './Loading';
|
||||
import FilterItem from './FilterItem';
|
||||
import MarkDown from '../ChatMsg/MarkDown';
|
||||
import classNames from 'classnames';
|
||||
import { isMobile } from '../../utils/utils';
|
||||
import dayjs from 'dayjs';
|
||||
import dayjs, { Dayjs } from 'dayjs';
|
||||
import quarterOfYear from 'dayjs/plugin/quarterOfYear';
|
||||
dayjs.extend(quarterOfYear);
|
||||
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
@@ -30,10 +32,16 @@ type Props = {
|
||||
onFiltersChange: (filters: FilterItemType[]) => void;
|
||||
onDateInfoChange: (dateRange: any) => void;
|
||||
onRefresh: () => void;
|
||||
handlePresetClick: any;
|
||||
};
|
||||
|
||||
const MAX_OPTION_VALUES_COUNT = 2;
|
||||
|
||||
|
||||
type RangeValue = [Dayjs, Dayjs];
|
||||
type RangeKeys = '近7日' | '近14日' | '近30日' | '本周' | '本月' | '上月' | '本季度' | '本年';
|
||||
|
||||
|
||||
const ParseTip: React.FC<Props> = ({
|
||||
parseLoading,
|
||||
parseInfoOptions,
|
||||
@@ -52,7 +60,18 @@ const ParseTip: React.FC<Props> = ({
|
||||
onFiltersChange,
|
||||
onDateInfoChange,
|
||||
onRefresh,
|
||||
handlePresetClick
|
||||
}) => {
|
||||
const ranges: Record<RangeKeys, RangeValue> = {
|
||||
'近7日': [dayjs().subtract(7, 'day'), dayjs()],
|
||||
'近14日': [dayjs().subtract(14, 'day'), dayjs()],
|
||||
'近30日': [dayjs().subtract(30, 'day'), dayjs()],
|
||||
'本周': [dayjs().startOf('week'), dayjs().endOf('week')],
|
||||
'本月': [dayjs().startOf('month'), dayjs().endOf('month')],
|
||||
'上月': [dayjs().subtract(1, 'month').startOf('month'), dayjs().subtract(1, 'month').endOf('month')],
|
||||
'本季度': [dayjs().startOf('quarter'), dayjs().endOf('quarter')], // 使用 quarterOfYear 插件
|
||||
'本年': [dayjs().startOf('year'), dayjs().endOf('year')],
|
||||
};
|
||||
const prefixCls = `${PREFIX_CLS}-item`;
|
||||
const getNode = (tipTitle: ReactNode, tipNode?: ReactNode) => {
|
||||
return (
|
||||
@@ -66,9 +85,8 @@ const ParseTip: React.FC<Props> = ({
|
||||
</div>
|
||||
{(tipNode || tipNode === null) && (
|
||||
<div
|
||||
className={`${prefixCls}-content-container ${
|
||||
tipNode === null ? `${prefixCls}-empty-content-container` : ''
|
||||
}`}
|
||||
className={`${prefixCls}-content-container ${tipNode === null ? `${prefixCls}-empty-content-container` : ''
|
||||
}`}
|
||||
>
|
||||
{tipNode}
|
||||
</div>
|
||||
@@ -149,9 +167,9 @@ const ParseTip: React.FC<Props> = ({
|
||||
) : (
|
||||
<>
|
||||
{(queryMode?.includes('ENTITY') || queryMode === 'LLM_S2SQL') &&
|
||||
typeof entityId === 'string' &&
|
||||
!!entityAlias &&
|
||||
!!entityName ? (
|
||||
typeof entityId === 'string' &&
|
||||
!!entityAlias &&
|
||||
!!entityName ? (
|
||||
<div className={`${prefixCls}-tip-item`}>
|
||||
<div className={`${prefixCls}-tip-item-name`}>{entityAlias}:</div>
|
||||
<div className={itemValueClass}>{entityName}</div>
|
||||
@@ -241,9 +259,30 @@ const ParseTip: React.FC<Props> = ({
|
||||
<RangePicker
|
||||
value={[dayjs(startDate), dayjs(endDate)]}
|
||||
onChange={onDateInfoChange}
|
||||
getPopupContainer={trigger => trigger.parentNode as HTMLElement}
|
||||
allowClear={false}
|
||||
format="YYYY/MM/DD"
|
||||
renderExtraFooter={() => (
|
||||
<Row gutter={[28, 28]}>
|
||||
{Object.keys(ranges).map((key) => (
|
||||
<Col key={key}>
|
||||
<label
|
||||
style={{
|
||||
backgroundColor: '#F0FDFF',
|
||||
borderColor: '#33BDFC',
|
||||
color: '#33BDFC',
|
||||
borderWidth: 1,
|
||||
borderStyle: 'solid',
|
||||
cursor: 'pointer'
|
||||
}}
|
||||
onClick={() => handlePresetClick(ranges[key as RangeKeys])}>
|
||||
{key}
|
||||
</label>
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
)}
|
||||
/>
|
||||
|
||||
|
||||
)}
|
||||
</div>
|
||||
{filters?.map((filter: any, index: number) => (
|
||||
@@ -304,9 +343,8 @@ const ParseTip: React.FC<Props> = ({
|
||||
<div className={`${prefixCls}-content-options`}>
|
||||
{parseInfoOptions.map((parseInfo, index) => (
|
||||
<div
|
||||
className={`${prefixCls}-content-option ${
|
||||
parseInfo.id === currentParseInfo?.id ? `${prefixCls}-content-option-active` : ''
|
||||
}`}
|
||||
className={`${prefixCls}-content-option ${parseInfo.id === currentParseInfo?.id ? `${prefixCls}-content-option-active` : ''
|
||||
}`}
|
||||
onClick={() => {
|
||||
onSelectParseInfo(parseInfo);
|
||||
}}
|
||||
|
||||
@@ -19,8 +19,7 @@ import classNames from 'classnames';
|
||||
import Tools from '../Tools';
|
||||
import SqlItem from './SqlItem';
|
||||
import SimilarQuestionItem from './SimilarQuestionItem';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import dayjs, { Dayjs } from 'dayjs';
|
||||
type Props = {
|
||||
msg: string;
|
||||
conversationId?: number;
|
||||
@@ -235,16 +234,37 @@ const ChatItem: React.FC<Props> = ({
|
||||
setDimensionFilters(dimensionFilters);
|
||||
};
|
||||
|
||||
const onDateInfoChange = (dateRange: any) => {
|
||||
type RangeValue = [Dayjs, Dayjs];
|
||||
const [selectedRange, setSelectedRange] = useState<RangeValue | null>(null);
|
||||
|
||||
const onDateInfoChange = (dates: [Dayjs | null, Dayjs | null] | null) => {
|
||||
if (dates && dates[0] && dates[1]) {
|
||||
const [start, end] = dates;
|
||||
setSelectedRange([start, end] as RangeValue);
|
||||
setDateInfo({
|
||||
...(dateInfo || {}),
|
||||
startDate: dayjs(start).format('YYYY-MM-DD'),
|
||||
endDate: dayjs(end).format('YYYY-MM-DD'),
|
||||
dateMode: 'BETWEEN',
|
||||
unit: 0,
|
||||
});
|
||||
} else {
|
||||
setSelectedRange(null);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePresetClick = (range: RangeValue) => {
|
||||
setSelectedRange(range);
|
||||
setDateInfo({
|
||||
...(dateInfo || {}),
|
||||
startDate: dayjs(dateRange[0]).format('YYYY-MM-DD'),
|
||||
endDate: dayjs(dateRange[1]).format('YYYY-MM-DD'),
|
||||
startDate: dayjs(range[0]).format('YYYY-MM-DD'),
|
||||
endDate: dayjs(range[1]).format('YYYY-MM-DD'),
|
||||
dateMode: 'BETWEEN',
|
||||
unit: 0,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const onRefresh = async () => {
|
||||
setEntitySwitchLoading(true);
|
||||
const { dimensions, metrics, id, queryId } = parseInfo || {};
|
||||
@@ -341,6 +361,7 @@ const ChatItem: React.FC<Props> = ({
|
||||
onFiltersChange={onFiltersChange}
|
||||
onDateInfoChange={onDateInfoChange}
|
||||
onRefresh={onRefresh}
|
||||
handlePresetClick={handlePresetClick}
|
||||
/>
|
||||
{executeMode && (
|
||||
<>
|
||||
|
||||
29035
webapp/pnpm-lock.yaml
generated
29035
webapp/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user