cozy-search 2.6.2 → 2.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Assistant/AssistantAvatar.js +3 -1
- package/dist/components/Assistant/AssistantContainer.js +3 -1
- package/dist/components/Assistant/AssistantMenu.d.ts +16 -0
- package/dist/components/Assistant/AssistantMenu.js +160 -0
- package/dist/components/Assistant/AssistantSelection.d.ts +12 -1
- package/dist/components/Assistant/AssistantSelection.js +55 -115
- package/dist/components/Assistant/AssistantSelectionItem.js +3 -1
- package/dist/components/Assistant/AssistantSidebarItem.d.ts +9 -0
- package/dist/components/Assistant/AssistantSidebarItem.js +108 -0
- package/dist/components/Assistant/styles.styl +13 -0
- package/dist/components/Conversations/Conversation.js +74 -14
- package/dist/components/Conversations/ConversationBar.js +13 -5
- package/dist/components/Conversations/ConversationComposer.js +53 -23
- package/dist/components/Conversations/ConversationListItem.js +20 -40
- package/dist/components/Conversations/ConversationListItemWider.js +14 -11
- package/dist/components/Conversations/styles.styl +110 -23
- package/dist/components/CozyAssistantRuntimeProvider.js +15 -8
- package/dist/components/CreateAssistantSteps/BasicInfoStep.js +37 -1
- package/dist/components/CreateAssistantSteps/Provider.js +1 -0
- package/dist/components/CreateAssistantSteps/ProviderSelectionStep.js +1 -0
- package/dist/components/CreateAssistantSteps/styles.styl +14 -0
- package/dist/components/KnowledgeBase/FolderPickerDialog.js +3 -1
- package/dist/components/KnowledgeBase/KnowledgeBaseChip.d.ts +7 -5
- package/dist/components/KnowledgeBase/KnowledgeBaseChip.js +65 -31
- package/dist/components/KnowledgeBase/conversationAssistant.d.ts +2 -1
- package/dist/components/KnowledgeBase/conversationAssistant.js +6 -1
- package/dist/components/KnowledgeBase/conversationAssistant.spec.js +24 -0
- package/dist/components/KnowledgeBase/styles.styl +18 -0
- package/dist/components/Messages/AssistantMessage.js +25 -21
- package/dist/components/Messages/UserMessage.js +4 -1
- package/dist/components/Messages/styles.styl +41 -0
- package/dist/components/Search/SearchBarMobile.js +13 -5
- package/dist/components/Sidebar/index.js +55 -30
- package/dist/components/Sidebar/styles.styl +12 -11
- package/dist/components/TwakeKnowledges/SourceButton.d.ts +14 -0
- package/dist/components/TwakeKnowledges/SourceButton.js +98 -0
- package/dist/components/TwakeKnowledges/TwakeKnowledgeSelector.d.ts +9 -0
- package/dist/components/TwakeKnowledges/TwakeKnowledgeSelector.js +75 -50
- package/dist/components/TwakeKnowledges/styles.styl +29 -2
- package/dist/components/Views/AssistantView.js +9 -1
- package/dist/components/Views/CreateAssistantDialog.js +5 -1
- package/dist/components/Views/DeleteAssistantDialog.js +1 -0
- package/dist/components/Views/EditAssistantDialog.js +5 -1
- package/dist/hooks/useConversation.d.ts +2 -2
- package/dist/hooks/useConversation.js +25 -4
- package/dist/hooks/useConversation.spec.js +14 -2
- package/dist/hooks/useConversation.spec.jsx +21 -3
- package/dist/locales/en.json +5 -1
- package/dist/locales/fr.json +6 -2
- package/dist/locales/index.js +21 -5
- package/dist/locales/ru.json +5 -1
- package/dist/locales/vi.json +5 -1
- package/dist/stylesheet.css +253 -30
- package/package.json +3 -3
- package/dist/components/TwakeKnowledges/TwakeKnowledgeChip.d.ts +0 -13
- package/dist/components/TwakeKnowledges/TwakeKnowledgeChip.js +0 -80
- package/dist/components/TwakeKnowledges/WebSearchChip.d.ts +0 -5
- package/dist/components/TwakeKnowledges/WebSearchChip.js +0 -75
|
@@ -11,24 +11,44 @@ var _classnames = _interopRequireDefault(require("classnames"));
|
|
|
11
11
|
|
|
12
12
|
var _react = _interopRequireDefault(require("react"));
|
|
13
13
|
|
|
14
|
+
var _twakeIcons = require("@linagora/twake-icons");
|
|
15
|
+
|
|
14
16
|
var _cozyFlags = _interopRequireDefault(require("cozy-flags"));
|
|
15
17
|
|
|
16
|
-
var
|
|
18
|
+
var _Chips = _interopRequireDefault(require("cozy-ui/transpiled/react/Chips"));
|
|
19
|
+
|
|
20
|
+
var _Breakpoints = require("cozy-ui/transpiled/react/providers/Breakpoints");
|
|
17
21
|
|
|
18
22
|
var _twakeI18n = require("twake-i18n");
|
|
19
23
|
|
|
20
|
-
var
|
|
24
|
+
var _SourceButton = _interopRequireWildcard(require("./SourceButton"));
|
|
21
25
|
|
|
22
|
-
var
|
|
26
|
+
var _KnowledgeBaseChip = _interopRequireDefault(require("../KnowledgeBase/KnowledgeBaseChip"));
|
|
23
27
|
|
|
24
|
-
var
|
|
28
|
+
var _useSelectedAssistantKnowledgeBase = require("../KnowledgeBase/useSelectedAssistantKnowledgeBase");
|
|
25
29
|
|
|
26
|
-
var
|
|
30
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
27
31
|
|
|
28
|
-
var
|
|
32
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
29
33
|
|
|
30
|
-
var
|
|
34
|
+
var styles = {
|
|
35
|
+
"source-button": "styles__source-button___9t9wI",
|
|
36
|
+
"source-button-image": "styles__source-button-image___2batD",
|
|
37
|
+
"source-button-image--inactive": "styles__source-button-image--inactive___3hs2C",
|
|
38
|
+
"source-chip": "styles__source-chip___1h51w",
|
|
39
|
+
"source-chip-icon": "styles__source-chip-icon___3-N0x",
|
|
40
|
+
"source-chip-label": "styles__source-chip-label___2mLIx"
|
|
41
|
+
};
|
|
31
42
|
|
|
43
|
+
/**
|
|
44
|
+
* The knowledge sources of the composer. The Drive source is always on:
|
|
45
|
+
* on desktop it is a chip named after the knowledge base folder (the
|
|
46
|
+
* whole Drive without one), whose menu opens the folder or changes it;
|
|
47
|
+
* on mobile it is an icon button. Web search (a toggle) and emails are
|
|
48
|
+
* icon buttons behind their flags: emails show on the default assistant
|
|
49
|
+
* always, on a custom assistant once enabled in the wizard. Sources are
|
|
50
|
+
* enabled/disabled from the wizard, never from the composer.
|
|
51
|
+
*/
|
|
32
52
|
var TwakeKnowledgeSelector = function TwakeKnowledgeSelector(_ref) {
|
|
33
53
|
var className = _ref.className,
|
|
34
54
|
websearchEnabled = _ref.websearchEnabled,
|
|
@@ -37,6 +57,9 @@ var TwakeKnowledgeSelector = function TwakeKnowledgeSelector(_ref) {
|
|
|
37
57
|
var _useI18n = (0, _twakeI18n.useI18n)(),
|
|
38
58
|
t = _useI18n.t;
|
|
39
59
|
|
|
60
|
+
var _useBreakpoints = (0, _Breakpoints.useBreakpoints)(),
|
|
61
|
+
isMobile = _useBreakpoints.isMobile;
|
|
62
|
+
|
|
40
63
|
var _useSelectedAssistant = (0, _useSelectedAssistantKnowledgeBase.useSelectedAssistantKnowledgeBase)(),
|
|
41
64
|
dirId = _useSelectedAssistant.dirId,
|
|
42
65
|
folder = _useSelectedAssistant.folder,
|
|
@@ -48,54 +71,56 @@ var TwakeKnowledgeSelector = function TwakeKnowledgeSelector(_ref) {
|
|
|
48
71
|
|
|
49
72
|
var websearchEnabledFlag = (0, _cozyFlags.default)('cozy.assistant.websearch.enabled');
|
|
50
73
|
var mailSourceEnabledFlag = (0, _cozyFlags.default)('cozy.assistant.source-knowledge.mail.enabled');
|
|
51
|
-
var
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return twakeKnowledge.display;
|
|
67
|
-
});
|
|
68
|
-
var showSourceChips = twakeKnowledges.length > 0;
|
|
69
|
-
return /*#__PURE__*/_react.default.createElement("div", {
|
|
70
|
-
className: (0, _classnames.default)('u-flex u-flex-row u-flex-wrap u-flex-items-center u-flex-justify-end', className)
|
|
71
|
-
}, /*#__PURE__*/_react.default.createElement(_Typography.default, {
|
|
72
|
-
className: "u-mr-half u-fz-tiny u-coolGrey"
|
|
73
|
-
}, t('assistant.twake_knowledges.search_in')), websearchEnabledFlag && /*#__PURE__*/_react.default.createElement(_WebSearchChip.default, {
|
|
74
|
-
websearchEnabled: websearchEnabled,
|
|
75
|
-
onToggleWebsearch: onToggleWebsearch
|
|
76
|
-
}), hasKnowledgeBase ? /*#__PURE__*/_react.default.createElement(_KnowledgeBaseChip.default, {
|
|
74
|
+
var showMail = mailSourceEnabledFlag && (!isRealAssistant || hasEmail); // Pointer activation leaves the focus on the button, whose focus style
|
|
75
|
+
// would then differ from the sibling sources until something else takes
|
|
76
|
+
// it. Drop it for pointer activation only (`detail > 0`), so keyboard
|
|
77
|
+
// users keep their focus ring.
|
|
78
|
+
|
|
79
|
+
var handleToggleWebsearch = function handleToggleWebsearch(event) {
|
|
80
|
+
if (event.detail > 0) {
|
|
81
|
+
event.currentTarget.blur();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
onToggleWebsearch(event);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
var driveSource = dirId ? /*#__PURE__*/_react.default.createElement(_KnowledgeBaseChip.default, {
|
|
88
|
+
variant: isMobile ? 'icon' : 'chip',
|
|
77
89
|
dirId: dirId,
|
|
78
90
|
folder: folder,
|
|
79
91
|
isRoot: isRoot,
|
|
80
92
|
isUnavailable: isUnavailable,
|
|
81
|
-
isLast: !showSourceChips,
|
|
82
93
|
onChangeFolder: setKnowledgeBaseFolder
|
|
83
|
-
}) : /*#__PURE__*/_react.default.createElement(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
94
|
+
}) : isMobile ? /*#__PURE__*/_react.default.createElement(_SourceButton.default, {
|
|
95
|
+
icon: _twakeIcons.Drive,
|
|
96
|
+
preserveColor: true,
|
|
97
|
+
label: t('assistant.twake_knowledges.drive')
|
|
98
|
+
}) : /*#__PURE__*/_react.default.createElement(_Chips.default, {
|
|
99
|
+
icon: /*#__PURE__*/_react.default.createElement(_twakeIcons.Icon, {
|
|
100
|
+
icon: _twakeIcons.Drive,
|
|
101
|
+
size: 16,
|
|
102
|
+
preserveColor: true
|
|
103
|
+
}),
|
|
104
|
+
label: t('assistant.twake_knowledges.drive'),
|
|
105
|
+
className: styles['source-chip'],
|
|
106
|
+
classes: _SourceButton.CHIP_CLASSES
|
|
107
|
+
});
|
|
108
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
109
|
+
role: "group",
|
|
110
|
+
"aria-label": t('assistant.twake_knowledges.search_in'),
|
|
111
|
+
className: (0, _classnames.default)('u-flex u-flex-items-center', className)
|
|
112
|
+
}, driveSource, websearchEnabledFlag && /*#__PURE__*/_react.default.createElement(_SourceButton.default, {
|
|
113
|
+
icon: _twakeIcons.Globe,
|
|
114
|
+
label: t('assistant.websearch.label'),
|
|
115
|
+
isActive: websearchEnabled,
|
|
116
|
+
"aria-pressed": websearchEnabled,
|
|
117
|
+
onClick: handleToggleWebsearch,
|
|
118
|
+
className: "u-ml-half"
|
|
119
|
+
}), showMail && /*#__PURE__*/_react.default.createElement(_SourceButton.default, {
|
|
120
|
+
icon: _twakeIcons.Mail,
|
|
121
|
+
preserveColor: true,
|
|
122
|
+
label: t('assistant.twake_knowledges.mail'),
|
|
123
|
+
className: "u-ml-half"
|
|
99
124
|
}));
|
|
100
125
|
};
|
|
101
126
|
|
|
@@ -1,4 +1,31 @@
|
|
|
1
|
-
.
|
|
2
|
-
|
|
1
|
+
.source-button
|
|
2
|
+
width 32px
|
|
3
|
+
height 32px
|
|
4
|
+
padding 0 !important
|
|
5
|
+
border-radius 100px
|
|
6
|
+
|
|
7
|
+
.source-button-image
|
|
8
|
+
width 20px
|
|
9
|
+
height 20px
|
|
10
|
+
|
|
11
|
+
&--inactive
|
|
12
|
+
opacity 0.6
|
|
13
|
+
|
|
14
|
+
.source-chip
|
|
15
|
+
// The chip of the design: 32px, 12px padding, icon 16px, 4px before the
|
|
16
|
+
// 12px medium label
|
|
17
|
+
height 32px !important
|
|
18
|
+
border-radius 100px !important
|
|
19
|
+
padding 0 12px !important
|
|
20
|
+
|
|
21
|
+
.source-chip-icon
|
|
3
22
|
width 16px
|
|
23
|
+
height 16px
|
|
4
24
|
margin 0 !important
|
|
25
|
+
|
|
26
|
+
.source-chip-label
|
|
27
|
+
padding 0 0 0 4px !important
|
|
28
|
+
font-size 12px
|
|
29
|
+
font-weight 500
|
|
30
|
+
line-height 16px
|
|
31
|
+
letter-spacing 0.5px
|
|
@@ -15,6 +15,8 @@ var _Breakpoints = require("cozy-ui/transpiled/react/providers/Breakpoints");
|
|
|
15
15
|
|
|
16
16
|
var _CozyTheme = _interopRequireDefault(require("cozy-ui-plus/dist/providers/CozyTheme"));
|
|
17
17
|
|
|
18
|
+
var _twakeI18n = require("twake-i18n");
|
|
19
|
+
|
|
18
20
|
var _AssistantProvider = _interopRequireWildcard(require("../AssistantProvider"));
|
|
19
21
|
|
|
20
22
|
var _CreateAssistantDialog = _interopRequireDefault(require("./CreateAssistantDialog"));
|
|
@@ -23,6 +25,8 @@ var _DeleteAssistantDialog = _interopRequireDefault(require("./DeleteAssistantDi
|
|
|
23
25
|
|
|
24
26
|
var _EditAssistantDialog = _interopRequireDefault(require("./EditAssistantDialog"));
|
|
25
27
|
|
|
28
|
+
var _locales = require("../../locales");
|
|
29
|
+
|
|
26
30
|
var _AssistantContainer = _interopRequireDefault(require("../Assistant/AssistantContainer"));
|
|
27
31
|
|
|
28
32
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
@@ -39,6 +43,10 @@ var styles = {
|
|
|
39
43
|
};
|
|
40
44
|
|
|
41
45
|
var AssistantView = function AssistantView() {
|
|
46
|
+
// The view is mounted by the app on its own route, without the search
|
|
47
|
+
// bar that otherwise registers the translations of this package.
|
|
48
|
+
(0, _twakeI18n.useExtendI18n)(_locales.locales);
|
|
49
|
+
|
|
42
50
|
var _useAssistant = (0, _AssistantProvider.useAssistant)(),
|
|
43
51
|
isOpenCreateAssistant = _useAssistant.isOpenCreateAssistant,
|
|
44
52
|
setIsOpenCreateAssistant = _useAssistant.setIsOpenCreateAssistant,
|
|
@@ -52,7 +60,7 @@ var AssistantView = function AssistantView() {
|
|
|
52
60
|
|
|
53
61
|
return /*#__PURE__*/_react.default.createElement("div", {
|
|
54
62
|
className: (0, _classnames.default)('u-w-100 u-flex u-flex-column u-ov-hidden', styles['assistantWrapper'], {
|
|
55
|
-
'u-
|
|
63
|
+
'u-pb-1-t u-bxz': isMobile
|
|
56
64
|
})
|
|
57
65
|
}, /*#__PURE__*/_react.default.createElement(_AssistantContainer.default, null), /*#__PURE__*/_react.default.createElement("div", {
|
|
58
66
|
className: "u-w-100"
|
|
@@ -52,6 +52,7 @@ var styles = {
|
|
|
52
52
|
"avatar-container": "styles__avatar-container___kJ_64",
|
|
53
53
|
"avatar-image": "styles__avatar-image___2Mkxj",
|
|
54
54
|
"file-input": "styles__file-input___2fB5n",
|
|
55
|
+
"avatar-tooltip": "styles__avatar-tooltip___1o6_5",
|
|
55
56
|
"ModelSelectionStep": "styles__ModelSelectionStep___1auXB",
|
|
56
57
|
"grid-container": "styles__grid-container___3wOus",
|
|
57
58
|
"grid-container--mobile": "styles__grid-container--mobile___uCAg1",
|
|
@@ -170,7 +171,10 @@ var CreateAssistantDialog = function CreateAssistantDialog(_ref) {
|
|
|
170
171
|
return /*#__PURE__*/_react.default.createElement(_Dialog.default, {
|
|
171
172
|
open: open,
|
|
172
173
|
onClose: onClose,
|
|
173
|
-
maxWidth: "
|
|
174
|
+
maxWidth: "md",
|
|
175
|
+
classes: {
|
|
176
|
+
paper: 'large'
|
|
177
|
+
},
|
|
174
178
|
fullScreen: !!isMobile,
|
|
175
179
|
className: styles.CreateAssistantDialog
|
|
176
180
|
}, /*#__PURE__*/_react.default.createElement(_Dialog.DialogTitle, {
|
|
@@ -46,6 +46,7 @@ var styles = {
|
|
|
46
46
|
"avatar-container": "styles__avatar-container___kJ_64",
|
|
47
47
|
"avatar-image": "styles__avatar-image___2Mkxj",
|
|
48
48
|
"file-input": "styles__file-input___2fB5n",
|
|
49
|
+
"avatar-tooltip": "styles__avatar-tooltip___1o6_5",
|
|
49
50
|
"ModelSelectionStep": "styles__ModelSelectionStep___1auXB",
|
|
50
51
|
"grid-container": "styles__grid-container___3wOus",
|
|
51
52
|
"grid-container--mobile": "styles__grid-container--mobile___uCAg1",
|
|
@@ -60,6 +60,7 @@ var styles = {
|
|
|
60
60
|
"avatar-container": "styles__avatar-container___kJ_64",
|
|
61
61
|
"avatar-image": "styles__avatar-image___2Mkxj",
|
|
62
62
|
"file-input": "styles__file-input___2fB5n",
|
|
63
|
+
"avatar-tooltip": "styles__avatar-tooltip___1o6_5",
|
|
63
64
|
"ModelSelectionStep": "styles__ModelSelectionStep___1auXB",
|
|
64
65
|
"grid-container": "styles__grid-container___3wOus",
|
|
65
66
|
"grid-container--mobile": "styles__grid-container--mobile___uCAg1",
|
|
@@ -227,7 +228,10 @@ var EditAssistantDialog = function EditAssistantDialog(_ref) {
|
|
|
227
228
|
return /*#__PURE__*/_react.default.createElement(_Dialog.default, {
|
|
228
229
|
open: open,
|
|
229
230
|
onClose: onClose,
|
|
230
|
-
maxWidth: "
|
|
231
|
+
maxWidth: "md",
|
|
232
|
+
classes: {
|
|
233
|
+
paper: 'large'
|
|
234
|
+
},
|
|
231
235
|
fullScreen: !!isMobile,
|
|
232
236
|
className: styles.CreateAssistantDialog
|
|
233
237
|
}, /*#__PURE__*/_react.default.createElement(_Dialog.DialogTitle, {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export default useConversation;
|
|
2
2
|
declare function useConversation(): {
|
|
3
|
-
goToConversation: (conversationId: any) => void;
|
|
4
|
-
createNewConversation: () => void;
|
|
3
|
+
goToConversation: (conversationId: any, { assistantId }?: any) => void;
|
|
4
|
+
createNewConversation: (assistantId: any) => void;
|
|
5
5
|
};
|
|
@@ -31,23 +31,44 @@ var useConversation = function useConversation() {
|
|
|
31
31
|
navigateRef.current = navigate;
|
|
32
32
|
locationRef.current = location;
|
|
33
33
|
}, [navigate, location]);
|
|
34
|
+
/**
|
|
35
|
+
* Opens a conversation. `assistantId` is the assistant a new conversation
|
|
36
|
+
* starts on, carried in the history state: without it, a new conversation
|
|
37
|
+
* starts on the configured default.
|
|
38
|
+
*/
|
|
39
|
+
|
|
34
40
|
var goToConversation = (0, _react.useCallback)(function (conversationId) {
|
|
35
41
|
var _match$;
|
|
36
42
|
|
|
43
|
+
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
44
|
+
assistantId = _ref.assistantId;
|
|
45
|
+
|
|
37
46
|
var loc = locationRef.current; // Extract base path safely by identifying the start of '/assistant' if it exists.
|
|
38
47
|
|
|
39
48
|
var match = loc.pathname.match(/^(.*?)(\/assistant(\/|$).*|$)/);
|
|
40
49
|
var basePath = ((_match$ = match === null || match === void 0 ? void 0 : match[1]) !== null && _match$ !== void 0 ? _match$ : loc.pathname).replace(/\/$/, '');
|
|
41
50
|
var newPathname = "".concat(basePath, "/assistant/").concat(conversationId);
|
|
42
51
|
setIsOpenSearchConversation(false);
|
|
43
|
-
|
|
52
|
+
var to = {
|
|
44
53
|
pathname: newPathname,
|
|
45
54
|
search: loc.search,
|
|
46
55
|
hash: loc.hash
|
|
47
|
-
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
if (assistantId) {
|
|
59
|
+
navigateRef.current(to, {
|
|
60
|
+
state: {
|
|
61
|
+
assistantId: assistantId
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
} else {
|
|
65
|
+
navigateRef.current(to);
|
|
66
|
+
}
|
|
48
67
|
}, [setIsOpenSearchConversation]);
|
|
49
|
-
var createNewConversation = (0, _react.useCallback)(function () {
|
|
50
|
-
goToConversation((0, _helpers.makeConversationId)()
|
|
68
|
+
var createNewConversation = (0, _react.useCallback)(function (assistantId) {
|
|
69
|
+
goToConversation((0, _helpers.makeConversationId)(), {
|
|
70
|
+
assistantId: typeof assistantId === 'string' ? assistantId : undefined
|
|
71
|
+
});
|
|
51
72
|
}, [goToConversation]);
|
|
52
73
|
return {
|
|
53
74
|
goToConversation: goToConversation,
|
|
@@ -13,6 +13,7 @@ jest.mock('../components/AssistantProvider');
|
|
|
13
13
|
jest.mock('../components/helpers');
|
|
14
14
|
// Set up mock implementations
|
|
15
15
|
import * as routerModule from 'react-router-dom';
|
|
16
|
+
import useConversation from './useConversation';
|
|
16
17
|
import * as assistantModule from '../components/AssistantProvider';
|
|
17
18
|
import * as helpersModule from '../components/helpers';
|
|
18
19
|
routerModule.useNavigate.mockImplementation(() => mockNavigate);
|
|
@@ -21,8 +22,6 @@ assistantModule.useAssistant.mockImplementation(() => ({
|
|
|
21
22
|
setIsOpenSearchConversation: mockSetIsOpenSearchConversation
|
|
22
23
|
}));
|
|
23
24
|
helpersModule.makeConversationId.mockImplementation(() => 'mock-id-123');
|
|
24
|
-
// Now import the hook after setting up mocks
|
|
25
|
-
import useConversation from './useConversation';
|
|
26
25
|
describe('useConversation', () => {
|
|
27
26
|
beforeEach(() => {
|
|
28
27
|
jest.clearAllMocks();
|
|
@@ -119,5 +118,18 @@ describe('useConversation', () => {
|
|
|
119
118
|
hash: ''
|
|
120
119
|
});
|
|
121
120
|
});
|
|
121
|
+
it('carries the picked assistant in the history state', () => {
|
|
122
|
+
mockLocation.pathname = '/docs';
|
|
123
|
+
routerModule.useLocation.mockImplementation(() => mockLocation);
|
|
124
|
+
const { result } = renderHook(() => useConversation());
|
|
125
|
+
act(() => {
|
|
126
|
+
result.current.createNewConversation('meeting');
|
|
127
|
+
});
|
|
128
|
+
expect(mockNavigate).toHaveBeenCalledWith({
|
|
129
|
+
pathname: '/docs/assistant/mock-id-123',
|
|
130
|
+
search: '',
|
|
131
|
+
hash: ''
|
|
132
|
+
}, { state: { assistantId: 'meeting' } });
|
|
133
|
+
});
|
|
122
134
|
});
|
|
123
135
|
});
|
|
@@ -17,6 +17,8 @@ jest.mock('../components/helpers')
|
|
|
17
17
|
|
|
18
18
|
// Set up mock implementations
|
|
19
19
|
import * as routerModule from 'react-router-dom'
|
|
20
|
+
|
|
21
|
+
import useConversation from './useConversation'
|
|
20
22
|
import * as assistantModule from '../components/AssistantProvider'
|
|
21
23
|
import * as helpersModule from '../components/helpers'
|
|
22
24
|
|
|
@@ -27,9 +29,6 @@ assistantModule.useAssistant.mockImplementation(() => ({
|
|
|
27
29
|
}))
|
|
28
30
|
helpersModule.makeConversationId.mockImplementation(() => 'mock-id-123')
|
|
29
31
|
|
|
30
|
-
// Now import the hook after setting up mocks
|
|
31
|
-
import useConversation from './useConversation'
|
|
32
|
-
|
|
33
32
|
describe('useConversation', () => {
|
|
34
33
|
beforeEach(() => {
|
|
35
34
|
jest.clearAllMocks()
|
|
@@ -144,5 +143,24 @@ describe('useConversation', () => {
|
|
|
144
143
|
hash: ''
|
|
145
144
|
})
|
|
146
145
|
})
|
|
146
|
+
|
|
147
|
+
it('carries the picked assistant in the history state', () => {
|
|
148
|
+
mockLocation.pathname = '/docs'
|
|
149
|
+
routerModule.useLocation.mockImplementation(() => mockLocation)
|
|
150
|
+
const { result } = renderHook(() => useConversation())
|
|
151
|
+
|
|
152
|
+
act(() => {
|
|
153
|
+
result.current.createNewConversation('meeting')
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
expect(mockNavigate).toHaveBeenCalledWith(
|
|
157
|
+
{
|
|
158
|
+
pathname: '/docs/assistant/mock-id-123',
|
|
159
|
+
search: '',
|
|
160
|
+
hash: ''
|
|
161
|
+
},
|
|
162
|
+
{ state: { assistantId: 'meeting' } }
|
|
163
|
+
)
|
|
164
|
+
})
|
|
147
165
|
})
|
|
148
166
|
})
|
package/dist/locales/en.json
CHANGED
|
@@ -28,10 +28,11 @@
|
|
|
28
28
|
"edited": "Message saved"
|
|
29
29
|
},
|
|
30
30
|
"sidebar": {
|
|
31
|
-
"create_new": "
|
|
31
|
+
"create_new": "New chat",
|
|
32
32
|
"toggle_sidebar": "Toggle sidebar",
|
|
33
33
|
"toggle_search": "Toggle search",
|
|
34
34
|
"close_sidebar": "Close sidebar",
|
|
35
|
+
"assistant": "Assistant",
|
|
35
36
|
"recent_chats": "Recent",
|
|
36
37
|
"conversation": {
|
|
37
38
|
"actions": {
|
|
@@ -47,6 +48,7 @@
|
|
|
47
48
|
"yesterday": "Yesterday"
|
|
48
49
|
},
|
|
49
50
|
"default_error": "An error occurred during response generation. Please try again",
|
|
51
|
+
"disclaimer": "Twake AI can make mistakes. Please verify important information.",
|
|
50
52
|
"default_empty_response": "I could not find an answer to your request. Please try rephrasing it",
|
|
51
53
|
"hide": "Hide",
|
|
52
54
|
"show": "Show",
|
|
@@ -70,6 +72,7 @@
|
|
|
70
72
|
},
|
|
71
73
|
"knowledge_base": {
|
|
72
74
|
"change_folder": "Change folder…",
|
|
75
|
+
"folder_hint": "The assistant can access all the files stored in this Drive folder",
|
|
73
76
|
"emails": "Emails",
|
|
74
77
|
"open_folder": "Open in Drive",
|
|
75
78
|
"picker_error": "Unable to open the Drive folder picker. Please try again.",
|
|
@@ -85,6 +88,7 @@
|
|
|
85
88
|
"basic_info": {
|
|
86
89
|
"description": "Customize your agent. Choose its knowledge base, then its AI model.",
|
|
87
90
|
"avatar": "Avatar (optional)",
|
|
91
|
+
"upload_photo": "Upload a photo",
|
|
88
92
|
"name": "Name",
|
|
89
93
|
"name_placeholder": "Name your agent",
|
|
90
94
|
"description_label": "Description",
|
package/dist/locales/fr.json
CHANGED
|
@@ -28,11 +28,12 @@
|
|
|
28
28
|
"edited": "Message enregistré"
|
|
29
29
|
},
|
|
30
30
|
"sidebar": {
|
|
31
|
-
"create_new": "
|
|
31
|
+
"create_new": "Nouveau chat",
|
|
32
32
|
"toggle_sidebar": "Basculer la barre latérale",
|
|
33
33
|
"toggle_search": "Basculer la recherche",
|
|
34
34
|
"close_sidebar": "Fermer la barre latérale",
|
|
35
|
-
"
|
|
35
|
+
"assistant": "Assistant",
|
|
36
|
+
"recent_chats": "Récents",
|
|
36
37
|
"conversation": {
|
|
37
38
|
"actions": {
|
|
38
39
|
"delete": "Supprimer",
|
|
@@ -47,6 +48,7 @@
|
|
|
47
48
|
"yesterday": "Hier"
|
|
48
49
|
},
|
|
49
50
|
"default_error": "Une erreur est survenue lors de la génération de la réponse. Veuillez réessayer",
|
|
51
|
+
"disclaimer": "Twake AI peut faire des erreurs. Vérifiez les informations importantes.",
|
|
50
52
|
"default_empty_response": "Je n'ai pas trouvé de réponse à votre demande. Essayez de reformuler votre question",
|
|
51
53
|
"hide": "Masquer",
|
|
52
54
|
"show": "Afficher",
|
|
@@ -70,6 +72,7 @@
|
|
|
70
72
|
},
|
|
71
73
|
"knowledge_base": {
|
|
72
74
|
"change_folder": "Modifier le dossier…",
|
|
75
|
+
"folder_hint": "L'assistant peut accéder à tous les fichiers stockés dans ce dossier Drive",
|
|
73
76
|
"emails": "Emails",
|
|
74
77
|
"open_folder": "Ouvrir dans Drive",
|
|
75
78
|
"picker_error": "Impossible d'ouvrir le sélecteur de dossier Drive. Veuillez réessayer.",
|
|
@@ -85,6 +88,7 @@
|
|
|
85
88
|
"basic_info": {
|
|
86
89
|
"description": "Personnalisez votre agent. Choisissez la base de connaissances, puis son modèle d'IA.",
|
|
87
90
|
"avatar": "Avatar (optionnel)",
|
|
91
|
+
"upload_photo": "Importer une photo",
|
|
88
92
|
"name": "Nom",
|
|
89
93
|
"name_placeholder": "Nommez votre agent",
|
|
90
94
|
"description_label": "Description",
|
package/dist/locales/index.js
CHANGED
|
@@ -34,10 +34,11 @@ var en = {
|
|
|
34
34
|
edited: "Message saved"
|
|
35
35
|
},
|
|
36
36
|
sidebar: {
|
|
37
|
-
create_new: "
|
|
37
|
+
create_new: "New chat",
|
|
38
38
|
toggle_sidebar: "Toggle sidebar",
|
|
39
39
|
toggle_search: "Toggle search",
|
|
40
40
|
close_sidebar: "Close sidebar",
|
|
41
|
+
assistant: "Assistant",
|
|
41
42
|
recent_chats: "Recent",
|
|
42
43
|
conversation: {
|
|
43
44
|
actions: {
|
|
@@ -53,6 +54,7 @@ var en = {
|
|
|
53
54
|
yesterday: "Yesterday"
|
|
54
55
|
},
|
|
55
56
|
default_error: "An error occurred during response generation. Please try again",
|
|
57
|
+
disclaimer: "Twake AI can make mistakes. Please verify important information.",
|
|
56
58
|
default_empty_response: "I could not find an answer to your request. Please try rephrasing it",
|
|
57
59
|
hide: "Hide",
|
|
58
60
|
show: "Show",
|
|
@@ -76,6 +78,7 @@ var en = {
|
|
|
76
78
|
},
|
|
77
79
|
knowledge_base: {
|
|
78
80
|
change_folder: "Change folder\u2026",
|
|
81
|
+
folder_hint: "The assistant can access all the files stored in this Drive folder",
|
|
79
82
|
emails: "Emails",
|
|
80
83
|
open_folder: "Open in Drive",
|
|
81
84
|
picker_error: "Unable to open the Drive folder picker. Please try again.",
|
|
@@ -91,6 +94,7 @@ var en = {
|
|
|
91
94
|
basic_info: {
|
|
92
95
|
description: "Customize your agent. Choose its knowledge base, then its AI model.",
|
|
93
96
|
avatar: "Avatar (optional)",
|
|
97
|
+
upload_photo: "Upload a photo",
|
|
94
98
|
name: "Name",
|
|
95
99
|
name_placeholder: "Name your agent",
|
|
96
100
|
description_label: "Description",
|
|
@@ -218,11 +222,12 @@ var fr = {
|
|
|
218
222
|
edited: "Message enregistr\xE9"
|
|
219
223
|
},
|
|
220
224
|
sidebar: {
|
|
221
|
-
create_new: "
|
|
225
|
+
create_new: "Nouveau chat",
|
|
222
226
|
toggle_sidebar: "Basculer la barre lat\xE9rale",
|
|
223
227
|
toggle_search: "Basculer la recherche",
|
|
224
228
|
close_sidebar: "Fermer la barre lat\xE9rale",
|
|
225
|
-
|
|
229
|
+
assistant: "Assistant",
|
|
230
|
+
recent_chats: "R\xE9cents",
|
|
226
231
|
conversation: {
|
|
227
232
|
actions: {
|
|
228
233
|
"delete": "Supprimer",
|
|
@@ -237,6 +242,7 @@ var fr = {
|
|
|
237
242
|
yesterday: "Hier"
|
|
238
243
|
},
|
|
239
244
|
default_error: "Une erreur est survenue lors de la g\xE9n\xE9ration de la r\xE9ponse. Veuillez r\xE9essayer",
|
|
245
|
+
disclaimer: "Twake AI peut faire des erreurs. V\xE9rifiez les informations importantes.",
|
|
240
246
|
default_empty_response: "Je n'ai pas trouv\xE9 de r\xE9ponse \xE0 votre demande. Essayez de reformuler votre question",
|
|
241
247
|
hide: "Masquer",
|
|
242
248
|
show: "Afficher",
|
|
@@ -260,6 +266,7 @@ var fr = {
|
|
|
260
266
|
},
|
|
261
267
|
knowledge_base: {
|
|
262
268
|
change_folder: "Modifier le dossier\u2026",
|
|
269
|
+
folder_hint: "L'assistant peut acc\xE9der \xE0 tous les fichiers stock\xE9s dans ce dossier Drive",
|
|
263
270
|
emails: "Emails",
|
|
264
271
|
open_folder: "Ouvrir dans Drive",
|
|
265
272
|
picker_error: "Impossible d'ouvrir le s\xE9lecteur de dossier Drive. Veuillez r\xE9essayer.",
|
|
@@ -275,6 +282,7 @@ var fr = {
|
|
|
275
282
|
basic_info: {
|
|
276
283
|
description: "Personnalisez votre agent. Choisissez la base de connaissances, puis son mod\xE8le d'IA.",
|
|
277
284
|
avatar: "Avatar (optionnel)",
|
|
285
|
+
upload_photo: "Importer une photo",
|
|
278
286
|
name: "Nom",
|
|
279
287
|
name_placeholder: "Nommez votre agent",
|
|
280
288
|
description_label: "Description",
|
|
@@ -392,10 +400,11 @@ var ru = {
|
|
|
392
400
|
reorganise_files: "\u0420\u0435\u043E\u0440\u0433\u0430\u043D\u0438\u0437\u043E\u0432\u0430\u0442\u044C \u043C\u043E\u0438 \u0444\u0430\u0439\u043B\u044B"
|
|
393
401
|
},
|
|
394
402
|
sidebar: {
|
|
395
|
-
create_new: "\
|
|
403
|
+
create_new: "\u041D\u043E\u0432\u044B\u0439 \u0447\u0430\u0442",
|
|
396
404
|
toggle_sidebar: "\u041F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u0431\u043E\u043A\u043E\u0432\u0443\u044E \u043F\u0430\u043D\u0435\u043B\u044C",
|
|
397
405
|
toggle_search: "\u041F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u043F\u043E\u0438\u0441\u043A",
|
|
398
406
|
close_sidebar: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C \u0431\u043E\u043A\u043E\u0432\u0443\u044E \u043F\u0430\u043D\u0435\u043B\u044C",
|
|
407
|
+
assistant: "\u0410\u0441\u0441\u0438\u0441\u0442\u0435\u043D\u0442",
|
|
399
408
|
recent_chats: "\u041D\u0435\u0434\u0430\u0432\u043D\u0438\u0435",
|
|
400
409
|
conversation: {
|
|
401
410
|
actions: {
|
|
@@ -411,6 +420,7 @@ var ru = {
|
|
|
411
420
|
yesterday: "\u0412\u0447\u0435\u0440\u0430"
|
|
412
421
|
},
|
|
413
422
|
default_error: "\u041F\u0440\u043E\u0438\u0437\u043E\u0448\u043B\u0430 \u043E\u0448\u0438\u0431\u043A\u0430, \u043F\u043E\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u0441\u043D\u043E\u0432\u0430",
|
|
423
|
+
disclaimer: "Twake AI \u043C\u043E\u0436\u0435\u0442 \u043E\u0448\u0438\u0431\u0430\u0442\u044C\u0441\u044F. \u041F\u0440\u043E\u0432\u0435\u0440\u044F\u0439\u0442\u0435 \u0432\u0430\u0436\u043D\u0443\u044E \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044E.",
|
|
414
424
|
default_empty_response: "\u042F \u043D\u0435 \u0441\u043C\u043E\u0433 \u043D\u0430\u0439\u0442\u0438 \u043E\u0442\u0432\u0435\u0442 \u043D\u0430 \u0432\u0430\u0448 \u0437\u0430\u043F\u0440\u043E\u0441. \u041F\u043E\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u043F\u0435\u0440\u0435\u0444\u043E\u0440\u043C\u0443\u043B\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0432\u043E\u043F\u0440\u043E\u0441",
|
|
415
425
|
hide: "\u0421\u043A\u0440\u044B\u0442\u044C",
|
|
416
426
|
show: "\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C",
|
|
@@ -458,6 +468,7 @@ var ru = {
|
|
|
458
468
|
},
|
|
459
469
|
knowledge_base: {
|
|
460
470
|
change_folder: "\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C \u043F\u0430\u043F\u043A\u0443\u2026",
|
|
471
|
+
folder_hint: "\u0410\u0441\u0441\u0438\u0441\u0442\u0435\u043D\u0442 \u0438\u043C\u0435\u0435\u0442 \u0434\u043E\u0441\u0442\u0443\u043F \u043A\u043E \u0432\u0441\u0435\u043C \u0444\u0430\u0439\u043B\u0430\u043C, \u0445\u0440\u0430\u043D\u044F\u0449\u0438\u043C\u0441\u044F \u0432 \u044D\u0442\u043E\u0439 \u043F\u0430\u043F\u043A\u0435 Drive",
|
|
461
472
|
emails: "\u041F\u0438\u0441\u044C\u043C\u0430",
|
|
462
473
|
open_folder: "\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u0432 Drive",
|
|
463
474
|
picker_error: "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043E\u0442\u043A\u0440\u044B\u0442\u044C \u0432\u044B\u0431\u043E\u0440 \u043F\u0430\u043F\u043A\u0438 Drive. \u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u043F\u043E\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u0435\u0449\u0451 \u0440\u0430\u0437.",
|
|
@@ -476,6 +487,7 @@ var ru = {
|
|
|
476
487
|
basic_info: {
|
|
477
488
|
description: "\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u0442\u0435 \u0432\u0430\u0448\u0435\u0433\u043E \u0430\u0433\u0435\u043D\u0442\u0430. \u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0431\u0430\u0437\u0443 \u0437\u043D\u0430\u043D\u0438\u0439, \u0437\u0430\u0442\u0435\u043C \u043C\u043E\u0434\u0435\u043B\u044C \u0418\u0418.",
|
|
478
489
|
avatar: "\u0410\u0432\u0430\u0442\u0430\u0440 (\u043D\u0435\u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E)",
|
|
490
|
+
upload_photo: "\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0444\u043E\u0442\u043E",
|
|
479
491
|
name: "\u0418\u043C\u044F",
|
|
480
492
|
name_placeholder: "\u041D\u0430\u0437\u043E\u0432\u0438\u0442\u0435 \u0432\u0430\u0448\u0435\u0433\u043E \u0430\u0433\u0435\u043D\u0442\u0430",
|
|
481
493
|
description_label: "\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435",
|
|
@@ -600,10 +612,11 @@ var vi = {
|
|
|
600
612
|
edited: "\u0110\xE3 l\u01B0u tin nh\u1EAFn"
|
|
601
613
|
},
|
|
602
614
|
sidebar: {
|
|
603
|
-
create_new: "
|
|
615
|
+
create_new: "Cu\u1ED9c tr\xF2 chuy\u1EC7n m\u1EDBi",
|
|
604
616
|
toggle_sidebar: "B\u1EADt/t\u1EAFt thanh b\xEAn",
|
|
605
617
|
toggle_search: "B\u1EADt/t\u1EAFt t\xECm ki\u1EBFm",
|
|
606
618
|
close_sidebar: "\u0110\xF3ng thanh b\xEAn",
|
|
619
|
+
assistant: "Tr\u1EE3 l\xFD",
|
|
607
620
|
recent_chats: "G\u1EA7n \u0111\xE2y",
|
|
608
621
|
conversation: {
|
|
609
622
|
actions: {
|
|
@@ -619,6 +632,7 @@ var vi = {
|
|
|
619
632
|
yesterday: "H\xF4m qua"
|
|
620
633
|
},
|
|
621
634
|
default_error: "\u0110\xE3 x\u1EA3y ra l\u1ED7i, vui l\xF2ng th\u1EED l\u1EA1i",
|
|
635
|
+
disclaimer: "Twake AI c\xF3 th\u1EC3 m\u1EAFc l\u1ED7i. H\xE3y ki\u1EC3m tra l\u1EA1i c\xE1c th\xF4ng tin quan tr\u1ECDng.",
|
|
622
636
|
default_empty_response: "T\xF4i kh\xF4ng t\xECm th\u1EA5y c\xE2u tr\u1EA3 l\u1EDDi cho y\xEAu c\u1EA7u c\u1EE7a b\u1EA1n. Vui l\xF2ng th\u1EED di\u1EC5n \u0111\u1EA1t l\u1EA1i",
|
|
623
637
|
hide: "\u1EA8n",
|
|
624
638
|
show: "Hi\u1EC7n",
|
|
@@ -659,6 +673,7 @@ var vi = {
|
|
|
659
673
|
},
|
|
660
674
|
knowledge_base: {
|
|
661
675
|
change_folder: "Thay \u0111\u1ED5i th\u01B0 m\u1EE5c\u2026",
|
|
676
|
+
folder_hint: "Tr\u1EE3 l\xFD c\xF3 th\u1EC3 truy c\u1EADp t\u1EA5t c\u1EA3 c\xE1c t\u1EC7p \u0111\u01B0\u1EE3c l\u01B0u trong th\u01B0 m\u1EE5c Drive n\xE0y",
|
|
662
677
|
emails: "Email",
|
|
663
678
|
open_folder: "M\u1EDF trong Drive",
|
|
664
679
|
picker_error: "Kh\xF4ng th\u1EC3 m\u1EDF b\u1ED9 ch\u1ECDn th\u01B0 m\u1EE5c Drive. Vui l\xF2ng th\u1EED l\u1EA1i.",
|
|
@@ -677,6 +692,7 @@ var vi = {
|
|
|
677
692
|
basic_info: {
|
|
678
693
|
description: "T\xF9y ch\u1EC9nh t\xE1c nh\xE2n c\u1EE7a b\u1EA1n. Ch\u1ECDn c\u01A1 s\u1EDF tri th\u1EE9c, sau \u0111\xF3 l\xE0 m\xF4 h\xECnh AI.",
|
|
679
694
|
avatar: "\u1EA2nh \u0111\u1EA1i di\u1EC7n (t\xF9y ch\u1ECDn)",
|
|
695
|
+
upload_photo: "T\u1EA3i \u1EA3nh l\xEAn",
|
|
680
696
|
name: "T\xEAn",
|
|
681
697
|
name_placeholder: "\u0110\u1EB7t t\xEAn cho t\xE1c nh\xE2n c\u1EE7a b\u1EA1n",
|
|
682
698
|
description_label: "M\xF4 t\u1EA3",
|