balibabu
commited on
Commit
·
f30b544
1
Parent(s):
ef0f1be
feat: display chunk token number when category of knowledge as general and unavailable llm models appear disabled and if the backend returns 401, it will jump to the login page and fixed the issue where the greeting would disappear when clicking on a new dialog (#117)
Browse files* feat: Fixed the issue where the greeting would disappear when clicking on a new dialog
* feat: replace favicon with logo.svg
* feat: if the backend returns 401, it will jump to the login page.
* feat: unavailable llm models appear disabled
* feat: display chunk token number when category of knowledge as general
- web/.umirc.ts +1 -0
- web/public/logo.svg +29 -0
- web/src/hooks/llmHooks.ts +1 -0
- web/src/pages/add-knowledge/components/knowledge-setting/configuration.tsx +48 -0
- web/src/pages/add-knowledge/components/knowledge-setting/index.less +3 -0
- web/src/pages/chat/chat-configuration-modal/index.tsx +24 -26
- web/src/pages/chat/chat-configuration-modal/model-setting.tsx +1 -1
- web/src/pages/chat/hooks.ts +80 -19
- web/src/pages/chat/index.tsx +20 -10
- web/src/pages/chat/model.ts +8 -3
- web/src/utils/history.ts +0 -3
- web/src/utils/request.ts +4 -7
web/.umirc.ts
CHANGED
@@ -11,6 +11,7 @@ export default defineConfig({
|
|
11 |
esbuildMinifyIIFE: true,
|
12 |
icons: {},
|
13 |
hash: true,
|
|
|
14 |
history: {
|
15 |
type: 'browser',
|
16 |
},
|
|
|
11 |
esbuildMinifyIIFE: true,
|
12 |
icons: {},
|
13 |
hash: true,
|
14 |
+
favicons: ['/logo.svg'],
|
15 |
history: {
|
16 |
type: 'browser',
|
17 |
},
|
web/public/logo.svg
ADDED
|
web/src/hooks/llmHooks.ts
CHANGED
@@ -30,6 +30,7 @@ export const useSelectLlmOptions = () => {
|
|
30 |
options: value.map((x) => ({
|
31 |
label: x.llm_name,
|
32 |
value: x.llm_name,
|
|
|
33 |
})),
|
34 |
};
|
35 |
});
|
|
|
30 |
options: value.map((x) => ({
|
31 |
label: x.llm_name,
|
32 |
value: x.llm_name,
|
33 |
+
disabled: !x.available,
|
34 |
})),
|
35 |
};
|
36 |
});
|
web/src/pages/add-knowledge/components/knowledge-setting/configuration.tsx
CHANGED
@@ -10,10 +10,13 @@ import {
|
|
10 |
import {
|
11 |
Button,
|
12 |
Divider,
|
|
|
13 |
Form,
|
14 |
Input,
|
|
|
15 |
Radio,
|
16 |
Select,
|
|
|
17 |
Space,
|
18 |
Typography,
|
19 |
Upload,
|
@@ -80,6 +83,7 @@ const Configuration = () => {
|
|
80 |
'permission',
|
81 |
'embd_id',
|
82 |
'parser_id',
|
|
|
83 |
]),
|
84 |
avatar: fileList,
|
85 |
});
|
@@ -144,6 +148,7 @@ const Configuration = () => {
|
|
144 |
name="embd_id"
|
145 |
label="Embedding Model"
|
146 |
rules={[{ required: true }]}
|
|
|
147 |
>
|
148 |
<Select
|
149 |
placeholder="Please select a country"
|
@@ -153,6 +158,7 @@ const Configuration = () => {
|
|
153 |
<Form.Item
|
154 |
name="parser_id"
|
155 |
label="Knowledge base category"
|
|
|
156 |
rules={[{ required: true }]}
|
157 |
>
|
158 |
<Select placeholder="Please select a country">
|
@@ -163,6 +169,48 @@ const Configuration = () => {
|
|
163 |
))}
|
164 |
</Select>
|
165 |
</Form.Item>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
<Form.Item>
|
167 |
<div className={styles.buttonWrapper}>
|
168 |
<Space>
|
|
|
10 |
import {
|
11 |
Button,
|
12 |
Divider,
|
13 |
+
Flex,
|
14 |
Form,
|
15 |
Input,
|
16 |
+
InputNumber,
|
17 |
Radio,
|
18 |
Select,
|
19 |
+
Slider,
|
20 |
Space,
|
21 |
Typography,
|
22 |
Upload,
|
|
|
83 |
'permission',
|
84 |
'embd_id',
|
85 |
'parser_id',
|
86 |
+
'parser_config.chunk_token_num',
|
87 |
]),
|
88 |
avatar: fileList,
|
89 |
});
|
|
|
148 |
name="embd_id"
|
149 |
label="Embedding Model"
|
150 |
rules={[{ required: true }]}
|
151 |
+
tooltip="xx"
|
152 |
>
|
153 |
<Select
|
154 |
placeholder="Please select a country"
|
|
|
158 |
<Form.Item
|
159 |
name="parser_id"
|
160 |
label="Knowledge base category"
|
161 |
+
tooltip="xx"
|
162 |
rules={[{ required: true }]}
|
163 |
>
|
164 |
<Select placeholder="Please select a country">
|
|
|
169 |
))}
|
170 |
</Select>
|
171 |
</Form.Item>
|
172 |
+
<Form.Item noStyle dependencies={['parser_id']}>
|
173 |
+
{({ getFieldValue }) => {
|
174 |
+
const parserId = getFieldValue('parser_id');
|
175 |
+
|
176 |
+
if (parserId === 'general') {
|
177 |
+
return (
|
178 |
+
<Form.Item label="Chunk token number" tooltip="xxx">
|
179 |
+
<Flex gap={20} align="center">
|
180 |
+
<Flex flex={1}>
|
181 |
+
<Form.Item
|
182 |
+
name={['parser_config', 'chunk_token_num']}
|
183 |
+
noStyle
|
184 |
+
initialValue={128}
|
185 |
+
rules={[
|
186 |
+
{ required: true, message: 'Province is required' },
|
187 |
+
]}
|
188 |
+
>
|
189 |
+
<Slider className={styles.variableSlider} max={2048} />
|
190 |
+
</Form.Item>
|
191 |
+
</Flex>
|
192 |
+
<Form.Item
|
193 |
+
name={['parser_config', 'chunk_token_num']}
|
194 |
+
noStyle
|
195 |
+
initialValue={128}
|
196 |
+
rules={[
|
197 |
+
{ required: true, message: 'Street is required' },
|
198 |
+
]}
|
199 |
+
>
|
200 |
+
<InputNumber
|
201 |
+
className={styles.sliderInputNumber}
|
202 |
+
max={2048}
|
203 |
+
min={0}
|
204 |
+
/>
|
205 |
+
</Form.Item>
|
206 |
+
</Flex>
|
207 |
+
</Form.Item>
|
208 |
+
);
|
209 |
+
}
|
210 |
+
|
211 |
+
return null;
|
212 |
+
}}
|
213 |
+
</Form.Item>
|
214 |
<Form.Item>
|
215 |
<div className={styles.buttonWrapper}>
|
216 |
<Space>
|
web/src/pages/add-knowledge/components/knowledge-setting/index.less
CHANGED
@@ -27,4 +27,7 @@
|
|
27 |
.buttonWrapper {
|
28 |
text-align: right;
|
29 |
}
|
|
|
|
|
|
|
30 |
}
|
|
|
27 |
.buttonWrapper {
|
28 |
text-align: right;
|
29 |
}
|
30 |
+
.variableSlider {
|
31 |
+
width: 100%;
|
32 |
+
}
|
33 |
}
|
web/src/pages/chat/chat-configuration-modal/index.tsx
CHANGED
@@ -1,19 +1,18 @@
|
|
1 |
import { ReactComponent as ChatConfigurationAtom } from '@/assets/svg/chat-configuration-atom.svg';
|
2 |
import { IModalManagerChildrenProps } from '@/components/modal-manager';
|
|
|
3 |
import { Divider, Flex, Form, Modal, Segmented, UploadFile } from 'antd';
|
4 |
import { SegmentedValue } from 'antd/es/segmented';
|
5 |
import omit from 'lodash/omit';
|
6 |
import { useEffect, useRef, useState } from 'react';
|
7 |
-
import AssistantSetting from './assistant-setting';
|
8 |
-
import ModelSetting from './model-setting';
|
9 |
-
import PromptEngine from './prompt-engine';
|
10 |
-
|
11 |
-
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
12 |
import { variableEnabledFieldMap } from '../constants';
|
13 |
-
import { useFetchDialog, useResetCurrentDialog, useSetDialog } from '../hooks';
|
14 |
import { IPromptConfigParameters } from '../interface';
|
15 |
import { excludeUnEnabledVariables } from '../utils';
|
|
|
16 |
import { useFetchModelId } from './hooks';
|
|
|
|
|
|
|
17 |
import styles from './index.less';
|
18 |
|
19 |
enum ConfigurationSegmented {
|
@@ -45,22 +44,27 @@ const validateMessages = {
|
|
45 |
};
|
46 |
|
47 |
interface IProps extends IModalManagerChildrenProps {
|
48 |
-
|
|
|
|
|
|
|
49 |
}
|
50 |
|
51 |
-
const ChatConfigurationModal = ({
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
const [form] = Form.useForm();
|
53 |
const [value, setValue] = useState<ConfigurationSegmented>(
|
54 |
ConfigurationSegmented.AssistantSetting,
|
55 |
);
|
56 |
const promptEngineRef = useRef<Array<IPromptConfigParameters>>([]);
|
57 |
-
const loading = useOneNamespaceEffectsLoading('chatModel', ['setDialog']);
|
58 |
const modelId = useFetchModelId(visible);
|
59 |
|
60 |
-
const setDialog = useSetDialog();
|
61 |
-
const currentDialog = useFetchDialog(id, visible);
|
62 |
-
const { resetCurrentDialog } = useResetCurrentDialog();
|
63 |
-
|
64 |
const handleOk = async () => {
|
65 |
const values = await form.validateFields();
|
66 |
const nextValues: any = omit(values, [
|
@@ -78,7 +82,7 @@ const ChatConfigurationModal = ({ visible, hideModal, id }: IProps) => {
|
|
78 |
}
|
79 |
|
80 |
const finalValues = {
|
81 |
-
dialog_id: id,
|
82 |
...nextValues,
|
83 |
prompt_config: {
|
84 |
...nextValues.prompt_config,
|
@@ -87,13 +91,7 @@ const ChatConfigurationModal = ({ visible, hideModal, id }: IProps) => {
|
|
87 |
},
|
88 |
icon,
|
89 |
};
|
90 |
-
|
91 |
-
console.info(nextValues);
|
92 |
-
console.info(finalValues);
|
93 |
-
const retcode: number = await setDialog(finalValues);
|
94 |
-
if (retcode === 0) {
|
95 |
-
hideModal();
|
96 |
-
}
|
97 |
};
|
98 |
|
99 |
const handleCancel = () => {
|
@@ -105,7 +103,7 @@ const ChatConfigurationModal = ({ visible, hideModal, id }: IProps) => {
|
|
105 |
};
|
106 |
|
107 |
const handleModalAfterClose = () => {
|
108 |
-
|
109 |
form.resetFields();
|
110 |
};
|
111 |
|
@@ -124,19 +122,19 @@ const ChatConfigurationModal = ({ visible, hideModal, id }: IProps) => {
|
|
124 |
|
125 |
useEffect(() => {
|
126 |
if (visible) {
|
127 |
-
const icon =
|
128 |
let fileList: UploadFile[] = [];
|
129 |
|
130 |
if (icon) {
|
131 |
fileList = [{ uid: '1', name: 'file', thumbUrl: icon, status: 'done' }];
|
132 |
}
|
133 |
form.setFieldsValue({
|
134 |
-
...
|
135 |
icon: fileList,
|
136 |
-
llm_id:
|
137 |
});
|
138 |
}
|
139 |
-
}, [
|
140 |
|
141 |
return (
|
142 |
<Modal
|
|
|
1 |
import { ReactComponent as ChatConfigurationAtom } from '@/assets/svg/chat-configuration-atom.svg';
|
2 |
import { IModalManagerChildrenProps } from '@/components/modal-manager';
|
3 |
+
import { IDialog } from '@/interfaces/database/chat';
|
4 |
import { Divider, Flex, Form, Modal, Segmented, UploadFile } from 'antd';
|
5 |
import { SegmentedValue } from 'antd/es/segmented';
|
6 |
import omit from 'lodash/omit';
|
7 |
import { useEffect, useRef, useState } from 'react';
|
|
|
|
|
|
|
|
|
|
|
8 |
import { variableEnabledFieldMap } from '../constants';
|
|
|
9 |
import { IPromptConfigParameters } from '../interface';
|
10 |
import { excludeUnEnabledVariables } from '../utils';
|
11 |
+
import AssistantSetting from './assistant-setting';
|
12 |
import { useFetchModelId } from './hooks';
|
13 |
+
import ModelSetting from './model-setting';
|
14 |
+
import PromptEngine from './prompt-engine';
|
15 |
+
|
16 |
import styles from './index.less';
|
17 |
|
18 |
enum ConfigurationSegmented {
|
|
|
44 |
};
|
45 |
|
46 |
interface IProps extends IModalManagerChildrenProps {
|
47 |
+
initialDialog: IDialog;
|
48 |
+
loading: boolean;
|
49 |
+
onOk: (dialog: IDialog) => void;
|
50 |
+
clearDialog: () => void;
|
51 |
}
|
52 |
|
53 |
+
const ChatConfigurationModal = ({
|
54 |
+
visible,
|
55 |
+
hideModal,
|
56 |
+
initialDialog,
|
57 |
+
loading,
|
58 |
+
onOk,
|
59 |
+
clearDialog,
|
60 |
+
}: IProps) => {
|
61 |
const [form] = Form.useForm();
|
62 |
const [value, setValue] = useState<ConfigurationSegmented>(
|
63 |
ConfigurationSegmented.AssistantSetting,
|
64 |
);
|
65 |
const promptEngineRef = useRef<Array<IPromptConfigParameters>>([]);
|
|
|
66 |
const modelId = useFetchModelId(visible);
|
67 |
|
|
|
|
|
|
|
|
|
68 |
const handleOk = async () => {
|
69 |
const values = await form.validateFields();
|
70 |
const nextValues: any = omit(values, [
|
|
|
82 |
}
|
83 |
|
84 |
const finalValues = {
|
85 |
+
dialog_id: initialDialog.id,
|
86 |
...nextValues,
|
87 |
prompt_config: {
|
88 |
...nextValues.prompt_config,
|
|
|
91 |
},
|
92 |
icon,
|
93 |
};
|
94 |
+
onOk(finalValues);
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
};
|
96 |
|
97 |
const handleCancel = () => {
|
|
|
103 |
};
|
104 |
|
105 |
const handleModalAfterClose = () => {
|
106 |
+
clearDialog();
|
107 |
form.resetFields();
|
108 |
};
|
109 |
|
|
|
122 |
|
123 |
useEffect(() => {
|
124 |
if (visible) {
|
125 |
+
const icon = initialDialog.icon;
|
126 |
let fileList: UploadFile[] = [];
|
127 |
|
128 |
if (icon) {
|
129 |
fileList = [{ uid: '1', name: 'file', thumbUrl: icon, status: 'done' }];
|
130 |
}
|
131 |
form.setFieldsValue({
|
132 |
+
...initialDialog,
|
133 |
icon: fileList,
|
134 |
+
llm_id: initialDialog.llm_id ?? modelId,
|
135 |
});
|
136 |
}
|
137 |
+
}, [initialDialog, form, visible, modelId]);
|
138 |
|
139 |
return (
|
140 |
<Modal
|
web/src/pages/chat/chat-configuration-modal/model-setting.tsx
CHANGED
@@ -54,7 +54,7 @@ const ModelSetting = ({ show, form }: ISegmentedContentProps) => {
|
|
54 |
name="llm_id"
|
55 |
rules={[{ required: true, message: 'Please select!' }]}
|
56 |
>
|
57 |
-
<Select options={modelOptions} />
|
58 |
</Form.Item>
|
59 |
<Divider></Divider>
|
60 |
<Form.Item
|
|
|
54 |
name="llm_id"
|
55 |
rules={[{ required: true, message: 'Please select!' }]}
|
56 |
>
|
57 |
+
<Select options={modelOptions} showSearch />
|
58 |
</Form.Item>
|
59 |
<Divider></Divider>
|
60 |
<Form.Item
|
web/src/pages/chat/hooks.ts
CHANGED
@@ -45,24 +45,42 @@ export const useSetDialog = () => {
|
|
45 |
return setDialog;
|
46 |
};
|
47 |
|
48 |
-
export const
|
49 |
-
const dispatch = useDispatch();
|
50 |
const currentDialog: IDialog = useSelector(
|
51 |
(state: any) => state.chatModel.currentDialog,
|
52 |
);
|
53 |
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
|
63 |
useEffect(() => {
|
64 |
if (dialogId && visible) {
|
65 |
-
fetchDialog();
|
66 |
}
|
67 |
}, [dialogId, fetchDialog, visible]);
|
68 |
|
@@ -123,14 +141,6 @@ export const useSelectPromptConfigParameters = (): VariableTableDataType[] => {
|
|
123 |
return finalParameters;
|
124 |
};
|
125 |
|
126 |
-
export const useSelectCurrentDialog = () => {
|
127 |
-
const currentDialog: IDialog = useSelector(
|
128 |
-
(state: any) => state.chatModel.currentDialog,
|
129 |
-
);
|
130 |
-
|
131 |
-
return currentDialog;
|
132 |
-
};
|
133 |
-
|
134 |
export const useRemoveDialog = () => {
|
135 |
const dispatch = useDispatch();
|
136 |
|
@@ -231,6 +241,57 @@ export const useHandleItemHover = () => {
|
|
231 |
};
|
232 |
};
|
233 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
234 |
//#region conversation
|
235 |
|
236 |
export const useFetchConversationList = () => {
|
|
|
45 |
return setDialog;
|
46 |
};
|
47 |
|
48 |
+
export const useSelectCurrentDialog = () => {
|
|
|
49 |
const currentDialog: IDialog = useSelector(
|
50 |
(state: any) => state.chatModel.currentDialog,
|
51 |
);
|
52 |
|
53 |
+
return currentDialog;
|
54 |
+
};
|
55 |
+
|
56 |
+
export const useFetchDialog = () => {
|
57 |
+
const dispatch = useDispatch();
|
58 |
+
|
59 |
+
const fetchDialog = useCallback(
|
60 |
+
(dialogId: string, needToBeSaved = true) => {
|
61 |
+
if (dialogId) {
|
62 |
+
return dispatch<any>({
|
63 |
+
type: 'chatModel/getDialog',
|
64 |
+
payload: { dialog_id: dialogId, needToBeSaved },
|
65 |
+
});
|
66 |
+
}
|
67 |
+
},
|
68 |
+
[dispatch],
|
69 |
+
);
|
70 |
+
|
71 |
+
return fetchDialog;
|
72 |
+
};
|
73 |
+
|
74 |
+
export const useFetchDialogOnMount = (
|
75 |
+
dialogId: string,
|
76 |
+
visible: boolean,
|
77 |
+
): IDialog => {
|
78 |
+
const currentDialog: IDialog = useSelectCurrentDialog();
|
79 |
+
const fetchDialog = useFetchDialog();
|
80 |
|
81 |
useEffect(() => {
|
82 |
if (dialogId && visible) {
|
83 |
+
fetchDialog(dialogId);
|
84 |
}
|
85 |
}, [dialogId, fetchDialog, visible]);
|
86 |
|
|
|
141 |
return finalParameters;
|
142 |
};
|
143 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
export const useRemoveDialog = () => {
|
145 |
const dispatch = useDispatch();
|
146 |
|
|
|
241 |
};
|
242 |
};
|
243 |
|
244 |
+
export const useEditDialog = () => {
|
245 |
+
const [dialog, setDialog] = useState<IDialog>({} as IDialog);
|
246 |
+
const fetchDialog = useFetchDialog();
|
247 |
+
const submitDialog = useSetDialog();
|
248 |
+
const loading = useOneNamespaceEffectsLoading('chatModel', ['setDialog']);
|
249 |
+
|
250 |
+
const {
|
251 |
+
visible: dialogEditVisible,
|
252 |
+
hideModal: hideDialogEditModal,
|
253 |
+
showModal: showDialogEditModal,
|
254 |
+
} = useSetModalState();
|
255 |
+
|
256 |
+
const onDialogEditOk = useCallback(
|
257 |
+
async (dialog: IDialog) => {
|
258 |
+
const ret = await submitDialog(dialog);
|
259 |
+
|
260 |
+
if (ret === 0) {
|
261 |
+
hideDialogEditModal();
|
262 |
+
}
|
263 |
+
},
|
264 |
+
[submitDialog, hideDialogEditModal],
|
265 |
+
);
|
266 |
+
|
267 |
+
const handleShowDialogEditModal = useCallback(
|
268 |
+
async (dialogId?: string) => {
|
269 |
+
if (dialogId) {
|
270 |
+
const ret = await fetchDialog(dialogId, false);
|
271 |
+
if (ret.retcode === 0) {
|
272 |
+
setDialog(ret.data);
|
273 |
+
}
|
274 |
+
}
|
275 |
+
showDialogEditModal();
|
276 |
+
},
|
277 |
+
[showDialogEditModal, fetchDialog],
|
278 |
+
);
|
279 |
+
|
280 |
+
const clearDialog = useCallback(() => {
|
281 |
+
setDialog({} as IDialog);
|
282 |
+
}, []);
|
283 |
+
|
284 |
+
return {
|
285 |
+
dialogSettingLoading: loading,
|
286 |
+
initialDialog: dialog,
|
287 |
+
onDialogEditOk,
|
288 |
+
dialogEditVisible,
|
289 |
+
hideDialogEditModal,
|
290 |
+
showDialogEditModal: handleShowDialogEditModal,
|
291 |
+
clearDialog,
|
292 |
+
};
|
293 |
+
};
|
294 |
+
|
295 |
//#region conversation
|
296 |
|
297 |
export const useFetchConversationList = () => {
|
web/src/pages/chat/index.tsx
CHANGED
@@ -20,8 +20,9 @@ import ChatContainer from './chat-container';
|
|
20 |
import {
|
21 |
useClickConversationCard,
|
22 |
useClickDialogCard,
|
|
|
23 |
useFetchConversationList,
|
24 |
-
|
25 |
useGetChatSearchParams,
|
26 |
useHandleItemHover,
|
27 |
useRemoveConversation,
|
@@ -60,8 +61,17 @@ const Chat = () => {
|
|
60 |
hideConversationRenameModal,
|
61 |
showConversationRenameModal,
|
62 |
} = useRenameConversation();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
|
64 |
-
|
65 |
|
66 |
const handleAppCardEnter = (id: string) => () => {
|
67 |
handleItemEnter(id);
|
@@ -76,10 +86,7 @@ const Chat = () => {
|
|
76 |
(info: any) => {
|
77 |
info?.domEvent?.preventDefault();
|
78 |
info?.domEvent?.stopPropagation();
|
79 |
-
|
80 |
-
setCurrentDialog(dialogId ?? '');
|
81 |
-
// }
|
82 |
-
showModal();
|
83 |
};
|
84 |
|
85 |
const handleRemoveDialog =
|
@@ -276,10 +283,13 @@ const Chat = () => {
|
|
276 |
<Divider type={'vertical'} className={styles.divider}></Divider>
|
277 |
<ChatContainer></ChatContainer>
|
278 |
<ChatConfigurationModal
|
279 |
-
visible={
|
280 |
-
|
281 |
-
|
282 |
-
|
|
|
|
|
|
|
283 |
></ChatConfigurationModal>
|
284 |
<RenameModal
|
285 |
visible={conversationRenameVisible}
|
|
|
20 |
import {
|
21 |
useClickConversationCard,
|
22 |
useClickDialogCard,
|
23 |
+
useEditDialog,
|
24 |
useFetchConversationList,
|
25 |
+
useFetchDialogOnMount,
|
26 |
useGetChatSearchParams,
|
27 |
useHandleItemHover,
|
28 |
useRemoveConversation,
|
|
|
61 |
hideConversationRenameModal,
|
62 |
showConversationRenameModal,
|
63 |
} = useRenameConversation();
|
64 |
+
const {
|
65 |
+
dialogSettingLoading,
|
66 |
+
initialDialog,
|
67 |
+
onDialogEditOk,
|
68 |
+
dialogEditVisible,
|
69 |
+
clearDialog,
|
70 |
+
hideDialogEditModal,
|
71 |
+
showDialogEditModal,
|
72 |
+
} = useEditDialog();
|
73 |
|
74 |
+
useFetchDialogOnMount(dialogId, true);
|
75 |
|
76 |
const handleAppCardEnter = (id: string) => () => {
|
77 |
handleItemEnter(id);
|
|
|
86 |
(info: any) => {
|
87 |
info?.domEvent?.preventDefault();
|
88 |
info?.domEvent?.stopPropagation();
|
89 |
+
showDialogEditModal(dialogId);
|
|
|
|
|
|
|
90 |
};
|
91 |
|
92 |
const handleRemoveDialog =
|
|
|
283 |
<Divider type={'vertical'} className={styles.divider}></Divider>
|
284 |
<ChatContainer></ChatContainer>
|
285 |
<ChatConfigurationModal
|
286 |
+
visible={dialogEditVisible}
|
287 |
+
initialDialog={initialDialog}
|
288 |
+
showModal={showDialogEditModal}
|
289 |
+
hideModal={hideDialogEditModal}
|
290 |
+
loading={dialogSettingLoading}
|
291 |
+
onOk={onDialogEditOk}
|
292 |
+
clearDialog={clearDialog}
|
293 |
></ChatConfigurationModal>
|
294 |
<RenameModal
|
295 |
visible={conversationRenameVisible}
|
web/src/pages/chat/model.ts
CHANGED
@@ -63,16 +63,21 @@ const model: DvaModel<ChatModelState> = {
|
|
63 |
|
64 |
effects: {
|
65 |
*getDialog({ payload }, { call, put }) {
|
66 |
-
const
|
67 |
-
|
|
|
|
|
|
|
|
|
68 |
yield put({ type: 'setCurrentDialog', payload: data.data });
|
69 |
}
|
|
|
70 |
},
|
71 |
*setDialog({ payload }, { call, put }) {
|
72 |
const { data } = yield call(chatService.setDialog, payload);
|
73 |
if (data.retcode === 0) {
|
74 |
yield put({ type: 'listDialog' });
|
75 |
-
message.success('
|
76 |
}
|
77 |
return data.retcode;
|
78 |
},
|
|
|
63 |
|
64 |
effects: {
|
65 |
*getDialog({ payload }, { call, put }) {
|
66 |
+
const needToBeSaved =
|
67 |
+
payload.needToBeSaved === undefined ? true : payload.needToBeSaved;
|
68 |
+
const { data } = yield call(chatService.getDialog, {
|
69 |
+
dialog_id: payload.dialog_id,
|
70 |
+
});
|
71 |
+
if (data.retcode === 0 && needToBeSaved) {
|
72 |
yield put({ type: 'setCurrentDialog', payload: data.data });
|
73 |
}
|
74 |
+
return data;
|
75 |
},
|
76 |
*setDialog({ payload }, { call, put }) {
|
77 |
const { data } = yield call(chatService.setDialog, payload);
|
78 |
if (data.retcode === 0) {
|
79 |
yield put({ type: 'listDialog' });
|
80 |
+
message.success(payload.dialog_id ? 'Modified!' : 'Created!');
|
81 |
}
|
82 |
return data.retcode;
|
83 |
},
|
web/src/utils/history.ts
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
import { createBrowserHistory } from 'history';
|
2 |
-
|
3 |
-
export const history = createBrowserHistory();
|
|
|
|
|
|
|
|
web/src/utils/request.ts
CHANGED
@@ -1,11 +1,8 @@
|
|
1 |
-
import { message, notification } from 'antd';
|
2 |
-
import { RequestMethod, extend } from 'umi-request';
|
3 |
-
|
4 |
import { Authorization } from '@/constants/authorization';
|
5 |
-
import api from '@/utils/api';
|
6 |
import authorizationUtil from '@/utils/authorizationUtil';
|
7 |
-
|
8 |
-
|
|
|
9 |
|
10 |
const ABORT_REQUEST_ERR_MESSAGE = 'The user aborted a request.'; // 手动中断请求。errorHandler 抛出的error message
|
11 |
|
@@ -120,7 +117,7 @@ request.interceptors.response.use(async (response: any, options) => {
|
|
120 |
duration: 3,
|
121 |
});
|
122 |
authorizationUtil.removeAll();
|
123 |
-
|
124 |
} else if (data.retcode !== 0) {
|
125 |
if (data.retcode === 100) {
|
126 |
message.error(data.retmsg);
|
|
|
|
|
|
|
|
|
1 |
import { Authorization } from '@/constants/authorization';
|
|
|
2 |
import authorizationUtil from '@/utils/authorizationUtil';
|
3 |
+
import { message, notification } from 'antd';
|
4 |
+
import { history } from 'umi';
|
5 |
+
import { RequestMethod, extend } from 'umi-request';
|
6 |
|
7 |
const ABORT_REQUEST_ERR_MESSAGE = 'The user aborted a request.'; // 手动中断请求。errorHandler 抛出的error message
|
8 |
|
|
|
117 |
duration: 3,
|
118 |
});
|
119 |
authorizationUtil.removeAll();
|
120 |
+
history.push('/login'); // Will not jump to the login page
|
121 |
} else if (data.retcode !== 0) {
|
122 |
if (data.retcode === 100) {
|
123 |
message.error(data.retmsg);
|