@zenify-omni/chat-ui-react-js 0.1.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 (403) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +92 -0
  3. package/assets/asset-url.js +6 -0
  4. package/assets/icons/chatter_agent.js +27 -0
  5. package/assets/icons/chatter_chatbot.js +43 -0
  6. package/assets/icons/chatter_contact.js +36 -0
  7. package/assets/icons/email_icon.png +0 -0
  8. package/assets/icons/emoji/angry.svg +56 -0
  9. package/assets/icons/emoji/haha.svg +20 -0
  10. package/assets/icons/emoji/like.svg +10 -0
  11. package/assets/icons/emoji/like_out_line.png +0 -0
  12. package/assets/icons/emoji/love.svg +10 -0
  13. package/assets/icons/emoji/sad.svg +46 -0
  14. package/assets/icons/emoji/wow.svg +51 -0
  15. package/assets/icons/instagram.js +29 -0
  16. package/assets/icons/not_found.png +0 -0
  17. package/assets/icons/not_found_template.svg +9 -0
  18. package/assets/icons/phone_icon.png +0 -0
  19. package/assets/icons/shopee.js +17 -0
  20. package/assets/icons/sms_icon.png +0 -0
  21. package/assets/icons/tiktok.js +17 -0
  22. package/assets/icons/whatsapp.js +28 -0
  23. package/assets/icons/zalo.js +17 -0
  24. package/assets/icons/zalo_icon.png +0 -0
  25. package/assets/icons/zns_icon.png +0 -0
  26. package/assets/images/emoji.webp +0 -0
  27. package/assets/images/error.png +0 -0
  28. package/assets/images/menu.png +0 -0
  29. package/assets/images/money.png +0 -0
  30. package/assets/images/success.png +0 -0
  31. package/assets/public-urls.js +78 -0
  32. package/components/campaign-detail-route/select/group.js +38 -0
  33. package/components/campaign-detail-route/select/multi-groups.js +43 -0
  34. package/components/chat-route/chat-box/ads-context-card.js +143 -0
  35. package/components/chat-route/chat-box/chat-drop-file.js +18 -0
  36. package/components/chat-route/chat-box/chat-feedback/chat-insight.js +214 -0
  37. package/components/chat-route/chat-box/chat-feedback/index.js +127 -0
  38. package/components/chat-route/chat-box/chat-header-actions-inline.js +1055 -0
  39. package/components/chat-route/chat-box/chat-header.js +465 -0
  40. package/components/chat-route/chat-box/chat-input.js +1164 -0
  41. package/components/chat-route/chat-box/chat-message-action.js +399 -0
  42. package/components/chat-route/chat-box/chat-message-list.js +995 -0
  43. package/components/chat-route/chat-box/chat-message.js +2099 -0
  44. package/components/chat-route/chat-box/chat-reply-preview.js +317 -0
  45. package/components/chat-route/chat-box/common-groups-modal.js +430 -0
  46. package/components/chat-route/chat-box/constants.js +29 -0
  47. package/components/chat-route/chat-box/contact-card/index.js +87 -0
  48. package/components/chat-route/chat-box/edit-customer-alias-dialog.js +197 -0
  49. package/components/chat-route/chat-box/emoji-picker-combined.js +91 -0
  50. package/components/chat-route/chat-box/emoji-sprite.js +45 -0
  51. package/components/chat-route/chat-box/emojiMap.js +92 -0
  52. package/components/chat-route/chat-box/facebook-reconnect-notice.js +49 -0
  53. package/components/chat-route/chat-box/forward-message-modal.js +659 -0
  54. package/components/chat-route/chat-box/index.js +165 -0
  55. package/components/chat-route/chat-box/message-time.js +44 -0
  56. package/components/chat-route/chat-box/message-viewers.js +114 -0
  57. package/components/chat-route/chat-box/pasted-file-preview.js +138 -0
  58. package/components/chat-route/chat-box/pinned-messages.js +255 -0
  59. package/components/chat-route/chat-box/react-message/react-preview.js +83 -0
  60. package/components/chat-route/chat-box/react-message/reaction-button.js +200 -0
  61. package/components/chat-route/chat-box/right-side/chat-history.js +142 -0
  62. package/components/chat-route/chat-box/right-side/chat-tag-selector.js +232 -0
  63. package/components/chat-route/chat-box/right-side/create-personal-tag-modal.js +458 -0
  64. package/components/chat-route/chat-box/right-side/customer/customer-info-item.js +60 -0
  65. package/components/chat-route/chat-box/right-side/in-room-dialog.js +225 -0
  66. package/components/chat-route/chat-box/right-side/zalo-group/add-friend-dialog.js +154 -0
  67. package/components/chat-route/chat-box/right-side/zalo-group/send-message-dialog.js +165 -0
  68. package/components/chat-route/chat-box/send-contact-card-modal.js +102 -0
  69. package/components/chat-route/chat-box/send-contact-card.js +80 -0
  70. package/components/chat-route/chat-box/text-content.js +400 -0
  71. package/components/chat-route/chat-box/use-facebook-page-invalid.js +22 -0
  72. package/components/chat-route/chat-box/zalo-emoji-decoration.js +98 -0
  73. package/components/chat-route/chat-box/zalo-emoji-picker.js +74 -0
  74. package/components/chat-route/chat-box/zalo-personal-editor.js +590 -0
  75. package/components/chat-route/chat-box/zalo-reminder/create-zalo-reminder.js +868 -0
  76. package/components/chat-route/chat-box/zalo-reminder/use-send-zalo-reminder.js +98 -0
  77. package/components/chat-route/chat-box/zalo-reminder/zalo-reminder-content.js +294 -0
  78. package/components/chat-route/chat-box/zalo-rtf-utils.js +422 -0
  79. package/components/chat-route/chat-list/action-chat-item.js +116 -0
  80. package/components/chat-route/chat-list/assign-agent-dialog.js +170 -0
  81. package/components/chat-route/chat-list/assign-tag-dialog.js +242 -0
  82. package/components/chat-route/chat-list/chat-item-tags.js +105 -0
  83. package/components/chat-route/chat-list/chat-item.js +749 -0
  84. package/components/chat-route/chat-list/chat-list-item.js +370 -0
  85. package/components/chat-route/chat-list/chat-list-selection-bar.js +426 -0
  86. package/components/chat-route/chat-list/chat-search-preview.js +48 -0
  87. package/components/chat-route/chat-list/chat-sort-menu.js +89 -0
  88. package/components/chat-route/chat-list/edit-filter-modal.js +468 -0
  89. package/components/chat-route/chat-list/filter-chat-sources.js +222 -0
  90. package/components/chat-route/chat-list/filter-chat.js +501 -0
  91. package/components/chat-route/chat-list/filter-criteria-rows.js +845 -0
  92. package/components/chat-route/chat-list/filter-group-select.js +66 -0
  93. package/components/chat-route/chat-list/filter-pin-menu.js +165 -0
  94. package/components/chat-route/chat-list/friend-request/list-friend-request.js +287 -0
  95. package/components/chat-route/chat-list/index.js +243 -0
  96. package/components/chat-route/chat-list/inline-search-results.js +178 -0
  97. package/components/chat-route/chat-list/post-ids-field.js +104 -0
  98. package/components/chat-route/chat-list/quick-filter-bar.js +391 -0
  99. package/components/chat-route/chat-list/save-filter-popover.js +258 -0
  100. package/components/chat-route/chat-list/search-messages/index.js +225 -0
  101. package/components/chat-route/chat-list/search-result-header.js +51 -0
  102. package/components/chat-route/chat-list/util.js +604 -0
  103. package/components/chat-route/chat-toolbar.js +108 -0
  104. package/components/chat-route/hooks/use-reassign.js +111 -0
  105. package/components/chat-route/shared/close-conversation-dialog.js +111 -0
  106. package/components/chat-route/shared/force-transfer-dialog.js +109 -0
  107. package/components/chat-route/shared/in-queue-confirm-dialog.js +40 -0
  108. package/components/chat-route/util.js +146 -0
  109. package/components/chat-route/zalo/modal-action-zalo.js +76 -0
  110. package/components/chat-route/zalo/modal-add-friend-zalo.js +277 -0
  111. package/components/custom/SafeHTML.js +45 -0
  112. package/components/custom/audio-player.js +81 -0
  113. package/components/custom/avatar.js +95 -0
  114. package/components/custom/between-date-picker/index.js +86 -0
  115. package/components/custom/button-close.js +28 -0
  116. package/components/custom/button.js +80 -0
  117. package/components/custom/color-picker.js +81 -0
  118. package/components/custom/combobox.js +168 -0
  119. package/components/custom/custom-dialog.js +44 -0
  120. package/components/custom/custom-select.js +256 -0
  121. package/components/custom/cycle-value-helpers.js +11 -0
  122. package/components/custom/cycle-value.js +93 -0
  123. package/components/custom/date-time-picker/components/date-time-group.js +44 -0
  124. package/components/custom/date-time-picker/components/date-time-input.js +383 -0
  125. package/components/custom/date-time-picker/components/date-time-unit-input.js +138 -0
  126. package/components/custom/date-time-picker/components/month-year-picker.js +232 -0
  127. package/components/custom/date-time-picker/hooks/use-merge-refs.js +18 -0
  128. package/components/custom/date-time-picker/hooks/use-scroll-to-center.js +18 -0
  129. package/components/custom/date-time-picker/index.js +348 -0
  130. package/components/custom/field-file-upload/files-upload.js +87 -0
  131. package/components/custom/field-file-upload/image-upload.js +115 -0
  132. package/components/custom/field-file-upload/preview-images-modal.js +284 -0
  133. package/components/custom/field-file-upload/preview-list-file.js +134 -0
  134. package/components/custom/field-file-upload/preview-list-image.js +108 -0
  135. package/components/custom/field-file-upload/upload-custom.js +222 -0
  136. package/components/custom/field-generator.js +639 -0
  137. package/components/custom/field-layout-popover.js +304 -0
  138. package/components/custom/file-preview-modal.js +351 -0
  139. package/components/custom/html-edtior.js +100 -0
  140. package/components/custom/icon.js +49 -0
  141. package/components/custom/infinite-scroll-combobox.js +253 -0
  142. package/components/custom/inline-edit-popover.js +90 -0
  143. package/components/custom/inputs/calendar-input.js +0 -0
  144. package/components/custom/inputs/chip-input.js +136 -0
  145. package/components/custom/inputs/file-input.js +71 -0
  146. package/components/custom/inputs/mask-data/mask-data-input.js +80 -0
  147. package/components/custom/inputs/mask-data/mask-data-select.js +78 -0
  148. package/components/custom/inputs/mask-data/mask-data-textarea.js +75 -0
  149. package/components/custom/inputs/mask-data/reconcile-masked-edit.js +20 -0
  150. package/components/custom/jxl-decode.js +34 -0
  151. package/components/custom/jxl-image.js +68 -0
  152. package/components/custom/jxl-worker.js +12 -0
  153. package/components/custom/label.js +55 -0
  154. package/components/custom/layout.js +30 -0
  155. package/components/custom/multi-select-search-cc.js +179 -0
  156. package/components/custom/multiple-select-setting-tags.js +404 -0
  157. package/components/custom/multiple-selector.js +821 -0
  158. package/components/custom/pagination.js +95 -0
  159. package/components/custom/popup-confirm.js +120 -0
  160. package/components/custom/previews/facebook/facebook-appointment-booking-preview.js +83 -0
  161. package/components/custom/previews/facebook/facebook-audio-preview.js +130 -0
  162. package/components/custom/previews/facebook/facebook-event-preview.js +72 -0
  163. package/components/custom/previews/facebook/facebook-file-preview.js +95 -0
  164. package/components/custom/previews/facebook/facebook-group-preview.js +103 -0
  165. package/components/custom/previews/facebook/facebook-image-preview.js +81 -0
  166. package/components/custom/previews/facebook/facebook-page-preview.js +85 -0
  167. package/components/custom/previews/facebook/facebook-post-preview.js +77 -0
  168. package/components/custom/previews/facebook/facebook-reel-preview.js +83 -0
  169. package/components/custom/previews/facebook/facebook-sticker-preview.js +23 -0
  170. package/components/custom/previews/facebook/facebook-video-preview.js +114 -0
  171. package/components/custom/previews/facebook/index.js +24 -0
  172. package/components/custom/previews/file-preview.js +747 -0
  173. package/components/custom/previews/image-preview.js +288 -0
  174. package/components/custom/previews/instagram/index.js +4 -0
  175. package/components/custom/previews/instagram/instagram-share-post-preview.js +77 -0
  176. package/components/custom/previews/link-preview.js +166 -0
  177. package/components/custom/previews/product-preview.js +334 -0
  178. package/components/custom/previews/tiktok-order-preview.js +278 -0
  179. package/components/custom/previews/tiktok-product-preview.js +321 -0
  180. package/components/custom/previews/tiktok-voucher-preview.js +151 -0
  181. package/components/custom/previews/whatsapp/index.js +10 -0
  182. package/components/custom/previews/whatsapp/whatsapp-contact-card-preview.js +150 -0
  183. package/components/custom/previews/whatsapp/whatsapp-order-preview.js +38 -0
  184. package/components/custom/previews/whatsapp/whatsapp-poll-preview.js +29 -0
  185. package/components/custom/previews/whatsapp/whatsapp-product-preview.js +29 -0
  186. package/components/custom/retry-image.js +44 -0
  187. package/components/custom/search-input.js +26 -0
  188. package/components/custom/separator-with-text.js +14 -0
  189. package/components/custom/showToast.js +21 -0
  190. package/components/custom/sortable-header.js +62 -0
  191. package/components/custom/table-resize-line.js +92 -0
  192. package/components/custom/time-picker/index.js +73 -0
  193. package/components/custom/time-picker/time-picker-input.js +159 -0
  194. package/components/custom/time-picker/time-picker-utils.js +152 -0
  195. package/components/custom/viewers/audio-player.js +192 -0
  196. package/components/custom/viewers/code-viewer.js +140 -0
  197. package/components/custom/viewers/csv-viewer.js +174 -0
  198. package/components/custom/viewers/docx-viewer.js +145 -0
  199. package/components/custom/viewers/image-viewer.js +104 -0
  200. package/components/custom/viewers/markdown-viewer.js +124 -0
  201. package/components/custom/viewers/pdf-viewer.js +333 -0
  202. package/components/custom/viewers/spreadsheet-viewer.js +232 -0
  203. package/components/custom/viewers/unsupported-viewer.js +85 -0
  204. package/components/custom/viewers/video-player.js +241 -0
  205. package/components/customers-route/change-owner-modal.js +430 -0
  206. package/components/customers-route/contact-note-button.js +212 -0
  207. package/components/customers-route/customer-source.js +37 -0
  208. package/components/customers-route/table/columns.js +675 -0
  209. package/components/customers-route/table/edit-fields.js +125 -0
  210. package/components/customers-route/table/editable-cell.js +218 -0
  211. package/components/customers-route/table/note-cell.js +77 -0
  212. package/components/dialogs/invite-agent.js +677 -0
  213. package/components/error-boundary.js +53 -0
  214. package/components/leads-route/duplicate-phone-warning-toast.js +96 -0
  215. package/components/leads-route/table/columns.js +523 -0
  216. package/components/leads-route/table/contact-cell-name.js +82 -0
  217. package/components/leads-route/table/edit-fields.js +142 -0
  218. package/components/leads-route/table/editable-cell.js +228 -0
  219. package/components/org-tree/group-name-display.js +36 -0
  220. package/components/org-tree/group-tree-multi-select.js +208 -0
  221. package/components/org-tree/group-tree-select.js +220 -0
  222. package/components/posts-route/dialog-select-posts.js +284 -0
  223. package/components/reports-route/agents/multi-select-agents.js +55 -0
  224. package/components/reports-route/agents/multi-select-search-agents.js +43 -0
  225. package/components/settings-route/chat-layout/detail/constants.js +353 -0
  226. package/components/settings-route/chat-layout/detail/form.js +43 -0
  227. package/components/settings-route/chat-timeout/channel-multi-select.js +119 -0
  228. package/components/settings-route/multi-channel/facebook/hooks/use-facebook-sdk.js +3 -0
  229. package/components/settings-route/object-rule/util.js +79 -0
  230. package/components/settings-route/routing/settings-dialog.js +561 -0
  231. package/components/settings-route/switchboard/queue-new/constant.js +9 -0
  232. package/components/shared/linked-customer-fields/LinkedCustomerFields.js +91 -0
  233. package/components/shared/linked-customer-fields/use-linked-customer-fields.js +123 -0
  234. package/components/smartqc-route/qc-form/controls/multi-select-search-agents.js +50 -0
  235. package/components/ui/alert-dialog.js +112 -0
  236. package/components/ui/avatar.js +44 -0
  237. package/components/ui/badge.js +54 -0
  238. package/components/ui/button.js +48 -0
  239. package/components/ui/calendar.js +70 -0
  240. package/components/ui/card.js +58 -0
  241. package/components/ui/carousel.js +238 -0
  242. package/components/ui/checkbox.js +27 -0
  243. package/components/ui/command.js +111 -0
  244. package/components/ui/context-menu.js +154 -0
  245. package/components/ui/dialog.js +104 -0
  246. package/components/ui/dropdown-menu.js +169 -0
  247. package/components/ui/form.js +104 -0
  248. package/components/ui/input.js +115 -0
  249. package/components/ui/label.js +20 -0
  250. package/components/ui/popover.js +29 -0
  251. package/components/ui/radio-group.js +53 -0
  252. package/components/ui/scroll-area.js +38 -0
  253. package/components/ui/select.js +147 -0
  254. package/components/ui/separator.js +24 -0
  255. package/components/ui/sheet.js +113 -0
  256. package/components/ui/skeleton.js +17 -0
  257. package/components/ui/slider.js +26 -0
  258. package/components/ui/sonner.js +76 -0
  259. package/components/ui/switch.js +54 -0
  260. package/components/ui/table-v2.js +269 -0
  261. package/components/ui/table.js +245 -0
  262. package/components/ui/tabs.js +89 -0
  263. package/components/ui/textarea.js +33 -0
  264. package/components/ui/tooltip.js +40 -0
  265. package/components/workflow-editor/nodes/ticket/picker-field.js +233 -0
  266. package/components/zalo-login-qr.js +237 -0
  267. package/components/zalo-login-status-modal.js +45 -0
  268. package/config/env.js +27 -0
  269. package/config/hmr.js +8 -0
  270. package/config/navigation.js +54 -0
  271. package/config/runtime.js +46 -0
  272. package/config/theme.js +274 -0
  273. package/constants/brand-colors.js +32 -0
  274. package/constants/chat-icon.js +34 -0
  275. package/dist/chat.css +1 -0
  276. package/exceptions/throw-exception.js +15 -0
  277. package/hooks/use-chat-attachments.js +106 -0
  278. package/hooks/use-chat-configs.js +62 -0
  279. package/hooks/use-chat-customer.js +33 -0
  280. package/hooks/use-chat-display-config-sync.js +72 -0
  281. package/hooks/use-chat-permission.js +68 -0
  282. package/hooks/use-chat-room-detail.js +44 -0
  283. package/hooks/use-chat-selection.js +26 -0
  284. package/hooks/use-chat-sort.js +69 -0
  285. package/hooks/use-chat-surface.js +8 -0
  286. package/hooks/use-common-filter-options.js +70 -0
  287. package/hooks/use-crm-organization-filter-options.js +0 -0
  288. package/hooks/use-crm-organizations-data.js +23 -0
  289. package/hooks/use-debounce.js +14 -0
  290. package/hooks/use-dynamic-fields.js +7 -0
  291. package/hooks/use-facebook-notice.js +24 -0
  292. package/hooks/use-feature-flags.js +6 -0
  293. package/hooks/use-field-layout-override.js +46 -0
  294. package/hooks/use-file-upload.js +119 -0
  295. package/hooks/use-file-viewer.js +93 -0
  296. package/hooks/use-frozen-columns.js +29 -0
  297. package/hooks/use-horizontal-scroll.js +41 -0
  298. package/hooks/use-image-preview-queue.js +101 -0
  299. package/hooks/use-inline-editable-cell.js +97 -0
  300. package/hooks/use-intersection-observer.js +24 -0
  301. package/hooks/use-interval.js +20 -0
  302. package/hooks/use-latest-message-id.js +13 -0
  303. package/hooks/use-lead-filter-options.js +0 -0
  304. package/hooks/use-logout-listener.js +43 -0
  305. package/hooks/use-org-tree.js +43 -0
  306. package/hooks/use-permission.js +33 -0
  307. package/hooks/use-quick-filters.js +175 -0
  308. package/hooks/use-resizable-table.js +0 -0
  309. package/hooks/use-setting-common.js +389 -0
  310. package/hooks/use-settings.js +41 -0
  311. package/hooks/use-sort-bindings.js +24 -0
  312. package/hooks/use-table-display-config.js +0 -0
  313. package/hooks/use-tenant-config.js +99 -0
  314. package/hooks/use-update-user-config.js +150 -0
  315. package/hooks/use-zalo-connection.js +57 -0
  316. package/hooks/use-zalo-mention-list.js +31 -0
  317. package/index.css +624 -0
  318. package/index.js +100 -0
  319. package/lib/deal-name.js +27 -0
  320. package/lib/i18n/react.js +7 -0
  321. package/lib/i18n/use-language.js +0 -0
  322. package/lib/query-client.js +34 -0
  323. package/lib/utils.js +25 -0
  324. package/package.json +108 -0
  325. package/provider/chat-context.js +9 -0
  326. package/provider/chat-provider.js +177 -0
  327. package/provider/chat-room-context.js +9 -0
  328. package/provider/chat-room-hooks.js +8 -0
  329. package/provider/chat-room-provider.js +84 -0
  330. package/provider/hooks.js +22 -0
  331. package/provider/index.js +42 -0
  332. package/public/contact-card-user.svg +25 -0
  333. package/public/images/icons/facebook.svg +1 -0
  334. package/public/images/icons/instagram.svg +1 -0
  335. package/public/images/icons/shopee.svg +1 -0
  336. package/public/images/icons/whatsapp.svg +1 -0
  337. package/public/images/icons/zalo.png +0 -0
  338. package/public/images/images.jpg +0 -0
  339. package/public/images/ticket_sources/api.png +0 -0
  340. package/public/images/ticket_sources/email.png +0 -0
  341. package/public/images/ticket_sources/facebook.png +0 -0
  342. package/public/images/ticket_sources/hand.png +0 -0
  343. package/public/images/ticket_sources/instagram.png +0 -0
  344. package/public/images/ticket_sources/livechat.png +0 -0
  345. package/public/images/ticket_sources/shopee.svg +1 -0
  346. package/public/images/ticket_sources/sms.png +0 -0
  347. package/public/images/ticket_sources/telephone-call-in.png +0 -0
  348. package/public/images/ticket_sources/telephone-call-out.png +0 -0
  349. package/public/images/ticket_sources/tiktok.png +0 -0
  350. package/public/images/ticket_sources/tiktok_shop.png +0 -0
  351. package/public/images/ticket_sources/whatsapp.png +0 -0
  352. package/public/images/ticket_sources/whatsapp.svg +1 -0
  353. package/public/images/ticket_sources/zalo.png +0 -0
  354. package/public/placeholder.svg +13 -0
  355. package/store/app-status-store.js +17 -0
  356. package/store/chat-display-config-store.js +182 -0
  357. package/store/chat-display-config.resolvers.js +88 -0
  358. package/store/chat-store-helpers.js +62 -0
  359. package/store/chat-store.js +931 -0
  360. package/store/crm-organization-list-filter-store.js +126 -0
  361. package/store/customer-list-filter-store.js +139 -0
  362. package/store/devtools.js +9 -0
  363. package/store/duplicate-phone-warning-store.js +18 -0
  364. package/store/entity-extract-store.js +72 -0
  365. package/store/file-preview-store.js +27 -0
  366. package/store/filter-store.js +289 -0
  367. package/store/index.js +22 -0
  368. package/store/knowledge-crawl-store.js +53 -0
  369. package/store/lead-list-filter-store.js +142 -0
  370. package/store/list-pagination-state.js +44 -0
  371. package/store/lumi-learn-from-chat-store.js +69 -0
  372. package/store/merge-suggestion-store.js +27 -0
  373. package/store/notification-store.js +63 -0
  374. package/store/preview-image-store.js +22 -0
  375. package/store/settings-store/multi-channel/email-list-store.js +20 -0
  376. package/store/settings-store/multi-channel/facebook-list-store.js +22 -0
  377. package/store/settings-store/multi-channel/google-list-store.js +20 -0
  378. package/store/settings-store/multi-channel/instagram-list-store.js +20 -0
  379. package/store/settings-store/multi-channel/misa-list-store.js +20 -0
  380. package/store/settings-store/multi-channel/nhanhvn-list-store.js +20 -0
  381. package/store/settings-store/multi-channel/shopee-list-store.js +20 -0
  382. package/store/settings-store/multi-channel/shopee-order-list-store.js +20 -0
  383. package/store/settings-store/multi-channel/sms-list-store.js +20 -0
  384. package/store/settings-store/multi-channel/tiktok-business-list-store.js +20 -0
  385. package/store/settings-store/multi-channel/tiktok-list-store.js +20 -0
  386. package/store/settings-store/multi-channel/zalo-list-store.js +22 -0
  387. package/store/settings-store/multi-channel/zalo-user-list-store.js +25 -0
  388. package/store/smart-qc-store/smart-qc-list-filter-store.js +70 -0
  389. package/store/tenant-config-store.js +21 -0
  390. package/store/user-detail-store.js +17 -0
  391. package/store/user-status-store.js +33 -0
  392. package/store/workflow-store.js +24 -0
  393. package/store/workspace-store.js +32 -0
  394. package/tailwind-preset.js +129 -0
  395. package/utils/chat-actions.js +414 -0
  396. package/utils/chat_socket.js +1225 -0
  397. package/utils/extra-columns.js +108 -0
  398. package/utils/file.js +316 -0
  399. package/utils/html-to-plain-text.js +12 -0
  400. package/utils/notification.js +71 -0
  401. package/utils/replaceZaloSprite.js +64 -0
  402. package/utils/show-be-error.js +17 -0
  403. package/utils/typing_socket.js +101 -0
