@droppii-org/chat-sdk 0.6.55 → 0.7.0

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 (441) hide show
  1. package/dist/components/canned-response/CannedResponseBody.d.ts.map +1 -1
  2. package/dist/components/canned-response/CannedResponseBody.js +4 -3
  3. package/dist/components/canned-response/CannedResponsePanel.d.ts +9 -0
  4. package/dist/components/canned-response/CannedResponsePanel.d.ts.map +1 -0
  5. package/dist/components/canned-response/CannedResponsePanel.js +72 -0
  6. package/dist/components/canned-response/CannedResponseRow.d.ts +10 -0
  7. package/dist/components/canned-response/CannedResponseRow.d.ts.map +1 -0
  8. package/dist/components/canned-response/CannedResponseRow.js +6 -0
  9. package/dist/components/canned-response/CannedScopeChips.d.ts +10 -0
  10. package/dist/components/canned-response/CannedScopeChips.d.ts.map +1 -0
  11. package/dist/components/canned-response/CannedScopeChips.js +34 -0
  12. package/dist/components/canned-response/cannedScopes.d.ts +16 -0
  13. package/dist/components/canned-response/cannedScopes.d.ts.map +1 -0
  14. package/dist/components/canned-response/cannedScopes.js +39 -0
  15. package/dist/components/canned-response/index.d.ts.map +1 -1
  16. package/dist/components/canned-response/index.js +11 -10
  17. package/dist/components/canned-response/insertCannedContent.d.ts +7 -0
  18. package/dist/components/canned-response/insertCannedContent.d.ts.map +1 -0
  19. package/dist/components/canned-response/insertCannedContent.js +39 -0
  20. package/dist/components/canned-response/team/TeamItem.d.ts.map +1 -1
  21. package/dist/components/canned-response/team/TeamItem.js +5 -4
  22. package/dist/components/common/ConfirmModal.d.ts +13 -1
  23. package/dist/components/common/ConfirmModal.d.ts.map +1 -1
  24. package/dist/components/common/ConfirmModal.js +24 -6
  25. package/dist/components/common/DeskPanelDrawer.d.ts +17 -0
  26. package/dist/components/common/DeskPanelDrawer.d.ts.map +1 -0
  27. package/dist/components/common/DeskPanelDrawer.js +21 -0
  28. package/dist/components/common/DeskSidePanel.d.ts +17 -0
  29. package/dist/components/common/DeskSidePanel.d.ts.map +1 -0
  30. package/dist/components/common/DeskSidePanel.js +23 -0
  31. package/dist/components/common/TintedAvatar.d.ts +11 -0
  32. package/dist/components/common/TintedAvatar.d.ts.map +1 -0
  33. package/dist/components/common/TintedAvatar.js +17 -0
  34. package/dist/components/compose/ComposeNewMessageModal.d.ts.map +1 -1
  35. package/dist/components/compose/ComposeNewMessageModal.js +11 -1
  36. package/dist/components/conversation/ConversationByGroupItem.d.ts.map +1 -1
  37. package/dist/components/conversation/ConversationByGroupItem.js +10 -6
  38. package/dist/components/conversation/ConversationBySessionItem.d.ts +4 -1
  39. package/dist/components/conversation/ConversationBySessionItem.d.ts.map +1 -1
  40. package/dist/components/conversation/ConversationBySessionItem.js +36 -10
  41. package/dist/components/conversation/DeskConversationList.d.ts.map +1 -1
  42. package/dist/components/conversation/DeskConversationList.js +44 -29
  43. package/dist/components/conversation/DeskConversationRow.d.ts +19 -0
  44. package/dist/components/conversation/DeskConversationRow.d.ts.map +1 -0
  45. package/dist/components/conversation/DeskConversationRow.js +18 -0
  46. package/dist/components/conversation/DeskListEmptyState.d.ts +6 -0
  47. package/dist/components/conversation/DeskListEmptyState.d.ts.map +1 -0
  48. package/dist/components/conversation/DeskListEmptyState.js +11 -0
  49. package/dist/components/conversation/DeskListHeader.d.ts +14 -0
  50. package/dist/components/conversation/DeskListHeader.d.ts.map +1 -0
  51. package/dist/components/conversation/DeskListHeader.js +39 -0
  52. package/dist/components/conversation/DeskListSkeleton.d.ts +6 -0
  53. package/dist/components/conversation/DeskListSkeleton.d.ts.map +1 -0
  54. package/dist/components/conversation/DeskListSkeleton.js +9 -0
  55. package/dist/components/conversation/DeskRowAvatar.d.ts +8 -0
  56. package/dist/components/conversation/DeskRowAvatar.d.ts.map +1 -0
  57. package/dist/components/conversation/DeskRowAvatar.js +6 -0
  58. package/dist/components/conversation/RowChip.d.ts +14 -0
  59. package/dist/components/conversation/RowChip.d.ts.map +1 -0
  60. package/dist/components/conversation/RowChip.js +11 -0
  61. package/dist/components/conversation/avatarTint.d.ts +6 -0
  62. package/dist/components/conversation/avatarTint.d.ts.map +1 -0
  63. package/dist/components/conversation/avatarTint.js +27 -0
  64. package/dist/components/conversation/folderEmptyState.d.ts +2 -0
  65. package/dist/components/conversation/folderEmptyState.d.ts.map +1 -0
  66. package/dist/components/conversation/folderEmptyState.js +14 -0
  67. package/dist/components/conversation/internalNotePreview.d.ts +6 -0
  68. package/dist/components/conversation/internalNotePreview.d.ts.map +1 -0
  69. package/dist/components/conversation/internalNotePreview.js +11 -0
  70. package/dist/components/conversation/listHeading.d.ts +19 -0
  71. package/dist/components/conversation/listHeading.d.ts.map +1 -0
  72. package/dist/components/conversation/listHeading.js +24 -0
  73. package/dist/components/conversation/rowDisplayName.d.ts +7 -0
  74. package/dist/components/conversation/rowDisplayName.d.ts.map +1 -0
  75. package/dist/components/conversation/rowDisplayName.js +8 -0
  76. package/dist/components/conversation/rowTime.d.ts +4 -0
  77. package/dist/components/conversation/rowTime.d.ts.map +1 -0
  78. package/dist/components/conversation/rowTime.js +10 -0
  79. package/dist/components/conversation-detail/PinLimitModal.d.ts.map +1 -1
  80. package/dist/components/conversation-detail/PinLimitModal.js +3 -1
  81. package/dist/components/group/AddMemberModal.d.ts.map +1 -1
  82. package/dist/components/group/AddMemberModal.js +15 -4
  83. package/dist/components/group/AdminPermissionModal.d.ts +1 -0
  84. package/dist/components/group/AdminPermissionModal.d.ts.map +1 -1
  85. package/dist/components/group/AdminPermissionModal.js +38 -3
  86. package/dist/components/group/CreateGroupForm.d.ts +3 -1
  87. package/dist/components/group/CreateGroupForm.d.ts.map +1 -1
  88. package/dist/components/group/CreateGroupForm.js +7 -1
  89. package/dist/components/group/CreateGroupFormCrmView.d.ts +23 -0
  90. package/dist/components/group/CreateGroupFormCrmView.d.ts.map +1 -0
  91. package/dist/components/group/CreateGroupFormCrmView.js +25 -0
  92. package/dist/components/group/DisableSendPermissionConfirm.d.ts +11 -0
  93. package/dist/components/group/DisableSendPermissionConfirm.d.ts.map +1 -0
  94. package/dist/components/group/DisableSendPermissionConfirm.js +10 -0
  95. package/dist/components/group/GroupCompositeAvatar.d.ts.map +1 -1
  96. package/dist/components/group/GroupCompositeAvatar.js +39 -4
  97. package/dist/components/group/GroupMemberPicker.d.ts +5 -2
  98. package/dist/components/group/GroupMemberPicker.d.ts.map +1 -1
  99. package/dist/components/group/GroupMemberPicker.js +8 -42
  100. package/dist/components/group/GroupMemberPickerCrm.d.ts +4 -0
  101. package/dist/components/group/GroupMemberPickerCrm.d.ts.map +1 -0
  102. package/dist/components/group/GroupMemberPickerCrm.js +48 -0
  103. package/dist/components/group/GroupMemberPickerLegacy.d.ts +8 -0
  104. package/dist/components/group/GroupMemberPickerLegacy.d.ts.map +1 -0
  105. package/dist/components/group/GroupMemberPickerLegacy.js +46 -0
  106. package/dist/components/group/GroupPanelHeader.d.ts +10 -0
  107. package/dist/components/group/GroupPanelHeader.d.ts.map +1 -0
  108. package/dist/components/group/GroupPanelHeader.js +11 -0
  109. package/dist/components/group/MemberPermissionPanel.d.ts.map +1 -1
  110. package/dist/components/group/MemberPermissionPanel.js +31 -2
  111. package/dist/components/group/PermissionPanelCrm.d.ts +24 -0
  112. package/dist/components/group/PermissionPanelCrm.d.ts.map +1 -0
  113. package/dist/components/group/PermissionPanelCrm.js +16 -0
  114. package/dist/components/group/PersonAvatar.d.ts +11 -0
  115. package/dist/components/group/PersonAvatar.d.ts.map +1 -0
  116. package/dist/components/group/PersonAvatar.js +21 -0
  117. package/dist/components/group/crmIcon.d.ts +9 -0
  118. package/dist/components/group/crmIcon.d.ts.map +1 -0
  119. package/dist/components/group/crmIcon.js +38 -0
  120. package/dist/components/icon/AdaptiveIcon.d.ts +15 -0
  121. package/dist/components/icon/AdaptiveIcon.d.ts.map +1 -0
  122. package/dist/components/icon/AdaptiveIcon.js +10 -0
  123. package/dist/components/icon/StrokeIcon.d.ts +14 -0
  124. package/dist/components/icon/StrokeIcon.d.ts.map +1 -0
  125. package/dist/components/icon/StrokeIcon.js +5 -0
  126. package/dist/components/icon/strokeIconNodes.d.ts +431 -0
  127. package/dist/components/icon/strokeIconNodes.d.ts.map +1 -0
  128. package/dist/components/icon/strokeIconNodes.js +269 -0
  129. package/dist/components/media-collection/index.d.ts.map +1 -1
  130. package/dist/components/media-collection/index.js +21 -5
  131. package/dist/components/message/GroupMembersDrawer.d.ts.map +1 -1
  132. package/dist/components/message/GroupMembersDrawer.js +60 -13
  133. package/dist/components/message/GroupMembersPanelCrm.d.ts +23 -0
  134. package/dist/components/message/GroupMembersPanelCrm.d.ts.map +1 -0
  135. package/dist/components/message/GroupMembersPanelCrm.js +55 -0
  136. package/dist/components/message/MessageHeader.d.ts.map +1 -1
  137. package/dist/components/message/MessageHeader.js +76 -27
  138. package/dist/components/message/MessageInfiniteScroll.d.ts +4 -2
  139. package/dist/components/message/MessageInfiniteScroll.d.ts.map +1 -1
  140. package/dist/components/message/MessageInfiniteScroll.js +1 -1
  141. package/dist/components/message/MessageList.d.ts +2 -1
  142. package/dist/components/message/MessageList.d.ts.map +1 -1
  143. package/dist/components/message/MessageList.js +12 -1
  144. package/dist/components/message/SelectSession.d.ts +4 -1
  145. package/dist/components/message/SelectSession.d.ts.map +1 -1
  146. package/dist/components/message/SelectSession.js +13 -4
  147. package/dist/components/message/UnassignedSessionFooter.js +2 -2
  148. package/dist/components/message/footer/ActionBar.d.ts +5 -1
  149. package/dist/components/message/footer/ActionBar.d.ts.map +1 -1
  150. package/dist/components/message/footer/ActionBar.js +14 -1
  151. package/dist/components/message/footer/CannedResponsePlugin.d.ts.map +1 -1
  152. package/dist/components/message/footer/CannedResponsePlugin.js +18 -3
  153. package/dist/components/message/footer/ClosedSessionBanner.d.ts +9 -0
  154. package/dist/components/message/footer/ClosedSessionBanner.d.ts.map +1 -0
  155. package/dist/components/message/footer/ClosedSessionBanner.js +13 -0
  156. package/dist/components/message/footer/ComposerEditor.d.ts.map +1 -1
  157. package/dist/components/message/footer/ComposerEditor.js +9 -4
  158. package/dist/components/message/footer/ComposerTabs.d.ts +1 -2
  159. package/dist/components/message/footer/ComposerTabs.d.ts.map +1 -1
  160. package/dist/components/message/footer/ComposerTabs.js +14 -35
  161. package/dist/components/message/footer/CrmComposerCard.d.ts +11 -0
  162. package/dist/components/message/footer/CrmComposerCard.d.ts.map +1 -0
  163. package/dist/components/message/footer/CrmComposerCard.js +30 -0
  164. package/dist/components/message/footer/EnterHandler.d.ts.map +1 -1
  165. package/dist/components/message/footer/EnterHandler.js +3 -0
  166. package/dist/components/message/footer/FilePreview.js +2 -2
  167. package/dist/components/message/footer/LinkInputPreview.js +2 -2
  168. package/dist/components/message/footer/MediaActions.d.ts +2 -1
  169. package/dist/components/message/footer/MediaActions.d.ts.map +1 -1
  170. package/dist/components/message/footer/MediaActions.js +21 -4
  171. package/dist/components/message/footer/SessionClosedModal.d.ts +3 -1
  172. package/dist/components/message/footer/SessionClosedModal.d.ts.map +1 -1
  173. package/dist/components/message/footer/SessionClosedModal.js +6 -2
  174. package/dist/components/message/footer/ToolbarPlugin.d.ts +3 -1
  175. package/dist/components/message/footer/ToolbarPlugin.d.ts.map +1 -1
  176. package/dist/components/message/footer/ToolbarPlugin.js +2 -2
  177. package/dist/components/message/footer/clearComposerHistory.d.ts +3 -0
  178. package/dist/components/message/footer/clearComposerHistory.d.ts.map +1 -0
  179. package/dist/components/message/footer/clearComposerHistory.js +11 -0
  180. package/dist/components/message/footer/index.d.ts +2 -2
  181. package/dist/components/message/footer/index.d.ts.map +1 -1
  182. package/dist/components/message/footer/index.js +15 -5
  183. package/dist/components/message/footer/mention/MentionMenu.d.ts.map +1 -1
  184. package/dist/components/message/footer/mention/MentionMenu.js +4 -1
  185. package/dist/components/message/footer/useComposerFocusRequest.d.ts +10 -0
  186. package/dist/components/message/footer/useComposerFocusRequest.d.ts.map +1 -0
  187. package/dist/components/message/footer/useComposerFocusRequest.js +28 -0
  188. package/dist/components/message/groupMemberMenuCrm.d.ts +32 -0
  189. package/dist/components/message/groupMemberMenuCrm.d.ts.map +1 -0
  190. package/dist/components/message/groupMemberMenuCrm.js +83 -0
  191. package/dist/components/message/groupMemberTypes.d.ts +13 -0
  192. package/dist/components/message/groupMemberTypes.d.ts.map +1 -0
  193. package/dist/components/message/groupMemberTypes.js +1 -0
  194. package/dist/components/message/headerIconButton.d.ts +10 -0
  195. package/dist/components/message/headerIconButton.d.ts.map +1 -0
  196. package/dist/components/message/headerIconButton.js +9 -0
  197. package/dist/components/message/item/CrmSystemLine.d.ts +10 -0
  198. package/dist/components/message/item/CrmSystemLine.d.ts.map +1 -0
  199. package/dist/components/message/item/CrmSystemLine.js +6 -0
  200. package/dist/components/message/item/DateDivider.d.ts +5 -0
  201. package/dist/components/message/item/DateDivider.d.ts.map +1 -0
  202. package/dist/components/message/item/DateDivider.js +5 -0
  203. package/dist/components/message/item/GroupNotificationMessage.d.ts.map +1 -1
  204. package/dist/components/message/item/GroupNotificationMessage.js +9 -0
  205. package/dist/components/message/item/MemberEventSummary.d.ts +8 -0
  206. package/dist/components/message/item/MemberEventSummary.d.ts.map +1 -0
  207. package/dist/components/message/item/MemberEventSummary.js +18 -0
  208. package/dist/components/message/item/MessageBubble.d.ts +3 -1
  209. package/dist/components/message/item/MessageBubble.d.ts.map +1 -1
  210. package/dist/components/message/item/MessageBubble.js +27 -13
  211. package/dist/components/message/item/MessageMoreButton.d.ts +13 -0
  212. package/dist/components/message/item/MessageMoreButton.d.ts.map +1 -0
  213. package/dist/components/message/item/MessageMoreButton.js +42 -0
  214. package/dist/components/message/item/QuoteMessage.d.ts.map +1 -1
  215. package/dist/components/message/item/QuoteMessage.js +23 -2
  216. package/dist/components/message/item/RevokeMessage.js +1 -1
  217. package/dist/components/message/item/SessionEventMessage.d.ts.map +1 -1
  218. package/dist/components/message/item/SessionEventMessage.js +13 -1
  219. package/dist/components/message/item/SystemLogMessage.d.ts.map +1 -1
  220. package/dist/components/message/item/SystemLogMessage.js +7 -0
  221. package/dist/components/message/item/index.d.ts.map +1 -1
  222. package/dist/components/message/item/index.js +80 -18
  223. package/dist/components/message/item/otherSenders.d.ts +7 -0
  224. package/dist/components/message/item/otherSenders.d.ts.map +1 -0
  225. package/dist/components/message/item/otherSenders.js +29 -0
  226. package/dist/components/message/item/textStyle.d.ts +1 -1
  227. package/dist/components/message/item/textStyle.d.ts.map +1 -1
  228. package/dist/components/message/item/textStyle.js +2 -2
  229. package/dist/components/message/messageKeyboardNav.d.ts +8 -0
  230. package/dist/components/message/messageKeyboardNav.d.ts.map +1 -0
  231. package/dist/components/message/messageKeyboardNav.js +24 -0
  232. package/dist/components/message/reply/ReplyPreviewBar.d.ts.map +1 -1
  233. package/dist/components/message/reply/ReplyPreviewBar.js +11 -4
  234. package/dist/components/message/toolbox/MessageToolboxMenu.d.ts.map +1 -1
  235. package/dist/components/message/toolbox/MessageToolboxMenu.js +16 -1
  236. package/dist/components/search-conversation/SearchAll.d.ts.map +1 -1
  237. package/dist/components/search-conversation/SearchAll.js +12 -1
  238. package/dist/components/search-conversation/SearchDrawer.d.ts.map +1 -1
  239. package/dist/components/search-conversation/SearchDrawer.js +31 -15
  240. package/dist/components/search-conversation/SearchMessageOnCurrentConversation.d.ts.map +1 -1
  241. package/dist/components/search-conversation/SearchMessageOnCurrentConversation.js +5 -2
  242. package/dist/components/search-conversation/index.d.ts.map +1 -1
  243. package/dist/components/search-conversation/index.js +3 -1
  244. package/dist/components/search-conversation/item/SearchItemAsGroup.d.ts.map +1 -1
  245. package/dist/components/search-conversation/item/SearchItemAsGroup.js +14 -4
  246. package/dist/components/search-conversation/item/SearchItemAsMessage.d.ts.map +1 -1
  247. package/dist/components/search-conversation/item/SearchItemAsMessage.js +18 -7
  248. package/dist/components/search-conversation/item/SearchItemAsUser.d.ts.map +1 -1
  249. package/dist/components/search-conversation/item/SearchItemAsUser.js +23 -5
  250. package/dist/components/search-conversation/item/searchRowClass.d.ts +3 -0
  251. package/dist/components/search-conversation/item/searchRowClass.d.ts.map +1 -0
  252. package/dist/components/search-conversation/item/searchRowClass.js +5 -0
  253. package/dist/components/session/DeskAssignedSession.d.ts +5 -1
  254. package/dist/components/session/DeskAssignedSession.d.ts.map +1 -1
  255. package/dist/components/session/DeskAssignedSession.js +40 -12
  256. package/dist/components/session/DeskTeamInbox.d.ts.map +1 -1
  257. package/dist/components/session/DeskTeamInbox.js +15 -22
  258. package/dist/components/session/FolderRow.d.ts +21 -0
  259. package/dist/components/session/FolderRow.d.ts.map +1 -0
  260. package/dist/components/session/FolderRow.js +16 -0
  261. package/dist/components/session/SessionFolderList.d.ts +23 -0
  262. package/dist/components/session/SessionFolderList.d.ts.map +1 -0
  263. package/dist/components/session/SessionFolderList.js +27 -0
  264. package/dist/components/session/sessionFilters.d.ts +24 -0
  265. package/dist/components/session/sessionFilters.d.ts.map +1 -0
  266. package/dist/components/session/sessionFilters.js +80 -0
  267. package/dist/components/shortcut-help/ShortcutHelpModal.d.ts +8 -0
  268. package/dist/components/shortcut-help/ShortcutHelpModal.d.ts.map +1 -0
  269. package/dist/components/shortcut-help/ShortcutHelpModal.js +23 -0
  270. package/dist/components/thread/AssignConfirmModal.d.ts.map +1 -1
  271. package/dist/components/thread/AssignConfirmModal.js +4 -3
  272. package/dist/components/thread/EndSessionConfirm.d.ts +11 -0
  273. package/dist/components/thread/EndSessionConfirm.d.ts.map +1 -0
  274. package/dist/components/thread/EndSessionConfirm.js +31 -0
  275. package/dist/components/thread/EndSessionToast.d.ts +6 -0
  276. package/dist/components/thread/EndSessionToast.d.ts.map +1 -0
  277. package/dist/components/thread/EndSessionToast.js +18 -0
  278. package/dist/components/thread/GroupInfoBodyCrm.d.ts +46 -0
  279. package/dist/components/thread/GroupInfoBodyCrm.d.ts.map +1 -0
  280. package/dist/components/thread/GroupInfoBodyCrm.js +41 -0
  281. package/dist/components/thread/GroupInfoRows.d.ts +33 -0
  282. package/dist/components/thread/GroupInfoRows.d.ts.map +1 -0
  283. package/dist/components/thread/GroupInfoRows.js +18 -0
  284. package/dist/components/thread/GroupThreadInfo.d.ts.map +1 -1
  285. package/dist/components/thread/GroupThreadInfo.js +23 -6
  286. package/dist/components/thread/ManualAssignPopover.d.ts +3 -1
  287. package/dist/components/thread/ManualAssignPopover.d.ts.map +1 -1
  288. package/dist/components/thread/ManualAssignPopover.js +21 -9
  289. package/dist/components/thread/SessionDetailCard.d.ts +6 -0
  290. package/dist/components/thread/SessionDetailCard.d.ts.map +1 -0
  291. package/dist/components/thread/SessionDetailCard.js +103 -0
  292. package/dist/components/thread/SessionSection.d.ts +2 -4
  293. package/dist/components/thread/SessionSection.d.ts.map +1 -1
  294. package/dist/components/thread/SessionSection.js +19 -122
  295. package/dist/components/thread/SessionTagPicker.d.ts +11 -0
  296. package/dist/components/thread/SessionTagPicker.d.ts.map +1 -0
  297. package/dist/components/thread/SessionTagPicker.js +27 -0
  298. package/dist/components/thread/SingleThreadInfo.d.ts.map +1 -1
  299. package/dist/components/thread/SingleThreadInfo.js +16 -6
  300. package/dist/components/thread/SupportSessionPanel.d.ts +18 -0
  301. package/dist/components/thread/SupportSessionPanel.d.ts.map +1 -0
  302. package/dist/components/thread/SupportSessionPanel.js +46 -0
  303. package/dist/components/thread/ThreadInfo.d.ts +8 -1
  304. package/dist/components/thread/ThreadInfo.d.ts.map +1 -1
  305. package/dist/components/thread/ThreadInfo.js +27 -29
  306. package/dist/components/thread/ThreadInfoHeader.d.ts +13 -0
  307. package/dist/components/thread/ThreadInfoHeader.d.ts.map +1 -0
  308. package/dist/components/thread/ThreadInfoHeader.js +11 -0
  309. package/dist/components/thread/UserSection.d.ts.map +1 -1
  310. package/dist/components/thread/UserSection.js +35 -22
  311. package/dist/components/thread/sessionDateFormat.d.ts +3 -0
  312. package/dist/components/thread/sessionDateFormat.d.ts.map +1 -0
  313. package/dist/components/thread/sessionDateFormat.js +13 -0
  314. package/dist/components/thread/sessionDuration.d.ts +5 -0
  315. package/dist/components/thread/sessionDuration.d.ts.map +1 -0
  316. package/dist/components/thread/sessionDuration.js +24 -0
  317. package/dist/constants/index.d.ts +1 -0
  318. package/dist/constants/index.d.ts.map +1 -1
  319. package/dist/constants/index.js +2 -0
  320. package/dist/constants/layout.d.ts +24 -0
  321. package/dist/constants/layout.d.ts.map +1 -0
  322. package/dist/constants/layout.js +23 -0
  323. package/dist/context/ChatContext.d.ts.map +1 -1
  324. package/dist/context/ChatContext.js +27 -1
  325. package/dist/hooks/canned-response/useSearchCannedAcrossScopes.d.ts +7 -0
  326. package/dist/hooks/canned-response/useSearchCannedAcrossScopes.d.ts.map +1 -0
  327. package/dist/hooks/canned-response/useSearchCannedAcrossScopes.js +46 -0
  328. package/dist/hooks/common/useCloseOnSidePanelOpen.d.ts +3 -0
  329. package/dist/hooks/common/useCloseOnSidePanelOpen.d.ts.map +1 -0
  330. package/dist/hooks/common/useCloseOnSidePanelOpen.js +15 -0
  331. package/dist/hooks/common/useDeskShortcuts.d.ts +11 -0
  332. package/dist/hooks/common/useDeskShortcuts.d.ts.map +1 -0
  333. package/dist/hooks/common/useDeskShortcuts.js +94 -0
  334. package/dist/hooks/common/useEscapeLayer.d.ts +3 -0
  335. package/dist/hooks/common/useEscapeLayer.d.ts.map +1 -0
  336. package/dist/hooks/common/useEscapeLayer.js +18 -0
  337. package/dist/hooks/common/useMediaQuery.d.ts +3 -0
  338. package/dist/hooks/common/useMediaQuery.d.ts.map +1 -0
  339. package/dist/hooks/common/useMediaQuery.js +12 -0
  340. package/dist/hooks/common/useSidePanel.d.ts +12 -0
  341. package/dist/hooks/common/useSidePanel.d.ts.map +1 -0
  342. package/dist/hooks/common/useSidePanel.js +32 -0
  343. package/dist/hooks/group/useConversationGroups.d.ts.map +1 -1
  344. package/dist/hooks/group/useConversationGroups.js +3 -0
  345. package/dist/hooks/message/useNewMessageAnnouncement.d.ts +3 -0
  346. package/dist/hooks/message/useNewMessageAnnouncement.d.ts.map +1 -0
  347. package/dist/hooks/message/useNewMessageAnnouncement.js +30 -0
  348. package/dist/hooks/search/useSearchGroups.js +2 -1
  349. package/dist/hooks/search/useSearchMessage.d.ts +3 -1
  350. package/dist/hooks/search/useSearchMessage.d.ts.map +1 -1
  351. package/dist/hooks/search/useSearchMessage.js +2 -2
  352. package/dist/hooks/session/useBotSessionOwnerIdentity.d.ts +12 -0
  353. package/dist/hooks/session/useBotSessionOwnerIdentity.d.ts.map +1 -0
  354. package/dist/hooks/session/useBotSessionOwnerIdentity.js +22 -0
  355. package/dist/hooks/session/useCloseSession.d.ts +1 -0
  356. package/dist/hooks/session/useCloseSession.d.ts.map +1 -1
  357. package/dist/hooks/session/useCloseSession.js +9 -8
  358. package/dist/hooks/session/useEndSession.d.ts +11 -0
  359. package/dist/hooks/session/useEndSession.d.ts.map +1 -0
  360. package/dist/hooks/session/useEndSession.js +45 -0
  361. package/dist/hooks/session/useGetSession.d.ts.map +1 -1
  362. package/dist/hooks/session/useGetSession.js +27 -6
  363. package/dist/hooks/session/usePendingSessionClose.d.ts +5 -0
  364. package/dist/hooks/session/usePendingSessionClose.d.ts.map +1 -0
  365. package/dist/hooks/session/usePendingSessionClose.js +12 -0
  366. package/dist/hooks/session/useSessionCustomerName.d.ts +3 -0
  367. package/dist/hooks/session/useSessionCustomerName.d.ts.map +1 -0
  368. package/dist/hooks/session/useSessionCustomerName.js +19 -0
  369. package/dist/hooks/session/useSessionFieldAutosave.d.ts +19 -0
  370. package/dist/hooks/session/useSessionFieldAutosave.d.ts.map +1 -0
  371. package/dist/hooks/session/useSessionFieldAutosave.js +52 -0
  372. package/dist/hooks/user/useUserUsername.d.ts +3 -0
  373. package/dist/hooks/user/useUserUsername.d.ts.map +1 -0
  374. package/dist/hooks/user/useUserUsername.js +49 -0
  375. package/dist/index.d.ts +8 -2
  376. package/dist/index.d.ts.map +1 -1
  377. package/dist/index.js +5 -1
  378. package/dist/locales/vi/common.json +201 -21
  379. package/dist/locales/vi/conversation-inbox.json +21 -2
  380. package/dist/screens/desk-message/DeskWorkspace.d.ts +12 -0
  381. package/dist/screens/desk-message/DeskWorkspace.d.ts.map +1 -0
  382. package/dist/screens/desk-message/DeskWorkspace.js +57 -0
  383. package/dist/screens/desk-message/FolderOverlay.d.ts +4 -0
  384. package/dist/screens/desk-message/FolderOverlay.d.ts.map +1 -0
  385. package/dist/screens/desk-message/FolderOverlay.js +32 -0
  386. package/dist/screens/desk-message/SkipLinks.d.ts +4 -0
  387. package/dist/screens/desk-message/SkipLinks.d.ts.map +1 -0
  388. package/dist/screens/desk-message/SkipLinks.js +19 -0
  389. package/dist/screens/desk-message/ViewportNotice.d.ts +4 -0
  390. package/dist/screens/desk-message/ViewportNotice.d.ts.map +1 -0
  391. package/dist/screens/desk-message/ViewportNotice.js +9 -0
  392. package/dist/screens/desk-message/index.d.ts +3 -2
  393. package/dist/screens/desk-message/index.d.ts.map +1 -1
  394. package/dist/screens/desk-message/index.js +4 -12
  395. package/dist/store/deskPanelHost.d.ts +13 -0
  396. package/dist/store/deskPanelHost.d.ts.map +1 -0
  397. package/dist/store/deskPanelHost.js +9 -0
  398. package/dist/store/escapeLayers.d.ts +15 -0
  399. package/dist/store/escapeLayers.d.ts.map +1 -0
  400. package/dist/store/escapeLayers.js +15 -0
  401. package/dist/store/pendingSessionClose.d.ts +19 -0
  402. package/dist/store/pendingSessionClose.d.ts.map +1 -0
  403. package/dist/store/pendingSessionClose.js +74 -0
  404. package/dist/store/session.d.ts +2 -1
  405. package/dist/store/session.d.ts.map +1 -1
  406. package/dist/store/session.js +4 -1
  407. package/dist/store/sessionFolder.d.ts +15 -0
  408. package/dist/store/sessionFolder.d.ts.map +1 -0
  409. package/dist/store/sessionFolder.js +18 -0
  410. package/dist/store/shortcutPrefs.d.ts +9 -0
  411. package/dist/store/shortcutPrefs.d.ts.map +1 -0
  412. package/dist/store/shortcutPrefs.js +23 -0
  413. package/dist/store/sidePanel.d.ts +12 -0
  414. package/dist/store/sidePanel.d.ts.map +1 -0
  415. package/dist/store/sidePanel.js +9 -0
  416. package/dist/store/workspaceLayout.d.ts +12 -0
  417. package/dist/store/workspaceLayout.d.ts.map +1 -0
  418. package/dist/store/workspaceLayout.js +9 -0
  419. package/dist/styles/global.css +1 -1
  420. package/dist/types/chat.d.ts +18 -0
  421. package/dist/types/chat.d.ts.map +1 -1
  422. package/dist/types/dto.d.ts +2 -1
  423. package/dist/types/dto.d.ts.map +1 -1
  424. package/dist/utils/a11yClickable.d.ts +10 -0
  425. package/dist/utils/a11yClickable.d.ts.map +1 -0
  426. package/dist/utils/a11yClickable.js +15 -0
  427. package/dist/utils/events.d.ts +4 -0
  428. package/dist/utils/events.d.ts.map +1 -1
  429. package/dist/utils/headerMemberCount.d.ts +10 -0
  430. package/dist/utils/headerMemberCount.d.ts.map +1 -0
  431. package/dist/utils/headerMemberCount.js +3 -0
  432. package/dist/utils/memberEventRun.d.ts +16 -0
  433. package/dist/utils/memberEventRun.d.ts.map +1 -0
  434. package/dist/utils/memberEventRun.js +40 -0
  435. package/package.json +1 -1
  436. package/dist/components/session/SessionFilterMenu.d.ts +0 -15
  437. package/dist/components/session/SessionFilterMenu.d.ts.map +0 -1
  438. package/dist/components/session/SessionFilterMenu.js +0 -30
  439. package/dist/components/session/sessionMenuItems.d.ts +0 -28
  440. package/dist/components/session/sessionMenuItems.d.ts.map +0 -1
  441. package/dist/components/session/sessionMenuItems.js +0 -119
