@droppii-org/chat-sdk 0.1.19 → 0.1.21

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.
Files changed (131) hide show
  1. package/dist/components/conversation/ConversationBySessionItem.d.ts +3 -1
  2. package/dist/components/conversation/ConversationBySessionItem.d.ts.map +1 -1
  3. package/dist/components/conversation/ConversationBySessionItem.js +4 -7
  4. package/dist/components/conversation/DeskConversationList.d.ts.map +1 -1
  5. package/dist/components/conversation/DeskConversationList.js +6 -2
  6. package/dist/components/message/GroupMembersDrawer.d.ts +4 -1
  7. package/dist/components/message/GroupMembersDrawer.d.ts.map +1 -1
  8. package/dist/components/message/GroupMembersDrawer.js +39 -5
  9. package/dist/components/message/MessageHeader.d.ts +2 -1
  10. package/dist/components/message/MessageHeader.d.ts.map +1 -1
  11. package/dist/components/message/MessageHeader.js +3 -4
  12. package/dist/components/message/MessageList.d.ts.map +1 -1
  13. package/dist/components/message/MessageList.js +8 -11
  14. package/dist/components/message/UnassignedSessionFooter.d.ts +7 -0
  15. package/dist/components/message/UnassignedSessionFooter.d.ts.map +1 -0
  16. package/dist/components/message/UnassignedSessionFooter.js +26 -0
  17. package/dist/components/message/footer/ActionBar.d.ts.map +1 -1
  18. package/dist/components/message/footer/ActionBar.js +4 -1
  19. package/dist/components/message/footer/EnterHandler.d.ts.map +1 -1
  20. package/dist/components/message/footer/EnterHandler.js +20 -2
  21. package/dist/components/message/footer/SessionClosedModal.d.ts +10 -0
  22. package/dist/components/message/footer/SessionClosedModal.d.ts.map +1 -0
  23. package/dist/components/message/footer/SessionClosedModal.js +9 -0
  24. package/dist/components/message/footer/index.d.ts.map +1 -1
  25. package/dist/components/message/footer/index.js +103 -18
  26. package/dist/components/message/item/SystemLogMessage.d.ts.map +1 -1
  27. package/dist/components/message/item/SystemLogMessage.js +9 -10
  28. package/dist/components/searchConversation/SearchAll.d.ts.map +1 -1
  29. package/dist/components/searchConversation/SearchAll.js +5 -3
  30. package/dist/components/searchConversation/SearchConversationAsMessages.d.ts.map +1 -1
  31. package/dist/components/searchConversation/SearchConversationAsMessages.js +1 -1
  32. package/dist/components/searchConversation/SearchConversationAsUsers.js +1 -1
  33. package/dist/components/searchConversation/SearchConversationMyInbox.d.ts +6 -0
  34. package/dist/components/searchConversation/SearchConversationMyInbox.d.ts.map +1 -0
  35. package/dist/components/searchConversation/SearchConversationMyInbox.js +24 -0
  36. package/dist/components/searchConversation/SearchDrawer.js +10 -10
  37. package/dist/components/searchConversation/SearchMessageOnCurrentConversation.d.ts.map +1 -1
  38. package/dist/components/searchConversation/SearchMessageOnCurrentConversation.js +1 -1
  39. package/dist/components/searchConversation/index.d.ts +1 -0
  40. package/dist/components/searchConversation/index.d.ts.map +1 -1
  41. package/dist/components/searchConversation/index.js +8 -1
  42. package/dist/components/searchConversation/item/SearchItemAsMessage.d.ts +1 -0
  43. package/dist/components/searchConversation/item/SearchItemAsMessage.d.ts.map +1 -1
  44. package/dist/components/searchConversation/item/SearchItemAsMessage.js +4 -4
  45. package/dist/components/thread/ManualAssignPopover.d.ts +5 -2
  46. package/dist/components/thread/ManualAssignPopover.d.ts.map +1 -1
  47. package/dist/components/thread/ManualAssignPopover.js +40 -21
  48. package/dist/components/thread/SessionSection.d.ts.map +1 -1
  49. package/dist/components/thread/SessionSection.js +4 -2
  50. package/dist/components/thread/ThreadInfo.d.ts.map +1 -1
  51. package/dist/components/thread/ThreadInfo.js +2 -1
  52. package/dist/constants/index.d.ts +6 -1
  53. package/dist/constants/index.d.ts.map +1 -1
  54. package/dist/constants/index.js +6 -1
  55. package/dist/hooks/cannedResponse/useFetchCannedResponse.js +2 -2
  56. package/dist/hooks/global/useGlobalEvent.d.ts.map +1 -1
  57. package/dist/hooks/global/useGlobalEvent.js +11 -0
  58. package/dist/hooks/group/useGroupMembers.d.ts.map +1 -1
  59. package/dist/hooks/group/useGroupMembers.js +17 -0
  60. package/dist/hooks/message/useMessage.js +5 -5
  61. package/dist/hooks/message/usePullSessionMessages.d.ts +2 -0
  62. package/dist/hooks/message/usePullSessionMessages.d.ts.map +1 -1
  63. package/dist/hooks/message/usePullSessionMessages.js +18 -15
  64. package/dist/hooks/search/useSearchMessage.d.ts +2 -1
  65. package/dist/hooks/search/useSearchMessage.d.ts.map +1 -1
  66. package/dist/hooks/search/useSearchMessage.js +9 -9
  67. package/dist/hooks/session/useAssignSession.d.ts +4 -0
  68. package/dist/hooks/session/useAssignSession.d.ts.map +1 -1
  69. package/dist/hooks/session/useAssignSession.js +44 -11
  70. package/dist/hooks/session/useConversationSessionState.d.ts +1 -8
  71. package/dist/hooks/session/useConversationSessionState.d.ts.map +1 -1
  72. package/dist/hooks/session/useConversationSessionState.js +2 -25
  73. package/dist/hooks/session/useGetListSessionByConversation.d.ts.map +1 -1
  74. package/dist/hooks/session/useGetListSessionByConversation.js +2 -1
  75. package/dist/hooks/session/useGetSession.d.ts.map +1 -1
  76. package/dist/hooks/session/useGetSession.js +2 -2
  77. package/dist/hooks/session/useGetTeamSupporters.d.ts +2 -1
  78. package/dist/hooks/session/useGetTeamSupporters.d.ts.map +1 -1
  79. package/dist/hooks/session/useGetTeamSupporters.js +2 -2
  80. package/dist/hooks/session/useIsJoinedGroup.d.ts +1 -1
  81. package/dist/hooks/session/useIsJoinedGroup.d.ts.map +1 -1
  82. package/dist/hooks/session/useIsJoinedGroup.js +13 -19
  83. package/dist/hooks/session/useJoinGroupFlow.d.ts +8 -6
  84. package/dist/hooks/session/useJoinGroupFlow.d.ts.map +1 -1
  85. package/dist/hooks/session/useJoinGroupFlow.js +19 -57
  86. package/dist/hooks/session/useJoinSession.d.ts.map +1 -1
  87. package/dist/hooks/session/useJoinSession.js +3 -0
  88. package/dist/hooks/session/useLeaveConversation.d.ts +5 -0
  89. package/dist/hooks/session/useLeaveConversation.d.ts.map +1 -0
  90. package/dist/hooks/session/useLeaveConversation.js +35 -0
  91. package/dist/hooks/session/useReopenOrCreateSession.d.ts +4 -0
  92. package/dist/hooks/session/useReopenOrCreateSession.d.ts.map +1 -0
  93. package/dist/hooks/session/useReopenOrCreateSession.js +32 -0
  94. package/dist/hooks/session/useSessionLatestPreview.d.ts +7 -0
  95. package/dist/hooks/session/useSessionLatestPreview.d.ts.map +1 -0
  96. package/dist/hooks/session/useSessionLatestPreview.js +82 -0
  97. package/dist/hooks/session/useSortedSessions.d.ts +4 -0
  98. package/dist/hooks/session/useSortedSessions.d.ts.map +1 -0
  99. package/dist/hooks/session/useSortedSessions.js +13 -0
  100. package/dist/hooks/session/useSyncGroupStateAfterJoin.d.ts +9 -0
  101. package/dist/hooks/session/useSyncGroupStateAfterJoin.d.ts.map +1 -0
  102. package/dist/hooks/session/useSyncGroupStateAfterJoin.js +23 -0
  103. package/dist/index.d.ts +1 -0
  104. package/dist/index.d.ts.map +1 -1
  105. package/dist/index.js +1 -0
  106. package/dist/locales/vi/common.json +18 -2
  107. package/dist/services/query.d.ts +5 -0
  108. package/dist/services/query.d.ts.map +1 -1
  109. package/dist/services/query.js +5 -0
  110. package/dist/services/routes.d.ts +4 -0
  111. package/dist/services/routes.d.ts.map +1 -1
  112. package/dist/services/routes.js +4 -0
  113. package/dist/store/conversation.d.ts.map +1 -1
  114. package/dist/store/conversation.js +5 -2
  115. package/dist/styles/global.css +1 -1
  116. package/dist/tsconfig.tsbuildinfo +1 -1
  117. package/dist/types/chat.d.ts +1 -1
  118. package/dist/types/chat.d.ts.map +1 -1
  119. package/dist/types/dto.d.ts +4 -0
  120. package/dist/types/dto.d.ts.map +1 -1
  121. package/dist/utils/events.d.ts +2 -0
  122. package/dist/utils/events.d.ts.map +1 -1
  123. package/dist/utils/messageLog.d.ts +1 -1
  124. package/dist/utils/messageLog.d.ts.map +1 -1
  125. package/dist/utils/messageLog.js +23 -6
  126. package/dist/utils/messageTransform.d.ts.map +1 -1
  127. package/dist/utils/messageTransform.js +1 -1
  128. package/dist/utils/queryHelpers.d.ts +1 -1
  129. package/dist/utils/queryHelpers.d.ts.map +1 -1
  130. package/dist/utils/queryHelpers.js +1 -1
  131. package/package.json +1 -1
