@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.
- package/dist/components/canned-response/CannedResponseBody.d.ts.map +1 -1
- package/dist/components/canned-response/CannedResponseBody.js +4 -3
- package/dist/components/canned-response/CannedResponsePanel.d.ts +9 -0
- package/dist/components/canned-response/CannedResponsePanel.d.ts.map +1 -0
- package/dist/components/canned-response/CannedResponsePanel.js +72 -0
- package/dist/components/canned-response/CannedResponseRow.d.ts +10 -0
- package/dist/components/canned-response/CannedResponseRow.d.ts.map +1 -0
- package/dist/components/canned-response/CannedResponseRow.js +6 -0
- package/dist/components/canned-response/CannedScopeChips.d.ts +10 -0
- package/dist/components/canned-response/CannedScopeChips.d.ts.map +1 -0
- package/dist/components/canned-response/CannedScopeChips.js +34 -0
- package/dist/components/canned-response/cannedScopes.d.ts +16 -0
- package/dist/components/canned-response/cannedScopes.d.ts.map +1 -0
- package/dist/components/canned-response/cannedScopes.js +39 -0
- package/dist/components/canned-response/index.d.ts.map +1 -1
- package/dist/components/canned-response/index.js +11 -10
- package/dist/components/canned-response/insertCannedContent.d.ts +7 -0
- package/dist/components/canned-response/insertCannedContent.d.ts.map +1 -0
- package/dist/components/canned-response/insertCannedContent.js +39 -0
- package/dist/components/canned-response/team/TeamItem.d.ts.map +1 -1
- package/dist/components/canned-response/team/TeamItem.js +5 -4
- package/dist/components/common/ConfirmModal.d.ts +13 -1
- package/dist/components/common/ConfirmModal.d.ts.map +1 -1
- package/dist/components/common/ConfirmModal.js +24 -6
- package/dist/components/common/DeskPanelDrawer.d.ts +17 -0
- package/dist/components/common/DeskPanelDrawer.d.ts.map +1 -0
- package/dist/components/common/DeskPanelDrawer.js +21 -0
- package/dist/components/common/DeskSidePanel.d.ts +17 -0
- package/dist/components/common/DeskSidePanel.d.ts.map +1 -0
- package/dist/components/common/DeskSidePanel.js +23 -0
- package/dist/components/common/TintedAvatar.d.ts +11 -0
- package/dist/components/common/TintedAvatar.d.ts.map +1 -0
- package/dist/components/common/TintedAvatar.js +17 -0
- package/dist/components/compose/ComposeNewMessageModal.d.ts.map +1 -1
- package/dist/components/compose/ComposeNewMessageModal.js +11 -1
- package/dist/components/conversation/ConversationByGroupItem.d.ts.map +1 -1
- package/dist/components/conversation/ConversationByGroupItem.js +10 -6
- package/dist/components/conversation/ConversationBySessionItem.d.ts +4 -1
- package/dist/components/conversation/ConversationBySessionItem.d.ts.map +1 -1
- package/dist/components/conversation/ConversationBySessionItem.js +36 -10
- package/dist/components/conversation/DeskConversationList.d.ts.map +1 -1
- package/dist/components/conversation/DeskConversationList.js +44 -29
- package/dist/components/conversation/DeskConversationRow.d.ts +19 -0
- package/dist/components/conversation/DeskConversationRow.d.ts.map +1 -0
- package/dist/components/conversation/DeskConversationRow.js +18 -0
- package/dist/components/conversation/DeskListEmptyState.d.ts +6 -0
- package/dist/components/conversation/DeskListEmptyState.d.ts.map +1 -0
- package/dist/components/conversation/DeskListEmptyState.js +11 -0
- package/dist/components/conversation/DeskListHeader.d.ts +14 -0
- package/dist/components/conversation/DeskListHeader.d.ts.map +1 -0
- package/dist/components/conversation/DeskListHeader.js +39 -0
- package/dist/components/conversation/DeskListSkeleton.d.ts +6 -0
- package/dist/components/conversation/DeskListSkeleton.d.ts.map +1 -0
- package/dist/components/conversation/DeskListSkeleton.js +9 -0
- package/dist/components/conversation/DeskRowAvatar.d.ts +8 -0
- package/dist/components/conversation/DeskRowAvatar.d.ts.map +1 -0
- package/dist/components/conversation/DeskRowAvatar.js +6 -0
- package/dist/components/conversation/RowChip.d.ts +14 -0
- package/dist/components/conversation/RowChip.d.ts.map +1 -0
- package/dist/components/conversation/RowChip.js +11 -0
- package/dist/components/conversation/avatarTint.d.ts +6 -0
- package/dist/components/conversation/avatarTint.d.ts.map +1 -0
- package/dist/components/conversation/avatarTint.js +27 -0
- package/dist/components/conversation/folderEmptyState.d.ts +2 -0
- package/dist/components/conversation/folderEmptyState.d.ts.map +1 -0
- package/dist/components/conversation/folderEmptyState.js +14 -0
- package/dist/components/conversation/internalNotePreview.d.ts +6 -0
- package/dist/components/conversation/internalNotePreview.d.ts.map +1 -0
- package/dist/components/conversation/internalNotePreview.js +11 -0
- package/dist/components/conversation/listHeading.d.ts +19 -0
- package/dist/components/conversation/listHeading.d.ts.map +1 -0
- package/dist/components/conversation/listHeading.js +24 -0
- package/dist/components/conversation/rowDisplayName.d.ts +7 -0
- package/dist/components/conversation/rowDisplayName.d.ts.map +1 -0
- package/dist/components/conversation/rowDisplayName.js +8 -0
- package/dist/components/conversation/rowTime.d.ts +4 -0
- package/dist/components/conversation/rowTime.d.ts.map +1 -0
- package/dist/components/conversation/rowTime.js +10 -0
- package/dist/components/conversation-detail/PinLimitModal.d.ts.map +1 -1
- package/dist/components/conversation-detail/PinLimitModal.js +3 -1
- package/dist/components/group/AddMemberModal.d.ts.map +1 -1
- package/dist/components/group/AddMemberModal.js +15 -4
- package/dist/components/group/AdminPermissionModal.d.ts +1 -0
- package/dist/components/group/AdminPermissionModal.d.ts.map +1 -1
- package/dist/components/group/AdminPermissionModal.js +38 -3
- package/dist/components/group/CreateGroupForm.d.ts +3 -1
- package/dist/components/group/CreateGroupForm.d.ts.map +1 -1
- package/dist/components/group/CreateGroupForm.js +7 -1
- package/dist/components/group/CreateGroupFormCrmView.d.ts +23 -0
- package/dist/components/group/CreateGroupFormCrmView.d.ts.map +1 -0
- package/dist/components/group/CreateGroupFormCrmView.js +25 -0
- package/dist/components/group/DisableSendPermissionConfirm.d.ts +11 -0
- package/dist/components/group/DisableSendPermissionConfirm.d.ts.map +1 -0
- package/dist/components/group/DisableSendPermissionConfirm.js +10 -0
- package/dist/components/group/GroupCompositeAvatar.d.ts.map +1 -1
- package/dist/components/group/GroupCompositeAvatar.js +39 -4
- package/dist/components/group/GroupMemberPicker.d.ts +5 -2
- package/dist/components/group/GroupMemberPicker.d.ts.map +1 -1
- package/dist/components/group/GroupMemberPicker.js +8 -42
- package/dist/components/group/GroupMemberPickerCrm.d.ts +4 -0
- package/dist/components/group/GroupMemberPickerCrm.d.ts.map +1 -0
- package/dist/components/group/GroupMemberPickerCrm.js +48 -0
- package/dist/components/group/GroupMemberPickerLegacy.d.ts +8 -0
- package/dist/components/group/GroupMemberPickerLegacy.d.ts.map +1 -0
- package/dist/components/group/GroupMemberPickerLegacy.js +46 -0
- package/dist/components/group/GroupPanelHeader.d.ts +10 -0
- package/dist/components/group/GroupPanelHeader.d.ts.map +1 -0
- package/dist/components/group/GroupPanelHeader.js +11 -0
- package/dist/components/group/MemberPermissionPanel.d.ts.map +1 -1
- package/dist/components/group/MemberPermissionPanel.js +31 -2
- package/dist/components/group/PermissionPanelCrm.d.ts +24 -0
- package/dist/components/group/PermissionPanelCrm.d.ts.map +1 -0
- package/dist/components/group/PermissionPanelCrm.js +16 -0
- package/dist/components/group/PersonAvatar.d.ts +11 -0
- package/dist/components/group/PersonAvatar.d.ts.map +1 -0
- package/dist/components/group/PersonAvatar.js +21 -0
- package/dist/components/group/crmIcon.d.ts +9 -0
- package/dist/components/group/crmIcon.d.ts.map +1 -0
- package/dist/components/group/crmIcon.js +38 -0
- package/dist/components/icon/AdaptiveIcon.d.ts +15 -0
- package/dist/components/icon/AdaptiveIcon.d.ts.map +1 -0
- package/dist/components/icon/AdaptiveIcon.js +10 -0
- package/dist/components/icon/StrokeIcon.d.ts +14 -0
- package/dist/components/icon/StrokeIcon.d.ts.map +1 -0
- package/dist/components/icon/StrokeIcon.js +5 -0
- package/dist/components/icon/strokeIconNodes.d.ts +431 -0
- package/dist/components/icon/strokeIconNodes.d.ts.map +1 -0
- package/dist/components/icon/strokeIconNodes.js +269 -0
- package/dist/components/media-collection/index.d.ts.map +1 -1
- package/dist/components/media-collection/index.js +21 -5
- package/dist/components/message/GroupMembersDrawer.d.ts.map +1 -1
- package/dist/components/message/GroupMembersDrawer.js +60 -13
- package/dist/components/message/GroupMembersPanelCrm.d.ts +23 -0
- package/dist/components/message/GroupMembersPanelCrm.d.ts.map +1 -0
- package/dist/components/message/GroupMembersPanelCrm.js +55 -0
- package/dist/components/message/MessageHeader.d.ts.map +1 -1
- package/dist/components/message/MessageHeader.js +76 -27
- package/dist/components/message/MessageInfiniteScroll.d.ts +4 -2
- package/dist/components/message/MessageInfiniteScroll.d.ts.map +1 -1
- package/dist/components/message/MessageInfiniteScroll.js +1 -1
- package/dist/components/message/MessageList.d.ts +2 -1
- package/dist/components/message/MessageList.d.ts.map +1 -1
- package/dist/components/message/MessageList.js +12 -1
- package/dist/components/message/SelectSession.d.ts +4 -1
- package/dist/components/message/SelectSession.d.ts.map +1 -1
- package/dist/components/message/SelectSession.js +13 -4
- package/dist/components/message/UnassignedSessionFooter.js +2 -2
- package/dist/components/message/footer/ActionBar.d.ts +5 -1
- package/dist/components/message/footer/ActionBar.d.ts.map +1 -1
- package/dist/components/message/footer/ActionBar.js +14 -1
- package/dist/components/message/footer/CannedResponsePlugin.d.ts.map +1 -1
- package/dist/components/message/footer/CannedResponsePlugin.js +18 -3
- package/dist/components/message/footer/ClosedSessionBanner.d.ts +9 -0
- package/dist/components/message/footer/ClosedSessionBanner.d.ts.map +1 -0
- package/dist/components/message/footer/ClosedSessionBanner.js +13 -0
- package/dist/components/message/footer/ComposerEditor.d.ts.map +1 -1
- package/dist/components/message/footer/ComposerEditor.js +9 -4
- package/dist/components/message/footer/ComposerTabs.d.ts +1 -2
- package/dist/components/message/footer/ComposerTabs.d.ts.map +1 -1
- package/dist/components/message/footer/ComposerTabs.js +14 -35
- package/dist/components/message/footer/CrmComposerCard.d.ts +11 -0
- package/dist/components/message/footer/CrmComposerCard.d.ts.map +1 -0
- package/dist/components/message/footer/CrmComposerCard.js +30 -0
- package/dist/components/message/footer/EnterHandler.d.ts.map +1 -1
- package/dist/components/message/footer/EnterHandler.js +3 -0
- package/dist/components/message/footer/FilePreview.js +2 -2
- package/dist/components/message/footer/LinkInputPreview.js +2 -2
- package/dist/components/message/footer/MediaActions.d.ts +2 -1
- package/dist/components/message/footer/MediaActions.d.ts.map +1 -1
- package/dist/components/message/footer/MediaActions.js +21 -4
- package/dist/components/message/footer/SessionClosedModal.d.ts +3 -1
- package/dist/components/message/footer/SessionClosedModal.d.ts.map +1 -1
- package/dist/components/message/footer/SessionClosedModal.js +6 -2
- package/dist/components/message/footer/ToolbarPlugin.d.ts +3 -1
- package/dist/components/message/footer/ToolbarPlugin.d.ts.map +1 -1
- package/dist/components/message/footer/ToolbarPlugin.js +2 -2
- package/dist/components/message/footer/clearComposerHistory.d.ts +3 -0
- package/dist/components/message/footer/clearComposerHistory.d.ts.map +1 -0
- package/dist/components/message/footer/clearComposerHistory.js +11 -0
- package/dist/components/message/footer/index.d.ts +2 -2
- package/dist/components/message/footer/index.d.ts.map +1 -1
- package/dist/components/message/footer/index.js +15 -5
- package/dist/components/message/footer/mention/MentionMenu.d.ts.map +1 -1
- package/dist/components/message/footer/mention/MentionMenu.js +4 -1
- package/dist/components/message/footer/useComposerFocusRequest.d.ts +10 -0
- package/dist/components/message/footer/useComposerFocusRequest.d.ts.map +1 -0
- package/dist/components/message/footer/useComposerFocusRequest.js +28 -0
- package/dist/components/message/groupMemberMenuCrm.d.ts +32 -0
- package/dist/components/message/groupMemberMenuCrm.d.ts.map +1 -0
- package/dist/components/message/groupMemberMenuCrm.js +83 -0
- package/dist/components/message/groupMemberTypes.d.ts +13 -0
- package/dist/components/message/groupMemberTypes.d.ts.map +1 -0
- package/dist/components/message/groupMemberTypes.js +1 -0
- package/dist/components/message/headerIconButton.d.ts +10 -0
- package/dist/components/message/headerIconButton.d.ts.map +1 -0
- package/dist/components/message/headerIconButton.js +9 -0
- package/dist/components/message/item/CrmSystemLine.d.ts +10 -0
- package/dist/components/message/item/CrmSystemLine.d.ts.map +1 -0
- package/dist/components/message/item/CrmSystemLine.js +6 -0
- package/dist/components/message/item/DateDivider.d.ts +5 -0
- package/dist/components/message/item/DateDivider.d.ts.map +1 -0
- package/dist/components/message/item/DateDivider.js +5 -0
- package/dist/components/message/item/GroupNotificationMessage.d.ts.map +1 -1
- package/dist/components/message/item/GroupNotificationMessage.js +9 -0
- package/dist/components/message/item/MemberEventSummary.d.ts +8 -0
- package/dist/components/message/item/MemberEventSummary.d.ts.map +1 -0
- package/dist/components/message/item/MemberEventSummary.js +18 -0
- package/dist/components/message/item/MessageBubble.d.ts +3 -1
- package/dist/components/message/item/MessageBubble.d.ts.map +1 -1
- package/dist/components/message/item/MessageBubble.js +27 -13
- package/dist/components/message/item/MessageMoreButton.d.ts +13 -0
- package/dist/components/message/item/MessageMoreButton.d.ts.map +1 -0
- package/dist/components/message/item/MessageMoreButton.js +42 -0
- package/dist/components/message/item/QuoteMessage.d.ts.map +1 -1
- package/dist/components/message/item/QuoteMessage.js +23 -2
- package/dist/components/message/item/RevokeMessage.js +1 -1
- package/dist/components/message/item/SessionEventMessage.d.ts.map +1 -1
- package/dist/components/message/item/SessionEventMessage.js +13 -1
- package/dist/components/message/item/SystemLogMessage.d.ts.map +1 -1
- package/dist/components/message/item/SystemLogMessage.js +7 -0
- package/dist/components/message/item/index.d.ts.map +1 -1
- package/dist/components/message/item/index.js +80 -18
- package/dist/components/message/item/otherSenders.d.ts +7 -0
- package/dist/components/message/item/otherSenders.d.ts.map +1 -0
- package/dist/components/message/item/otherSenders.js +29 -0
- package/dist/components/message/item/textStyle.d.ts +1 -1
- package/dist/components/message/item/textStyle.d.ts.map +1 -1
- package/dist/components/message/item/textStyle.js +2 -2
- package/dist/components/message/messageKeyboardNav.d.ts +8 -0
- package/dist/components/message/messageKeyboardNav.d.ts.map +1 -0
- package/dist/components/message/messageKeyboardNav.js +24 -0
- package/dist/components/message/reply/ReplyPreviewBar.d.ts.map +1 -1
- package/dist/components/message/reply/ReplyPreviewBar.js +11 -4
- package/dist/components/message/toolbox/MessageToolboxMenu.d.ts.map +1 -1
- package/dist/components/message/toolbox/MessageToolboxMenu.js +16 -1
- package/dist/components/search-conversation/SearchAll.d.ts.map +1 -1
- package/dist/components/search-conversation/SearchAll.js +12 -1
- package/dist/components/search-conversation/SearchDrawer.d.ts.map +1 -1
- package/dist/components/search-conversation/SearchDrawer.js +31 -15
- package/dist/components/search-conversation/SearchMessageOnCurrentConversation.d.ts.map +1 -1
- package/dist/components/search-conversation/SearchMessageOnCurrentConversation.js +5 -2
- package/dist/components/search-conversation/index.d.ts.map +1 -1
- package/dist/components/search-conversation/index.js +3 -1
- package/dist/components/search-conversation/item/SearchItemAsGroup.d.ts.map +1 -1
- package/dist/components/search-conversation/item/SearchItemAsGroup.js +14 -4
- package/dist/components/search-conversation/item/SearchItemAsMessage.d.ts.map +1 -1
- package/dist/components/search-conversation/item/SearchItemAsMessage.js +18 -7
- package/dist/components/search-conversation/item/SearchItemAsUser.d.ts.map +1 -1
- package/dist/components/search-conversation/item/SearchItemAsUser.js +23 -5
- package/dist/components/search-conversation/item/searchRowClass.d.ts +3 -0
- package/dist/components/search-conversation/item/searchRowClass.d.ts.map +1 -0
- package/dist/components/search-conversation/item/searchRowClass.js +5 -0
- package/dist/components/session/DeskAssignedSession.d.ts +5 -1
- package/dist/components/session/DeskAssignedSession.d.ts.map +1 -1
- package/dist/components/session/DeskAssignedSession.js +40 -12
- package/dist/components/session/DeskTeamInbox.d.ts.map +1 -1
- package/dist/components/session/DeskTeamInbox.js +15 -22
- package/dist/components/session/FolderRow.d.ts +21 -0
- package/dist/components/session/FolderRow.d.ts.map +1 -0
- package/dist/components/session/FolderRow.js +16 -0
- package/dist/components/session/SessionFolderList.d.ts +23 -0
- package/dist/components/session/SessionFolderList.d.ts.map +1 -0
- package/dist/components/session/SessionFolderList.js +27 -0
- package/dist/components/session/sessionFilters.d.ts +24 -0
- package/dist/components/session/sessionFilters.d.ts.map +1 -0
- package/dist/components/session/sessionFilters.js +80 -0
- package/dist/components/shortcut-help/ShortcutHelpModal.d.ts +8 -0
- package/dist/components/shortcut-help/ShortcutHelpModal.d.ts.map +1 -0
- package/dist/components/shortcut-help/ShortcutHelpModal.js +23 -0
- package/dist/components/thread/AssignConfirmModal.d.ts.map +1 -1
- package/dist/components/thread/AssignConfirmModal.js +4 -3
- package/dist/components/thread/EndSessionConfirm.d.ts +11 -0
- package/dist/components/thread/EndSessionConfirm.d.ts.map +1 -0
- package/dist/components/thread/EndSessionConfirm.js +31 -0
- package/dist/components/thread/EndSessionToast.d.ts +6 -0
- package/dist/components/thread/EndSessionToast.d.ts.map +1 -0
- package/dist/components/thread/EndSessionToast.js +18 -0
- package/dist/components/thread/GroupInfoBodyCrm.d.ts +46 -0
- package/dist/components/thread/GroupInfoBodyCrm.d.ts.map +1 -0
- package/dist/components/thread/GroupInfoBodyCrm.js +41 -0
- package/dist/components/thread/GroupInfoRows.d.ts +33 -0
- package/dist/components/thread/GroupInfoRows.d.ts.map +1 -0
- package/dist/components/thread/GroupInfoRows.js +18 -0
- package/dist/components/thread/GroupThreadInfo.d.ts.map +1 -1
- package/dist/components/thread/GroupThreadInfo.js +23 -6
- package/dist/components/thread/ManualAssignPopover.d.ts +3 -1
- package/dist/components/thread/ManualAssignPopover.d.ts.map +1 -1
- package/dist/components/thread/ManualAssignPopover.js +21 -9
- package/dist/components/thread/SessionDetailCard.d.ts +6 -0
- package/dist/components/thread/SessionDetailCard.d.ts.map +1 -0
- package/dist/components/thread/SessionDetailCard.js +103 -0
- package/dist/components/thread/SessionSection.d.ts +2 -4
- package/dist/components/thread/SessionSection.d.ts.map +1 -1
- package/dist/components/thread/SessionSection.js +19 -122
- package/dist/components/thread/SessionTagPicker.d.ts +11 -0
- package/dist/components/thread/SessionTagPicker.d.ts.map +1 -0
- package/dist/components/thread/SessionTagPicker.js +27 -0
- package/dist/components/thread/SingleThreadInfo.d.ts.map +1 -1
- package/dist/components/thread/SingleThreadInfo.js +16 -6
- package/dist/components/thread/SupportSessionPanel.d.ts +18 -0
- package/dist/components/thread/SupportSessionPanel.d.ts.map +1 -0
- package/dist/components/thread/SupportSessionPanel.js +46 -0
- package/dist/components/thread/ThreadInfo.d.ts +8 -1
- package/dist/components/thread/ThreadInfo.d.ts.map +1 -1
- package/dist/components/thread/ThreadInfo.js +27 -29
- package/dist/components/thread/ThreadInfoHeader.d.ts +13 -0
- package/dist/components/thread/ThreadInfoHeader.d.ts.map +1 -0
- package/dist/components/thread/ThreadInfoHeader.js +11 -0
- package/dist/components/thread/UserSection.d.ts.map +1 -1
- package/dist/components/thread/UserSection.js +35 -22
- package/dist/components/thread/sessionDateFormat.d.ts +3 -0
- package/dist/components/thread/sessionDateFormat.d.ts.map +1 -0
- package/dist/components/thread/sessionDateFormat.js +13 -0
- package/dist/components/thread/sessionDuration.d.ts +5 -0
- package/dist/components/thread/sessionDuration.d.ts.map +1 -0
- package/dist/components/thread/sessionDuration.js +24 -0
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +2 -0
- package/dist/constants/layout.d.ts +24 -0
- package/dist/constants/layout.d.ts.map +1 -0
- package/dist/constants/layout.js +23 -0
- package/dist/context/ChatContext.d.ts.map +1 -1
- package/dist/context/ChatContext.js +27 -1
- package/dist/hooks/canned-response/useSearchCannedAcrossScopes.d.ts +7 -0
- package/dist/hooks/canned-response/useSearchCannedAcrossScopes.d.ts.map +1 -0
- package/dist/hooks/canned-response/useSearchCannedAcrossScopes.js +46 -0
- package/dist/hooks/common/useCloseOnSidePanelOpen.d.ts +3 -0
- package/dist/hooks/common/useCloseOnSidePanelOpen.d.ts.map +1 -0
- package/dist/hooks/common/useCloseOnSidePanelOpen.js +15 -0
- package/dist/hooks/common/useDeskShortcuts.d.ts +11 -0
- package/dist/hooks/common/useDeskShortcuts.d.ts.map +1 -0
- package/dist/hooks/common/useDeskShortcuts.js +94 -0
- package/dist/hooks/common/useEscapeLayer.d.ts +3 -0
- package/dist/hooks/common/useEscapeLayer.d.ts.map +1 -0
- package/dist/hooks/common/useEscapeLayer.js +18 -0
- package/dist/hooks/common/useMediaQuery.d.ts +3 -0
- package/dist/hooks/common/useMediaQuery.d.ts.map +1 -0
- package/dist/hooks/common/useMediaQuery.js +12 -0
- package/dist/hooks/common/useSidePanel.d.ts +12 -0
- package/dist/hooks/common/useSidePanel.d.ts.map +1 -0
- package/dist/hooks/common/useSidePanel.js +32 -0
- package/dist/hooks/group/useConversationGroups.d.ts.map +1 -1
- package/dist/hooks/group/useConversationGroups.js +3 -0
- package/dist/hooks/message/useNewMessageAnnouncement.d.ts +3 -0
- package/dist/hooks/message/useNewMessageAnnouncement.d.ts.map +1 -0
- package/dist/hooks/message/useNewMessageAnnouncement.js +30 -0
- package/dist/hooks/search/useSearchGroups.js +2 -1
- package/dist/hooks/search/useSearchMessage.d.ts +3 -1
- package/dist/hooks/search/useSearchMessage.d.ts.map +1 -1
- package/dist/hooks/search/useSearchMessage.js +2 -2
- package/dist/hooks/session/useBotSessionOwnerIdentity.d.ts +12 -0
- package/dist/hooks/session/useBotSessionOwnerIdentity.d.ts.map +1 -0
- package/dist/hooks/session/useBotSessionOwnerIdentity.js +22 -0
- package/dist/hooks/session/useCloseSession.d.ts +1 -0
- package/dist/hooks/session/useCloseSession.d.ts.map +1 -1
- package/dist/hooks/session/useCloseSession.js +9 -8
- package/dist/hooks/session/useEndSession.d.ts +11 -0
- package/dist/hooks/session/useEndSession.d.ts.map +1 -0
- package/dist/hooks/session/useEndSession.js +45 -0
- package/dist/hooks/session/useGetSession.d.ts.map +1 -1
- package/dist/hooks/session/useGetSession.js +27 -6
- package/dist/hooks/session/usePendingSessionClose.d.ts +5 -0
- package/dist/hooks/session/usePendingSessionClose.d.ts.map +1 -0
- package/dist/hooks/session/usePendingSessionClose.js +12 -0
- package/dist/hooks/session/useSessionCustomerName.d.ts +3 -0
- package/dist/hooks/session/useSessionCustomerName.d.ts.map +1 -0
- package/dist/hooks/session/useSessionCustomerName.js +19 -0
- package/dist/hooks/session/useSessionFieldAutosave.d.ts +19 -0
- package/dist/hooks/session/useSessionFieldAutosave.d.ts.map +1 -0
- package/dist/hooks/session/useSessionFieldAutosave.js +52 -0
- package/dist/hooks/user/useUserUsername.d.ts +3 -0
- package/dist/hooks/user/useUserUsername.d.ts.map +1 -0
- package/dist/hooks/user/useUserUsername.js +49 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/locales/vi/common.json +201 -21
- package/dist/locales/vi/conversation-inbox.json +21 -2
- package/dist/screens/desk-message/DeskWorkspace.d.ts +12 -0
- package/dist/screens/desk-message/DeskWorkspace.d.ts.map +1 -0
- package/dist/screens/desk-message/DeskWorkspace.js +57 -0
- package/dist/screens/desk-message/FolderOverlay.d.ts +4 -0
- package/dist/screens/desk-message/FolderOverlay.d.ts.map +1 -0
- package/dist/screens/desk-message/FolderOverlay.js +32 -0
- package/dist/screens/desk-message/SkipLinks.d.ts +4 -0
- package/dist/screens/desk-message/SkipLinks.d.ts.map +1 -0
- package/dist/screens/desk-message/SkipLinks.js +19 -0
- package/dist/screens/desk-message/ViewportNotice.d.ts +4 -0
- package/dist/screens/desk-message/ViewportNotice.d.ts.map +1 -0
- package/dist/screens/desk-message/ViewportNotice.js +9 -0
- package/dist/screens/desk-message/index.d.ts +3 -2
- package/dist/screens/desk-message/index.d.ts.map +1 -1
- package/dist/screens/desk-message/index.js +4 -12
- package/dist/store/deskPanelHost.d.ts +13 -0
- package/dist/store/deskPanelHost.d.ts.map +1 -0
- package/dist/store/deskPanelHost.js +9 -0
- package/dist/store/escapeLayers.d.ts +15 -0
- package/dist/store/escapeLayers.d.ts.map +1 -0
- package/dist/store/escapeLayers.js +15 -0
- package/dist/store/pendingSessionClose.d.ts +19 -0
- package/dist/store/pendingSessionClose.d.ts.map +1 -0
- package/dist/store/pendingSessionClose.js +74 -0
- package/dist/store/session.d.ts +2 -1
- package/dist/store/session.d.ts.map +1 -1
- package/dist/store/session.js +4 -1
- package/dist/store/sessionFolder.d.ts +15 -0
- package/dist/store/sessionFolder.d.ts.map +1 -0
- package/dist/store/sessionFolder.js +18 -0
- package/dist/store/shortcutPrefs.d.ts +9 -0
- package/dist/store/shortcutPrefs.d.ts.map +1 -0
- package/dist/store/shortcutPrefs.js +23 -0
- package/dist/store/sidePanel.d.ts +12 -0
- package/dist/store/sidePanel.d.ts.map +1 -0
- package/dist/store/sidePanel.js +9 -0
- package/dist/store/workspaceLayout.d.ts +12 -0
- package/dist/store/workspaceLayout.d.ts.map +1 -0
- package/dist/store/workspaceLayout.js +9 -0
- package/dist/styles/global.css +1 -1
- package/dist/types/chat.d.ts +18 -0
- package/dist/types/chat.d.ts.map +1 -1
- package/dist/types/dto.d.ts +2 -1
- package/dist/types/dto.d.ts.map +1 -1
- package/dist/utils/a11yClickable.d.ts +10 -0
- package/dist/utils/a11yClickable.d.ts.map +1 -0
- package/dist/utils/a11yClickable.js +15 -0
- package/dist/utils/events.d.ts +4 -0
- package/dist/utils/events.d.ts.map +1 -1
- package/dist/utils/headerMemberCount.d.ts +10 -0
- package/dist/utils/headerMemberCount.d.ts.map +1 -0
- package/dist/utils/headerMemberCount.js +3 -0
- package/dist/utils/memberEventRun.d.ts +16 -0
- package/dist/utils/memberEventRun.d.ts.map +1 -0
- package/dist/utils/memberEventRun.js +40 -0
- package/package.json +1 -1
- package/dist/components/session/SessionFilterMenu.d.ts +0 -15
- package/dist/components/session/SessionFilterMenu.d.ts.map +0 -1
- package/dist/components/session/SessionFilterMenu.js +0 -30
- package/dist/components/session/sessionMenuItems.d.ts +0 -28
- package/dist/components/session/sessionMenuItems.d.ts.map +0 -1
- package/dist/components/session/sessionMenuItems.js +0 -119
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { jsx as _jsx,
|
|
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-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
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;
|
|
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 {
|
|
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 {
|
|
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-
|
|
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
|
|
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-
|
|
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-
|
|
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:
|
|
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(
|
|
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 @@
|
|
|
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
|
|
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":"
|
|
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 {
|
|
3
|
-
import {
|
|
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 {
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
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
|
|
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 (
|
|
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
|
-
|
|
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
|
|
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":"
|
|
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"}
|