@@ -1,11 +1,12 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useRef, useState } from "react";
3
3
  import { Input, Modal, Switch, message } from "antd";
4
4
  import ConfirmModal from "../../components/common/ConfirmModal";
5
5
  import { useTranslation } from "react-i18next";
6
- import { GroupMemberRole, GroupStatus, MessageReceiveOptType } from "@droppii-org/wasm-client-sdk";
6
+ import { GroupMemberRole, GroupStatus, GroupVisibility, MessageReceiveOptType } from "@droppii-org/wasm-client-sdk";
7
7
  import { Icon } from "../../components/icon";
8
8
  import useConversationStore from "../../store/conversation";
9
+ import useAuthStore from "../../store/auth";
9
10
  import { useLeaveConversation } from "../../hooks/session/useLeaveConversation";
10
11
  import { useDeleteConversation } from "../../hooks/session/useDeleteConversation";
11
12
  import { useToggleConversationNotification } from "../../hooks/session/useToggleConversationNotification";
@@ -17,15 +18,21 @@ import { useUploadFile } from "../../hooks/common/useUploadFile";
17
18
  import { ACCEPTED_IMAGE_TYPES, MAX_IMAGE_SIZE_MB } from "../../utils/fileValidation";
18
19
  import AdminPermissionModal from "../../components/group/AdminPermissionModal";