@@ -1,7 +1,9 @@
1
+ import type { LatestPreview } from "../../hooks/session/useSessionLatestPreview";
1
2
  import { ISessionByStatus } from "../../store/type";
2
3
  interface ConversationBySessionItemProps {
3
4
  sessionItem: ISessionByStatus;
5
+ latestPreview?: LatestPreview;
4
6
  }
5
- declare const ConversationBySessionItem: ({ sessionItem, }: ConversationBySessionItemProps) => import("react/jsx-runtime").JSX.Element | null;
7
+ declare const ConversationBySessionItem: ({ sessionItem, latestPreview, }: ConversationBySessionItemProps) => import("react/jsx-runtime").JSX.Element | null;
6
8
  export default ConversationBySessionItem;
7
9
  //# sourceMappingURL=ConversationBySessionItem.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ConversationBySessionItem.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/ConversationBySessionItem.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AASpD,UAAU,8BAA8B;IACtC,WAAW,EAAE,gBAAgB,CAAC;CAC/B;AAED,QAAA,MAAM,yBAAyB,GAAI,kBAEhC,8BAA8B,mDAgGhC,CAAC;AAEF,eAAe,yBAAyB,CAAC"}
1
+ {"version":3,"file":"ConversationBySessionItem.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/ConversationBySessionItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAEjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAQpD,UAAU,8BAA8B;IACtC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,QAAA,MAAM,yBAAyB,GAAI,iCAGhC,8BAA8B,mDAyFhC,CAAC;AAEF,eAAe,yBAAyB,CAAC"}
@@ -6,9 +6,8 @@ import { usePathname, useRouter, useSearchParams } from "next/navigation";
6
6
  import { Avatar, Badge } from "antd";
7
7
  import { useChatContext } from "../../context/ChatContext";
8
8
  import { useConversationDisplayData } from "../../hooks/conversation/useConversation";
9
- import { useConversationPreview } from "../../hooks/conversation/useConversationPreview";
10
9
  import { formatTimestamp, parseLatestMessage } from "../../utils/common";
