balibabu
commited on
Commit
·
7651eb4
1
Parent(s):
a5eac11
feat: #345 even if the backend data returns empty, the skeleton of the chart will be displayed. (#461)
Browse files… 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)
- web/src/components/line-chart/index.tsx +3 -2
- web/src/locales/en.ts +2 -3
- web/src/locales/zh-traditional.ts +5 -6
- web/src/locales/zh.ts +4 -5
- web/src/pages/chat/chat-api-key-modal/index.tsx +2 -0
- web/src/pages/chat/chat-overview-modal/index.less +1 -1
- web/src/pages/chat/chat-overview-modal/index.tsx +27 -14
- web/src/pages/chat/model.ts +1 -0
web/src/components/line-chart/index.tsx
CHANGED
@@ -50,9 +50,10 @@ const data = [
|
|
50 |
|
51 |
interface IProps extends CategoricalChartProps {
|
52 |
data?: Array<{ xAxis: string; yAxis: number }>;
|
|
|
53 |
}
|
54 |
|
55 |
-
const RagLineChart = ({ data }: IProps) => {
|
56 |
return (
|
57 |
<ResponsiveContainer width="100%" height="100%">
|
58 |
<LineChart
|
@@ -72,7 +73,7 @@ const RagLineChart = ({ data }: IProps) => {
|
|
72 |
<XAxis dataKey="xAxis" />
|
73 |
<YAxis />
|
74 |
<Tooltip />
|
75 |
-
<Legend />
|
76 |
<Line
|
77 |
type="monotone"
|
78 |
dataKey="yAxis"
|
|
|
50 |
|
51 |
interface IProps extends CategoricalChartProps {
|
52 |
data?: Array<{ xAxis: string; yAxis: number }>;
|
53 |
+
showLegend?: boolean;
|
54 |
}
|
55 |
|
56 |
+
const RagLineChart = ({ data, showLegend = false }: IProps) => {
|
57 |
return (
|
58 |
<ResponsiveContainer width="100%" height="100%">
|
59 |
<LineChart
|
|
|
73 |
<XAxis dataKey="xAxis" />
|
74 |
<YAxis />
|
75 |
<Tooltip />
|
76 |
+
{showLegend && <Legend />}
|
77 |
<Line
|
78 |
type="monotone"
|
79 |
dataKey="yAxis"
|
web/src/locales/en.ts
CHANGED
@@ -349,19 +349,18 @@ export default {
|
|
349 |
'This sets the maximum length of the model’s output, measured in the number of tokens (words or pieces of words).',
|
350 |
quote: 'Show Quote',
|
351 |
quoteTip: 'Should the source of the original text be displayed?',
|
352 |
-
overview: 'API',
|
353 |
pv: 'Number of messages',
|
354 |
uv: 'Active user number',
|
355 |
speed: 'Token output speed',
|
356 |
tokens: 'Consume the token number',
|
357 |
round: 'Session Interaction Number',
|
358 |
thumbUp: 'customer satisfaction',
|
359 |
-
publicUrl: 'Public URL',
|
360 |
preview: 'Preview',
|
361 |
embedded: 'Embedded',
|
362 |
serviceApiEndpoint: 'Service API Endpoint',
|
363 |
apiKey: 'Api Key',
|
364 |
-
apiReference: '
|
365 |
dateRange: 'Date Range:',
|
366 |
backendServiceApi: 'Backend service API',
|
367 |
createNewKey: 'Create new key',
|
|
|
349 |
'This sets the maximum length of the model’s output, measured in the number of tokens (words or pieces of words).',
|
350 |
quote: 'Show Quote',
|
351 |
quoteTip: 'Should the source of the original text be displayed?',
|
352 |
+
overview: 'Chat Bot API',
|
353 |
pv: 'Number of messages',
|
354 |
uv: 'Active user number',
|
355 |
speed: 'Token output speed',
|
356 |
tokens: 'Consume the token number',
|
357 |
round: 'Session Interaction Number',
|
358 |
thumbUp: 'customer satisfaction',
|
|
|
359 |
preview: 'Preview',
|
360 |
embedded: 'Embedded',
|
361 |
serviceApiEndpoint: 'Service API Endpoint',
|
362 |
apiKey: 'Api Key',
|
363 |
+
apiReference: 'API Documents',
|
364 |
dateRange: 'Date Range:',
|
365 |
backendServiceApi: 'Backend service API',
|
366 |
createNewKey: 'Create new key',
|
web/src/locales/zh-traditional.ts
CHANGED
@@ -321,21 +321,20 @@ export default {
|
|
321 |
'這設置了模型輸出的最大長度,以標記(單詞或單詞片段)的數量來衡量。',
|
322 |
quote: '顯示引文',
|
323 |
quoteTip: '是否應該顯示原文出處?',
|
324 |
-
overview: 'API',
|
325 |
pv: '消息數',
|
326 |
uv: '活躍用戶數',
|
327 |
speed: 'Token 輸出速度',
|
328 |
tokens: '消耗Token數',
|
329 |
round: '會話互動數',
|
330 |
thumbUp: '用戶滿意度',
|
331 |
-
publicUrl: '公共url',
|
332 |
preview: '預覽',
|
333 |
embedded: '嵌入',
|
334 |
-
serviceApiEndpoint: '服務API端點',
|
335 |
-
apiKey: 'API鍵',
|
336 |
-
apiReference: 'API
|
337 |
dateRange: '日期範圍:',
|
338 |
-
backendServiceApi: '後端服務API',
|
339 |
createNewKey: '創建新密鑰',
|
340 |
created: '創建於',
|
341 |
action: '操作',
|
|
|
321 |
'這設置了模型輸出的最大長度,以標記(單詞或單詞片段)的數量來衡量。',
|
322 |
quote: '顯示引文',
|
323 |
quoteTip: '是否應該顯示原文出處?',
|
324 |
+
overview: '聊天 API',
|
325 |
pv: '消息數',
|
326 |
uv: '活躍用戶數',
|
327 |
speed: 'Token 輸出速度',
|
328 |
tokens: '消耗Token數',
|
329 |
round: '會話互動數',
|
330 |
thumbUp: '用戶滿意度',
|
|
|
331 |
preview: '預覽',
|
332 |
embedded: '嵌入',
|
333 |
+
serviceApiEndpoint: '服務 API 端點',
|
334 |
+
apiKey: 'API 鍵',
|
335 |
+
apiReference: 'API 文件',
|
336 |
dateRange: '日期範圍:',
|
337 |
+
backendServiceApi: '後端服務 API',
|
338 |
createNewKey: '創建新密鑰',
|
339 |
created: '創建於',
|
340 |
action: '操作',
|
web/src/locales/zh.ts
CHANGED
@@ -338,21 +338,20 @@ export default {
|
|
338 |
'这设置了模型输出的最大长度,以标记(单词或单词片段)的数量来衡量。',
|
339 |
quote: '显示引文',
|
340 |
quoteTip: '是否应该显示原文出处?',
|
341 |
-
overview: 'API',
|
342 |
pv: '消息数',
|
343 |
uv: '活跃用户数',
|
344 |
speed: 'Token 输出速度',
|
345 |
tokens: '消耗Token数',
|
346 |
round: '会话互动数',
|
347 |
thumbUp: '用户满意度',
|
348 |
-
publicUrl: '公共Url',
|
349 |
preview: '预览',
|
350 |
embedded: '嵌入',
|
351 |
serviceApiEndpoint: '服务API端点',
|
352 |
-
apiKey: 'API键',
|
353 |
-
apiReference: 'API
|
354 |
dateRange: '日期范围:',
|
355 |
-
backendServiceApi: '后端服务API',
|
356 |
createNewKey: '创建新密钥',
|
357 |
created: '创建于',
|
358 |
action: '操作',
|
|
|
338 |
'这设置了模型输出的最大长度,以标记(单词或单词片段)的数量来衡量。',
|
339 |
quote: '显示引文',
|
340 |
quoteTip: '是否应该显示原文出处?',
|
341 |
+
overview: '聊天 API',
|
342 |
pv: '消息数',
|
343 |
uv: '活跃用户数',
|
344 |
speed: 'Token 输出速度',
|
345 |
tokens: '消耗Token数',
|
346 |
round: '会话互动数',
|
347 |
thumbUp: '用户满意度',
|
|
|
348 |
preview: '预览',
|
349 |
embedded: '嵌入',
|
350 |
serviceApiEndpoint: '服务API端点',
|
351 |
+
apiKey: 'API 键',
|
352 |
+
apiReference: 'API 文档',
|
353 |
dateRange: '日期范围:',
|
354 |
+
backendServiceApi: '后端服务 API',
|
355 |
createNewKey: '创建新密钥',
|
356 |
created: '创建于',
|
357 |
action: '操作',
|
web/src/pages/chat/chat-api-key-modal/index.tsx
CHANGED
@@ -50,7 +50,9 @@ const ChatApiKeyModal = ({
|
|
50 |
title={t('apiKey')}
|
51 |
open={visible}
|
52 |
onCancel={hideModal}
|
|
|
53 |
style={{ top: 300 }}
|
|
|
54 |
width={'50vw'}
|
55 |
>
|
56 |
<Table
|
|
|
50 |
title={t('apiKey')}
|
51 |
open={visible}
|
52 |
onCancel={hideModal}
|
53 |
+
cancelButtonProps={{ style: { display: 'none' } }}
|
54 |
style={{ top: 300 }}
|
55 |
+
onOk={hideModal}
|
56 |
width={'50vw'}
|
57 |
>
|
58 |
<Table
|
web/src/pages/chat/chat-overview-modal/index.less
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
|
6 |
.chartItem {
|
7 |
height: 300px;
|
8 |
-
padding: 10px 0
|
9 |
}
|
10 |
|
11 |
.chartLabel {
|
|
|
5 |
|
6 |
.chartItem {
|
7 |
height: 300px;
|
8 |
+
padding: 10px 0 50px;
|
9 |
}
|
10 |
|
11 |
.chartLabel {
|
web/src/pages/chat/chat-overview-modal/index.tsx
CHANGED
@@ -2,6 +2,7 @@ import LineChart from '@/components/line-chart';
|
|
2 |
import { useSetModalState, useTranslate } from '@/hooks/commonHooks';
|
3 |
import { IModalProps } from '@/interfaces/common';
|
4 |
import { IDialog, IStats } from '@/interfaces/database/chat';
|
|
|
5 |
import { Button, Card, DatePicker, Flex, Modal, Space, Typography } from 'antd';
|
6 |
import { RangePickerProps } from 'antd/es/date-picker';
|
7 |
import dayjs from 'dayjs';
|
@@ -19,13 +20,29 @@ import styles from './index.less';
|
|
19 |
const { Paragraph } = Typography;
|
20 |
const { RangePicker } = DatePicker;
|
21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
const ChatOverviewModal = ({
|
23 |
visible,
|
24 |
hideModal,
|
25 |
dialog,
|
26 |
}: IModalProps<any> & { dialog: IDialog }) => {
|
27 |
const { t } = useTranslate('chat');
|
28 |
-
const chartList = useSelectChartStatsList();
|
29 |
const {
|
30 |
visible: apiKeyVisible,
|
31 |
hideModal: hideApiKeyModal,
|
@@ -53,6 +70,8 @@ const ChatOverviewModal = ({
|
|
53 |
title={t('overview')}
|
54 |
open={visible}
|
55 |
onCancel={hideModal}
|
|
|
|
|
56 |
width={'100vw'}
|
57 |
>
|
58 |
<Flex vertical gap={'middle'}>
|
@@ -76,14 +95,8 @@ const ChatOverviewModal = ({
|
|
76 |
</a>
|
77 |
</Space>
|
78 |
</Card>
|
79 |
-
<Card title={dialog.name}>
|
80 |
<Flex gap={8} vertical>
|
81 |
-
{t('publicUrl')}
|
82 |
-
{/* <Flex className={styles.linkText} gap={10}>
|
83 |
-
<span>{urlWithToken}</span>
|
84 |
-
<CopyToClipboard text={urlWithToken}></CopyToClipboard>
|
85 |
-
<ReloadOutlined onClick={createUrlToken} />
|
86 |
-
</Flex> */}
|
87 |
<Space size={'middle'}>
|
88 |
<Button onClick={handlePreview}>{t('preview')}</Button>
|
89 |
<Button onClick={showEmbedModal}>{t('embedded')}</Button>
|
@@ -101,12 +114,12 @@ const ChatOverviewModal = ({
|
|
101 |
/>
|
102 |
</Space>
|
103 |
<div className={styles.chartWrapper}>
|
104 |
-
{
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
</div>
|
111 |
</Flex>
|
112 |
<ChatApiKeyModal
|
|
|
2 |
import { useSetModalState, useTranslate } from '@/hooks/commonHooks';
|
3 |
import { IModalProps } from '@/interfaces/common';
|
4 |
import { IDialog, IStats } from '@/interfaces/database/chat';
|
5 |
+
import { formatDate } from '@/utils/date';
|
6 |
import { Button, Card, DatePicker, Flex, Modal, Space, Typography } from 'antd';
|
7 |
import { RangePickerProps } from 'antd/es/date-picker';
|
8 |
import dayjs from 'dayjs';
|
|
|
20 |
const { Paragraph } = Typography;
|
21 |
const { RangePicker } = DatePicker;
|
22 |
|
23 |
+
const StatsLineChart = ({ statsType }: { statsType: keyof IStats }) => {
|
24 |
+
const { t } = useTranslate('chat');
|
25 |
+
const chartList = useSelectChartStatsList();
|
26 |
+
const list =
|
27 |
+
chartList[statsType]?.map((x) => ({
|
28 |
+
...x,
|
29 |
+
xAxis: formatDate(x.xAxis),
|
30 |
+
})) ?? [];
|
31 |
+
|
32 |
+
return (
|
33 |
+
<div className={styles.chartItem}>
|
34 |
+
<b className={styles.chartLabel}>{t(camelCase(statsType))}</b>
|
35 |
+
<LineChart data={list}></LineChart>
|
36 |
+
</div>
|
37 |
+
);
|
38 |
+
};
|
39 |
+
|
40 |
const ChatOverviewModal = ({
|
41 |
visible,
|
42 |
hideModal,
|
43 |
dialog,
|
44 |
}: IModalProps<any> & { dialog: IDialog }) => {
|
45 |
const { t } = useTranslate('chat');
|
|
|
46 |
const {
|
47 |
visible: apiKeyVisible,
|
48 |
hideModal: hideApiKeyModal,
|
|
|
70 |
title={t('overview')}
|
71 |
open={visible}
|
72 |
onCancel={hideModal}
|
73 |
+
cancelButtonProps={{ style: { display: 'none' } }}
|
74 |
+
onOk={hideModal}
|
75 |
width={'100vw'}
|
76 |
>
|
77 |
<Flex vertical gap={'middle'}>
|
|
|
95 |
</a>
|
96 |
</Space>
|
97 |
</Card>
|
98 |
+
<Card title={`${dialog.name} Web App`}>
|
99 |
<Flex gap={8} vertical>
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
<Space size={'middle'}>
|
101 |
<Button onClick={handlePreview}>{t('preview')}</Button>
|
102 |
<Button onClick={showEmbedModal}>{t('embedded')}</Button>
|
|
|
114 |
/>
|
115 |
</Space>
|
116 |
<div className={styles.chartWrapper}>
|
117 |
+
<StatsLineChart statsType={'pv'}></StatsLineChart>
|
118 |
+
<StatsLineChart statsType={'round'}></StatsLineChart>
|
119 |
+
<StatsLineChart statsType={'speed'}></StatsLineChart>
|
120 |
+
<StatsLineChart statsType={'thumb_up'}></StatsLineChart>
|
121 |
+
<StatsLineChart statsType={'tokens'}></StatsLineChart>
|
122 |
+
<StatsLineChart statsType={'uv'}></StatsLineChart>
|
123 |
</div>
|
124 |
</Flex>
|
125 |
<ChatApiKeyModal
|
web/src/pages/chat/model.ts
CHANGED
@@ -210,6 +210,7 @@ const model: DvaModel<ChatModelState> = {
|
|
210 |
omit(payload, ['dialogId']),
|
211 |
);
|
212 |
if (data.retcode === 0) {
|
|
|
213 |
yield put({
|
214 |
type: 'listToken',
|
215 |
payload: { dialog_id: payload.dialogId },
|
|
|
210 |
omit(payload, ['dialogId']),
|
211 |
);
|
212 |
if (data.retcode === 0) {
|
213 |
+
message.success(i18n.t('message.deleted'));
|
214 |
yield put({
|
215 |
type: 'listToken',
|
216 |
payload: { dialog_id: payload.dialogId },
|