19
20
  import MemberPermissionPanel from "../../components/group/MemberPermissionPanel";
21
+ import DisableSendPermissionConfirm from "../../components/group/DisableSendPermissionConfirm";
20
22
  import InviteLinkPanel from "../../components/group/InviteLinkPanel";
21
23
  import GroupCompositeAvatar from "../../components/group/GroupCompositeAvatar";
24
+ import GroupPanelHeader from "../../components/group/GroupPanelHeader";
25
+ import GroupInfoBodyCrm from "./GroupInfoBodyCrm";
22
26
  const GroupThreadInfo = ({ onClose, config }) => {
23
27
  var _a, _b, _c, _d;
24
28
  const { t } = useTranslation();
29
+ const isCrm = useAuthStore((state) => state.isCrm);
25
30
  const conversationData = useConversationStore((state) => state.conversationData);
26
31
  const groupID = (conversationData === null || conversationData === void 0 ? void 0 : conversationData.groupID) || "";
27
32
  const currentGroupInfo = useConversationStore((state) => state.currentGroupInfo.get(groupID));
28
33
  const conversationID = (conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationID) || "";
34
+ // The header already shows the conversation name; keep it here while group info is missing.
35
+ const groupDisplayName = (currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.groupName) || (conversationData === null || conversationData === void 0 ? void 0 : conversationData.showName) || "";
29
36
  const permissions = useGroupPermission(groupID);
30
37
  const currentMemberInGroup = useConversationStore((state) => state.currentMemberInGroup.get(groupID));
31
38
  // Muted-chat-list and disband-group aren't part of the 11-permission
@@ -182,6 +189,13 @@ const GroupThreadInfo = ({ onClose, config }) => {
182
189
  const handleToggleSendMessage = (checked) => {
183
190
  if (!groupID || !isOwner)
184
191
  return;
192
+ if (!checked && isCrm) {
193
+ setConfirmAction("mute-all");
194
+ return;
195
+ }
196
+ applySendMessage(checked);
197
+ };
198
+ const applySendMessage = (checked) => {
185
199
  const previous = allowSendMessage;
186
200
  setAllowSendMessage(checked);
187
201
  toggleSendMessage({ groupID, allowSendMessage: checked }, {
@@ -242,9 +256,12 @@ const GroupThreadInfo = ({ onClose, config }) => {
242
256
  if (!groupID) {
243
257
  return null;
244
258
  }
245
- return (_jsxs("div", { className: "h-full w-[330px] bg-white shadow-md flex flex-col relative overflow-hidden", "data-cp-name": "GroupThreadInfo", children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-4 border-b border-gray-100", children: [_jsx("span", { className: "text-lg font-medium", children: t("thread_info_title") }), _jsx("button", { type: "button", className: "flex items-center justify-center w-8 h-8 rounded-full text-gray-500 hover:bg-gray-100", onClick: onClose, children: _jsx(Icon, { icon: "close-o", size: 20 }) })] }), _jsxs("div", { className: "flex-1 overflow-y-auto", children: [_jsxs("div", { className: "flex items-center gap-3 px-4 py-4", children: [_jsxs("div", { className: "relative shrink-0", children: [_jsx(GroupCompositeAvatar, { groupID: groupID, faceURL: currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.faceURL, ownerUserID: currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.ownerUserID, groupName: currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.groupName, size: 56 }), isAvatarUploading && (_jsx("span", { className: "absolute inset-0 flex items-center justify-center rounded-full bg-black/30", children: _jsx("span", { className: "h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent" }) })), permissions.updateGroupAvatar && (_jsxs(_Fragment, { children: [_jsx("input", { ref: avatarInputRef, type: "file", accept: ACCEPTED_IMAGE_TYPES.join(", "), className: "hidden", onChange: handleAvatarSelect }), _jsx("button", { type: "button", disabled: isAvatarUploading, onClick: handleAvatarClick, className: "absolute -bottom-1 -right-1 flex items-center justify-center w-5 h-5 rounded-full bg-black text-white", children: _jsx(Icon, { icon: "camera-o", size: 12 }) })] }))] }), _jsx("div", { className: "flex-1 min-w-0", children: editingField !== "name" && (_jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [_jsx("p", { className: "text-base font-medium truncate", children: currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.groupName }), permissions.updateGroupName && (_jsx(Icon, { icon: "edit-o", size: 16, className: "shrink-0 cursor-pointer text-gray-500", onClick: startEditName }))] })) })] }), editingField === "name" && (_jsx("div", { className: "px-4 pb-4", children: _jsxs("div", { className: "flex flex-col gap-3 bg-[#f5f5f5] rounded-lg p-3", children: [_jsx(Input, { autoFocus: true, value: nameValue, onChange: (event) => setNameValue(event.target.value), maxLength: 255, showCount: true, disabled: isSavingGroupInfo, className: "bg-white" }), _jsxs("div", { className: "flex items-center justify-end gap-2", children: [_jsx("button", { type: "button", className: "px-4 py-1.5 rounded-lg border border-[var(--dc-color-primary-hover)] text-[var(--dc-color-primary-hover)] text-sm font-medium disabled:border-gray-200 disabled:text-gray-300", disabled: isSavingGroupInfo, onClick: cancelEditName, children: t("cancel") }), _jsx("button", { type: "button", className: "px-4 py-1.5 rounded-lg bg-[var(--dc-color-primary-hover)] text-white text-sm font-medium disabled:bg-gray-100 disabled:text-gray-300", disabled: isSavingGroupInfo ||
246
- !nameValue.trim() ||
247
- nameValue.trim() === ((_c = currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.groupName) !== null && _c !== void 0 ? _c : ""), onClick: saveName, children: t("save") })] })] }) })), _jsx("div", { className: "px-4 pb-4", children: editingField === "description" ? (_jsxs("div", { className: "flex flex-col gap-3 bg-[#f5f5f5] rounded-lg p-3", children: [_jsxs("span", { className: "flex items-center gap-2 text-sm font-medium text-gray-900", children: [_jsx(Icon, { icon: "info-circle-o", size: 18, className: "text-gray-500" }), t("description")] }), _jsx(Input.TextArea, { ref: descriptionInputRef, value: descriptionValue, onChange: (event) => setDescriptionValue(event.target.value), placeholder: t("enter_group_description"), autoSize: { minRows: 1, maxRows: 4 }, maxLength: 500, disabled: isSavingGroupInfo, className: "bg-white" }), _jsxs("span", { className: "self-end text-xs text-gray-400", children: [descriptionValue.length, " / 500"] }), _jsxs("div", { className: "flex items-center justify-end gap-2", children: [_jsx("button", { type: "button", className: "px-4 py-1.5 rounded-lg border border-[var(--dc-color-primary-hover)] text-[var(--dc-color-primary-hover)] text-sm font-medium disabled:border-gray-200 disabled:text-gray-300", disabled: isSavingGroupInfo, onClick: cancelEditDescription, children: t("cancel") }), _jsx("button", { type: "button", className: "px-4 py-1.5 rounded-lg bg-[var(--dc-color-primary-hover)] text-white text-sm font-medium disabled:bg-gray-100 disabled:text-gray-300", disabled: isSavingGroupInfo ||
248
- descriptionValue.trim() === ((_d = currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.introduction) !== null && _d !== void 0 ? _d : ""), onClick: saveDescription, children: t("save") })] })] })) : (_jsxs("div", { className: "flex items-start justify-between gap-2 bg-[#f5f5f5] rounded-lg px-3 py-2.5", children: [_jsxs("div", { className: "flex items-start gap-2 flex-1 min-w-0", children: [_jsx(Icon, { icon: "info-circle-o", size: 18, className: "shrink-0 mt-0.5 text-gray-900" }), _jsxs("div", { className: "flex flex-col gap-0.5 min-w-0", children: [_jsx("span", { className: "text-sm font-semibold text-gray-900", children: t("description") }), _jsx("p", { className: "text-sm text-gray-400 truncate", children: (currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.introduction) || t("no_description") })] })] }), permissions.updateGroupDescription && (_jsx(Icon, { icon: "edit-o", size: 16, className: "shrink-0 cursor-pointer text-gray-500", onClick: startEditDescription }))] })) }), _jsxs("div", { className: "flex flex-col gap-1 bg-[#f5f5f5] mx-4 rounded-lg overflow-hidden", children: [_jsxs("div", { className: "flex items-center justify-between px-3 py-3", children: [_jsxs("span", { className: "flex items-center gap-3 text-sm", children: [_jsx(Icon, { icon: "bell-o", size: 18 }), t("notification")] }), _jsx(Switch, { checked: notifyEnabled, onChange: handleToggleNotification, loading: isTogglingNotification })] }), (config === null || config === void 0 ? void 0 : config.showAllowSendMessage) && isOwner && (_jsxs("div", { className: "flex items-center justify-between px-3 py-3", children: [_jsxs("span", { className: "flex items-center gap-3 text-sm", children: [_jsx(Icon, { icon: "user-check-o", size: 18 }), t("allow_send_message")] }), _jsx(Switch, { checked: allowSendMessage, onChange: handleToggleSendMessage, loading: isTogglingSendMessage })] })), isAdminOrOwner && (config === null || config === void 0 ? void 0 : config.showMutedChatList) && (_jsxs("button", { type: "button", className: "flex items-center justify-between px-3 py-3 text-left", onClick: () => setActiveRow("muted-chat-list"), children: [_jsxs("span", { className: "flex items-center gap-3 text-sm", children: [_jsx(Icon, { icon: "bell-off-o", size: 18 }), t("muted_chat_list")] }), _jsx(Icon, { icon: "angle-right-o", size: 16, className: "text-gray-400" })] })), isAdminOrOwner && (_jsxs("button", { type: "button", className: "flex items-center justify-between px-3 py-3 text-left", onClick: () => setActiveRow("block-list"), children: [_jsxs("span", { className: "flex items-center gap-3 text-sm", children: [_jsx(Icon, { icon: "user-del-o", size: 18 }), t("block_list")] }), _jsx(Icon, { icon: "angle-right-o", size: 16, className: "text-gray-400" })] }))] }), permissions.configGroupPermission && (_jsxs("div", { className: "flex flex-col gap-1 bg-[#f5f5f5] mx-4 mt-3 rounded-lg overflow-hidden", children: [_jsxs("button", { type: "button", className: "flex items-center justify-between px-3 py-3 text-left", onClick: () => setActiveRow("member-permission"), children: [_jsxs("span", { className: "flex items-center gap-3 text-sm", children: [_jsx(Icon, { icon: "shield-o", size: 18 }), t("member_permission_settings")] }), _jsx(Icon, { icon: "angle-right-o", size: 16, className: "text-gray-400" })] }), _jsxs("button", { type: "button", className: "flex items-center justify-between px-3 py-3 text-left", onClick: () => setActiveRow("admin-permission"), children: [_jsxs("span", { className: "flex items-center gap-3 text-sm", children: [_jsx(Icon, { icon: "shield-done-o", size: 18 }), t("admin_permission_settings")] }), _jsx(Icon, { icon: "angle-right-o", size: 16, className: "text-gray-400" })] })] })), isInviteLinkFeatureEnabled && !isViewOnlyMember && (_jsx("div", { className: "mx-4 mt-3 rounded-lg overflow-hidden bg-[#f5f5f5]", children: _jsxs("button", { type: "button", className: "w-full flex items-center justify-between px-3 py-3 text-left text-sm", onClick: () => setActiveRow("invite-link"), children: [_jsxs("span", { className: "flex items-center gap-3", children: [_jsx(Icon, { icon: "link-alt-o", size: 18 }), t("invite_via_link")] }), _jsx(Icon, { icon: "angle-right-o", size: 16, className: "text-gray-400" })] }) })), _jsxs("div", { className: "flex flex-col gap-1 bg-[#f5f5f5] mx-4 mt-3 mb-4 rounded-lg overflow-hidden", children: [isAdminOrOwner && (_jsxs("button", { type: "button", className: "flex items-center gap-3 px-3 py-3 text-left text-sm text-red-500", onClick: () => setConfirmAction("delete"), children: [_jsx(Icon, { icon: "trash-o", size: 18 }), t("delete_conversation")] })), !isViewOnlyMember && (_jsxs("button", { type: "button", className: "flex items-center gap-3 px-3 py-3 text-left text-sm text-red-500", onClick: () => setConfirmAction("leave"), children: [_jsx(Icon, { icon: "logout-o", size: 18 }), t("leave_group")] })), isOwner && (_jsxs("button", { type: "button", className: "flex items-center gap-3 px-3 py-3 text-left text-sm text-red-500", onClick: () => setConfirmAction("disband"), children: [_jsx(Icon, { icon: "user-del-o", size: 18 }), t("disband_group")] }))] })] }), _jsx(ConfirmModal, { open: confirmAction === "leave", onOk: handleConfirmLeave, onCancel: () => setConfirmAction(null), title: t("leave_group_confirm_title"), okText: t("leave_group"), cancelText: t("cancel"), okType: "danger", confirmLoading: isLeaving, children: _jsx("p", { children: t("leave_group_confirm_message") }) }), _jsx(ConfirmModal, { open: confirmAction === "disband", onOk: handleConfirmDisband, onCancel: () => setConfirmAction(null), title: t("disband_group_confirm_title"), okText: t("disband_group"), cancelText: t("cancel"), okType: "danger", confirmLoading: isDismissing, children: _jsx("p", { children: t("disband_group_confirm_message") }) }), _jsx(ConfirmModal, { open: confirmAction === "delete", onOk: handleConfirmDelete, onCancel: () => setConfirmAction(null), title: t("delete_conversation_confirm_title"), okText: t("delete_conversation"), cancelText: t("cancel"), okType: "danger", confirmLoading: isDeleting, children: _jsx("p", { children: t("delete_conversation_confirm_message") }) }), _jsx(MemberPermissionPanel, { open: activeRow === "member-permission", groupID: groupID, onClose: () => setActiveRow(null) }), _jsx(AdminPermissionModal, { open: activeRow === "admin-permission", groupID: groupID, onClose: () => setActiveRow(null), inline: true }), _jsx(InviteLinkPanel, { open: activeRow === "invite-link", groupID: groupID, conversationID: conversationID, onClose: () => setActiveRow(null) }), (activeRow === "muted-chat-list" || activeRow === "block-list") && (_jsx(Modal, { centered: true, open: true, footer: null, onCancel: () => setActiveRow(null), title: t(activeRow === "muted-chat-list" ? "muted_chat_list" : "block_list"), getContainer: false, forceRender: true, children: _jsx("p", { className: "text-sm text-gray-500", children: t("feature_coming_soon") }) }))] }));
259
+ return (_jsxs("div", { className: "h-full w-full bg-white flex flex-col relative overflow-hidden", "data-cp-name": "GroupThreadInfo", children: [isCrm ? (_jsxs(_Fragment, { children: [_jsx(GroupPanelHeader, { title: t("group_info_title"), onClose: onClose }), _jsx(GroupInfoBodyCrm, { groupID: groupID, groupName: groupDisplayName, faceURL: currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.faceURL, ownerUserID: currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.ownerUserID, introduction: currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.introduction, memberCount: currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.memberCount, isPublic: (currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.visibility) === GroupVisibility.Public, canEditAvatar: permissions.updateGroupAvatar, canEditName: permissions.updateGroupName, canEditDescription: permissions.updateGroupDescription, canConfigPermissions: permissions.configGroupPermission, showInviteLink: isInviteLinkFeatureEnabled && !isViewOnlyMember, showAllowSend: Boolean(config === null || config === void 0 ? void 0 : config.showAllowSendMessage) && isOwner, isOwner: isOwner, isAdminOrOwner: isAdminOrOwner, isViewOnlyMember: isViewOnlyMember, notifyEnabled: notifyEnabled, isTogglingNotification: isTogglingNotification, allowSendMessage: allowSendMessage, isTogglingSendMessage: isTogglingSendMessage, isAvatarUploading: isAvatarUploading, isSaving: isSavingGroupInfo, editingField: editingField, nameValue: nameValue, descriptionValue: descriptionValue, avatarInputRef: avatarInputRef, onNameChange: setNameValue, onDescriptionChange: setDescriptionValue, onStartEdit: (field) => (field === "name" ? startEditName() : startEditDescription()), onCancelEdit: (field) => (field === "name" ? cancelEditName() : cancelEditDescription()), onSaveEdit: (field) => (field === "name" ? saveName() : saveDescription()), onAvatarClick: handleAvatarClick, onAvatarSelect: handleAvatarSelect, onToggleNotification: handleToggleNotification, onToggleSendMessage: handleToggleSendMessage, onOpenRow: setActiveRow, onConfirm: setConfirmAction })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-4 border-b border-gray-100", children: [_jsx("span", { className: "text-lg font-medium", children: t("thread_info_title") }), _jsx("button", { type: "button", className: "flex items-center justify-center w-8 h-8 rounded-full text-gray-500 hover:bg-gray-100", onClick: onClose, children: _jsx(Icon, { icon: "close-o", size: 20 }) })] }), _jsxs("div", { className: "flex-1 overflow-y-auto", children: [_jsxs("div", { className: "flex items-center gap-3 px-4 py-4", children: [_jsxs("div", { className: "relative shrink-0", children: [_jsx(GroupCompositeAvatar, { groupID: groupID, faceURL: currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.faceURL, ownerUserID: currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.ownerUserID, groupName: groupDisplayName, size: 56 }), isAvatarUploading && (_jsx("span", { className: "absolute inset-0 flex items-center justify-center rounded-full bg-black/30", children: _jsx("span", { className: "h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent" }) })), permissions.updateGroupAvatar && (_jsxs(_Fragment, { children: [_jsx("input", { ref: avatarInputRef, type: "file", accept: ACCEPTED_IMAGE_TYPES.join(", "), className: "hidden", onChange: handleAvatarSelect }), _jsx("button", { type: "button", disabled: isAvatarUploading, onClick: handleAvatarClick, className: "absolute -bottom-1 -right-1 flex items-center justify-center w-5 h-5 rounded-full bg-black text-white", children: _jsx(Icon, { icon: "camera-o", size: 12 }) })] }))] }), _jsx("div", { className: "flex-1 min-w-0", children: editingField !== "name" && (_jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [_jsx("p", { className: "text-base font-medium truncate", children: groupDisplayName }), permissions.updateGroupName && (_jsx(Icon, { icon: "edit-o", size: 16, className: "shrink-0 cursor-pointer text-gray-500", onClick: startEditName }))] })) })] }), editingField === "name" && (_jsx("div", { className: "px-4 pb-4", children: _jsxs("div", { className: "flex flex-col gap-3 bg-[#f5f5f5] rounded-lg p-3", children: [_jsx(Input, { autoFocus: true, value: nameValue, onChange: (event) => setNameValue(event.target.value), maxLength: 255, showCount: true, disabled: isSavingGroupInfo, className: "bg-white" }), _jsxs("div", { className: "flex items-center justify-end gap-2", children: [_jsx("button", { type: "button", className: "px-4 py-1.5 rounded-lg border border-[var(--dc-color-primary-hover)] text-[var(--dc-color-primary-hover)] text-sm font-medium disabled:border-gray-200 disabled:text-gray-300", disabled: isSavingGroupInfo, onClick: cancelEditName, children: t("cancel") }), _jsx("button", { type: "button", className: "px-4 py-1.5 rounded-lg bg-[var(--dc-color-primary-hover)] text-white text-sm font-medium disabled:bg-gray-100 disabled:text-gray-300", disabled: isSavingGroupInfo ||
260
+ !nameValue.trim() ||
261
+ nameValue.trim() === ((_c = currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.groupName) !== null && _c !== void 0 ? _c : ""), onClick: saveName, children: t("save") })] })] }) })), _jsx("div", { className: "px-4 pb-4", children: editingField === "description" ? (_jsxs("div", { className: "flex flex-col gap-3 bg-[#f5f5f5] rounded-lg p-3", children: [_jsxs("span", { className: "flex items-center gap-2 text-sm font-medium text-gray-900", children: [_jsx(Icon, { icon: "info-circle-o", size: 18, className: "text-gray-500" }), t("description")] }), _jsx(Input.TextArea, { ref: descriptionInputRef, value: descriptionValue, onChange: (event) => setDescriptionValue(event.target.value), placeholder: t("enter_group_description"), autoSize: { minRows: 1, maxRows: 4 }, maxLength: 500, disabled: isSavingGroupInfo, className: "bg-white" }), _jsxs("span", { className: "self-end text-xs text-gray-400", children: [descriptionValue.length, " / 500"] }), _jsxs("div", { className: "flex items-center justify-end gap-2", children: [_jsx("button", { type: "button", className: "px-4 py-1.5 rounded-lg border border-[var(--dc-color-primary-hover)] text-[var(--dc-color-primary-hover)] text-sm font-medium disabled:border-gray-200 disabled:text-gray-300", disabled: isSavingGroupInfo, onClick: cancelEditDescription, children: t("cancel") }), _jsx("button", { type: "button", className: "px-4 py-1.5 rounded-lg bg-[var(--dc-color-primary-hover)] text-white text-sm font-medium disabled:bg-gray-100 disabled:text-gray-300", disabled: isSavingGroupInfo ||
262
+ descriptionValue.trim() === ((_d = currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.introduction) !== null && _d !== void 0 ? _d : ""), onClick: saveDescription, children: t("save") })] })] })) : (_jsxs("div", { className: "flex items-start justify-between gap-2 bg-[#f5f5f5] rounded-lg px-3 py-2.5", children: [_jsxs("div", { className: "flex items-start gap-2 flex-1 min-w-0", children: [_jsx(Icon, { icon: "info-circle-o", size: 18, className: "shrink-0 mt-0.5 text-gray-900" }), _jsxs("div", { className: "flex flex-col gap-0.5 min-w-0", children: [_jsx("span", { className: "text-sm font-semibold text-gray-900", children: t("description") }), _jsx("p", { className: "text-sm text-gray-400 truncate", children: (currentGroupInfo === null || currentGroupInfo === void 0 ? void 0 : currentGroupInfo.introduction) || t("no_description") })] })] }), permissions.updateGroupDescription && (_jsx(Icon, { icon: "edit-o", size: 16, className: "shrink-0 cursor-pointer text-gray-500", onClick: startEditDescription }))] })) }), _jsxs("div", { className: "flex flex-col gap-1 bg-[#f5f5f5] mx-4 rounded-lg overflow-hidden", children: [_jsxs("div", { className: "flex items-center justify-between px-3 py-3", children: [_jsxs("span", { className: "flex items-center gap-3 text-sm", children: [_jsx(Icon, { icon: "bell-o", size: 18 }), t("notification")] }), _jsx(Switch, { checked: notifyEnabled, onChange: handleToggleNotification, loading: isTogglingNotification })] }), (config === null || config === void 0 ? void 0 : config.showAllowSendMessage) && isOwner && (_jsxs("div", { className: "flex items-center justify-between px-3 py-3", children: [_jsxs("span", { className: "flex items-center gap-3 text-sm", children: [_jsx(Icon, { icon: "user-check-o", size: 18 }), t("allow_send_message")] }), _jsx(Switch, { checked: allowSendMessage, onChange: handleToggleSendMessage, loading: isTogglingSendMessage })] })), isAdminOrOwner && (config === null || config === void 0 ? void 0 : config.showMutedChatList) && (_jsxs("button", { type: "button", className: "flex items-center justify-between px-3 py-3 text-left", onClick: () => setActiveRow("muted-chat-list"), children: [_jsxs("span", { className: "flex items-center gap-3 text-sm", children: [_jsx(Icon, { icon: "bell-off-o", size: 18 }), t("muted_chat_list")] }), _jsx(Icon, { icon: "angle-right-o", size: 16, className: "text-gray-400" })] })), isAdminOrOwner && (_jsxs("button", { type: "button", className: "flex items-center justify-between px-3 py-3 text-left", onClick: () => setActiveRow("block-list"), children: [_jsxs("span", { className: "flex items-center gap-3 text-sm", children: [_jsx(Icon, { icon: "user-del-o", size: 18 }), t("block_list")] }), _jsx(Icon, { icon: "angle-right-o", size: 16, className: "text-gray-400" })] }))] }), permissions.configGroupPermission && (_jsxs("div", { className: "flex flex-col gap-1 bg-[#f5f5f5] mx-4 mt-3 rounded-lg overflow-hidden", children: [_jsxs("button", { type: "button", className: "flex items-center justify-between px-3 py-3 text-left", onClick: () => setActiveRow("member-permission"), children: [_jsxs("span", { className: "flex items-center gap-3 text-sm", children: [_jsx(Icon, { icon: "shield-o", size: 18 }), t("member_permission_settings")] }), _jsx(Icon, { icon: "angle-right-o", size: 16, className: "text-gray-400" })] }), _jsxs("button", { type: "button", className: "flex items-center justify-between px-3 py-3 text-left", onClick: () => setActiveRow("admin-permission"), children: [_jsxs("span", { className: "flex items-center gap-3 text-sm", children: [_jsx(Icon, { icon: "shield-done-o", size: 18 }), t("admin_permission_settings")] }), _jsx(Icon, { icon: "angle-right-o", size: 16, className: "text-gray-400" })] })] })), isInviteLinkFeatureEnabled && !isViewOnlyMember && (_jsx("div", { className: "mx-4 mt-3 rounded-lg overflow-hidden bg-[#f5f5f5]", children: _jsxs("button", { type: "button", className: "w-full flex items-center justify-between px-3 py-3 text-left text-sm", onClick: () => setActiveRow("invite-link"), children: [_jsxs("span", { className: "flex items-center gap-3", children: [_jsx(Icon, { icon: "link-alt-o", size: 18 }), t("invite_via_link")] }), _jsx(Icon, { icon: "angle-right-o", size: 16, className: "text-gray-400" })] }) })), _jsxs("div", { className: "flex flex-col gap-1 bg-[#f5f5f5] mx-4 mt-3 mb-4 rounded-lg overflow-hidden", children: [isAdminOrOwner && (_jsxs("button", { type: "button", className: "flex items-center gap-3 px-3 py-3 text-left text-sm text-red-500", onClick: () => setConfirmAction("delete"), children: [_jsx(Icon, { icon: "trash-o", size: 18 }), t("delete_conversation")] })), !isViewOnlyMember && (_jsxs("button", { type: "button", className: "flex items-center gap-3 px-3 py-3 text-left text-sm text-red-500", onClick: () => setConfirmAction("leave"), children: [_jsx(Icon, { icon: "logout-o", size: 18 }), t("leave_group")] })), isOwner && (_jsxs("button", { type: "button", className: "flex items-center gap-3 px-3 py-3 text-left text-sm text-red-500", onClick: () => setConfirmAction("disband"), children: [_jsx(Icon, { icon: "user-del-o", size: 18 }), t("disband_group")] }))] })] })] })), _jsx(ConfirmModal, { open: confirmAction === "leave", onOk: handleConfirmLeave, onCancel: () => setConfirmAction(null), title: t("leave_group_confirm_title"), okText: t("leave_group"), cancelText: t(isCrm ? "action_cancel" : "cancel"), okType: "danger", confirmLoading: isLeaving, children: _jsx("p", { children: t("leave_group_confirm_message") }) }), _jsx(ConfirmModal, { open: confirmAction === "disband", onOk: handleConfirmDisband, onCancel: () => setConfirmAction(null), title: t("disband_group_confirm_title"), okText: t("disband_group"), cancelText: t(isCrm ? "action_cancel" : "cancel"), okType: "danger", confirmLoading: isDismissing, children: _jsx("p", { children: t("disband_group_confirm_message") }) }), _jsx(ConfirmModal, { open: confirmAction === "delete", onOk: handleConfirmDelete, onCancel: () => setConfirmAction(null), title: t("delete_conversation_confirm_title"), okText: t("delete_conversation"), cancelText: t(isCrm ? "action_cancel" : "cancel"), okType: "danger", confirmLoading: isDeleting, children: _jsx("p", { children: t("delete_conversation_confirm_message") }) }), _jsx(DisableSendPermissionConfirm, { open: confirmAction === "mute-all", title: t("disable_send_permission_title_all_members"), onConfirm: () => {
263
+ setConfirmAction(null);
264
+ applySendMessage(false);
265
+ }, onCancel: () => setConfirmAction(null) }), _jsx(MemberPermissionPanel, { open: activeRow === "member-permission", groupID: groupID, onClose: () => setActiveRow(null) }), _jsx(AdminPermissionModal, { open: activeRow === "admin-permission", groupID: groupID, onClose: () => setActiveRow(null), inline: true }), _jsx(InviteLinkPanel, { open: activeRow === "invite-link", groupID: groupID, conversationID: conversationID, onClose: () => setActiveRow(null) }), (activeRow === "muted-chat-list" || activeRow === "block-list") && (_jsx(Modal, { centered: true, open: true, footer: null, onCancel: () => setActiveRow(null), title: t(activeRow === "muted-chat-list" ? "muted_chat_list" : "block_list"), getContainer: false, forceRender: true, children: _jsx("p", { className: "text-sm text-gray-500", children: t("feature_coming_soon") }) }))] }));
249
266
  };