11
- const ConversationBySessionItem = ({ sessionItem, }) => {
10
+ const ConversationBySessionItem = ({ sessionItem, latestPreview, }) => {
12
11
  var _a;
13
12
  const { t } = useTranslation();
14
13
  const user = useChatContext().user;
@@ -31,13 +30,11 @@ const ConversationBySessionItem = ({ sessionItem, }) => {
31
30
  setSelectedConversationId(conversation.conversationID);
32
31
  };
33
32
  const { avatar, displayName = "" } = useConversationDisplayData(conversation || null);
34
- const { latestMsg, latestMsgSendTime } = useConversationPreview({
35
- conversation,
36
- ownerUserID: sessionItem.ownerId,
37
- });
33
+ const latestMsg = (latestPreview === null || latestPreview === void 0 ? void 0 : latestPreview.latestMsg) || "";
34
+ const latestMsgSendTime = (latestPreview === null || latestPreview === void 0 ? void 0 : latestPreview.latestMsgSendTime) || 0;
38
35
  if (!conversation)
39
36
  return null;
40
- return (_jsxs("div", { onClick: () => handleConversationClick(conversation), className: `relative p-3 border-b border-gray-100 hover:bg-gray-100 cursor-pointer transition-colors ${isSelected ? "bg-blue-50" : "bg-white"}`, children: [isSelected && (_jsx("div", { className: "absolute left-0 top-0 bottom-0 w-1 bg-blue-500" })), _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "relative flex-shrink-0", children: _jsx(Badge, { dot: true, status: "success", offset: [-2, 36], children: _jsx(Avatar, { size: 48, src: avatar, children: ((_a = displayName === null || displayName === void 0 ? void 0 : displayName.charAt) === null || _a === void 0 ? void 0 : _a.call(displayName, 0)) || "A" }) }) }), _jsx("div", { className: "flex-1 min-w-0", children: _jsxs("div", { className: "flex items-start justify-between", children: [_jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("h3", { className: "font-semibold text-gray-900 text-sm truncate", children: displayName }), _jsx("p", { className: "text-xs text-gray-500 truncate mt-0.5", children: parseLatestMessage(latestMsg, user === null || user === void 0 ? void 0 : user.userID, t) })] }), _jsxs("div", { className: "flex flex-col items-end gap-1 ml-2", children: [latestMsgSendTime > 0 && (_jsx("span", { className: "text-xs text-gray-400", children: formatTimestamp(latestMsgSendTime, {
37
+ return (_jsxs("div", { onClick: () => handleConversationClick(conversation), className: `relative p-3 border-b border-gray-100 hover:bg-gray-100 cursor-pointer transition-colors ${isSelected ? "bg-blue-50" : "bg-white"}`, children: [isSelected && (_jsx("div", { className: "absolute left-0 top-0 bottom-0 w-1 bg-blue-500" })), _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "relative flex-shrink-0", children: _jsx(Avatar, { size: 48, src: avatar, children: ((_a = displayName === null || displayName === void 0 ? void 0 : displayName.charAt) === null || _a === void 0 ? void 0 : _a.call(displayName, 0)) || "A" }) }), _jsx("div", { className: "flex-1 min-w-0", children: _jsxs("div", { className: "flex items-start justify-between", children: [_jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("h3", { className: "font-semibold text-gray-900 text-sm truncate", children: displayName }), _jsx("p", { className: "text-xs text-gray-500 truncate mt-0.5", children: parseLatestMessage(latestMsg, user === null || user === void 0 ? void 0 : user.userID, t) })] }), _jsxs("div", { className: "flex flex-col items-end gap-1 ml-2", children: [latestMsgSendTime > 0 && (_jsx("span", { className: "text-xs text-gray-400", children: formatTimestamp(latestMsgSendTime, {
41
38
  hasTime: true,
42
39
  }) })), _jsx("div", { className: "flex items-center gap-1", children: conversation.unreadCount > 0 && (_jsx(Badge, { count: conversation.unreadCount })) })] })] }) })] })] }, conversation.conversationID));
43
40
  };
@@ -1 +1 @@
1
- {"version":3,"file":"DeskConversationList.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/DeskConversationList.tsx"],"names":[],"mappings":"AAoBA,QAAA,MAAM,oBAAoB,+CAoMzB,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"DeskConversationList.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/DeskConversationList.tsx"],"names":[],"mappings":"AAsBA,QAAA,MAAM,oBAAoB,+CAgNzB,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
@@ -12,6 +12,8 @@ import useSessionStore from "../../store/session";
12
12
  import InfiniteScroll from "react-infinite-scroll-component";
13
13
  import ConversationBySessionItem from "./ConversationBySessionItem";
14
14
  import { useGetSession } from "../../hooks/session/useGetSession";
15
+ import { useSortedSessions } from "../../hooks/session/useSortedSessions";
16
+ import { useSessionLatestPreview } from "../../hooks/session/useSessionLatestPreview";
15
17
  import { useGetTeamSessionSummary } from "../../hooks/session/useGetTeamSessionSummary";
16
18
  import { DChatSDK } from "../../constants/sdk";
17
19
  import emitter from "../../utils/events";
@@ -29,7 +31,9 @@ const DeskConversationList = () => {
29
31
  const updateConversationList = useConversationStore((state) => state.updateConversationList);
30
32
  const filterSummary = useSessionStore((state) => state.filterSummary);
31
33
  const { data: teamSummaries } = useGetTeamSessionSummary();
32
- const { dataFlatten: sessions, hasNextPage, fetchNextPage, refetch } = useGetSession({ filter: filterSummary });
34
+ const { dataFlatten: rawSessions, hasNextPage, fetchNextPage, refetch, } = useGetSession({ filter: filterSummary });
35
+ const latestPreviewMap = useSessionLatestPreview(rawSessions);
36
+ const sessions = useSortedSessions(rawSessions, latestPreviewMap);
33
37
  const currentFilterKey = filterSummary.status || filterSummary.tag || "";
34
38
  const filterConfig = getFilterConfig(currentFilterKey);
35
39
  const pathName = filterSummary.teamId
@@ -91,7 +95,7 @@ const DeskConversationList = () => {
91
95
  height: "100%",
92
96
  overflow: showSearch ? "hidden" : "auto",
93
97
  position: "relative",
94
- }, children: [_jsx(InfiniteScroll, { dataLength: (sessions === null || sessions === void 0 ? void 0 : sessions.length) || 0, next: fetchNextPage, hasMore: hasNextPage, loader: _jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) }), scrollableTarget: "scrollableConversationsDiv", children: (sessions === null || sessions === void 0 ? void 0 : sessions.length) === 0 ? (_jsx("div", { className: "flex items-center justify-center py-12", children: _jsx(Empty, { image: _jsx(Icon, { icon: "chat-square-b", size: 80, className: "text-gray-300" }), description: t("no_conversation") }) })) : ((_b = sessions === null || sessions === void 0 ? void 0 : sessions.map) === null || _b === void 0 ? void 0 : _b.call(sessions, (session) => (_jsx(ConversationBySessionItem, { sessionItem: session }, session.conversationId)))) }), _jsx(Drawer, { open: showSearch, mask: false, closeIcon: false, styles: {
98
+ }, children: [_jsx(InfiniteScroll, { dataLength: (sessions === null || sessions === void 0 ? void 0 : sessions.length) || 0, next: fetchNextPage, hasMore: hasNextPage, loader: _jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) }), scrollableTarget: "scrollableConversationsDiv", children: (sessions === null || sessions === void 0 ? void 0 : sessions.length) === 0 ? (_jsx("div", { className: "flex items-center justify-center py-12", children: _jsx(Empty, { image: _jsx(Icon, { icon: "chat-square-b", size: 80, className: "text-gray-300" }), description: t("no_conversation") }) })) : ((_b = sessions === null || sessions === void 0 ? void 0 : sessions.map) === null || _b === void 0 ? void 0 : _b.call(sessions, (session) => (_jsx(ConversationBySessionItem, { sessionItem: session, latestPreview: latestPreviewMap.get(session.conversationId) }, session.conversationId)))) }), _jsx(Drawer, { open: showSearch, mask: false, closeIcon: false, styles: {
95
99
  body: {
96
100
  padding: 0,
97
101
  },
@@ -1,7 +1,10 @@
1
+ import { ISessionResponse } from "../../types/dto";
1
2
  interface GroupMembersDrawerProps {
2
3
  groupID?: string;
4
+ conversationId?: string;
5
+ currentSession?: ISessionResponse;
3
6
  disabled?: boolean;
4
7
  }
5
- declare const GroupMembersDrawer: ({ groupID, disabled, }: GroupMembersDrawerProps) => import("react/jsx-runtime").JSX.Element;
8
+ declare const GroupMembersDrawer: ({ groupID, conversationId, currentSession, disabled, }: GroupMembersDrawerProps) => import("react/jsx-runtime").JSX.Element;
6
9
  export default GroupMembersDrawer;
7
10
  //# sourceMappingURL=GroupMembersDrawer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GroupMembersDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/message/GroupMembersDrawer.tsx"],"names":[],"mappings":"AAUA,UAAU,uBAAuB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAsCD,QAAA,MAAM,kBAAkB,GAAI,wBAGzB,uBAAuB,4CAwLzB,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"GroupMembersDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/message/GroupMembersDrawer.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAKnD,UAAU,uBAAuB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAsCD,QAAA,MAAM,kBAAkB,GAAI,wDAKzB,uBAAuB,4CA0OzB,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -1,11 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { GroupMemberRole } from "@openim/wasm-client-sdk";
3
- import { Avatar, Button, Drawer, Dropdown, Empty, Spin } from "antd";
3
+ import { Avatar, Button, Drawer, Dropdown, Empty, message, Modal, Spin } from "antd";
4
4
  import { useEffect, useMemo, useState } from "react";
5
5
  import { useTranslation } from "react-i18next";
6
+ import { usePathname, useRouter } from "next/navigation";
6
7
  import useAuthStore from "../../store/auth";
7
8
  import useConversationStore from "../../store/conversation";
8
9
  import { useGroupMembers } from "../../hooks/group/useGroupMembers";
10
+ import { useLeaveConversation } from "../../hooks/session/useLeaveConversation";
9
11
  import { Icon } from "../icon";
10
12
  const getMemberDisplayName = (member) => {
11
13
  return member.nickname || member.userID || "";
@@ -20,13 +22,17 @@ const getMemberRoleLabel = ({ member, customerUserID, t, }) => {
20
22
  }
21
23
  return t("group_member");
22
24
  };
23
- const GroupMembersDrawer = ({ groupID, disabled = false, }) => {
25
+ const GroupMembersDrawer = ({ groupID, conversationId, currentSession, disabled = false, }) => {
24
26
  var _a, _b;
25
27
  const { t } = useTranslation();
28
+ const router = useRouter();
29
+ const pathname = usePathname();
26
30
  const [isOpen, setIsOpen] = useState(false);
31
+ const [showLeaveConfirm, setShowLeaveConfirm] = useState(false);
27
32
  const authUserID = useAuthStore((state) => state.userID);
28
33
  const conversationData = useConversationStore((state) => state.conversationData);
29
- const { members, isLoading, error } = useGroupMembers(groupID);
34
+ const { members, isLoading, error, refetch } = useGroupMembers(groupID);
35
+ const { mutateAsync: leaveConversation, isPending: isLeaving } = useLeaveConversation();
30
36
  let customerUserID = "";
31
37
  try {
32
38
  const exConversationInfo = JSON.parse((conversationData === null || conversationData === void 0 ? void 0 : conversationData.ex) || "{}");
@@ -63,11 +69,39 @@ const GroupMembersDrawer = ({ groupID, disabled = false, }) => {
63
69
  return;
64
70
  }
65
71
  setIsOpen(true);
72
+ void refetch();
66
73
  };
67
74
  const handleCloseDrawer = () => {
68
75
  setIsOpen(false);
69
76
  };
70
- const handleLeaveGroup = () => { };
77
+ const isCurrentUserAssigneeOfActiveSession = useMemo(() => {
78
+ if (!currentSession || currentSession.isClosed)
79
+ return false;
80
+ return currentSession.supporterId === authUserID;
81
+ }, [currentSession, authUserID]);
82
+ const handleLeaveGroup = () => {
83
+ if (isCurrentUserAssigneeOfActiveSession) {
84
+ message.error(t("leave_group_assignee_error"));
85
+ return;
86
+ }
87
+ setShowLeaveConfirm(true);
88
+ };
89
+ const handleConfirmLeave = async () => {
90
+ var _a, _b;
91
+ if (!conversationId || !groupID)
92
+ return;
93
+ try {
94
+ await leaveConversation({ conversationId });
95
+ message.success(t("leave_group_success"));
96
+ router.replace(pathname);
97
+ setShowLeaveConfirm(false);
98
+ setIsOpen(false);
99
+ }
100
+ catch (error) {
101
+ const errorMessage = ((_b = (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) || t("leave_group_failed");
102
+ message.error(errorMessage);
103
+ }
104
+ };
71
105
  useEffect(() => {
72
106
  setIsOpen(false);
73
107
  }, [groupID]);
@@ -99,6 +133,6 @@ const GroupMembersDrawer = ({ groupID, disabled = false, }) => {
99
133
  padding: 0,
100
134
  height: "100%",
101
135
  },
102
- }, getContainer: false, width: 360, children: _jsxs("div", { className: "flex flex-col h-full bg-white", children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-100", children: [_jsx("span", { className: "text-lg font-medium", children: t("members") }), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: handleCloseDrawer, children: _jsx(Icon, { icon: "close-b", size: 22 }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto", children: renderContent() })] }) })] }));
136
+ }, getContainer: false, width: 360, children: _jsxs("div", { className: "flex flex-col h-full bg-white", children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-100", children: [_jsx("span", { className: "text-lg font-medium", children: t("members") }), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: handleCloseDrawer, children: _jsx(Icon, { icon: "close-b", size: 22 }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto", children: renderContent() })] }) }), _jsx(Modal, { centered: true, open: showLeaveConfirm, onOk: handleConfirmLeave, onCancel: () => setShowLeaveConfirm(false), title: t("leave_group_confirm_title"), okText: t("leave_group"), cancelText: t("cancel"), okType: "danger", confirmLoading: isLeaving, getContainer: false, children: _jsx("p", { children: t("leave_group_confirm_message") }) })] }));
103
137
  };
