@droppii-org/chat-sdk 0.8.1 → 0.8.3
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/canned-response/cannedTrigger.d.ts +2 -0
- package/dist/components/canned-response/cannedTrigger.d.ts.map +1 -0
- package/dist/components/canned-response/cannedTrigger.js +3 -0
- package/dist/components/canned-response/insertCannedContent.js +2 -2
- package/dist/components/conversation/ConversationByGroupItem.js +1 -1
- package/dist/components/conversation/ConversationBySessionItem.js +4 -4
- package/dist/components/conversation/DeskConversationList.d.ts.map +1 -1
- package/dist/components/conversation/DeskConversationList.js +6 -4
- package/dist/components/conversation/folderEmptyState.d.ts.map +1 -1
- package/dist/components/conversation/folderEmptyState.js +2 -0
- package/dist/components/conversation/internalNotePreview.d.ts +1 -1
- package/dist/components/conversation/internalNotePreview.d.ts.map +1 -1
- package/dist/components/conversation/internalNotePreview.js +22 -3
- package/dist/components/conversation/listHeading.d.ts +1 -1
- package/dist/components/conversation/listHeading.d.ts.map +1 -1
- package/dist/components/conversation/listHeading.js +7 -1
- package/dist/components/conversation/rowTime.d.ts +2 -2
- package/dist/components/conversation/rowTime.d.ts.map +1 -1
- package/dist/components/conversation/rowTime.js +2 -4
- package/dist/components/conversation-detail/ConversationDetailInput.d.ts.map +1 -1
- package/dist/components/conversation-detail/ConversationDetailInput.js +8 -3
- package/dist/components/conversation-detail/ConversationMessageList.d.ts.map +1 -1
- package/dist/components/conversation-detail/ConversationMessageList.js +6 -3
- package/dist/components/conversation-detail/bot/BotMenuSheet.d.ts.map +1 -1
- package/dist/components/conversation-detail/bot/BotMenuSheet.js +1 -1
- package/dist/components/conversation-inbox/ConversationInboxList.d.ts.map +1 -1
- package/dist/components/conversation-inbox/ConversationInboxList.js +4 -0
- package/dist/components/conversation-inbox/InboxBootStatus.d.ts.map +1 -1
- package/dist/components/conversation-inbox/InboxBootStatus.js +10 -2
- package/dist/components/group/CreateGroupForm.d.ts.map +1 -1
- package/dist/components/group/CreateGroupForm.js +2 -1
- package/dist/components/group/CreateGroupFormCrmView.d.ts.map +1 -1
- package/dist/components/group/CreateGroupFormCrmView.js +1 -1
- package/dist/components/group/GroupMemberPickerCrm.d.ts.map +1 -1
- package/dist/components/group/GroupMemberPickerCrm.js +1 -1
- package/dist/components/media-collection/FileCollection.d.ts.map +1 -1
- package/dist/components/media-collection/FileCollection.js +4 -3
- package/dist/components/media-collection/ImageCollection.d.ts.map +1 -1
- package/dist/components/media-collection/ImageCollection.js +2 -1
- package/dist/components/media-collection/LinkCollection.d.ts.map +1 -1
- package/dist/components/media-collection/LinkCollection.js +14 -26
- package/dist/components/media-collection/VideoCollection.d.ts.map +1 -1
- package/dist/components/media-collection/VideoCollection.js +2 -1
- package/dist/components/media-resources/FileResourceList.js +2 -2
- package/dist/components/media-resources/ResourceScrollContainer.d.ts.map +1 -1
- package/dist/components/media-resources/ResourceScrollContainer.js +34 -2
- package/dist/components/message/GroupMembersDrawer.d.ts.map +1 -1
- package/dist/components/message/GroupMembersDrawer.js +2 -3
- package/dist/components/message/MessageList.d.ts.map +1 -1
- package/dist/components/message/MessageList.js +15 -4
- package/dist/components/message/footer/ActionBar.d.ts.map +1 -1
- package/dist/components/message/footer/ActionBar.js +10 -44
- package/dist/components/message/footer/CannedResponsePlugin.d.ts.map +1 -1
- package/dist/components/message/footer/CannedResponsePlugin.js +3 -2
- package/dist/components/message/footer/EnterHandler.d.ts.map +1 -1
- package/dist/components/message/footer/EnterHandler.js +10 -47
- package/dist/components/message/footer/FilePreview.d.ts.map +1 -1
- package/dist/components/message/footer/FilePreview.js +2 -1
- package/dist/components/message/footer/LinkInputPreview.d.ts +1 -1
- package/dist/components/message/footer/LinkInputPreview.d.ts.map +1 -1
- package/dist/components/message/footer/LinkInputPreview.js +8 -1
- package/dist/components/message/footer/MediaUploadButtons.d.ts.map +1 -1
- package/dist/components/message/footer/MediaUploadButtons.js +4 -7
- package/dist/components/message/footer/index.d.ts.map +1 -1
- package/dist/components/message/footer/index.js +57 -16
- package/dist/components/message/footer/mention/useMentionOptions.d.ts.map +1 -1
- package/dist/components/message/footer/mention/useMentionOptions.js +2 -6
- package/dist/components/message/footer/resetEditorAfterSend.d.ts +7 -0
- package/dist/components/message/footer/resetEditorAfterSend.d.ts.map +1 -0
- package/dist/components/message/footer/resetEditorAfterSend.js +62 -0
- package/dist/components/message/groupMemberMenuCrm.d.ts +4 -4
- package/dist/components/message/groupMemberMenuCrm.d.ts.map +1 -1
- package/dist/components/message/groupMemberMenuCrm.js +73 -60
- package/dist/components/message/item/FileMessage.js +2 -2
- package/dist/components/message/item/SystemLogMessage.d.ts.map +1 -1
- package/dist/components/message/item/SystemLogMessage.js +5 -2
- package/dist/components/search-conversation/SearchConversationAsGroups.js +1 -1
- package/dist/components/search-conversation/SearchConversationAsMessages.js +1 -1
- package/dist/components/search-conversation/SearchConversationMyInbox.js +1 -1
- package/dist/components/session/SessionFolderList.d.ts +4 -3
- package/dist/components/session/SessionFolderList.d.ts.map +1 -1
- package/dist/components/session/SessionFolderList.js +14 -5
- package/dist/components/thread/GroupInfoBodyCrm.d.ts.map +1 -1
- package/dist/components/thread/GroupInfoBodyCrm.js +2 -2
- package/dist/components/thread/GroupThreadInfo.d.ts.map +1 -1
- package/dist/components/thread/GroupThreadInfo.js +2 -6
- package/dist/components/thread/ManualAssignPopover.d.ts.map +1 -1
- package/dist/components/thread/ManualAssignPopover.js +6 -8
- package/dist/components/thread/SessionDetailCard.d.ts.map +1 -1
- package/dist/components/thread/SessionDetailCard.js +3 -3
- package/dist/components/thread/SessionSection.d.ts.map +1 -1
- package/dist/components/thread/SessionSection.js +3 -9
- package/dist/components/thread/SessionTagPicker.d.ts +3 -1
- package/dist/components/thread/SessionTagPicker.d.ts.map +1 -1
- package/dist/components/thread/SessionTagPicker.js +2 -2
- package/dist/components/thread/sessionDateFormat.d.ts +2 -0
- package/dist/components/thread/sessionDateFormat.d.ts.map +1 -1
- package/dist/components/thread/sessionDateFormat.js +6 -0
- package/dist/constants/dateFormat.d.ts +2 -0
- package/dist/constants/dateFormat.d.ts.map +1 -0
- package/dist/constants/dateFormat.js +2 -0
- package/dist/hooks/common/useFetchUrlMetadata.d.ts +1 -0
- package/dist/hooks/common/useFetchUrlMetadata.d.ts.map +1 -1
- package/dist/hooks/conversation/useBotFlow.d.ts.map +1 -1
- package/dist/hooks/conversation/useBotFlow.js +64 -12
- package/dist/hooks/conversation/useCloseBotSession.d.ts +2 -0
- package/dist/hooks/conversation/useCloseBotSession.d.ts.map +1 -1
- package/dist/hooks/conversation/useCloseBotSession.js +17 -1
- package/dist/hooks/global/useGlobalEvent.d.ts.map +1 -1
- package/dist/hooks/global/useGlobalEvent.js +148 -16
- package/dist/hooks/global/useLoginHealth.d.ts +3 -0
- package/dist/hooks/global/useLoginHealth.d.ts.map +1 -0
- package/dist/hooks/global/useLoginHealth.js +55 -0
- package/dist/hooks/group/useCreateGroup.d.ts.map +1 -1
- package/dist/hooks/group/useCreateGroup.js +75 -6
- package/dist/hooks/init/useChatBootPhase.d.ts +2 -0
- package/dist/hooks/init/useChatBootPhase.d.ts.map +1 -1
- package/dist/hooks/init/useChatBootPhase.js +11 -6
- package/dist/hooks/message/useMessage.d.ts.map +1 -1
- package/dist/hooks/message/useMessage.js +97 -28
- package/dist/hooks/message/usePinnedMessages.d.ts.map +1 -1
- package/dist/hooks/message/usePinnedMessages.js +13 -2
- package/dist/hooks/message/useRevokeMessage.d.ts.map +1 -1
- package/dist/hooks/message/useRevokeMessage.js +25 -0
- package/dist/hooks/message/useSendMessage.d.ts +15 -12
- package/dist/hooks/message/useSendMessage.d.ts.map +1 -1
- package/dist/hooks/message/useSendMessage.js +199 -133
- package/dist/hooks/search/useSearchMessage.d.ts.map +1 -1
- package/dist/hooks/search/useSearchMessage.js +57 -3
- package/dist/hooks/session/useConversationSessionState.d.ts.map +1 -1
- package/dist/hooks/session/useConversationSessionState.js +4 -1
- package/dist/hooks/session/useGetSession.d.ts.map +1 -1
- package/dist/hooks/session/useGetSession.js +2 -0
- package/dist/hooks/session/useGetSessionList.d.ts +235 -0
- package/dist/hooks/session/useGetSessionList.d.ts.map +1 -0
- package/dist/hooks/session/useGetSessionList.js +23 -0
- package/dist/hooks/session/useSessionLatestPreview.d.ts.map +1 -1
- package/dist/hooks/session/useSessionLatestPreview.js +34 -4
- package/dist/hooks/user/useAuth.d.ts +1 -1
- package/dist/hooks/user/useAuth.d.ts.map +1 -1
- package/dist/hooks/user/useAuth.js +31 -15
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/locales/vi/boot.json +5 -1
- package/dist/locales/vi/common.json +35 -15
- package/dist/locales/vi/conversation-inbox.json +2 -1
- package/dist/screens/conversation-detail/index.d.ts.map +1 -1
- package/dist/screens/conversation-detail/index.js +6 -0
- package/dist/screens/desk-message/DeskBootCard.d.ts.map +1 -1
- package/dist/screens/desk-message/DeskBootCard.js +6 -4
- package/dist/store/boot.d.ts +5 -0
- package/dist/store/boot.d.ts.map +1 -1
- package/dist/store/boot.js +11 -1
- package/dist/store/conversation.d.ts.map +1 -1
- package/dist/store/conversation.js +5 -1
- package/dist/store/session.d.ts +1 -13
- package/dist/store/session.d.ts.map +1 -1
- package/dist/store/session.js +10 -9
- package/dist/store/sessionFolder.d.ts +2 -0
- package/dist/store/sessionFolder.d.ts.map +1 -1
- package/dist/store/sessionFolder.js +3 -1
- package/dist/store/type.d.ts +7 -1
- package/dist/store/type.d.ts.map +1 -1
- package/dist/styles/global.css +1 -1
- package/dist/types/chat.d.ts +1 -1
- package/dist/types/chat.d.ts.map +1 -1
- package/dist/utils/common.d.ts.map +1 -1
- package/dist/utils/common.js +4 -1
- package/dist/utils/download.d.ts +10 -0
- package/dist/utils/download.d.ts.map +1 -1
- package/dist/utils/download.js +51 -0
- package/dist/utils/fileValidation.d.ts +7 -0
- package/dist/utils/fileValidation.d.ts.map +1 -1
- package/dist/utils/fileValidation.js +37 -13
- package/dist/utils/latestMessagePreviewable.d.ts +2 -0
- package/dist/utils/latestMessagePreviewable.d.ts.map +1 -0
- package/dist/utils/latestMessagePreviewable.js +18 -0
- package/dist/utils/mentionMembers.d.ts +3 -0
- package/dist/utils/mentionMembers.d.ts.map +1 -0
- package/dist/utils/mentionMembers.js +29 -0
- package/dist/utils/messageLog.d.ts +2 -2
- package/dist/utils/messageLog.d.ts.map +1 -1
- package/dist/utils/messageLog.js +129 -40
- package/dist/utils/notifiableMessage.d.ts +7 -0
- package/dist/utils/notifiableMessage.d.ts.map +1 -0
- package/dist/utils/notifiableMessage.js +26 -0
- package/dist/utils/withSdkTimeout.d.ts +11 -0
- package/dist/utils/withSdkTimeout.d.ts.map +1 -0
- package/dist/utils/withSdkTimeout.js +30 -0
- package/package.json +1 -1
|
@@ -25,7 +25,7 @@ import CannedResponse from "../../../components/canned-response";
|
|
|
25
25
|
import CannedResponsePanel from "../../../components/canned-response/CannedResponsePanel";
|
|
26
26
|
import CrmComposerCard from "./CrmComposerCard";
|
|
27
27
|
import { CannedResponseTriggerPlugin } from "./CannedResponsePlugin";
|
|
28
|
-
import { useBoolean } from "ahooks";
|
|
28
|
+
import { useBoolean, useLatest } from "ahooks";
|
|
29
29
|
import useAuthStore from "../../../store/auth";
|
|
30
30
|
import useConversationStore from "../../../store/conversation";
|
|
31
31
|
import { useCurrentUserAccountType } from "../../../hooks/user/useCurrentUserAccountType";
|
|
@@ -142,6 +142,10 @@ const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
|
142
142
|
};
|
|
143
143
|
}, [showLinkPreview, previewUrl, previewMetadata]);
|
|
144
144
|
const [isSessionClosedModalOpen, { setTrue: openSessionClosedModal, setFalse: closeSessionClosedModal },] = useBoolean(false);
|
|
145
|
+
// Conversations whose message is still being built. Keyed per thread so a send in
|
|
146
|
+
// one thread neither blocks nor clears the composer of the thread opened next.
|
|
147
|
+
const buildingConversationsRef = useRef(new Set());
|
|
148
|
+
const currentConversationIdRef = useLatest(conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID);
|
|
145
149
|
const pendingMessageRef = useRef(null);
|
|
146
150
|
const { mutateAsync: createSession, isPending: isCreatingSession } = useCreateSession();
|
|
147
151
|
const { mutateAsync: reopenSession, isPending: isReopeningSession } = useReopenSession();
|
|
@@ -163,6 +167,7 @@ const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
|
163
167
|
? t("enter_internal_message")
|
|
164
168
|
: t("enter_message");
|
|
165
169
|
const onSendMessage = useCallback(({ plainText, richText, type, isInternal, mentions, }) => {
|
|
170
|
+
var _a;
|
|
166
171
|
if ((currentSession === null || currentSession === void 0 ? void 0 : currentSession.isClosed) && !isInternal) {
|
|
167
172
|
pendingMessageRef.current = {
|
|
168
173
|
plainText,
|
|
@@ -172,34 +177,61 @@ const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
|
172
177
|
files: [...listUploadFiles],
|
|
173
178
|
urlMetadata: resolveUrlMetadata(),
|
|
174
179
|
mentions,
|
|
180
|
+
conversationId: conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID,
|
|
175
181
|
};
|
|
176
182
|
openSessionClosedModal();
|
|
177
183
|
return false;
|
|
178
184
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
185
|
+
// A second Enter while the first message is still being built would send it twice.
|
|
186
|
+
const conversationId = (_a = conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID) !== null && _a !== void 0 ? _a : "";
|
|
187
|
+
if (buildingConversationsRef.current.has(conversationId))
|
|
188
|
+
return false;
|
|
189
|
+
buildingConversationsRef.current.add(conversationId);
|
|
190
|
+
const sentFileUids = new Set(listUploadFiles.map((file) => file.uid));
|
|
191
|
+
// The composer is cleared by the caller only when this resolves true, so a failed
|
|
192
|
+
// build (hung or rejected core call) keeps the text and files for another try.
|
|
193
|
+
return new Promise((resolve) => {
|
|
194
|
+
const settle = (shown) => {
|
|
195
|
+
buildingConversationsRef.current.delete(conversationId);
|
|
196
|
+
if (!shown)
|
|
197
|
+
toastMessage.error(t("message_send_failed_no_retry"));
|
|
198
|
+
if (shown) {
|
|
199
|
+
// The upload list is composer-wide: even after a thread switch the sent files
|
|
200
|
+
// must go, or they would ride along with the next thread's message.
|
|
201
|
+
setListUploadFiles((files) => files.filter((file) => !sentFileUids.has(file.uid)));
|
|
202
|
+
}
|
|
203
|
+
// After a thread switch the composer may still hold the sent text; the caller
|
|
204
|
+
// clears it only if it is unchanged, so a different draft is never touched.
|
|
205
|
+
resolve(shown);
|
|
206
|
+
};
|
|
207
|
+
void sendMergeMessage({
|
|
208
|
+
plainText,
|
|
209
|
+
richText,
|
|
210
|
+
files: listUploadFiles,
|
|
211
|
+
currentSession,
|
|
212
|
+
isInternal,
|
|
213
|
+
urlMetadata: resolveUrlMetadata(),
|
|
214
|
+
mentions,
|
|
215
|
+
onBuilt: settle,
|
|
216
|
+
});
|
|
187
217
|
});
|
|
188
|
-
setListUploadFiles([]);
|
|
189
|
-
return true;
|
|
190
218
|
}, [
|
|
219
|
+
t,
|
|
191
220
|
sendMergeMessage,
|
|
192
221
|
listUploadFiles,
|
|
193
222
|
currentSession,
|
|
194
223
|
openSessionClosedModal,
|
|
195
224
|
resolveUrlMetadata,
|
|
225
|
+
conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID,
|
|
226
|
+
currentConversationIdRef,
|
|
196
227
|
]);
|
|
197
228
|
const executePendingSend = useCallback((newSession) => {
|
|
198
229
|
const pending = pendingMessageRef.current;
|
|
199
230
|
if (!pending)
|
|
200
231
|
return;
|
|
201
232
|
const sessionToUse = newSession || currentSession;
|
|
202
|
-
|
|
233
|
+
pendingMessageRef.current = null;
|
|
234
|
+
void sendMergeMessage({
|
|
203
235
|
plainText: pending.plainText,
|
|
204
236
|
richText: pending.richText,
|
|
205
237
|
files: pending.files,
|
|
@@ -207,11 +239,20 @@ const MessageFooterProvider = ({ currentSession, openCreateCannedModal, }) => {
|
|
|
207
239
|
isInternal: pending.isInternal,
|
|
208
240
|
urlMetadata: pending.urlMetadata,
|
|
209
241
|
mentions: pending.mentions,
|
|
242
|
+
onBuilt: (shown) => {
|
|
243
|
+
if (!shown) {
|
|
244
|
+
toastMessage.error(t("message_send_failed_no_retry"));
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const sentUids = new Set(pending.files.map((file) => file.uid));
|
|
248
|
+
setListUploadFiles((files) => files.filter((file) => !sentUids.has(file.uid)));
|
|
249
|
+
// Only the thread the message was written in has a text composer to clear.
|
|
250
|
+
if (currentConversationIdRef.current !== pending.conversationId)
|
|
251
|
+
return;
|
|
252
|
+
emit("CLEAR_COMPOSER");
|
|
253
|
+
},
|
|
210
254
|
});
|
|
211
|
-
|
|
212
|
-
pendingMessageRef.current = null;
|
|
213
|
-
emit("CLEAR_COMPOSER");
|
|
214
|
-
}, [sendMergeMessage, currentSession]);
|
|
255
|
+
}, [t, sendMergeMessage, currentSession, currentConversationIdRef]);
|
|
215
256
|
const handleSessionAction = useCallback(async (action) => {
|
|
216
257
|
const conversationId = conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID;
|
|
217
258
|
if (!conversationId)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMentionOptions.d.ts","sourceRoot":"","sources":["../../../../../src/components/message/footer/mention/useMentionOptions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useMentionOptions.d.ts","sourceRoot":"","sources":["../../../../../src/components/message/footer/mention/useMentionOptions.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,mBAAmB,YAAY,CAAC;AAoB7C,eAAO,MAAM,iBAAiB,GAC5B,SAAS,MAAM,GAAG,SAAS,EAC3B,OAAO,MAAM,KACZ,aAAa,EAwDf,CAAC"}
|
|
@@ -2,7 +2,6 @@ import { useEffect, useMemo } from "react";
|
|
|
2
2
|
import { useTranslation } from "react-i18next";
|
|
3
3
|
import { useGroupMembers } from "../../../../hooks/group/useGroupMembers";
|
|
4
4
|
import { useSearchGroupMembers } from "../../../../hooks/group/useSearchGroupMembers";
|
|
5
|
-
import useAuthStore from "../../../../store/auth";
|
|
6
5
|
export const ALL_MEMBERS_USER_ID = "__all__";
|
|
7
6
|
// Typing a name loads a big group's remaining members up to this many.
|
|
8
7
|
const MENTION_MEMBER_LOAD_LIMIT = 10000;
|
|
@@ -27,7 +26,6 @@ export const useMentionOptions = (groupID, query) => {
|
|
|
27
26
|
// Core keeps only part of a big group locally, so its search alone misses
|
|
28
27
|
// members; typing a name also loads the rest, merged in as pages arrive.
|
|
29
28
|
const { results: searchResults } = useSearchGroupMembers(groupID, hasMore ? query : "");
|
|
30
|
-
const currentUserID = useAuthStore((state) => state.userID);
|
|
31
29
|
const hasKeyword = query.trim().length > 0;
|
|
32
30
|
useEffect(() => {
|
|
33
31
|
if (!hasKeyword || !hasMore || isLoadingMore)
|
|
@@ -42,10 +40,8 @@ export const useMentionOptions = (groupID, query) => {
|
|
|
42
40
|
const candidates = keyword
|
|
43
41
|
? [...members, ...searchResults.filter((member) => !loadedIDs.has(member.userID))]
|
|
44
42
|
: members;
|
|
45
|
-
//
|
|
46
|
-
// knows who they are — so the current user is filtered out entirely.
|
|
43
|
+
// The sender stays in the list: the spec lists every group member.
|
|
47
44
|
const memberOptions = candidates
|
|
48
|
-
.filter((member) => member.userID !== currentUserID)
|
|
49
45
|
.map((member) => ({
|
|
50
46
|
userID: member.userID,
|
|
51
47
|
displayName: member.nickname || member.userID,
|
|
@@ -69,5 +65,5 @@ export const useMentionOptions = (groupID, query) => {
|
|
|
69
65
|
};
|
|
70
66
|
const matchesAll = !keyword || allOption.displayName.toLowerCase().includes(keyword);
|
|
71
67
|
return matchesAll ? [allOption, ...memberOptions] : memberOptions;
|
|
72
|
-
}, [members, searchResults, query, t
|
|
68
|
+
}, [members, searchResults, query, t]);
|
|
73
69
|
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { LexicalEditor } from "lexical";
|
|
2
|
+
export declare const resetEditorIfUnchanged: (editor: LexicalEditor, sent: {
|
|
3
|
+
plainText: string;
|
|
4
|
+
richText: string;
|
|
5
|
+
}) => void;
|
|
6
|
+
export declare const resetEditorAfterSend: (editor: LexicalEditor) => void;
|
|
7
|
+
//# sourceMappingURL=resetEditorAfterSend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resetEditorAfterSend.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/resetEditorAfterSend.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAoE,MAAM,SAAS,CAAC;AAW1G,eAAO,MAAM,sBAAsB,GACjC,QAAQ,aAAa,EACrB,MAAM;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,SAU9C,CAAC;AAIF,eAAO,MAAM,oBAAoB,GAAI,QAAQ,aAAa,SAgDzD,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { $generateHtmlFromNodes } from "@lexical/html";
|
|
2
|
+
import { $createParagraphNode, $getRoot, $getSelection, $isRangeSelection } from "lexical";
|
|
3
|
+
import { $isListNode, INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, } from "@lexical/list";
|
|
4
|
+
import { $isQuoteNode } from "@lexical/rich-text";
|
|
5
|
+
import { clearComposerHistoryAfterUpdate } from "./clearComposerHistory";
|
|
6
|
+
// Resets only when the composer still holds what was sent; text typed while the
|
|
7
|
+
// message was being built stays as the next draft.
|
|
8
|
+
export const resetEditorIfUnchanged = (editor, sent) => {
|
|
9
|
+
let plainText = "";
|
|
10
|
+
let richText = "";
|
|
11
|
+
editor.getEditorState().read(() => {
|
|
12
|
+
plainText = $getRoot().getTextContent();
|
|
13
|
+
richText = $generateHtmlFromNodes(editor);
|
|
14
|
+
});
|
|
15
|
+
if (plainText !== sent.plainText || richText !== sent.richText)
|
|
16
|
+
return;
|
|
17
|
+
resetEditorAfterSend(editor);
|
|
18
|
+
};
|
|
19
|
+
// Empties the composer after a send but keeps the typing format, list and quote
|
|
20
|
+
// context, so the next message continues in the same block style.
|
|
21
|
+
export const resetEditorAfterSend = (editor) => {
|
|
22
|
+
clearComposerHistoryAfterUpdate(editor);
|
|
23
|
+
editor.update(() => {
|
|
24
|
+
const root = $getRoot();
|
|
25
|
+
root.clear();
|
|
26
|
+
const paragraph = $createParagraphNode();
|
|
27
|
+
root.append(paragraph);
|
|
28
|
+
paragraph.select();
|
|
29
|
+
const selection = $getSelection();
|
|
30
|
+
if ($isRangeSelection(selection)) {
|
|
31
|
+
const anchorNode = selection.anchor.getNode();
|
|
32
|
+
const topLevelNode = anchorNode.getTopLevelElementOrThrow();
|
|
33
|
+
const isListNode = $isListNode(topLevelNode);
|
|
34
|
+
const isQuoteNode = $isQuoteNode(topLevelNode);
|
|
35
|
+
const listType = isListNode
|
|
36
|
+
? topLevelNode.getListType()
|
|
37
|
+
: undefined;
|
|
38
|
+
if (selection.hasFormat("bold")) {
|
|
39
|
+
selection.formatText("bold");
|
|
40
|
+
}
|
|
41
|
+
if (selection.hasFormat("italic")) {
|
|
42
|
+
selection.formatText("italic");
|
|
43
|
+
}
|
|
44
|
+
if (selection.hasFormat("strikethrough")) {
|
|
45
|
+
selection.formatText("strikethrough");
|
|
46
|
+
}
|
|
47
|
+
if (isQuoteNode) {
|
|
48
|
+
// Nếu đang là QuoteNode → chuyển về Paragraph (bình thường)
|
|
49
|
+
const paragraph = $createParagraphNode();
|
|
50
|
+
// copy con của quote sang paragraph
|
|
51
|
+
const children = topLevelNode.getChildren();
|
|
52
|
+
children.forEach((child) => paragraph.append(child));
|
|
53
|
+
topLevelNode.replace(paragraph);
|
|
54
|
+
}
|
|
55
|
+
if (isListNode && listType) {
|
|
56
|
+
editor.dispatchCommand(listType === "number"
|
|
57
|
+
? INSERT_ORDERED_LIST_COMMAND
|
|
58
|
+
: INSERT_UNORDERED_LIST_COMMAND, undefined);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
};
|
|
@@ -14,7 +14,6 @@ export interface CrmMemberMenuHandlers {
|
|
|
14
14
|
}
|
|
15
15
|
interface BuildCrmMemberMenuParams {
|
|
16
16
|
member: MemberDisplayItem;
|
|
17
|
-
isRealGroup: boolean;
|
|
18
17
|
permissions: GroupPermissions;
|
|
19
18
|
actingIsOwner: boolean;
|
|
20
19
|
/** Set when leaving is not allowed; shown under the item instead of failing on click. */
|
|
@@ -24,9 +23,10 @@ interface BuildCrmMemberMenuParams {
|
|
|
24
23
|
}
|
|
25
24
|
type MenuItems = NonNullable<MenuProps["items"]>;
|
|
26
25
|
/**
|
|
27
|
-
* CRM member menu: no
|
|
28
|
-
*
|
|
26
|
+
* CRM member menu: actions the viewer has no right to are left out instead of
|
|
27
|
+
* shown disabled. Only leave keeps a reason, since it depends on live state.
|
|
28
|
+
* Empty result means the "..." button is hidden.
|
|
29
29
|
*/
|
|
30
|
-
export declare const buildCrmMemberMenu: ({ member,
|
|
30
|
+
export declare const buildCrmMemberMenu: ({ member, permissions, actingIsOwner, leaveBlockedReason, handlers, t, }: BuildCrmMemberMenuParams) => MenuItems;
|
|
31
31
|
export {};
|
|
32
32
|
//# sourceMappingURL=groupMemberMenuCrm.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"groupMemberMenuCrm.d.ts","sourceRoot":"","sources":["../../../src/components/message/groupMemberMenuCrm.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEtC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,KAAK,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC;AAE5E,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAClD,SAAS,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC/C,aAAa,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACnD,gBAAgB,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACtD,aAAa,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACnD,gBAAgB,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACtD,WAAW,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACjD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,UAAU,wBAAwB;IAChC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"groupMemberMenuCrm.d.ts","sourceRoot":"","sources":["../../../src/components/message/groupMemberMenuCrm.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEtC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,KAAK,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC;AAE5E,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAClD,SAAS,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC/C,aAAa,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACnD,gBAAgB,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACtD,aAAa,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACnD,gBAAgB,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACtD,WAAW,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACjD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,UAAU,wBAAwB;IAChC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,WAAW,EAAE,gBAAgB,CAAC;IAC9B,aAAa,EAAE,OAAO,CAAC;IACvB,yFAAyF;IACzF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,qBAAqB,CAAC;IAChC,CAAC,EAAE,SAAS,CAAC;CACd;AAED,KAAK,SAAS,GAAG,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;AAWjD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,0EAOhC,wBAAwB,KAAG,SA4F7B,CAAC"}
|
|
@@ -3,11 +3,11 @@ import { CrmIcon as Icon } from "../../components/group/crmIcon";
|
|
|
3
3
|
const label = (title, hint, tone) => (_jsxs("span", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: tone, children: title }), hint && _jsx("span", { className: "text-xs font-normal text-gray-600", children: hint })] }));
|
|
4
4
|
const DIVIDER = { type: "divider" };
|
|
5
5
|
/**
|
|
6
|
-
* CRM member menu: no
|
|
7
|
-
*
|
|
6
|
+
* CRM member menu: actions the viewer has no right to are left out instead of
|
|
7
|
+
* shown disabled. Only leave keeps a reason, since it depends on live state.
|
|
8
|
+
* Empty result means the "..." button is hidden.
|
|
8
9
|
*/
|
|
9
|
-
export const buildCrmMemberMenu = ({ member,
|
|
10
|
-
const ownerOnly = actingIsOwner ? undefined : t("group_owner_only");
|
|
10
|
+
export const buildCrmMemberMenu = ({ member, permissions, actingIsOwner, leaveBlockedReason, handlers, t, }) => {
|
|
11
11
|
if (member.isCurrentUser) {
|
|
12
12
|
return [
|
|
13
13
|
{
|
|
@@ -20,64 +20,77 @@ export const buildCrmMemberMenu = ({ member, isRealGroup, permissions, actingIsO
|
|
|
20
20
|
},
|
|
21
21
|
];
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
: member.isOwner
|
|
26
|
-
? t("cannot_remove_group_owner")
|
|
27
|
-
: member.isAdmin && !actingIsOwner
|
|
28
|
-
? t("group_owner_only")
|
|
29
|
-
: undefined;
|
|
23
|
+
// Mute and remove share one target guard: never the owner, and another admin only for the owner.
|
|
24
|
+
const canManageTarget = permissions.removeMember && !member.isOwner && (!member.isAdmin || actingIsOwner);
|
|
30
25
|
const adminItems = member.isAdmin
|
|
31
26
|
? [
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
27
|
+
...(permissions.transferOwnership
|
|
28
|
+
? [
|
|
29
|
+
{
|
|
30
|
+
key: "configure-admin-permission",
|
|
31
|
+
label: label(t("admin_permission_settings")),
|
|
32
|
+
icon: _jsx(Icon, { icon: "shield-o", size: 16 }),
|
|
33
|
+
onClick: () => handlers.onConfigureAdmin(member),
|
|
34
|
+
},
|
|
35
|
+
]
|
|
36
|
+
: []),
|
|
37
|
+
...(permissions.addAdmin
|
|
38
|
+
? [
|
|
39
|
+
{
|
|
40
|
+
key: "remove-admin",
|
|
41
|
+
label: label(t("remove_from_admin")),
|
|
42
|
+
icon: _jsx(Icon, { icon: "shield-fail-o", size: 16 }),
|
|
43
|
+
onClick: () => handlers.onRemoveAdmin(member),
|
|
44
|
+
},
|
|
45
|
+
]
|
|
46
|
+
: []),
|
|
46
47
|
]
|
|
47
|
-
:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
48
|
+
: permissions.addAdmin
|
|
49
|
+
? [
|
|
50
|
+
{
|
|
51
|
+
key: "assign-admin",
|
|
52
|
+
label: label(t("assign_as_admin")),
|
|
53
|
+
icon: _jsx(Icon, { icon: "shield-o", size: 16 }),
|
|
54
|
+
onClick: () => handlers.onAskAssignAdmin(member),
|
|
55
|
+
},
|
|
56
|
+
]
|
|
57
|
+
: [];
|
|
58
|
+
const groups = [
|
|
59
|
+
canManageTarget
|
|
60
|
+
? [
|
|
61
|
+
{
|
|
62
|
+
key: "mute",
|
|
63
|
+
label: label(member.isSendMessageDisabled ? t("unmute_member") : t("mute_member")),
|
|
64
|
+
icon: _jsx(Icon, { icon: "bell-off-o", size: 16 }),
|
|
65
|
+
onClick: () => member.isSendMessageDisabled ? handlers.onToggleMute(member) : handlers.onAskMute(member),
|
|
66
|
+
},
|
|
67
|
+
]
|
|
68
|
+
: [],
|
|
69
|
+
adminItems,
|
|
70
|
+
permissions.transferOwnership
|
|
71
|
+
? [
|
|
72
|
+
{
|
|
73
|
+
key: "transfer-owner",
|
|
74
|
+
label: label(t("transfer_owner"), t("transfer_owner_hint"), "text-warning-800"),
|
|
75
|
+
icon: _jsx(Icon, { icon: "key-o", size: 16, className: "text-warning-800" }),
|
|
76
|
+
onClick: () => handlers.onAskTransfer(member),
|
|
77
|
+
},
|
|
78
|
+
]
|
|
79
|
+
: [],
|
|
80
|
+
canManageTarget
|
|
81
|
+
? [
|
|
82
|
+
{
|
|
83
|
+
key: "remove-member",
|
|
84
|
+
label: label(t("remove_from_group")),
|
|
85
|
+
icon: _jsx(Icon, { icon: "user-x", size: 16 }),
|
|
86
|
+
danger: true,
|
|
87
|
+
onClick: () => handlers.onAskRemove(member),
|
|
88
|
+
},
|
|
89
|
+
]
|
|
90
|
+
: [],
|
|
82
91
|
];
|
|
92
|
+
// Dividers only between non-empty groups so the menu never starts, ends or doubles up on one.
|
|
93
|
+
return groups
|
|
94
|
+
.filter((group) => group.length > 0)
|
|
95
|
+
.flatMap((group, index) => (index === 0 ? group : [DIVIDER, ...group]));
|
|
83
96
|
};
|
|
@@ -4,7 +4,7 @@ import { Spin } from "antd";
|
|
|
4
4
|
import { Icon } from "../../../components/icon";
|
|
5
5
|
import { documentIcon } from "../../../assets/svg";
|
|
6
6
|
import { renderFileSize, shortenFileName } from "../../../utils/common";
|
|
7
|
-
import { downloadFileFromUrl } from "../../../utils/download";
|
|
7
|
+
import { downloadFileFromUrl, openFileOrDownload } from "../../../utils/download";
|
|
8
8
|
const FileMessageItem = (props) => {
|
|
9
9
|
var _a;
|
|
10
10
|
const { message } = props;
|
|
@@ -17,7 +17,7 @@ const FileMessageItem = (props) => {
|
|
|
17
17
|
const handleView = () => {
|
|
18
18
|
if (!hasUrl)
|
|
19
19
|
return;
|
|
20
|
-
|
|
20
|
+
void openFileOrDownload(sourceUrl, fileName);
|
|
21
21
|
};
|
|
22
22
|
const handleDownload = () => {
|
|
23
23
|
downloadFileFromUrl(sourceUrl, fileName);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SystemLogMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/SystemLogMessage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"SystemLogMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/message/item/SystemLogMessage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAU3D,UAAU,yBAAyB;IACjC,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,QAAA,MAAM,oBAAoB,GAAI,aAAa,yBAAyB,mDA4CnE,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
|
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { getSystemLogMessageHtml, getSystemLogMessageText, } from "../../../utils/messageLog";
|
|
4
4
|
import { sanitizeHtml } from "../../../utils/common";
|
|
5
|
+
import { useTranslation } from "react-i18next";
|
|
5
6
|
import useAuthStore from "../../../store/auth";
|
|
6
7
|
import CrmSystemLine from "./CrmSystemLine";
|
|
7
8
|
const SystemLogMessageItem = ({ message }) => {
|
|
8
9
|
const isCrm = useAuthStore((state) => state.isCrm);
|
|
9
|
-
const
|
|
10
|
-
const
|
|
10
|
+
const viewerId = useAuthStore((state) => state.userID);
|
|
11
|
+
const { t } = useTranslation();
|
|
12
|
+
const html = getSystemLogMessageHtml(message, viewerId, t);
|
|
13
|
+
const text = getSystemLogMessageText(message, viewerId, t);
|
|
11
14
|
if (!html && !text) {
|
|
12
15
|
return null;
|
|
13
16
|
}
|
|
@@ -15,7 +15,7 @@ const SearchConversationAsGroups = (props) => {
|
|
|
15
15
|
scope,
|
|
16
16
|
});
|
|
17
17
|
if ((groups.length === 0 && !isLoading) || searchTerm.trim() === "")
|
|
18
|
-
return _jsx(Empty, { description: t("
|
|
18
|
+
return _jsx(Empty, { description: t("search_no_result") });
|
|
19
19
|
if (isLoading)
|
|
20
20
|
return (_jsx("div", { className: "flex items-center justify-center", children: _jsx(Spin, {}) }));
|
|
21
21
|
return (_jsx("div", { id: "scrollableSearchGroupsTab", className: "h-full overflow-auto", "data-cp-name": "SearchConversationAsGroups", children: _jsx(InfiniteScroll, { dataLength: groups.length, next: fetchNextPage, hasMore: hasNextPage, loader: _jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) }), scrollableTarget: "scrollableSearchGroupsTab", children: groups.map((item) => (_jsx(SearchItemAsGroup, { group: item, searchTerm: searchTerm }, item.conversationId))) }) }));
|
|
@@ -18,7 +18,7 @@ const SearchConversationAsMessages = (props) => {
|
|
|
18
18
|
options: { scope },
|
|
19
19
|
});
|
|
20
20
|
if ((dataFlatten.length === 0 && !isLoading) || searchTerm.trim() === "")
|
|
21
|
-
return _jsx(Empty, { description: t("
|
|
21
|
+
return _jsx(Empty, { description: t("search_no_result") });
|
|
22
22
|
if (isLoading)
|
|
23
23
|
return (_jsx("div", { className: "flex items-center justify-center", children: _jsx(Spin, {}) }));
|
|
24
24
|
return (_jsx("div", { id: "scrollableSearchMessagesTab", className: "h-full overflow-auto", "data-cp-name": "SearchConversationAsMessages", children: _jsx(InfiniteScroll, { dataLength: dataFlatten.length, next: fetchNextPage, hasMore: hasNextPage, loader: _jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) }), scrollableTarget: "scrollableSearchMessagesTab", children: dataFlatten.map((item) => (_jsx(SearchItemAsMessage, { message: item.chatLog, searchTerm: searchTerm, displayTag: item.displayTag, tag: item.tag }, item.chatLog.clientMsgID))) }) }));
|
|
@@ -16,7 +16,7 @@ const SearchConversationMyInbox = ({ searchTerm = "", }) => {
|
|
|
16
16
|
options: { untilEmptyPage: true },
|
|
17
17
|
});
|
|
18
18
|
if ((dataFlatten.length === 0 && !isLoading) || searchTerm.trim() === "")
|
|
19
|
-
return _jsx(Empty, { description: t("
|
|
19
|
+
return _jsx(Empty, { description: t("search_no_result") });
|
|
20
20
|
if (isLoading)
|
|
21
21
|
return (_jsx("div", { className: "flex items-center justify-center", children: _jsx(Spin, {}) }));
|
|
22
22
|
return (_jsxs("div", { className: "overflow-auto", "data-cp-name": "SearchConversationMyInbox", children: [dataFlatten.map((item) => (_jsx(SearchItemAsMessage, { message: item.chatLog, searchTerm: searchTerm, displayTag: item.displayTag }, item.chatLog.clientMsgID))), _jsx("div", { className: "flex justify-center py-2", children: _jsx(Button, { type: "link", loading: isFetchingNextPage, onClick: () => fetchNextPage(), children: t("see_more") }) })] }));
|
|
@@ -14,9 +14,10 @@ interface SessionFolderListProps {
|
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
|
-
* Folders of one scope.
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* Folders of one scope. In "my messages" the "open" parent has two click
|
|
18
|
+
* targets: the label selects every open session (and reveals the children), the
|
|
19
|
+
* chevron collapses them. A team's parent label only reveals its children: the
|
|
20
|
+
* team query has no "all open" list.
|
|
20
21
|
*/
|
|
21
22
|
declare const SessionFolderList: ({ summary, teamId, activeFolderId, onFilterSelect, allGroups, }: SessionFolderListProps) => import("react/jsx-runtime").JSX.Element;
|
|
22
23
|
export default SessionFolderList;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionFolderList.d.ts","sourceRoot":"","sources":["../../../src/components/session/SessionFolderList.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SessionFolderList.d.ts","sourceRoot":"","sources":["../../../src/components/session/SessionFolderList.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAQ3D,UAAU,sBAAsB;IAC9B,OAAO,EAAE,uBAAuB,CAAC;IACjC,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IACjD,gEAAgE;IAChE,SAAS,CAAC,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;CACvD;AAED;;;;;GAKG;AACH,QAAA,MAAM,iBAAiB,GAAI,iEAMxB,sBAAsB,4CAoGxB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -4,13 +4,15 @@ import { useState } from "react";
|
|
|
4
4
|
import { useTranslation } from "react-i18next";
|
|
5
5
|
import { Tooltip } from "antd";
|
|
6
6
|
import { StrokeIcon } from "../../components/icon/StrokeIcon";
|
|
7
|
-
import { buildFolderId } from "../../store/sessionFolder";
|
|
7
|
+
import { buildFolderId, OPEN_FOLDER_KEY } from "../../store/sessionFolder";
|
|
8
|
+
import clsx from "clsx";
|
|
8
9
|
import FolderRow, { FolderCount } from "./FolderRow";
|
|
9
10
|
import { getCompletedFilterConfig, getFilterCount, getOpenFilterConfigs, } from "./sessionFilters";
|
|
10
11
|
/**
|
|
11
|
-
* Folders of one scope.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* Folders of one scope. In "my messages" the "open" parent has two click
|
|
13
|
+
* targets: the label selects every open session (and reveals the children), the
|
|
14
|
+
* chevron collapses them. A team's parent label only reveals its children: the
|
|
15
|
+
* team query has no "all open" list.
|
|
14
16
|
*/
|
|
15
17
|
const SessionFolderList = ({ summary, teamId, activeFolderId, onFilterSelect, allGroups, }) => {
|
|
16
18
|
const { t } = useTranslation();
|
|
@@ -19,9 +21,16 @@ const SessionFolderList = ({ summary, teamId, activeFolderId, onFilterSelect, al
|
|
|
19
21
|
const completed = getCompletedFilterConfig();
|
|
20
22
|
const isActive = (filterKey) => activeFolderId ===
|
|
21
23
|
buildFolderId({ scope: isTeam ? "team" : "mine", teamId, filterKey });
|
|
24
|
+
const isOpenActive = !isTeam && isActive(OPEN_FOLDER_KEY);
|
|
22
25
|
const groupLabel = t("active_sessions");
|
|
23
26
|
const toggleLabel = t(isOpenGroupExpanded ? "folder_group_collapse" : "folder_group_expand", { name: groupLabel });
|
|
24
|
-
return (_jsxs("div", { className: "flex flex-col gap-0.5", "data-cp-name": "SessionFolderList", children: [_jsxs("div", { className: "flex items-center gap-0.5", children: [_jsxs("button", { type: "button", onClick: () =>
|
|
27
|
+
return (_jsxs("div", { className: "flex flex-col gap-0.5", "data-cp-name": "SessionFolderList", children: [_jsxs("div", { className: "flex items-center gap-0.5", children: [_jsxs("button", { type: "button", onClick: () => {
|
|
28
|
+
setIsOpenGroupExpanded(true);
|
|
29
|
+
if (!isTeam)
|
|
30
|
+
onFilterSelect({ status: undefined, tag: undefined, open: true });
|
|
31
|
+
}, "aria-current": isOpenActive ? "true" : undefined, className: clsx("flex h-9 min-w-0 flex-1 items-center gap-2.5 rounded-lg pr-2 text-left text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-400", isTeam ? "pl-5" : "pl-2", isOpenActive
|
|
32
|
+
? "bg-primary-25 font-semibold text-primary-500"
|
|
33
|
+
: "text-gray-900 hover:bg-gray-5"), children: [_jsx(StrokeIcon, { name: "message-circle", size: 18, className: "text-gray-600" }), _jsx("span", { className: "min-w-0 flex-1 truncate", children: groupLabel }), _jsx(FolderCount, { count: summary.activeSessionCount })] }), !isTeam && (_jsx(Tooltip, { title: toggleLabel, children: _jsx("button", { type: "button", "aria-label": toggleLabel, "aria-expanded": isOpenGroupExpanded, onClick: () => setIsOpenGroupExpanded((expanded) => !expanded), className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-lg text-gray-600 hover:bg-gray-5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-400", children: _jsx(StrokeIcon, { name: isOpenGroupExpanded ? "chevron-down" : "chevron-right", size: 16 }) }) }))] }), (isTeam || isOpenGroupExpanded) &&
|
|
25
34
|
getOpenFilterConfigs(isTeam).map((config) => (_jsx("div", { className: "flex", children: _jsx(FolderRow, { label: t(config.labelKey), iconName: config.iconName, iconClassName: config.iconClassName, count: getFilterCount(config, summary), highlighted: config.highlighted, active: isActive(config.key), indentClassName: isTeam ? "pl-8" : "pl-7", onClick: () => onFilterSelect(Object.assign(Object.assign({}, config.filter), (teamId && { teamId }))) }) }, config.key))), completed && (_jsx("div", { className: "flex", children: _jsx(FolderRow, { label: t(completed.labelKey), iconName: completed.iconName, iconClassName: completed.iconClassName, count: getFilterCount(completed, summary), active: isActive(completed.key), indentClassName: isTeam ? "pl-5" : "pl-2", onClick: () => onFilterSelect(Object.assign(Object.assign({}, completed.filter), (teamId && { teamId }))) }) })), allGroups && (_jsx("div", { className: "flex", children: _jsx(FolderRow, { label: t("all_groups"), iconName: "inbox", iconClassName: "text-gray-600", active: allGroups.active, onClick: allGroups.onSelect }) }))] }));
|
|
26
35
|
};
|
|
27
36
|
export default SessionFolderList;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GroupInfoBodyCrm.d.ts","sourceRoot":"","sources":["../../../src/components/thread/GroupInfoBodyCrm.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAUzC,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,kBAAkB,GAAG,aAAa,CAAC;AACpF,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE9D,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,sBAAsB,EAAE,OAAO,CAAC;IAChC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAAC;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAClD,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,mBAAmB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,KAAK,IAAI,CAAC;IACrD,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,KAAK,IAAI,CAAC;IACtD,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,KAAK,IAAI,CAAC;IACpD,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAC/D,oBAAoB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,mBAAmB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAChD,SAAS,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;CAC/C;AA6BD,kGAAkG;AAClG,QAAA,MAAM,gBAAgB,GAAI,OAAO,qBAAqB,
|
|
1
|
+
{"version":3,"file":"GroupInfoBodyCrm.d.ts","sourceRoot":"","sources":["../../../src/components/thread/GroupInfoBodyCrm.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAUzC,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,kBAAkB,GAAG,aAAa,CAAC;AACpF,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE9D,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,sBAAsB,EAAE,OAAO,CAAC;IAChC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAAC;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAClD,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,mBAAmB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,KAAK,IAAI,CAAC;IACrD,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,KAAK,IAAI,CAAC;IACtD,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,KAAK,IAAI,CAAC;IACpD,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAC/D,oBAAoB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,mBAAmB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAChD,SAAS,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;CAC/C;AA6BD,kGAAkG;AAClG,QAAA,MAAM,gBAAgB,GAAI,OAAO,qBAAqB,4CAwJrD,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|