250
267
  export default GroupThreadInfo;
@@ -1,4 +1,5 @@
1
1
  import { type ReactNode } from "react";
2
+ import type { TooltipProps } from "antd";
2
3
  interface SupporterInfo {
3
4
  avatar: string;
4
5
  username: string;
@@ -11,7 +12,8 @@ interface ManualAssignPopoverProps {
11
12
  teamId?: string;
12
13
  children?: ReactNode;
13
14
  excludeCurrentUser?: boolean;
15
+ placement?: TooltipProps["placement"];
14
16
  }
15
- declare const ManualAssignPopover: ({ sessionId, supporter, teamId: propTeamId, children, excludeCurrentUser, }: ManualAssignPopoverProps) => import("react/jsx-runtime").JSX.Element;
17
+ declare const ManualAssignPopover: ({ sessionId, supporter, teamId: propTeamId, children, excludeCurrentUser, placement, }: ManualAssignPopoverProps) => import("react/jsx-runtime").JSX.Element;
16
18
  export default ManualAssignPopover;
17
19
  //# sourceMappingURL=ManualAssignPopover.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ManualAssignPopover.d.ts","sourceRoot":"","sources":["../../../src/components/thread/ManualAssignPopover.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAkBjD,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,UAAU,wBAAwB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AA+CD,QAAA,MAAM,mBAAmB,GAAI,6EAM1B,wBAAwB,4CA4O1B,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"ManualAssignPopover.d.ts","sourceRoot":"","sources":["../../../src/components/thread/ManualAssignPopover.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAkBzC,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,UAAU,wBAAwB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,SAAS,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC;CACvC;AA0ED,QAAA,MAAM,mBAAmB,GAAI,wFAO1B,wBAAwB,4CA2O1B,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -1,27 +1,39 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useState } from "react";
3
- import { Popover, Input, Avatar, Spin, Badge, Divider } from "antd";
3
+ import { useEscapeLayer } from "../../hooks/common/useEscapeLayer";
4
+ import { useCloseOnSidePanelOpen } from "../../hooks/common/useCloseOnSidePanelOpen";
5
+ import { Popover, Input, Spin, Divider, Tooltip } from "antd";
4
6
  import { useTranslation } from "react-i18next";
5
7
  import clsx from "clsx";
6
- import { Icon } from "../../components/icon";
8
+ import { AdaptiveIcon } from "../../components/icon/AdaptiveIcon";
7
9
  import { useGetTeamSupporters } from "../../hooks/session/useGetTeamSupporters";
8
10
  import { useAssignSession, useAutoAssignSession, } from "../../hooks/session/useAssignSession";
9
11
  import { message as antdMessage } from "antd";
10
12
  import AssignConfirmModal from "./AssignConfirmModal";
11
13
  import { useDebounce } from "ahooks";
12
14
  import useAuthStore from "../../store/auth";
15
+ import TintedAvatar from "../../components/common/TintedAvatar";
13
16
  const SEARCH_DEBOUNCE_WAIT = 300;
14
17
  const SupporterItem = ({ supporter, onClick, isCurrentUser, }) => {
15
18
  var _a;
16
19
  const { t } = useTranslation();
17
20
  const isOnline = supporter.status === "ONLINE";
18
- return (_jsxs("div", { role: "option", tabIndex: 0, className: "flex items-center gap-3 px-3 py-2 rounded-md transition-colors cursor-pointer hover:bg-[#f5f5f5]", onClick: () => onClick(supporter), "data-cp-name": "SupporterItem", children: [_jsx(Badge, { dot: true, color: isOnline ? "#52c41a" : "#d9d9d9", offset: [-2, 24], children: _jsx(Avatar, { src: supporter.avatar, size: 32, children: ((_a = supporter.displayName) === null || _a === void 0 ? void 0 : _a.charAt(0)) || "A" }) }), _jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: [_jsx("span", { className: "text-sm truncate", children: supporter.displayName }), isCurrentUser && (_jsx("span", { className: "text-xs text-blue-500 shrink-0", children: t("current_account") }))] }), _jsx("div", { className: "flex items-center gap-2 shrink-0", children: !!supporter.openSessionCount && supporter.openSessionCount > 0 && (_jsxs("span", { className: "flex items-center gap-0.5 bg-blue-500 text-white text-xs font-medium px-1.5 py-0.5 rounded-full", children: [_jsx(Icon, { icon: "chat-square-b", size: 11 }), supporter.openSessionCount] })) })] }));
21
+ return (_jsxs("div", { role: "option", "aria-selected": false, tabIndex: 0, className: "flex items-center gap-3 px-3 py-2 rounded-lg transition-colors cursor-pointer hover:bg-gray-5 focus-visible:outline focus-visible:outline-2 focus-visible:outline-primary-200", onClick: () => onClick(supporter), onKeyDown: (e) => {
22
+ if (e.key === "Enter" || e.key === " ") {
23
+ e.preventDefault();
24
+ onClick(supporter);
25
+ }
26
+ }, "data-cp-name": "SupporterItem", children: [_jsxs("span", { className: "relative shrink-0", children: [_jsx(TintedAvatar, { name: (_a = supporter.displayName) !== null && _a !== void 0 ? _a : "", src: supporter.avatar, size: 32 }), _jsx("span", { "aria-hidden": true, className: clsx("absolute bottom-0 right-0 h-2.5 w-2.5 rounded-full border-2 border-white", isOnline ? "bg-success-400" : "bg-gray-200") })] }), _jsx("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: _jsxs("span", { className: "flex min-w-0 flex-col", children: [_jsxs("span", { className: "flex items-center gap-1", children: [_jsx("span", { className: "text-sm truncate", children: supporter.displayName }), isCurrentUser && (_jsx("span", { className: "text-xs text-primary-400 shrink-0", children: t("current_account") }))] }), supporter.username && (_jsx("span", { className: "truncate text-xs text-gray-600", children: supporter.username }))] }) }), _jsx("div", { className: "flex items-center gap-2 shrink-0", children: !!supporter.openSessionCount && supporter.openSessionCount > 0 && (_jsx(Tooltip, { title: t("manual_assign_open_sessions", {
27
+ count: supporter.openSessionCount,
28
+ }), children: _jsxs("span", { className: "flex items-center gap-0.5 bg-primary-400 text-white text-xs font-medium px-1.5 py-0.5 rounded-full", children: [_jsx(AdaptiveIcon, { stroke: "message-circle", font: "chat-square-b", size: 11, strokeSize: 12 }), supporter.openSessionCount] }) })) })] }));
19
29
  };