104
138
  export default GroupMembersDrawer;
@@ -3,6 +3,7 @@ import { ISessionResponse } from "../../types/dto";
3
3
  interface MessageHeaderProps {
4
4
  onClose?: () => void;
5
5
  currentSession?: ISessionResponse;
6
+ isJoined?: boolean | null;
6
7
  }
7
8
  type SelectSessionValueType = SessionStatus | SessionTag;
8
9
  export interface SelectSessionOption {
@@ -12,6 +13,6 @@ export interface SelectSessionOption {
12
13
  tintColorClassnameBg: string;
13
14
  bgTintColorClassname: string;
14
15
  }
15
- declare const MessageHeader: ({ onClose, currentSession }: MessageHeaderProps) => import("react/jsx-runtime").JSX.Element;
16
+ declare const MessageHeader: ({ onClose, currentSession, isJoined, }: MessageHeaderProps) => import("react/jsx-runtime").JSX.Element;
16
17
  export default MessageHeader;
17
18
  //# sourceMappingURL=MessageHeader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessageHeader.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageHeader.tsx"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAOnD,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,gBAAgB,CAAC;CACnC;AAED,KAAK,sBAAsB,GAAG,aAAa,GAAG,UAAU,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,sBAAsB,CAAC;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,QAAA,MAAM,aAAa,GAAI,6BAA6B,kBAAkB,4CA0MrE,CAAC;AAEF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"MessageHeader.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageHeader.tsx"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAMnD,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC3B;AAED,KAAK,sBAAsB,GAAG,aAAa,GAAG,UAAU,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,sBAAsB,CAAC;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,QAAA,MAAM,aAAa,GAAI,wCAIpB,kBAAkB,4CA6MpB,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -12,19 +12,18 @@ import SelectSession from "./SelectSession";
12
12
  import { useUpdateSession } from "../../hooks/session/useUpdateSession";
13
13
  import useAuthStore from "../../store/auth";
14
14
  import SearchDrawer from "../searchConversation/SearchDrawer";
15
- import { useIsJoinedGroup } from "../../hooks/session/useIsJoinedGroup";
16
15
  import { isGroupSession } from "../../utils/imCommon";
17
16
  import GroupMembersDrawer from "./GroupMembersDrawer";
18
- const MessageHeader = ({ onClose, currentSession }) => {
17
+ const MessageHeader = ({ onClose, currentSession, isJoined, }) => {
19
18
  var _a, _b;
20
19
  const { t } = useTranslation();
21
20
  const isCx = useAuthStore((state) => state.isCx);
21
+ const isCrm = useAuthStore((state) => state.isCrm);
22
22
  const conversationData = useConversationStore((state) => state.conversationData);
23
23
  const currentGroupInfo = useConversationStore((state) => state.currentGroupInfo);
24
24
  const { mutate: updateSession } = useUpdateSession();
25
25
  const { avatar, displayName } = useConversationDisplayData(conversationData);
26
26
  const shouldShowMemberCount = isGroupSession(conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationType);
27
- const { isJoined } = useIsJoinedGroup(conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID);
28
27
  const [currentSessionStatus, setCurrentSessionStatus] = useState(SessionStatus.UNASSIGNED);
29
28
  const [currentSessionTag, setCurrentSessionTag] = useState(SessionTag.NONE);
30
29
  const statusOptions = useMemo(() => {
@@ -128,6 +127,6 @@ const MessageHeader = ({ onClose, currentSession }) => {
128
127
  setCurrentSessionStatus(currentSession.status);
129
128
  }
130
129
  }, [currentSession]);
131
- return (_jsxs("div", { className: "px-4 py-3 flex items-center border-b gap-3 bg-white flex-wrap", children: [_jsx(Avatar, { src: avatar, size: "large", className: "min-w-10 min-h-10", children: ((_a = displayName === null || displayName === void 0 ? void 0 : displayName.charAt) === null || _a === void 0 ? void 0 : _a.call(displayName, 0)) || "A" }), _jsxs("div", { className: "flex flex-col overflow-hidden flex-1", children: [_jsx("p", { className: "text-base truncate", children: displayName || "" }), shouldShowMemberCount && (_jsx("p", { className: "text-xs text-gray-500 truncate", children: t("member_count", { count: (_b = currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.memberCount) !== null && _b !== void 0 ? _b : 0 }) }))] }), _jsxs("div", { className: "flex items-center gap-2 justify-end overflow-hidden", children: [isCx && (_jsx(SelectSession, { placeholder: t("select_tag"), options: tagOptions, value: currentSessionTag, onChange: (value) => handleUpdateSession(value, "tag", value === currentSessionTag), excludeOptions: [SessionTag.SLOW_PROCESSING, SessionTag.NONE] })), isCx && (_jsx(SelectSession, { placeholder: t("select_status"), options: statusOptions, value: currentSessionStatus, onChange: (value) => handleUpdateSession(value, "status", value === currentSessionStatus) })), _jsx(SearchDrawer, {}), shouldShowMemberCount && isJoined === true && (_jsx(GroupMembersDrawer, { groupID: conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID })), _jsx(MediaCollection, {}), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", children: _jsx(Icon, { icon: "align-justify-o", size: 22 }) }), !!onClose && (_jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: onClose, children: _jsx(Icon, { icon: "close-b", size: 22 }) }))] })] }));
130
+ return (_jsxs("div", { className: "px-4 py-3 flex items-center border-b gap-3 bg-white flex-wrap", children: [_jsx(Avatar, { src: avatar, size: "large", className: "min-w-10 min-h-10", children: ((_a = displayName === null || displayName === void 0 ? void 0 : displayName.charAt) === null || _a === void 0 ? void 0 : _a.call(displayName, 0)) || "A" }), _jsxs("div", { className: "flex flex-col overflow-hidden flex-1", children: [_jsx("p", { className: "text-base truncate", children: displayName || "" }), shouldShowMemberCount && (_jsx("p", { className: "text-xs text-gray-500 truncate", children: t("member_count", { count: (_b = currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.memberCount) !== null && _b !== void 0 ? _b : 0 }) }))] }), _jsxs("div", { className: "flex items-center gap-2 justify-end overflow-hidden", children: [isCx && (_jsx(SelectSession, { placeholder: t("select_tag"), options: tagOptions, value: currentSessionTag, onChange: (value) => handleUpdateSession(value, "tag", value === currentSessionTag), excludeOptions: [SessionTag.SLOW_PROCESSING, SessionTag.NONE] })), isCx && (_jsx(SelectSession, { placeholder: t("select_status"), options: statusOptions, value: currentSessionStatus, onChange: (value) => handleUpdateSession(value, "status", value === currentSessionStatus) })), _jsx(SearchDrawer, {}), shouldShowMemberCount && isJoined === true && isCrm && (_jsx(GroupMembersDrawer, { groupID: conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID, conversationId: conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID, currentSession: currentSession })), _jsx(MediaCollection, {}), _jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", children: _jsx(Icon, { icon: "align-justify-o", size: 22 }) }), !!onClose && (_jsx(Button, { type: "text", shape: "default", className: "text-gray-500 w-8 h-8 p-0", onClick: onClose, children: _jsx(Icon, { icon: "close-b", size: 22 }) }))] })] }));
132
131
  };
133
132
  export default MessageHeader;
@@ -1 +1 @@
1
- {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageList.tsx"],"names":[],"mappings":"AA2BA,UAAU,gBAAgB;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AAGD,QAAA,MAAM,WAAW,GAAI,OAAO,gBAAgB,4CAkV3C,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/message/MessageList.tsx"],"names":[],"mappings":"AA4BA,UAAU,gBAAgB;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AAGD,QAAA,MAAM,WAAW,GAAI,OAAO,gBAAgB,4CA6V3C,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -10,6 +10,7 @@ import MessageItem from "./item";
10
10
  import InfiniteScroll from "react-infinite-scroll-component";
11
11
  import MessageHeader from "./MessageHeader";
12
12
  import MessageFooter from "./footer";
13
+ import UnassignedSessionFooter from "./UnassignedSessionFooter";
13
14
  import { images } from "../../constants/images";
14
15
  import { useTranslation } from "react-i18next";
15
16
  import useConversationStore from "../../store/conversation";
@@ -21,7 +22,7 @@ import { useChatContext } from "../../context/ChatContext";
21
22
  import { useRevokeMessage } from "../../hooks/message/useRevokeMessage";
22
23
  import { useConversationSessionState } from "../../hooks/session/useConversationSessionState";
23
24
  import { useJoinGroupFlow } from "../../hooks/session/useJoinGroupFlow";
24
- import { ConnectStatus } from "../../types/chat";
25
+ import { ConnectStatus, SessionStatus } from "../../types/chat";
25
26
  dayjs.extend(isToday);
26
27
  const BOTTOM_THRESHOLD = -5;
27
28
  const MessageList = (props) => {
@@ -37,19 +38,15 @@ const MessageList = (props) => {
37
38
  const [selectedItem, setSelectedItem] = useState(null);
38
39
  const [showConfirmRevoke, { setTrue: openConfirmRevoke, setFalse: closeConfirmRevoke },] = useBoolean(false);
39
40
  const { revokeMessage, loading: isRevoking } = useRevokeMessage();
40
- const { isNotGroupMember, latestConversationSession, customerUserID, refetchConversationSessions, refetchIsJoined, } = useConversationSessionState({
41
+ const { groupId, latestConversationSession, customerUserID, refetchConversationSessions, } = useConversationSessionState({
41
42
  conversationId,
42
43
  conversationType: conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationType,
43
44
  groupId: conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID,
44
- userID: user === null || user === void 0 ? void 0 : user.userID,
45
45
  });
46
- const { handleJoinGroup, isJoining } = useJoinGroupFlow({
47
- groupId: conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID,
48
- latestConversationSessionId: latestConversationSession === null || latestConversationSession === void 0 ? void 0 : latestConversationSession.id,
49
- refetchConversationSessions,
50
- refetchIsJoined,
46
+ const { isJoined, isCheckingMembership, shouldRestrictToLastSession, joinGroup, isJoining, } = useJoinGroupFlow({
47
+ groupId,
48
+ sessionId: latestConversationSession === null || latestConversationSession === void 0 ? void 0 : latestConversationSession.id,
51
49
  });
52
- const shouldRestrictToLastSession = isNotGroupMember || isJoining;
53
50
  const { getMoreOldMessages, moreOldLoading, loadState, getMoreNewMessages, moreNewLoading, latestLoadState, } = useConversationMessages({
54
51
  conversationId,
55
52
  searchClientMsgID,
@@ -188,7 +185,7 @@ const MessageList = (props) => {
188
185
  backgroundSize: "cover",
189
186
  backgroundPosition: "center",
190
187
  overflowX: "hidden",
191
- }, children: [_jsx(MessageHeader, { onClose: onClose, currentSession: latestConversationSession }), _jsx("div", { id: "scrollableMessagesDiv", ref: scrollRef, style: {
188
+ }, children: [_jsx(MessageHeader, { onClose: onClose, currentSession: latestConversationSession, isJoined: isJoined }), _jsx("div", { id: "scrollableMessagesDiv", ref: scrollRef, style: {
192
189
  height: "100%",
193
190
  overflowY: "auto",
194
191
  overflowX: "hidden",
@@ -206,6 +203,6 @@ const MessageList = (props) => {
206
203
  handleMarkConversationMessageAsRead();
207
204
  loadMoreNewMessage();
208
205
  }
209
- }, children: loadState.messageList.map((message, _, array) => (_jsx(MessageItem, { message: message, allMessages: array, contextMenuOpen: openMenuId === message.clientMsgID, onContextMenuOpenChange: (open) => setOpenMenuId(open ? message.clientMsgID : null), onRevokeMessage: handleOpenRevoke, onQuoteMessage: setQuotedMessage, onPressQuoteMessage: onPressQuoteMessage }, message.clientMsgID))) }) }), moreNewLoading && (_jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) })), shouldRestrictToLastSession ? (_jsxs("div", { className: "border-t bg-white py-4 flex flex-col items-center gap-2", children: [_jsx("p", { className: "text-sm text-gray-500", children: t("join_group_required") }), _jsx(Button, { type: "primary", onClick: handleJoinGroup, loading: isJoining, children: t("join_group") })] })) : (_jsx(MessageFooter, { currentSession: latestConversationSession, openCreateCannedModal: openCreateCannedModal })), _jsx(Modal, { centered: true, open: showConfirmRevoke, onOk: onRevokeMessage, onCancel: handleCloseRevoke, title: t("revoke_message_confirm_title"), okText: t("revoke"), cancelText: t("cancel"), okType: "danger", confirmLoading: isRevoking, getContainer: false, forceRender: true, children: _jsx("p", { children: t("revoke_message_confirm_message") }) })] }));
206
+ }, children: loadState.messageList.map((message, _, array) => (_jsx(MessageItem, { message: message, allMessages: array, contextMenuOpen: openMenuId === message.clientMsgID, onContextMenuOpenChange: (open) => setOpenMenuId(open ? message.clientMsgID : null), onRevokeMessage: handleOpenRevoke, onQuoteMessage: setQuotedMessage, onPressQuoteMessage: onPressQuoteMessage }, message.clientMsgID))) }) }), moreNewLoading && (_jsx("div", { className: "flex items-center justify-center py-2", children: _jsx(Spin, {}) })), isCheckingMembership ? (_jsx("div", { className: "border-t bg-white py-4 flex items-center justify-center", children: _jsx(Spin, {}) })) : (latestConversationSession === null || latestConversationSession === void 0 ? void 0 : latestConversationSession.status) === SessionStatus.UNASSIGNED ? (_jsx(UnassignedSessionFooter, { sessionId: latestConversationSession.id, teamId: latestConversationSession.teamId })) : shouldRestrictToLastSession ? (_jsxs("div", { className: "border-t bg-white py-4 flex flex-col items-center gap-2", children: [_jsx("p", { className: "text-sm text-gray-500", children: t("join_group_required") }), _jsx(Button, { type: "primary", onClick: joinGroup, loading: isJoining, children: t("join_group") })] })) : (_jsx(MessageFooter, { currentSession: latestConversationSession, openCreateCannedModal: openCreateCannedModal })), _jsx(Modal, { centered: true, open: showConfirmRevoke, onOk: onRevokeMessage, onCancel: handleCloseRevoke, title: t("revoke_message_confirm_title"), okText: t("revoke"), cancelText: t("cancel"), okType: "danger", confirmLoading: isRevoking, getContainer: false, forceRender: true, children: _jsx("p", { children: t("revoke_message_confirm_message") }) })] }));
210
207
  };
211
208
  export default MessageList;
@@ -0,0 +1,7 @@
1
+ interface UnassignedSessionFooterProps {
2
+ sessionId: string;
3
+ teamId?: string;
4
+ }
5
+ declare const UnassignedSessionFooter: ({ sessionId, teamId, }: UnassignedSessionFooterProps) => import("react/jsx-runtime").JSX.Element | null;
6
+ export default UnassignedSessionFooter;
7
+ //# sourceMappingURL=UnassignedSessionFooter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UnassignedSessionFooter.d.ts","sourceRoot":"","sources":["../../../src/components/message/UnassignedSessionFooter.tsx"],"names":[],"mappings":"AASA,UAAU,4BAA4B;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,QAAA,MAAM,uBAAuB,GAAI,wBAG9B,4BAA4B,mDA2C9B,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Button, message as antdMessage } from "antd";
4
+ import { useTranslation } from "react-i18next";
5
+ import { useAssignSession } from "../../hooks/session/useAssignSession";
6
+ import useAuthStore from "../../store/auth";
7
+ import ManualAssignPopover from "../thread/ManualAssignPopover";
8
+ import { Icon } from "../icon";
9
+ const UnassignedSessionFooter = ({ sessionId, teamId, }) => {
10
+ const { t } = useTranslation();
11
+ const userID = useAuthStore((state) => state.userID);
12
+ const isCrm = useAuthStore((state) => state.isCrm);
13
+ const { mutateAsync: assignSession, isPending: isAssigning } = useAssignSession();
14
+ if (!isCrm)
15
+ return null;
16
+ const handleAssignToMe = async () => {
17
+ try {
18
+ await assignSession({ sessionId, supporterId: userID });
19
+ }
20
+ catch (_a) {
21
+ antdMessage.error(t("manual_assign_failed"));
22
+ }
23
+ };
24
+ return (_jsxs("div", { className: "border-t bg-white py-4 flex flex-col items-center gap-2", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-amber-500", children: [_jsx(Icon, { icon: "user-del-o", size: 16 }), _jsx("p", { className: "text-sm text-gray-500", children: t("unassigned_thread_notice") })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { type: "primary", onClick: handleAssignToMe, loading: isAssigning, disabled: isAssigning, children: t("assign_to_me") }), _jsx(ManualAssignPopover, { sessionId: sessionId, teamId: teamId, excludeCurrentUser: true, children: _jsx(Button, { disabled: isAssigning, children: t("assign_to_others") }) })] })] }));
25
+ };
26
+ export default UnassignedSessionFooter;
@@ -1 +1 @@
1
- {"version":3,"file":"ActionBar.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/ActionBar.tsx"],"names":[],"mappings":"AAsBA,QAAA,MAAM,SAAS,+CA2Gd,CAAC;AAEF,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"ActionBar.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/ActionBar.tsx"],"names":[],"mappings":"AAsBA,QAAA,MAAM,SAAS,+CA+Gd,CAAC;AAEF,eAAe,SAAS,CAAC"}
@@ -30,12 +30,15 @@ const ActionBar = () => {
30
30
  richText = $generateHtmlFromNodes(editor);
31
31
  });
32
32
  if (canSend) {
33
- onSendMessage({
33
+ const sent = onSendMessage({
34
34
  plainText,
35
35
  richText,
36
36
  type: listUploadFiles.length > 0 ? "file" : "text",
37
37
  isInternal,
38
38
  });
39
+ if (!sent) {
40
+ return;
41
+ }
39
42
  }
40
43
  editor.update(() => {
41
44
  const root = $getRoot();
@@ -1 +1 @@
1
- {"version":3,"file":"EnterHandler.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/EnterHandler.tsx"],"names":[],"mappings":"AAuBA,MAAM,CAAC,OAAO,UAAU,YAAY,SAiHnC"}
1
+ {"version":3,"file":"EnterHandler.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/EnterHandler.tsx"],"names":[],"mappings":"AAuBA,MAAM,CAAC,OAAO,UAAU,YAAY,SAsInC"}
@@ -7,7 +7,7 @@ import { $isListNode, INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND
7
7
  import { $isQuoteNode } from "@lexical/rich-text";
8
8
  import { useMessageFooterContext } from ".";
9
9
  import useConversationStore from "../../../store/conversation";
10
- import { emit } from "../../../utils/events";
10
+ import emitter, { emit } from "../../../utils/events";
11
11
  export default function EnterHandler() {
12
12
  const [editor] = useLexicalComposerContext();
13
13
  const { onSendMessage, isInternal, listUploadFiles, isOpenCanned, activeCannedIndex, } = useMessageFooterContext();
@@ -35,12 +35,15 @@ export default function EnterHandler() {
35
35
  const hasQuote = !!(quotedMessage === null || quotedMessage === void 0 ? void 0 : quotedMessage.clientMsgID);
36
36
  const canSend = hasQuote ? hasText : hasText || hasFiles;
37
37
  if (canSend) {
38
- onSendMessage({
38
+ const sent = onSendMessage({
39
39
  plainText,
40
40
  richText,
41
41
  type: hasFiles ? "file" : "text",
42
42
  isInternal,
43
43
  });
44
+ if (!sent) {
45
+ return true;
46
+ }
44
47
  }
45
48
  editor.update(() => {
46
49
  const root = $getRoot();
@@ -95,5 +98,20 @@ export default function EnterHandler() {
95
98
  isOpenCanned,
96
99
  activeCannedIndex,
97
100
  ]);
101
+ useEffect(() => {
102
+ const clearEditor = () => {
103
+ editor.update(() => {
104
+ const root = $getRoot();
105
+ root.clear();
106
+ const paragraph = $createParagraphNode();
107
+ root.append(paragraph);
108
+ paragraph.select();
109
+ });
110
+ };
111
+ emitter.on("CLEAR_COMPOSER", clearEditor);
112
+ return () => {
113
+ emitter.off("CLEAR_COMPOSER", clearEditor);
114
+ };
115
+ }, [editor]);
98
116
  return null;
99
117
  }
@@ -0,0 +1,10 @@
1
+ interface SessionClosedModalProps {
2
+ open: boolean;
3
+ loading: boolean;
4
+ onReopen: () => void;
5
+ onCreateNew: () => void;
6
+ onClose: () => void;
7
+ }
8
+ declare const SessionClosedModal: ({ open, loading, onReopen, onCreateNew, onClose, }: SessionClosedModalProps) => import("react/jsx-runtime").JSX.Element;
9
+ export default SessionClosedModal;
10
+ //# sourceMappingURL=SessionClosedModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionClosedModal.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/SessionClosedModal.tsx"],"names":[],"mappings":"AAKA,UAAU,uBAAuB;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,QAAA,MAAM,kBAAkB,GAAI,oDAMzB,uBAAuB,4CAmDzB,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Modal, Button } from "antd";
4
+ import { useTranslation } from "react-i18next";
5
+ const SessionClosedModal = ({ open, loading, onReopen, onCreateNew, onClose, }) => {
6
+ const { t } = useTranslation();
7
+ return (_jsx(Modal, { open: open, onCancel: onClose, footer: null, closable: !loading, centered: true, width: 400, maskClosable: !loading, keyboard: !loading, forceRender: true, children: _jsxs("div", { className: "flex flex-col gap-4 pt-2", role: "alertdialog", "aria-label": t("session_closed_modal_title"), children: [_jsx("p", { className: "text-base font-semibold", children: t("session_closed_modal_title") }), _jsx("p", { className: "text-sm text-gray-600", children: t("session_closed_modal_description") }), _jsxs("div", { className: "flex gap-3 w-full", children: [_jsx(Button, { type: "primary", className: "flex-1", size: "large", onClick: onReopen, loading: loading, disabled: loading, children: t("session_closed_modal_reopen") }), _jsx(Button, { type: "primary", className: "flex-1", size: "large", onClick: onCreateNew, loading: loading, disabled: loading, children: t("session_closed_modal_create_new") })] })] }) }));
8
+ };
9
+ export default SessionClosedModal;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/index.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAe,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAK5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAYtD,UAAU,kBAAkB;IAC1B,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AASD,eAAO,MAAM,oBAAoB,mDAY/B,CAAC;AAEH,eAAO,MAAM,uBAAuB,gCAAyC,CAAC;AAE9E,QAAA,MAAM,qBAAqB,GAAI,4CAG5B,kBAAkB,4CA+JpB,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/message/footer/index.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAe,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAK5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAkBtD,UAAU,kBAAkB;IAC1B,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;CACpC;AASD,eAAO,MAAM,oBAAoB,mDAY/B,CAAC;AAEH,eAAO,MAAM,uBAAuB,gCAAyC,CAAC;AAE9E,QAAA,MAAM,qBAAqB,GAAI,4CAG5B,kBAAkB,4CA8QpB,CAAC;AAEF,eAAe,qBAAqB,CAAC"}