@@ -0,0 +1,100 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import i18n from "@zenify-omni/chat-js/lib/i18n/index.js";
3
+ import { Editor } from "@tinymce/tinymce-react";
4
+ import { uploadFileToCloudflare } from "../../utils/file.js";
5
+ import { cn } from "../../lib/utils.js";
6
+ import React, { useEffect } from "react";
7
+ const HtmlEditor = React.forwardRef(
8
+ ({
9
+ value,
10
+ onValueChange,
11
+ initOptions = {},
12
+ className,
13
+ maxHeight,
14
+ toggleEditerOption = true,
15
+ minHeight = 200,
16
+ disabled = false
17
+ }, ref) => {
18
+ const handleImageUpload = async (blobInfo) => {
19
+ try {
20
+ const file = blobInfo.blob();
21
+ const fileType = file.type;
22
+ return await uploadFileToCloudflare(file, { content_type: fileType });
23
+ } catch (error) {
24
+ console.error("Image upload failed:", error);
25
+ throw error;
26
+ }
27
+ };
28
+ useEffect(() => {
29
+ if (ref?.current) {
30
+ const headerEl = ref.current.getContainer()?.querySelector(".tox-editor-header");
31
+ if (headerEl) {
32
+ if (toggleEditerOption) {
33
+ headerEl.style.display = "";
34
+ } else {
35
+ headerEl.style.display = "none";
36
+ }
37
+ }
38
+ }
39
+ }, [toggleEditerOption, ref]);
40
+ const toolbars = "undo redo | fontfamily fontsize | forecolor backcolor | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | removeformat | link image media | table | preview fullscreen | lineheight";
41
+ return /* @__PURE__ */ jsx("div", { className: cn(className), children: /* @__PURE__ */ jsx(
42
+ Editor,
43
+ {
44
+ onInit: (_, editor) => {
45
+ if (ref) {
46
+ ref.current = editor;
47
+ }
48
+ const headerEl = editor.getContainer()?.querySelector(".tox-editor-header");
49
+ if (headerEl) {
50
+ headerEl.style.display = toggleEditerOption ? "" : "none";
51
+ }
52
+ },
53
+ tinymceScriptSrc: `${window.location.origin}/tinymce/tinymce.min.js`,
54
+ licenseKey: "gpl",
55
+ value,
56
+ disabled,
57
+ onEditorChange: onValueChange,
58
+ init: {
59
+ line_height_formats: "0.5 0.8 1 1.2 1.5",
60
+ get placeholder() {
61
+ return i18n.t("common:placeholder.enterContent", {
62
+ defaultValue: "Nh\u1EADp n\u1ED9i dung"
63
+ });
64
+ },
65
+ content_style: 'body { font-size: 14px; } img {max-width: 100%; width: auto; height: auto;} .mce-content-body[data-mce-placeholder]:focus:not(.mce-visualblocks)::before { content: "" !important; }',
66
+ min_height: minHeight,
67
+ ...maxHeight ? { max_height: maxHeight } : {},
68
+ language: "vi",
69
+ menubar: false,
70
+ branding: false,
71
+ statusbar: false,
72
+ plugins: [
73
+ "advlist",
74
+ "autolink",
75
+ "autoresize",
76
+ "lists",
77
+ "link",
78
+ "image",
79
+ "preview",
80
+ "anchor",
81
+ "fullscreen",
82
+ "media",
83
+ "table"
84
+ ],
85
+ toolbar: toolbars,
86
+ font_size_formats: "10px 12px 14px 16px 18px 20px 24px 28px 32px 36px 48px 60px 72px 96px",
87
+ images_upload_handler: handleImageUpload,
88
+ automatic_uploads: true,
89
+ file_picker_types: "image",
90
+ ...initOptions
91
+ }
92
+ },
93
+ minHeight
94
+ ) });
95
+ }
96
+ );
97
+ HtmlEditor.displayName = "HtmlEditor";
98
+ export {
99
+ HtmlEditor
100
+ };
@@ -0,0 +1,49 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import Zalo__asset from "../../assets/icons/zalo_icon.png";
3
+ import Email__asset from "../../assets/icons/email_icon.png";
4
+ import Phone__asset from "../../assets/icons/phone_icon.png";
5
+ import SMS__asset from "../../assets/icons/sms_icon.png";
6
+ import ZNS__asset from "../../assets/icons/zns_icon.png";
7
+ import NOTFOUND__asset from "../../assets/icons/not_found.png";
8
+ import EMOJI_LIKE__asset from "../../assets/icons/emoji/like.svg";
9
+ import EMOJI_HAHA__asset from "../../assets/icons/emoji/haha.svg";
10
+ import EMOJI_SAD__asset from "../../assets/icons/emoji/sad.svg";
11
+ import EMOJI_WOW__asset from "../../assets/icons/emoji/wow.svg";
12
+ import EMOJI_LOVE__asset from "../../assets/icons/emoji/love.svg";
13
+ import EMOJI_ANGRY__asset from "../../assets/icons/emoji/angry.svg";
14
+ import EMOJI_LIKE_OUTLINE__asset from "../../assets/icons/emoji/like_out_line.png";
15
+ import { assetUrl } from "../../assets/asset-url.js";
16
+ const Zalo = assetUrl(Zalo__asset);
17
+ const Email = assetUrl(Email__asset);
18
+ const Phone = assetUrl(Phone__asset);
19
+ const SMS = assetUrl(SMS__asset);
20
+ const ZNS = assetUrl(ZNS__asset);
21
+ const NOTFOUND = assetUrl(NOTFOUND__asset);
22
+ const EMOJI_LIKE = assetUrl(EMOJI_LIKE__asset);
23
+ const EMOJI_HAHA = assetUrl(EMOJI_HAHA__asset);
24
+ const EMOJI_SAD = assetUrl(EMOJI_SAD__asset);
25
+ const EMOJI_WOW = assetUrl(EMOJI_WOW__asset);
26
+ const EMOJI_LOVE = assetUrl(EMOJI_LOVE__asset);
27
+ const EMOJI_ANGRY = assetUrl(EMOJI_ANGRY__asset);
28
+ const EMOJI_LIKE_OUTLINE = assetUrl(EMOJI_LIKE_OUTLINE__asset);
29
+ const names = {
30
+ zalo: Zalo,
31
+ email: Email,
32
+ phone: Phone,
33
+ sms: SMS,
34
+ zns: ZNS,
35
+ notFound: NOTFOUND,
36
+ emoji_like: EMOJI_LIKE,
37
+ emoji_haha: EMOJI_HAHA,
38
+ emoji_sad: EMOJI_SAD,
39
+ emoji_wow: EMOJI_WOW,
40
+ emoji_love: EMOJI_LOVE,
41
+ emoji_angry: EMOJI_ANGRY,
42
+ emoji_like_outline: EMOJI_LIKE_OUTLINE
43
+ };
44
+ const Icon = ({ name, className }) => /* @__PURE__ */ jsx("img", { src: names[name], className });
45
+ Icon.displayName = "Icon";
46
+ var icon_default = Icon;
47
+ export {
48
+ icon_default as default
49
+ };
@@ -0,0 +1,253 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState, useRef } from "react";
3
+ import { useInfiniteQuery, useQueryClient } from "@tanstack/react-query";
4
+ import {
5
+ CaretSortIcon,
6
+ CheckIcon,
7
+ MagnifyingGlassIcon
8
+ } from "@radix-ui/react-icons";
9
+ import { LoaderCircle } from "lucide-react";
10
+ import { cn } from "../../lib/utils.js";
11
+ import {
12
+ Command,
13
+ CommandEmpty,
14
+ CommandGroup,
15
+ CommandItem,
16
+ CommandList
17
+ } from "../ui/command.js";
18
+ import {
19
+ Popover,
20
+ PopoverContent,
21
+ PopoverTrigger
22
+ } from "../ui/popover.js";
23
+ import { Button } from "./button.js";
24
+ import useDebounce from "../../hooks/use-debounce.js";
25
+ import { cva } from "class-variance-authority";
26
+ import { maskData } from "@zenify-omni/chat-js/utils/data.js";
27
+ import { useTranslation } from "react-i18next";
28
+ const InfiniteScrollComboboxVariants = cva("", {
29
+ variants: {
30
+ size: {
31
+ default: "!text-sm",
32
+ small: "!text-xs",
33
+ large: "!text-base"
34
+ }
35
+ },
36
+ defaultVariants: {
37
+ size: "default"
38
+ }
39
+ });
40
+ function InfiniteScrollCombobox({
41
+ className,
42
+ value,
43
+ onChange,
44
+ onSearch,
45
+ placeholder = "",
46
+ disabled = false,
47
+ buildOption = (option) => option,
48
+ searchDelay = 500,
49
+ queryKey,
50
+ size,
51
+ isOutlineError = false,
52
+ defaultOptions = [],
53
+ multiple = false,
54
+ // Khi bật, áp maskData lên label HIỂN THỊ (trigger + item) để che dữ liệu nhạy
55
+ // cảm (vd sđt nằm trong tên KH). Giá trị thật của option giữ nguyên.
56
+ maskLabel = false
57
+ }) {
58
+ const { t } = useTranslation();
59
+ const [open, setOpen] = useState(false);
60
+ const displayLabel = (label) => maskLabel ? maskData(String(label ?? "")) || "" : label;
61
+ const [searchText, setSearchText] = useState("");
62
+ const debounceSearchText = useDebounce(searchText, searchDelay);
63
+ const observerRef = useRef(null);
64
+ const queryClient = useQueryClient();
65
+ const {
66
+ data: queryData,
67
+ isLoading,
68
+ isFetchingNextPage,
69
+ hasNextPage,
70
+ fetchNextPage
71
+ } = useInfiniteQuery({
72
+ queryKey: [queryKey, { keyword: debounceSearchText }],
73
+ queryFn: async ({ pageParam = 1 }) => {
74
+ const limit = 10;
75
+ const offset = (pageParam - 1) * limit;
76
+ const data = await onSearch(debounceSearchText, { limit, offset });
77
+ return {
78
+ data,
79
+ page: pageParam,
80
+ hasMore: data.length === limit
81
+ };
82
+ },
83
+ initialPageParam: 1,
84
+ getNextPageParam: (lastPage) => {
85
+ return lastPage.hasMore ? lastPage.page + 1 : void 0;
86
+ },
87
+ enabled: open
88
+ // Only fetch when dropdown is open
89
+ });
90
+ const searchResults = queryData?.pages.flatMap((page) => page.data.map(buildOption)) ?? [];
91
+ const allOptions = [...defaultOptions, ...searchResults];
92
+ const lastItemRef = (node) => {
93
+ if (isFetchingNextPage) return;
94
+ if (observerRef.current) observerRef.current.disconnect();
95
+ observerRef.current = new IntersectionObserver((entries) => {
96
+ if (entries[0].isIntersecting && hasNextPage) {
97
+ fetchNextPage();
98
+ }
99
+ });
100
+ if (node) observerRef.current.observe(node);
101
+ };
102
+ useEffect(() => {
103
+ const isEmpty = multiple ? !value || !Array.isArray(value) || value.length === 0 : !value;
104
+ if (isEmpty) {
105
+ setSearchText("");
106
+ }
107
+ }, [value, multiple]);
108
+ useEffect(() => {
109
+ const trimToFirstPage = () => {
110
+ queryClient.setQueryData(
111
+ [queryKey, { keyword: debounceSearchText }],
112
+ (oldData) => {
113
+ if (!oldData?.pages?.length) return void 0;
114
+ return {
115
+ pageParams: [1],
116
+ pages: [oldData.pages[0]]
117
+ };
118
+ }
119
+ );
120
+ };
121
+ if (!open) {
122
+ trimToFirstPage();
123
+ }
124
+ return () => {
125
+ trimToFirstPage();
126
+ };
127
+ }, [open, queryClient, queryKey, debounceSearchText]);
128
+ return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, modal: true, children: [
129
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
130
+ Button,
131
+ {
132
+ variant: "outline",
133
+ className: cn(
134
+ "flex w-full justify-between font-normal",
135
+ (multiple ? !Array.isArray(value) || value.length === 0 : !value) && "text-muted-foreground",
136
+ disabled && "cursor-not-allowed bg-muted",
137
+ className,
138
+ InfiniteScrollComboboxVariants({ size }),
139
+ isOutlineError && "border border-[--label-red-foreground] focus-visible:border-[--label-red-foreground] focus-visible:ring-0"
140
+ ),
141
+ onClick: (e) => {
142
+ if (!disabled) return;
143
+ e.preventDefault();
144
+ },
145
+ children: [
146
+ /* @__PURE__ */ jsx(
147
+ "div",
148
+ {
149
+ className: "max-w-[calc(100%-1.5rem)] truncate",
150
+ title: multiple ? Array.isArray(value) ? value.map((v) => displayLabel(v.label)).join(", ") : "" : displayLabel(value?.label),
151
+ children: multiple ? Array.isArray(value) && value.length > 0 ? value.map((v) => displayLabel(v.label)).join(", ") : placeholder : value && value.label ? displayLabel(value.label) : placeholder
152
+ }
153
+ ),
154
+ /* @__PURE__ */ jsx(CaretSortIcon, { className: "ml-2 h-4 w-4 shrink-0" })
155
+ ]
156
+ }
157
+ ) }),
158
+ /* @__PURE__ */ jsx(PopoverContent, { className: "max-h-[--radix-popover-content-available-height] w-[--radix-popover-trigger-width] overflow-auto p-0", children: /* @__PURE__ */ jsxs(Command, { children: [
159
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center border-b px-3", children: [
160
+ isLoading ? /* @__PURE__ */ jsx(LoaderCircle, { className: "mr-2 h-4 w-4 shrink-0 animate-spin" }) : /* @__PURE__ */ jsx(MagnifyingGlassIcon, { className: "mr-2 h-4 w-4 shrink-0 opacity-50" }),
161
+ /* @__PURE__ */ jsx(
162
+ "input",
163
+ {
164
+ className: cn(
165
+ "flex h-9 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
166
+ InfiniteScrollComboboxVariants({ size })
167
+ ),
168
+ placeholder: t("common:placeholder.typeToSearch", {
169
+ defaultValue: "Nh\u1EADp \u0111\u1EC3 t\xECm ki\u1EBFm"
170
+ }),
171
+ value: searchText,
172
+ onChange: (e) => {
173
+ setSearchText(e.target.value);
174
+ }
175
+ }
176
+ )
177
+ ] }),
178
+ /* @__PURE__ */ jsxs(CommandList, { children: [
179
+ !isLoading && allOptions.length === 0 && /* @__PURE__ */ jsx(
180
+ CommandEmpty,
181
+ {
182
+ className: cn(
183
+ "mt-2 text-center text-muted-foreground",
184
+ InfiniteScrollComboboxVariants({ size })
185
+ ),
186
+ children: t("common:empty.noData", { defaultValue: "Kh\xF4ng c\xF3 d\u1EEF li\u1EC7u" })
187
+ }
188
+ ),
189
+ /* @__PURE__ */ jsxs(CommandGroup, { children: [
190
+ allOptions.map((option, index) => {
191
+ const isLastItem = index === allOptions.length - 1;
192
+ return /* @__PURE__ */ jsxs(
193
+ CommandItem,
194
+ {
195
+ className: cn(
196
+ "cursor-pointer",
197
+ InfiniteScrollComboboxVariants({ size })
198
+ ),
199
+ value: option.value,
200
+ onSelect: () => {
201
+ if (multiple) {
202
+ const current = Array.isArray(value) ? value : [];
203
+ const alreadySelected = current.some(
204
+ (v) => v.value === option.value
205
+ );
206
+ onChange(
207
+ alreadySelected ? current.filter((v) => v.value !== option.value) : [...current, option]
208
+ );
209
+ } else {
210
+ onChange(option.value === value?.value ? null : option);
211
+ setOpen(false);
212
+ }
213
+ },
214
+ ref: isLastItem ? lastItemRef : null,
215
+ title: displayLabel(option.label),
216
+ children: [
217
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: displayLabel(option.label) }),
218
+ /* @__PURE__ */ jsx(
219
+ CheckIcon,
220
+ {
221
+ className: cn(
222
+ "ml-auto h-4 w-4 shrink-0",
223
+ (multiple ? Array.isArray(value) && value.some((v) => v.value === option.value) : value?.value === option.value) ? "opacity-100" : "opacity-0"
224
+ )
225
+ }
226
+ )
227
+ ]
228
+ },
229
+ option.value
230
+ );
231
+ }),
232
+ isFetchingNextPage && /* @__PURE__ */ jsxs(CommandItem, { disabled: true, children: [
233
+ /* @__PURE__ */ jsx(
234
+ LoaderCircle,
235
+ {
236
+ className: cn(
237
+ "mr-2 h-4 w-4 animate-spin",
238
+ InfiniteScrollComboboxVariants({ size })
239
+ )
240
+ }
241
+ ),
242
+ t("common:status.loadingMore", {
243
+ defaultValue: "\u0110ang t\u1EA3i th\xEAm..."
244
+ })
245
+ ] })
246
+ ] })
247
+ ] })
248
+ ] }) })
249
+ ] });
250
+ }
251
+ export {
252
+ InfiniteScrollCombobox as default
253
+ };
@@ -0,0 +1,90 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Check, LoaderCircle, X } from "lucide-react";
3
+ import { useTranslation } from "react-i18next";
4
+ import {
5
+ Popover,
6
+ PopoverContent,
7
+ PopoverTrigger
8
+ } from "../ui/popover.js";
9
+ import { Button } from "./button.js";
10
+ import { cn } from "../../lib/utils.js";
11
+ const PORTAL_SELECTOR = "[data-radix-popper-content-wrapper], [cmdk-list], [data-inline-portal]";
12
+ function InlineEditPopover({
13
+ open,
14
+ trigger,
15
+ children,
16
+ onSave,
17
+ onCancel,
18
+ isSaving = false,
19
+ align = "start",
20
+ className
21
+ }) {
22
+ const { t } = useTranslation();
23
+ return /* @__PURE__ */ jsxs(
24
+ Popover,
25
+ {
26
+ open,
27
+ onOpenChange: (nextOpen) => {
28
+ if (!nextOpen) onCancel();
29
+ },
30
+ children: [
31
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: trigger }),
32
+ /* @__PURE__ */ jsxs(
33
+ PopoverContent,
34
+ {
35
+ align,
36
+ className: cn("flex w-auto flex-col gap-2 p-2", className),
37
+ onClick: (event) => event.stopPropagation(),
38
+ onInteractOutside: (event) => {
39
+ const target = event.target;
40
+ if (target instanceof Element && target.closest(PORTAL_SELECTOR)) {
41
+ event.preventDefault();
42
+ }
43
+ },
44
+ children: [
45
+ /* @__PURE__ */ jsx("div", { className: "min-w-[220px]", children }),
46
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-1", children: [
47
+ isSaving && /* @__PURE__ */ jsx(
48
+ LoaderCircle,
49
+ {
50
+ "aria-label": t("common:status.saving"),
51
+ className: "h-3.5 w-3.5 shrink-0 animate-spin"
52
+ }
53
+ ),
54
+ /* @__PURE__ */ jsx(
55
+ Button,
56
+ {
57
+ type: "button",
58
+ size: "icon",
59
+ variant: "ghost",
60
+ "aria-label": t("common:action.cancelEdit"),
61
+ className: "h-6 w-6 shrink-0",
62
+ disabled: isSaving,
63
+ onClick: onCancel,
64
+ children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" })
65
+ }
66
+ ),
67
+ /* @__PURE__ */ jsx(
68
+ Button,
69
+ {
70
+ type: "button",
71
+ size: "icon",
72
+ variant: "ghost",
73
+ "aria-label": t("common:action.saveChanges"),
74
+ className: "h-6 w-6 shrink-0",
75
+ disabled: isSaving,
76
+ onClick: onSave,
77
+ children: /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5" })
78
+ }
79
+ )
80
+ ] })
81
+ ]
82
+ }
83
+ )
84
+ ]
85
+ }
86
+ );
87
+ }
88
+ export {
89
+ InlineEditPopover
90
+ };
File without changes
@@ -0,0 +1,136 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import i18n from "@zenify-omni/chat-js/lib/i18n/index.js";
3
+ import { useState } from "react";
4
+ import { X } from "lucide-react";
5
+ import { v4 as uuidv4 } from "uuid";
6
+ import { Badge } from "../../ui/badge.js";
7
+ import { cn } from "../../../lib/utils.js";
8
+ import { cva } from "class-variance-authority";
9
+ const ChipInput = ({
10
+ type = "text",
11
+ closeSize,
12
+ className,
13
+ value = [],
14
+ onValueChange,
15
+ disabled,
16
+ inputProps,
17
+ placeholder,
18
+ size
19
+ }) => {
20
+ const [inputValue, setInputValue] = useState("");
21
+ const fieldVariants = cva("", {
22
+ variants: {
23
+ size: {
24
+ small: "text-xs flex",
25
+ default: "text-sm"
26
+ }
27
+ },
28
+ defaultVariants: {
29
+ size: "default"
30
+ }
31
+ });
32
+ return /* @__PURE__ */ jsx(
33
+ "div",
34
+ {
35
+ className: cn(
36
+ "min-h-9 items-center rounded-md border border-input bg-card text-sm ring-offset-background focus-within:ring-1 focus-within:ring-ring",
37
+ {
38
+ "px-1 py-[0.35rem]": value.length !== 0,
39
+ "cursor-text": !disabled && value.length !== 0
40
+ },
41
+ fieldVariants({ size }),
42
+ className,
43
+ disabled && "bg-muted"
44
+ ),
45
+ children: /* @__PURE__ */ jsxs("div", { className: "relative flex flex-wrap gap-1 pr-[20px]", children: [
46
+ (Array.isArray(value) ? value : []).map((chip) => {
47
+ return /* @__PURE__ */ jsxs(
48
+ Badge,
49
+ {
50
+ variant: "chip",
51
+ className: cn(
52
+ "word-break break-all data-[disabled]:bg-muted-foreground data-[disabled]:text-muted data-[disabled]:hover:bg-muted-foreground",
53
+ fieldVariants({ size })
54
+ ),
55
+ "data-disabled": disabled || void 0,
56
+ children: [
57
+ chip.text,
58
+ /* @__PURE__ */ jsx(
59
+ "button",
60
+ {
61
+ className: cn(
62
+ "ml-1 rounded-full outline-none ring-offset-background focus:ring-1 focus:ring-ring",
63
+ disabled && "hidden"
64
+ ),
65
+ onMouseDown: (e) => {
66
+ e.preventDefault();
67
+ e.stopPropagation();
68
+ },
69
+ onClick: () => {
70
+ onValueChange(value.filter((v) => v.key !== chip.key));
71
+ },
72
+ children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3 text-muted-foreground hover:text-foreground" })
73
+ }
74
+ )
75
+ ]
76
+ },
77
+ chip.key
78
+ );
79
+ }),
80
+ /* @__PURE__ */ jsx(
81
+ "input",
82
+ {
83
+ type,
84
+ disabled,
85
+ className: cn(
86
+ "w-full flex-1 bg-transparent outline-none placeholder:text-muted-foreground",
87
+ {
88
+ "px-3 py-[0.35rem]": value.length === 0,
89
+ "ml-1": value.length !== 0,
90
+ "pr-6": !disabled && value.length !== 0
91
+ },
92
+ inputProps?.className
93
+ ),
94
+ placeholder: value.length == 0 ? placeholder || i18n.t("common:placeholder.enterTags", {
95
+ defaultValue: "Nh\u1EADp tags"
96
+ }) : null,
97
+ value: inputValue,
98
+ onChange: (e) => setInputValue(e.target.value),
99
+ onKeyDown: (e) => {
100
+ if (e.key === "Backspace") {
101
+ if (inputValue === "" && value.length > 0) {
102
+ onValueChange(value.slice(0, value.length - 1));
103
+ }
104
+ } else if (e.key === "Enter" && inputValue.trim() !== "") {
105
+ e.preventDefault();
106
+ e.stopPropagation();
107
+ if (!value.find((item) => item.text === inputValue)) {
108
+ onValueChange([...value, { key: uuidv4(), text: inputValue }]);
109
+ }
110
+ setInputValue("");
111
+ }
112
+ },
113
+ ...inputProps
114
+ }
115
+ ),
116
+ /* @__PURE__ */ jsx(
117
+ "button",
118
+ {
119
+ type: "button",
120
+ onClick: () => {
121
+ onValueChange([]);
122
+ },
123
+ className: cn(
124
+ "absolute right-0 h-5 w-5 p-0",
125
+ (disabled || value.length < 1) && "hidden"
126
+ ),
127
+ children: /* @__PURE__ */ jsx(X, { size: closeSize || 20 })
128
+ }
129
+ )
130
+ ] })
131
+ }
132
+ );
133
+ };
134
+ export {
135
+ ChipInput
136
+ };