20
- const ManualAssignPopover = ({ sessionId, supporter, teamId: propTeamId, children, excludeCurrentUser = false, }) => {
21
- var _a, _b;
30
+ const ManualAssignPopover = ({ sessionId, supporter, teamId: propTeamId, children, excludeCurrentUser = false, placement = "topLeft", }) => {
31
+ var _a;
22
32
  const { t } = useTranslation();
23
33
  const authUserID = useAuthStore((state) => state.userID);
24
34
  const [open, setOpen] = useState(false);
35
+ useCloseOnSidePanelOpen(() => setOpen(false));
36
+ useEscapeLayer(open, () => setOpen(false));
25
37
  const [searchText, setSearchText] = useState("");
26
38
  const [selectedAgent, setSelectedAgent] = useState(null);
27
39
  const [confirmModalOpen, setConfirmModalOpen] = useState(false);
@@ -92,9 +104,9 @@ const ManualAssignPopover = ({ sessionId, supporter, teamId: propTeamId, childre
92
104
  setSearchText("");
93
105
  }
94
106
  };
95
- const popoverContent = (_jsxs("div", { className: "w-64", children: [_jsxs("button", { type: "button", className: clsx("flex w-full items-center gap-3 rounded-md px-3 py-2 text-left text-sm transition-colors", isAutoAssignDisabled
107
+ const popoverContent = (_jsxs("div", { className: "w-64", children: [_jsxs("button", { type: "button", className: clsx("flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left text-sm transition-colors", isAutoAssignDisabled
96
108
  ? "cursor-not-allowed text-gray-400"
97
- : "text-gray-700 hover:bg-[#f5f5f5]"), onClick: handleAutoAssign, disabled: isAutoAssignDisabled, children: [isAutoAssigning ? (_jsx(Spin, { size: "small" })) : (_jsx("span", { className: "text-blue-500", children: _jsx(Icon, { icon: "refresh-b", size: 20 }) })), _jsx("span", { children: t("manual_assign_button_auto_reassign") })] }), _jsx(Divider, { className: "my-2" }), _jsx("div", { className: "mb-2", children: _jsx(Input, { autoFocus: true, placeholder: t("manual_assign_search_placeholder"), value: searchText, onChange: (e) => setSearchText(e.target.value), prefix: _jsx(Icon, { icon: "search-o", size: 16, className: "text-gray-400" }), className: "rounded-lg border-gray-300 focus-within:border-chat-focus focus-within:shadow-chat-focus-ring", allowClear: true }) }), _jsx("div", { className: "max-h-72 overflow-y-auto", role: "listbox", children: isLoading ? (_jsx("div", { className: "flex items-center justify-center py-8", children: _jsx(Spin, {}) })) : supporters && supporters.length > 0 ? (_jsx("div", { className: clsx("flex flex-col transition-opacity duration-200", isFetching && "opacity-50 pointer-events-none"), children: [...supporters]
109
+ : "text-gray-900 hover:bg-gray-5"), onClick: handleAutoAssign, disabled: isAutoAssignDisabled, children: [isAutoAssigning ? (_jsx(Spin, { size: "small" })) : (_jsx("span", { className: "text-primary-400", children: _jsx(AdaptiveIcon, { stroke: "refresh-cw", font: "refresh-b", size: 20, strokeSize: 18 }) })), _jsx("span", { children: t("manual_assign_button_auto_reassign") })] }), _jsx(Divider, { className: "my-2" }), _jsx("div", { className: "mb-2", children: _jsx(Input, { autoFocus: true, placeholder: t("manual_assign_search_placeholder"), value: searchText, onChange: (e) => setSearchText(e.target.value), prefix: _jsx(AdaptiveIcon, { stroke: "search", font: "search-o", size: 16, className: "text-gray-400" }), className: "rounded-lg border-gray-300 focus-within:border-chat-focus focus-within:shadow-chat-focus-ring", allowClear: true }) }), _jsx("div", { className: "max-h-72 overflow-y-auto", role: "listbox", children: isLoading ? (_jsx("div", { className: "flex items-center justify-center py-8", children: _jsx(Spin, {}) })) : supporters && supporters.length > 0 ? (_jsx("div", { className: clsx("flex flex-col transition-opacity duration-200", isFetching && "opacity-50 pointer-events-none"), children: [...supporters]
98
110
  .filter((item) => item.memberId !== (supporter === null || supporter === void 0 ? void 0 : supporter.id))
99
111
  .filter((item) => !excludeCurrentUser || item.memberId !== authUserID)
100
112
  .sort((supporterA, supporterB) => {
@@ -108,8 +120,8 @@ const ManualAssignPopover = ({ sessionId, supporter, teamId: propTeamId, childre
108
120
  });
109
121
  })
110
122
  .map((item) => (_jsx(SupporterItem, { supporter: item, onClick: handleSelectAgent, isCurrentUser: item.memberId === authUserID }, item.memberId))) })) : (_jsx("div", { className: "flex items-center justify-center py-8", children: _jsx("span", { className: "text-sm text-gray-400", children: t("manual_assign_no_results") }) })) })] }));
111
- return (_jsxs(_Fragment, { children: [_jsx(Popover, { content: popoverContent, trigger: "click", open: open, onOpenChange: handleOpenChange, placement: "topLeft", arrow: false, children: children !== null && children !== void 0 ? children : (_jsxs("div", { role: "button", tabIndex: 0, "aria-label": t("manual_assign_button_reassign"), className: clsx("flex items-center border border-gray-200 rounded-lg p-1 gap-1 transition-opacity", isSubmitting
123
+ return (_jsxs(_Fragment, { children: [_jsx(Popover, { content: popoverContent, trigger: "click", open: open, onOpenChange: handleOpenChange, placement: placement, arrow: false, children: children !== null && children !== void 0 ? children : (_jsxs("button", { type: "button", "aria-label": t("manual_assign_button_reassign"), className: clsx("flex items-center border border-gray-200 rounded-lg p-1 gap-1 bg-transparent transition-opacity focus-visible:outline focus-visible:outline-2 focus-visible:outline-primary-200", isSubmitting
112
124
  ? "opacity-50 pointer-events-none"
113
- : "cursor-pointer hover:opacity-80"), children: [_jsx(Avatar, { src: supporter === null || supporter === void 0 ? void 0 : supporter.avatar, size: 28, children: ((_b = (_a = supporter === null || supporter === void 0 ? void 0 : supporter.fullName) === null || _a === void 0 ? void 0 : _a.charAt) === null || _b === void 0 ? void 0 : _b.call(_a, 0)) || "A" }), _jsx("span", { className: "text-blue-500", children: _jsx(Icon, { icon: "shuffle-b", size: 20 }) })] })) }), _jsx(AssignConfirmModal, { open: confirmModalOpen, agent: selectedAgent, loading: isAssigning, onCancel: handleCancelConfirm, onConfirm: handleConfirmAssign, afterClose: handleAfterClose })] }));
125
+ : "cursor-pointer hover:opacity-80"), children: [_jsx(TintedAvatar, { name: (_a = supporter === null || supporter === void 0 ? void 0 : supporter.fullName) !== null && _a !== void 0 ? _a : "", src: supporter === null || supporter === void 0 ? void 0 : supporter.avatar, size: 28 }), _jsx("span", { className: "text-primary-400", children: _jsx(AdaptiveIcon, { stroke: "shuffle", font: "shuffle-b", size: 20, strokeSize: 18 }) })] })) }), _jsx(AssignConfirmModal, { open: confirmModalOpen, agent: selectedAgent, loading: isAssigning, onCancel: handleCancelConfirm, onConfirm: handleConfirmAssign, afterClose: handleAfterClose })] }));
114
126
  };
115
127
  export default ManualAssignPopover;
@@ -0,0 +1,6 @@
1
+ import { ISessionResponse } from "../../types/dto";
2
+ export declare const SessionDetailCard: ({ session, isActive, }: {
3
+ session: ISessionResponse;
4
+ isActive: boolean;
5
+ }) => import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=SessionDetailCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionDetailCard.d.ts","sourceRoot":"","sources":["../../../src/components/thread/SessionDetailCard.tsx"],"names":[],"mappings":"AAoBA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAsD/C,eAAO,MAAM,iBAAiB,GAAI,wBAG/B;IACD,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;CACnB,4CA8LA,CAAC"}
@@ -0,0 +1,103 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useId, useRef, useState } from "react";
3
+ import { Button, Input, message } from "antd";
4
+ import { StrokeIcon } from "../../components/icon/StrokeIcon";
5
+ import TintedAvatar from "../../components/common/TintedAvatar";
6
+ import { useQueryClient } from "@tanstack/react-query";
7
+ import { useTranslation } from "react-i18next";
8
+ import ManualAssignPopover from "./ManualAssignPopover";
9
+ import SessionTagPicker from "./SessionTagPicker";
10
+ import EndSessionConfirm from "./EndSessionConfirm";
11
+ import { formatSessionDate, formatSessionTime } from "./sessionDateFormat";
12
+ import { useGetLabelSession } from "../../hooks/session/useGetLabelSession";
13
+ import { useUpdateSessionInfo } from "../../hooks/session/useUpdateSessionInfo";
14
+ import { useSessionFieldAutosave, } from "../../hooks/session/useSessionFieldAutosave";
15
+ import { useEndSession } from "../../hooks/session/useEndSession";
16
+ import { useIsSessionClosePending } from "../../hooks/session/usePendingSessionClose";
17
+ import { useSessionCustomerName } from "../../hooks/session/useSessionCustomerName";
18
+ import { QUERY_KEYS } from "../../services/query";
19
+ import { SessionStatus } from "../../types/chat";
20
+ const { TextArea } = Input;
21
+ const mergeAutosaveStatus = (...statuses) => {
22
+ if (statuses.includes("error"))
23
+ return "error";
24
+ if (statuses.includes("saving"))
25
+ return "saving";
26
+ if (statuses.includes("saved"))
27
+ return "saved";
28
+ return "idle";
29
+ };
30
+ const SaveStatus = ({ status, onRetry, }) => {
31
+ const { t } = useTranslation("common");
32
+ if (status === "idle")
33
+ return null;
34
+ return (_jsxs("span", { role: "status", className: `flex items-center gap-1 text-xs ${status === "error"
35
+ ? "text-danger-600"
36
+ : status === "saved"
37
+ ? "text-success-900"
38
+ : "text-gray-600"}`, children: [status === "saving" && t("save_status_saving"), status === "saved" && (_jsxs(_Fragment, { children: [_jsx(StrokeIcon, { name: "check", size: 14 }), t("save_status_saved")] })), status === "error" && (_jsxs(_Fragment, { children: [t("save_status_failed"), " \u00B7", " ", _jsx("button", { type: "button", className: "underline", onClick: onRetry, children: t("retry") })] }))] }));
39
+ };
40
+ const fieldLabelClass = "text-xs font-medium text-gray-600";
41
+ const fieldClass = "!rounded-lg !border-gray-50 !px-2.5 !py-1.5 !text-sm";
42
+ export const SessionDetailCard = ({ session, isActive, }) => {
43
+ var _a, _b, _c, _d, _e;
44
+ const queryClient = useQueryClient();
45
+ const { t } = useTranslation("common");
46
+ const ids = useId();
47
+ const { data: availableLabels, isLoading: isLoadingLabels } = useGetLabelSession();
48
+ const { mutateAsync: updateSession } = useUpdateSessionInfo();
49
+ const endSession = useEndSession();
50
+ const isEnding = useIsSessionClosePending(session.id);
51
+ const customerName = useSessionCustomerName();
52
+ const [isEndConfirmOpen, setIsEndConfirmOpen] = useState(false);
53
+ const [tagStatus, setTagStatus] = useState("idle");
54
+ const tagSaveSeq = useRef(0);
55
+ const saveField = useCallback(async (data) => {
56
+ await updateSession(Object.assign({ sessionId: session.id }, data));
57
+ queryClient.invalidateQueries({
58
+ queryKey: [QUERY_KEYS.GET_LIST_SESSION_BY_CONVERSATION],
59
+ });
60
+ }, [session.id, updateSession, queryClient]);
61
+ const note = useSessionFieldAutosave({
62
+ serverValue: session.note || "",
63
+ save: (value) => saveField({ note: value }),
64
+ });
65
+ const issueDetail = useSessionFieldAutosave({
66
+ serverValue: session.issueDetail || "",
67
+ save: (value) => saveField({ issueDetail: value }),
68
+ });
69
+ const saveStatus = mergeAutosaveStatus(note.status, issueDetail.status, tagStatus);
70
+ const retrySave = () => {
71
+ if (note.status === "error")
72
+ void note.retry();
73
+ if (issueDetail.status === "error")
74
+ void issueDetail.retry();
75
+ };
76
+ const handleUpdateLabels = (labelIds) => {
77
+ const seq = ++tagSaveSeq.current;
78
+ setTagStatus("saving");
79
+ updateSession({ sessionId: session.id, labelIds })
80
+ .then(() => {
81
+ if (seq === tagSaveSeq.current)
82
+ setTagStatus("saved");
83
+ queryClient.invalidateQueries({
84
+ queryKey: [QUERY_KEYS.GET_LIST_SESSION_BY_CONVERSATION],
85
+ });
86
+ })
87
+ .catch(() => {
88
+ if (seq === tagSaveSeq.current)
89
+ setTagStatus("idle");
90
+ message.error(t("update_session_failed"));
91
+ });
92
+ };
93
+ const handleConfirmEnd = () => {
94
+ setIsEndConfirmOpen(false);
95
+ endSession({ sessionId: session.id, conversationId: session.conversationId });
96
+ };
97
+ return (_jsxs("div", { className: `flex flex-col gap-3 ${isActive ? "" : "rounded-lg border border-gray-50 p-3"}`, "data-cp-name": "SessionDetailCard", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm font-bold text-gray-900", children: t("session_label", { order: session.order }) }), _jsx("span", { className: "text-xs text-gray-600", children: isActive
98
+ ? t("session_started_at", {
99
+ time: formatSessionTime(session.createdDate),
100
+ })
101
+ : formatSessionDate(session.closedDate || session.createdDate) }), _jsx("span", { className: "flex-1" }), isActive ? (_jsx("span", { className: "inline-flex h-[22px] items-center rounded-full bg-success-25 px-2 text-xs font-medium text-success-900", children: t("session_active") })) : (_jsx(TintedAvatar, { name: ((_a = session.supporter) === null || _a === void 0 ? void 0 : _a.fullName) || "A", src: (_b = session.supporter) === null || _b === void 0 ? void 0 : _b.avatar, size: 24 }))] }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("label", { htmlFor: `${ids}-tags`, className: fieldLabelClass, children: t("session_tags_label") }), _jsx(SessionTagPicker, { labelId: `${ids}-tags`, available: availableLabels !== null && availableLabels !== void 0 ? availableLabels : [], selectedIds: (_d = (_c = session.labels) === null || _c === void 0 ? void 0 : _c.map((label) => label.id)) !== null && _d !== void 0 ? _d : [], loading: isLoadingLabels, onChange: handleUpdateLabels })] }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("label", { htmlFor: `${ids}-issue`, className: fieldLabelClass, children: t("session_issue_detail_label") }), _jsx(TextArea, { id: `${ids}-issue`, value: issueDetail.value, onChange: (e) => issueDetail.setValue(e.target.value), placeholder: t("session_issue_detail_placeholder"), className: `${fieldClass} !min-h-9`, autoSize: { minRows: 1, maxRows: 3 } })] }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("label", { htmlFor: `${ids}-note`, className: fieldLabelClass, children: t("session_note_label") }), _jsx(SaveStatus, { status: saveStatus, onRetry: retrySave })] }), _jsx(TextArea, { id: `${ids}-note`, value: note.value, onChange: (e) => note.setValue(e.target.value), placeholder: t("session_note_placeholder"), className: fieldClass, autoSize: { minRows: 2, maxRows: 4 } })] }), isActive && (_jsxs(_Fragment, { children: [session.status !== SessionStatus.UNASSIGNED &&
102
+ ((_e = session.supporter) === null || _e === void 0 ? void 0 : _e.id) && (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(TintedAvatar, { name: session.supporter.fullName || "A", src: session.supporter.avatar, size: 28 }), _jsxs("span", { className: "flex min-w-0 flex-1 flex-col", children: [_jsx("span", { className: "text-xs text-gray-600", children: t("session_owner_label") }), _jsx("span", { className: "truncate text-[13px] font-medium text-gray-900", children: session.supporter.fullName })] }), _jsx(ManualAssignPopover, { sessionId: session.id, supporter: session.supporter, teamId: session.teamId, placement: "topRight", children: _jsx(Button, { icon: _jsx(StrokeIcon, { name: "shuffle", size: 18 }), className: "!h-8 !rounded-lg !px-3.5 !text-[13px] !font-medium", children: t("manual_assign_button_reassign") }) })] })), _jsx(Button, { block: true, icon: _jsx(StrokeIcon, { name: "check-circle", size: 18 }), onClick: () => setIsEndConfirmOpen(true), disabled: isEnding, children: isEnding ? t("end_session_ending") : t("session_close_button") }), _jsx(EndSessionConfirm, { open: isEndConfirmOpen, session: session, customerName: customerName, onConfirm: handleConfirmEnd, onCancel: () => setIsEndConfirmOpen(false) })] }))] }));
103
+ };
@@ -1,8 +1,6 @@
1
+ import { SessionDetailCard } from "./SessionDetailCard";
1
2
  import { ISessionResponse } from "../../types/dto";
