feat: #345 even if the backend data returns empty, the skeleton of the chart will be displayed. (#461)

… chart will be displayed.

### What problem does this PR solve?

feat: #345 even if the backend data returns empty, the skeleton of the
chart will be displayed.

### Type of change

- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2024-04-19 19:05:30 +08:00
committed by GitHub
parent 7da3f88e54
commit c055f40dff
8 changed files with 45 additions and 31 deletions

View File

@ -50,9 +50,10 @@ const data = [
interface IProps extends CategoricalChartProps { interface IProps extends CategoricalChartProps {
data?: Array<{ xAxis: string; yAxis: number }>; data?: Array<{ xAxis: string; yAxis: number }>;
showLegend?: boolean;
} }
const RagLineChart = ({ data }: IProps) => { const RagLineChart = ({ data, showLegend = false }: IProps) => {
return ( return (
<ResponsiveContainer width="100%" height="100%"> <ResponsiveContainer width="100%" height="100%">
<LineChart <LineChart
@ -72,7 +73,7 @@ const RagLineChart = ({ data }: IProps) => {
<XAxis dataKey="xAxis" /> <XAxis dataKey="xAxis" />
<YAxis /> <YAxis />
<Tooltip /> <Tooltip />
<Legend /> {showLegend && <Legend />}
<Line <Line
type="monotone" type="monotone"
dataKey="yAxis" dataKey="yAxis"

View File

@ -349,19 +349,18 @@ export default {
'This sets the maximum length of the models output, measured in the number of tokens (words or pieces of words).', 'This sets the maximum length of the models output, measured in the number of tokens (words or pieces of words).',
quote: 'Show Quote', quote: 'Show Quote',
quoteTip: 'Should the source of the original text be displayed?', quoteTip: 'Should the source of the original text be displayed?',
overview: 'API', overview: 'Chat Bot API',
pv: 'Number of messages', pv: 'Number of messages',
uv: 'Active user number', uv: 'Active user number',
speed: 'Token output speed', speed: 'Token output speed',
tokens: 'Consume the token number', tokens: 'Consume the token number',
round: 'Session Interaction Number', round: 'Session Interaction Number',
thumbUp: 'customer satisfaction', thumbUp: 'customer satisfaction',
publicUrl: 'Public URL',
preview: 'Preview', preview: 'Preview',
embedded: 'Embedded', embedded: 'Embedded',
serviceApiEndpoint: 'Service API Endpoint', serviceApiEndpoint: 'Service API Endpoint',
apiKey: 'Api Key', apiKey: 'Api Key',
apiReference: 'Api Reference', apiReference: 'API Documents',
dateRange: 'Date Range:', dateRange: 'Date Range:',
backendServiceApi: 'Backend service API', backendServiceApi: 'Backend service API',
createNewKey: 'Create new key', createNewKey: 'Create new key',

View File

@ -321,21 +321,20 @@ export default {
'這設置了模型輸出的最大長度,以標記(單詞或單詞片段)的數量來衡量。', '這設置了模型輸出的最大長度,以標記(單詞或單詞片段)的數量來衡量。',
quote: '顯示引文', quote: '顯示引文',
quoteTip: '是否應該顯示原文出處?', quoteTip: '是否應該顯示原文出處?',
overview: 'API', overview: '聊天 API',
pv: '消息數', pv: '消息數',
uv: '活躍用戶數', uv: '活躍用戶數',
speed: 'Token 輸出速度', speed: 'Token 輸出速度',
tokens: '消耗Token數', tokens: '消耗Token數',
round: '會話互動數', round: '會話互動數',
thumbUp: '用戶滿意度', thumbUp: '用戶滿意度',
publicUrl: '公共url',
preview: '預覽', preview: '預覽',
embedded: '嵌入', embedded: '嵌入',
serviceApiEndpoint: '服務API端點', serviceApiEndpoint: '服務 API 端點',
apiKey: 'API鍵', apiKey: 'API 鍵',
apiReference: 'API參考', apiReference: 'API 文件',
dateRange: '日期範圍:', dateRange: '日期範圍:',
backendServiceApi: '後端服務API', backendServiceApi: '後端服務 API',
createNewKey: '創建新密鑰', createNewKey: '創建新密鑰',
created: '創建於', created: '創建於',
action: '操作', action: '操作',

View File

@ -338,21 +338,20 @@ export default {
'这设置了模型输出的最大长度,以标记(单词或单词片段)的数量来衡量。', '这设置了模型输出的最大长度,以标记(单词或单词片段)的数量来衡量。',
quote: '显示引文', quote: '显示引文',
quoteTip: '是否应该显示原文出处?', quoteTip: '是否应该显示原文出处?',
overview: 'API', overview: '聊天 API',
pv: '消息数', pv: '消息数',
uv: '活跃用户数', uv: '活跃用户数',
speed: 'Token 输出速度', speed: 'Token 输出速度',
tokens: '消耗Token数', tokens: '消耗Token数',
round: '会话互动数', round: '会话互动数',
thumbUp: '用户满意度', thumbUp: '用户满意度',
publicUrl: '公共Url',
preview: '预览', preview: '预览',
embedded: '嵌入', embedded: '嵌入',
serviceApiEndpoint: '服务API端点', serviceApiEndpoint: '服务API端点',
apiKey: 'API键', apiKey: 'API 键',
apiReference: 'API参考', apiReference: 'API 文档',
dateRange: '日期范围:', dateRange: '日期范围:',
backendServiceApi: '后端服务API', backendServiceApi: '后端服务 API',
createNewKey: '创建新密钥', createNewKey: '创建新密钥',
created: '创建于', created: '创建于',
action: '操作', action: '操作',

View File

@ -50,7 +50,9 @@ const ChatApiKeyModal = ({
title={t('apiKey')} title={t('apiKey')}
open={visible} open={visible}
onCancel={hideModal} onCancel={hideModal}
cancelButtonProps={{ style: { display: 'none' } }}
style={{ top: 300 }} style={{ top: 300 }}
onOk={hideModal}
width={'50vw'} width={'50vw'}
> >
<Table <Table

View File

@ -5,7 +5,7 @@
.chartItem { .chartItem {
height: 300px; height: 300px;
padding: 10px 0 30px; padding: 10px 0 50px;
} }
.chartLabel { .chartLabel {

View File

@ -2,6 +2,7 @@ import LineChart from '@/components/line-chart';
import { useSetModalState, useTranslate } from '@/hooks/commonHooks'; import { useSetModalState, useTranslate } from '@/hooks/commonHooks';
import { IModalProps } from '@/interfaces/common'; import { IModalProps } from '@/interfaces/common';
import { IDialog, IStats } from '@/interfaces/database/chat'; import { IDialog, IStats } from '@/interfaces/database/chat';
import { formatDate } from '@/utils/date';
import { Button, Card, DatePicker, Flex, Modal, Space, Typography } from 'antd'; import { Button, Card, DatePicker, Flex, Modal, Space, Typography } from 'antd';
import { RangePickerProps } from 'antd/es/date-picker'; import { RangePickerProps } from 'antd/es/date-picker';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
@ -19,13 +20,29 @@ import styles from './index.less';
const { Paragraph } = Typography; const { Paragraph } = Typography;
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
const StatsLineChart = ({ statsType }: { statsType: keyof IStats }) => {
const { t } = useTranslate('chat');
const chartList = useSelectChartStatsList();
const list =
chartList[statsType]?.map((x) => ({
...x,
xAxis: formatDate(x.xAxis),
})) ?? [];
return (
<div className={styles.chartItem}>
<b className={styles.chartLabel}>{t(camelCase(statsType))}</b>
<LineChart data={list}></LineChart>
</div>
);
};
const ChatOverviewModal = ({ const ChatOverviewModal = ({
visible, visible,
hideModal, hideModal,
dialog, dialog,
}: IModalProps<any> & { dialog: IDialog }) => { }: IModalProps<any> & { dialog: IDialog }) => {
const { t } = useTranslate('chat'); const { t } = useTranslate('chat');
const chartList = useSelectChartStatsList();
const { const {
visible: apiKeyVisible, visible: apiKeyVisible,
hideModal: hideApiKeyModal, hideModal: hideApiKeyModal,
@ -53,6 +70,8 @@ const ChatOverviewModal = ({
title={t('overview')} title={t('overview')}
open={visible} open={visible}
onCancel={hideModal} onCancel={hideModal}
cancelButtonProps={{ style: { display: 'none' } }}
onOk={hideModal}
width={'100vw'} width={'100vw'}
> >
<Flex vertical gap={'middle'}> <Flex vertical gap={'middle'}>
@ -76,14 +95,8 @@ const ChatOverviewModal = ({
</a> </a>
</Space> </Space>
</Card> </Card>
<Card title={dialog.name}> <Card title={`${dialog.name} Web App`}>
<Flex gap={8} vertical> <Flex gap={8} vertical>
{t('publicUrl')}
{/* <Flex className={styles.linkText} gap={10}>
<span>{urlWithToken}</span>
<CopyToClipboard text={urlWithToken}></CopyToClipboard>
<ReloadOutlined onClick={createUrlToken} />
</Flex> */}
<Space size={'middle'}> <Space size={'middle'}>
<Button onClick={handlePreview}>{t('preview')}</Button> <Button onClick={handlePreview}>{t('preview')}</Button>
<Button onClick={showEmbedModal}>{t('embedded')}</Button> <Button onClick={showEmbedModal}>{t('embedded')}</Button>
@ -101,12 +114,12 @@ const ChatOverviewModal = ({
/> />
</Space> </Space>
<div className={styles.chartWrapper}> <div className={styles.chartWrapper}>
{Object.keys(chartList).map((x) => ( <StatsLineChart statsType={'pv'}></StatsLineChart>
<div key={x} className={styles.chartItem}> <StatsLineChart statsType={'round'}></StatsLineChart>
<b className={styles.chartLabel}>{t(camelCase(x))}</b> <StatsLineChart statsType={'speed'}></StatsLineChart>
<LineChart data={chartList[x as keyof IStats]}></LineChart> <StatsLineChart statsType={'thumb_up'}></StatsLineChart>
</div> <StatsLineChart statsType={'tokens'}></StatsLineChart>
))} <StatsLineChart statsType={'uv'}></StatsLineChart>
</div> </div>
</Flex> </Flex>
<ChatApiKeyModal <ChatApiKeyModal

View File

@ -210,6 +210,7 @@ const model: DvaModel<ChatModelState> = {
omit(payload, ['dialogId']), omit(payload, ['dialogId']),
); );
if (data.retcode === 0) { if (data.retcode === 0) {
message.success(i18n.t('message.deleted'));
yield put({ yield put({
type: 'listToken', type: 'listToken',
payload: { dialog_id: payload.dialogId }, payload: { dialog_id: payload.dialogId },