[improvement] Enhanced date button, added shortcut TAB (#1387)

This commit is contained in:
open
2024-07-10 14:04:50 +08:00
committed by GitHub
parent 8ef5ce8b76
commit 62e70f5cb7
3 changed files with 16179 additions and 12951 deletions

View File

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

View File

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

File diff suppressed because it is too large Load Diff