2
- export declare const SessionDetailCard: ({ session, isActive, }: {
3
- session: ISessionResponse;
4
- isActive: boolean;
5
- }) => import("react/jsx-runtime").JSX.Element;
3
+ export { SessionDetailCard };
6
4
  interface SessionSectionProps {
7
5
  sessions: ISessionResponse[];
8
6
  isLoading: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"SessionSection.d.ts","sourceRoot":"","sources":["../../../src/components/thread/SessionSection.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAkB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAqB/D,eAAO,MAAM,iBAAiB,GAAI,wBAG/B;IACD,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;CACnB,4CAmNA,CAAC;AAiDF,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,QAAA,MAAM,cAAc,GAAI,yBAAyB,mBAAmB,4CAqCnE,CAAC;AAEF,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"SessionSection.d.ts","sourceRoot":"","sources":["../../../src/components/thread/SessionSection.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAoF7B,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,QAAA,MAAM,cAAc,GAAI,yBAAyB,mBAAmB,4CAmCnE,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -1,135 +1,32 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useDebounce } from "ahooks";
3
- import { Icon } from "../../components/icon";
4
- import { Button, Select, Spin, Tag, Input, message, Avatar } from "antd";
5
- import ManualAssignPopover from "./ManualAssignPopover";
6
- import { useGetLabelSession } from "../../hooks/session/useGetLabelSession";
7
- import { useUpdateSessionInfo } from "../../hooks/session/useUpdateSessionInfo";
8
- import { useCloseSession } from "../../hooks/session/useCloseSession";
9
- import { useQueryClient } from "@tanstack/react-query";
10
- import { QUERY_KEYS } from "../../services/query";
11
- import { useEffect, useState } from "react";
2
+ import { useState } from "react";
3
+ import { Spin } from "antd";
12
4
  import { useTranslation } from "react-i18next";
13
- import { SessionStatus } from "../../types/chat";
14
- const { TextArea } = Input;
15
- const formatSessionDate = (dateString) => {
5
+ import { SessionDetailCard } from "./SessionDetailCard";
6
+ import { formatSessionDuration } from "./sessionDuration";
7
+ export { SessionDetailCard };
8
+ const MAX_VISIBLE_TAGS = 2;
9
+ const pad = (value) => String(value).padStart(2, "0");
10
+ const formatDayMonth = (dateString) => {
16
11
  if (!dateString)
17
12
  return "";
18
13
  const date = new Date(dateString);
19
- const hours = String(date.getHours()).padStart(2, "0");
20
- const minutes = String(date.getMinutes()).padStart(2, "0");
21
- const day = String(date.getDate()).padStart(2, "0");
22
- const month = String(date.getMonth() + 1).padStart(2, "0");
23
- return `${hours}:${minutes} ${day}/${month}`;
24
- };
25
- export const SessionDetailCard = ({ session, isActive, }) => {
26
- var _a, _b, _c, _d, _e, _f;
27
- const queryClient = useQueryClient();
28
- const { t } = useTranslation("common");
29
- const { data: availableLabels, isLoading: isLoadingLabels } = useGetLabelSession();
30
- const { mutate: updateSession } = useUpdateSessionInfo();
31
- const { mutate: closeSession, isPending: isClosing } = useCloseSession();
32
- const [noteInput, setNoteInput] = useState({
33
- value: session.note || "",
34
- sessionId: session.id,
35
- });
36
- const [issueDetailInput, setIssueDetailInput] = useState({
37
- value: session.issueDetail || "",
38
- sessionId: session.id,
39
- });
40
- const debouncedNoteInput = useDebounce(noteInput, { wait: 500 });
41
- const debouncedIssueDetailInput = useDebounce(issueDetailInput, {
42
- wait: 500,
43
- });
44
- useEffect(() => {
45
- setNoteInput({ value: session.note || "", sessionId: session.id });
46
- setIssueDetailInput({
47
- value: session.issueDetail || "",
48
- sessionId: session.id,
49
- });
50
- }, [session.id]);
51
- useEffect(() => {
52
- if (debouncedNoteInput.sessionId === session.id &&
53
- debouncedNoteInput.value !== (session.note || "")) {
54
- updateSession({ sessionId: session.id, note: debouncedNoteInput.value }, {
55
- onSuccess: () => {
56
- queryClient.invalidateQueries({
57
- queryKey: [QUERY_KEYS.GET_LIST_SESSION_BY_CONVERSATION],
58
- });
59
- },
60
- });
61
- }
62
- }, [
63
- debouncedNoteInput,
64
- session.note,
65
- session.id,
66
- updateSession,
67
- queryClient,
68
- ]);
69
- useEffect(() => {
70
- if (debouncedIssueDetailInput.sessionId === session.id &&
71
- debouncedIssueDetailInput.value !== (session.issueDetail || "")) {
72
- updateSession({
73
- sessionId: session.id,
74
- issueDetail: debouncedIssueDetailInput.value,
75
- }, {
76
- onSuccess: () => {
77
- queryClient.invalidateQueries({
78
- queryKey: [QUERY_KEYS.GET_LIST_SESSION_BY_CONVERSATION],
79
- });
80
- },
81
- });
82
- }
83
- }, [
84
- debouncedIssueDetailInput,
85
- session.issueDetail,
86
- session.id,
87
- updateSession,
88
- queryClient,
89
- ]);
90
- const handleUpdateLabels = (labelIds) => {
91
- updateSession({ sessionId: session.id, labelIds }, {
92
- onSuccess: () => {
93
- queryClient.invalidateQueries({
94
- queryKey: [QUERY_KEYS.GET_LIST_SESSION_BY_CONVERSATION],
95
- });
96
- },
97
- });
98
- };
99
- const handleCloseSession = () => {
100
- closeSession(session.id, {
101
- onSuccess: () => {
102
- message.success(t("close_session_success"));
103
- queryClient.invalidateQueries({
104
- queryKey: [QUERY_KEYS.GET_LIST_SESSION_BY_CONVERSATION],
105
- });
106
- },
107
- onError: () => {
108
- message.error(t("close_session_failed"));
109
- },
110
- });
111
- };
112
- const labelOptions = availableLabels === null || availableLabels === void 0 ? void 0 : availableLabels.map((label) => ({
113
- value: label.id,
114
- label: label.name,
115
- }));
116
- return (_jsxs("div", { className: `p-3 border rounded-lg shadow-md ${isActive ? "border-blue-500" : "border-gray-300"}`, "data-cp-name": "SessionDetailCard", children: [_jsxs("div", { className: "flex justify-between items-start mb-3", children: [_jsx("div", { className: "flex items-center gap-2", children: _jsxs("div", { className: "flex flex-col", children: [_jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Icon, { icon: "chat-square-b", size: 16, className: "text-gray-500" }), _jsx("p", { className: "font-semibold text-sm", children: t("session_label", { order: session.order }) })] }), _jsx("p", { className: "text-xs text-gray-400", children: formatSessionDate(session.closedDate || session.createdDate) })] }) }), isActive ? (_jsx(Tag, { color: "processing", children: t("session_active") })) : (_jsx(Avatar, { src: (_a = session.supporter) === null || _a === void 0 ? void 0 : _a.avatar, size: 24, children: ((_d = (_c = (_b = session.supporter) === null || _b === void 0 ? void 0 : _b.fullName) === null || _c === void 0 ? void 0 : _c.charAt) === null || _d === void 0 ? void 0 : _d.call(_c, 0)) || "A" }))] }), _jsxs("div", { className: "flex flex-col gap-3 text-sm", children: [_jsxs("div", { className: "flex items-center gap-2 text-gray-500", children: [_jsx(Icon, { icon: "tag-o", size: 16, className: "mt-1" }), _jsx(Select, { mode: "multiple", loading: isLoadingLabels, className: "w-full", placeholder: t("session_add_tag_placeholder"), options: labelOptions, value: (_e = session.labels) === null || _e === void 0 ? void 0 : _e.map((label) => label.id), onChange: handleUpdateLabels, removeIcon: true })] }), _jsxs("div", { className: "flex items-start gap-2 text-gray-500", children: [_jsx(Icon, { icon: "info-circle-o", size: 16, className: "mt-1" }), _jsx(TextArea, { value: issueDetailInput.value, onChange: (e) => setIssueDetailInput({
117
- value: e.target.value,
118
- sessionId: session.id,
119
- }), placeholder: t("session_issue_detail_placeholder"), className: "border-none !shadow-none py-0 px-2", autoSize: { minRows: 1, maxRows: 3 } })] }), _jsxs("div", { className: "flex items-start gap-2 text-gray-500", children: [_jsx(Icon, { icon: "paper-o", size: 16, className: "mt-1" }), _jsx(TextArea, { value: noteInput.value, onChange: (e) => setNoteInput({ value: e.target.value, sessionId: session.id }), placeholder: t("session_note_placeholder"), className: "border-none !shadow-none py-0 px-2", autoSize: { minRows: 1, maxRows: 3 } })] })] }), isActive && (_jsxs("div", { className: "flex items-center gap-2 mt-4 border-t border-gray-200 pt-4", children: [session.status !== SessionStatus.UNASSIGNED &&
120
- ((_f = session.supporter) === null || _f === void 0 ? void 0 : _f.id) && (_jsx(ManualAssignPopover, { sessionId: session.id, supporter: session.supporter, teamId: session.teamId })), _jsx(Button, { type: "primary", className: "flex-1", onClick: handleCloseSession, loading: isClosing, children: t("session_close_button") })] }))] }));
14
+ return `${pad(date.getDate())}/${pad(date.getMonth() + 1)}`;
121
15
  };
16
+ // One row per past session: order, date and duration, then tags and handler.
122
17
  const ClosedSessionItem = ({ session, expandedSessionId, onToggleExpand, }) => {
123
- var _a, _b, _c, _d;
18
+ var _a, _b;
124
19
  const { t } = useTranslation("common");
125
20
  const isExpanded = session.id === expandedSessionId;
126
- const handleClick = () => {
127
- onToggleExpand(session.id);
128
- };
129
21
  if (isExpanded) {
130
- return (_jsx("div", { children: _jsx(SessionDetailCard, { session: session, isActive: false }) }));
22
+ return (_jsxs("div", { className: "border-t border-gray-25 py-2.5", children: [_jsx(SessionDetailCard, { session: session, isActive: false }, session.id), _jsx("button", { type: "button", className: "mt-2 text-xs font-medium text-primary-500 hover:underline", onClick: () => onToggleExpand(session.id), children: t("session_collapse") })] }));
131
23
  }
132
- return (_jsxs("div", { className: "flex justify-between items-center p-2 rounded-md hover:bg-gray-100 cursor-pointer", onClick: handleClick, children: [_jsxs("div", { className: "flex items-center gap-2 text-sm", children: [_jsx(Icon, { icon: "chat-square-b", size: 16, className: "text-gray-500" }), _jsx("span", { className: "font-semibold", children: t("session_label", { order: session.order }) }), _jsx("span", { className: "text-gray-400 text-xs", children: formatSessionDate(session.closedDate || session.createdDate) })] }), _jsx(Avatar, { src: (_a = session.supporter) === null || _a === void 0 ? void 0 : _a.avatar, size: 24, children: ((_d = (_c = (_b = session.supporter) === null || _b === void 0 ? void 0 : _b.fullName) === null || _c === void 0 ? void 0 : _c.charAt) === null || _d === void 0 ? void 0 : _d.call(_c, 0)) || "A" })] }));
24
+ const tags = (_a = session.labels) !== null && _a !== void 0 ? _a : [];
25
+ const duration = formatSessionDuration(session.createdDate, session.closedDate, t);
26
+ const dateText = [formatDayMonth(session.closedDate || session.createdDate), duration]
27
+ .filter(Boolean)
28
+ .join(" · ");
29
+ return (_jsxs("button", { type: "button", "aria-expanded": false, className: "flex w-full flex-col gap-1 border-t border-gray-25 py-2.5 text-left hover:bg-gray-5", onClick: () => onToggleExpand(session.id), "data-testid": "past-session-row", children: [_jsxs("span", { className: "flex items-center justify-between gap-2 text-[13px]", children: [_jsx("span", { className: "font-semibold text-gray-900", children: t("session_label", { order: session.order }) }), _jsx("span", { className: "text-gray-600", children: dateText })] }), _jsxs("span", { className: "flex min-w-0 items-center gap-1.5 text-xs text-gray-600", children: [tags.slice(0, MAX_VISIBLE_TAGS).map((label) => (_jsx("span", { className: "inline-flex h-5 max-w-[120px] shrink-0 items-center truncate rounded-full bg-[var(--dc-color-neutral-surface)] px-2 font-medium text-gray-900", children: label.name }, label.id))), tags.length > MAX_VISIBLE_TAGS && (_jsxs("span", { className: "shrink-0", children: ["+", tags.length - MAX_VISIBLE_TAGS] })), _jsx("span", { className: "truncate", children: (_b = session.supporter) === null || _b === void 0 ? void 0 : _b.fullName })] })] }));
133
30
  };
134
31
  const SessionSection = ({ sessions, isLoading }) => {
135
32
  const { t } = useTranslation("common");
@@ -137,6 +34,6 @@ const SessionSection = ({ sessions, isLoading }) => {
137
34
  const handleToggleExpand = (sessionId) => {
138
35
  setExpandedSessionId((prevId) => (prevId === sessionId ? null : sessionId));
139
36
  };
140
- return (_jsxs("div", { className: "flex flex-col border-b", "data-cp-name": "SessionSection", children: [_jsx("div", { className: "flex items-center justify-between px-4 py-2 sticky top-0 bg-white z-10", children: _jsx("h3", { className: "font-bold text-gray-500 text-xs tracking-wider", children: t("sessions_heading") }) }), _jsx("div", { className: "px-4 pt-2 pb-4", children: isLoading ? (_jsx("div", { className: "text-center mt-4", children: _jsx(Spin, {}) })) : (_jsx("div", { className: "flex flex-col gap-1", children: sessions.map((session) => (_jsx(ClosedSessionItem, { session: session, expandedSessionId: expandedSessionId, onToggleExpand: handleToggleExpand }, session.id))) })) })] }));
37
+ return (_jsxs("div", { className: "flex flex-col px-4 pb-2 pt-3", "data-cp-name": "SessionSection", children: [_jsx("h3", { className: "mb-1 text-[13px] font-semibold text-gray-900", children: t("sessions_previous_heading") }), isLoading ? (_jsx("div", { className: "mt-4 text-center", children: _jsx(Spin, {}) })) : sessions.length === 0 ? (_jsx("p", { className: "py-2 text-xs text-gray-600", children: t("sessions_previous_empty") })) : (_jsx("div", { className: "flex flex-col", children: sessions.map((session) => (_jsx(ClosedSessionItem, { session: session, expandedSessionId: expandedSessionId, onToggleExpand: handleToggleExpand }, session.id))) }))] }));
141
38
  };
142
39
  export default SessionSection;
@@ -0,0 +1,11 @@
1
+ import type { ILabelResponse } from "../../types/dto";
2
+ interface SessionTagPickerProps {
3
+ labelId: string;
4
+ available: ILabelResponse[];
5
+ selectedIds: string[];
6
+ loading?: boolean;
7
+ onChange: (ids: string[]) => void;
8
+ }
9
+ declare const SessionTagPicker: ({ labelId, available, selectedIds, loading, onChange, }: SessionTagPickerProps) => import("react/jsx-runtime").JSX.Element;
10
+ export default SessionTagPicker;
11
+ //# sourceMappingURL=SessionTagPicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionTagPicker.d.ts","sourceRoot":"","sources":["../../../src/components/thread/SessionTagPicker.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,UAAU,qBAAqB;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACnC;AAMD,QAAA,MAAM,gBAAgB,GAAI,yDAMvB,qBAAqB,4CAwFvB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,27 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useId, useState } from "react";
4
+ import { StrokeIcon } from "../../components/icon/StrokeIcon";
5
+ import { Spin } from "antd";
6
+ import { useTranslation } from "react-i18next";
7
+ const chipClass = "inline-flex h-[22px] items-center gap-1 whitespace-nowrap rounded-full bg-[var(--dc-color-neutral-surface)] px-2 text-xs font-medium text-gray-900";
8
+ // The option list opens inline under the field, so it pushes the card instead of floating over it.
9
+ const SessionTagPicker = ({ labelId, available, selectedIds, loading, onChange, }) => {
10
+ const { t } = useTranslation("common");
11
+ const [open, setOpen] = useState(false);
12
+ const listId = useId();
13
+ const selected = available.filter((label) => selectedIds.includes(label.id));
14
+ const toggle = (id) => onChange(selectedIds.includes(id)
15
+ ? selectedIds.filter((value) => value !== id)
16
+ : [...selectedIds, id]);
17
+ return (_jsxs("div", { onKeyDown: (event) => {
18
+ if (event.key === "Escape" && open) {
19
+ event.stopPropagation();
20
+ setOpen(false);
21
+ }
22
+ }, children: [_jsxs("div", { className: "flex min-h-9 flex-wrap items-center gap-1 rounded-lg border border-gray-50 px-1.5 py-1", children: [selected.map((label) => (_jsxs("span", { className: chipClass, children: [label.name, _jsx("button", { type: "button", "aria-label": t("session_remove_tag", { name: label.name }), className: "flex h-4 w-4 items-center justify-center rounded-full text-gray-600 hover:bg-gray-50", onClick: () => toggle(label.id), children: _jsx(StrokeIcon, { name: "x", size: 12 }) })] }, label.id))), _jsxs("button", { id: labelId, type: "button", "aria-label": t("session_add_tag"), "aria-expanded": open, "aria-controls": listId, className: "flex h-6 items-center gap-1 rounded px-1 text-[13px] text-gray-600 hover:text-gray-900", onClick: () => setOpen((value) => !value), children: [_jsx(StrokeIcon, { name: "plus", size: 14 }), t("session_add_tag")] })] }), open && (_jsxs("ul", { id: listId, role: "listbox", "aria-multiselectable": true, "aria-labelledby": labelId, className: "mt-1 max-h-40 overflow-y-auto rounded-lg border border-gray-50 p-1", children: [loading && (_jsx("li", { className: "flex justify-center py-2", children: _jsx(Spin, { size: "small" }) })), !loading && available.length === 0 && (_jsx("li", { className: "px-2 py-1.5 text-[13px] text-gray-600", children: t("session_no_tags") })), available.map((label) => {
23
+ const isSelected = selectedIds.includes(label.id);
24
+ return (_jsx("li", { role: "option", "aria-selected": isSelected, children: _jsxs("button", { type: "button", className: `flex h-8 w-full items-center justify-between rounded px-2 text-left text-[13px] text-gray-900 hover:bg-gray-5 ${isSelected ? "bg-primary-25" : ""}`, onClick: () => toggle(label.id), children: [label.name, isSelected && _jsx(StrokeIcon, { name: "check", size: 14 })] }) }, label.id));
25
+ })] }))] }));
26
+ };
27
+ export default SessionTagPicker;
@@ -1 +1 @@
1
- {"version":3,"file":"SingleThreadInfo.d.ts","sourceRoot":"","sources":["../../../src/components/thread/SingleThreadInfo.tsx"],"names":[],"mappings":"AAaA,UAAU,qBAAqB;IAC7B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,QAAA,MAAM,gBAAgB,GAAI,aAAa,qBAAqB,mDAoJ3D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"SingleThreadInfo.d.ts","sourceRoot":"","sources":["../../../src/components/thread/SingleThreadInfo.tsx"],"names":[],"mappings":"AAgBA,UAAU,qBAAqB;IAC7B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,QAAA,MAAM,gBAAgB,GAAI,aAAa,qBAAqB,mDA2J3D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}