@seamly/web-ui 20.6.0 → 20.8.0-alpha.1

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 (224) hide show
  1. package/CHANGELOG.md +234 -16
  2. package/build/dist/lib/hooks.js +1 -1
  3. package/build/dist/lib/hooks.min.js +1 -1
  4. package/build/dist/lib/index.debug.js +939 -784
  5. package/build/dist/lib/index.debug.min.js +1 -1
  6. package/build/dist/lib/index.debug.min.js.LICENSE.txt +186 -130
  7. package/build/dist/lib/index.js +24828 -19735
  8. package/build/dist/lib/index.min.js +1 -1
  9. package/build/dist/lib/index.min.js.LICENSE.txt +38 -4
  10. package/build/dist/lib/standalone.js +32930 -27053
  11. package/build/dist/lib/standalone.min.js +1 -1
  12. package/build/dist/lib/standalone.min.js.LICENSE.txt +39 -0
  13. package/build/dist/lib/storage.js +2 -2
  14. package/build/dist/lib/storage.min.js +1 -1
  15. package/build/dist/lib/style-guide.js +8653 -7885
  16. package/build/dist/lib/style-guide.min.js +2 -1
  17. package/build/dist/lib/style-guide.min.js.LICENSE.txt +38 -0
  18. package/build/dist/lib/styles.css +1 -1
  19. package/build/dist/lib/utils.js +1 -2
  20. package/build/dist/lib/utils.min.js +1 -1
  21. package/package.json +19 -9
  22. package/src/icons/avatar_agent-32.svg +7 -0
  23. package/src/icons/avatar_bot-32.svg +6 -1
  24. package/src/javascripts/api/index.js +1 -1
  25. package/src/javascripts/{config.js → config.ts} +3 -1
  26. package/src/javascripts/config.types.ts +95 -0
  27. package/src/javascripts/domains/app/actions.ts +83 -0
  28. package/src/javascripts/domains/app/app.types.ts +3 -0
  29. package/src/javascripts/domains/app/hooks.js +3 -5
  30. package/src/javascripts/domains/app/selectors.ts +6 -0
  31. package/src/javascripts/domains/app/slice.ts +30 -0
  32. package/src/javascripts/domains/config/actions.ts +45 -0
  33. package/src/javascripts/domains/config/hooks.ts +19 -0
  34. package/src/javascripts/domains/config/selectors.ts +24 -0
  35. package/src/javascripts/domains/config/slice.ts +111 -0
  36. package/src/javascripts/domains/errors/index.js +13 -9
  37. package/src/javascripts/domains/forms/context.ts +14 -0
  38. package/src/javascripts/domains/forms/forms.types.ts +24 -0
  39. package/src/javascripts/domains/forms/{hooks.js → hooks.ts} +23 -26
  40. package/src/javascripts/domains/forms/{provider.js → provider.tsx} +20 -14
  41. package/src/javascripts/domains/forms/{selectors.js → selectors.ts} +7 -8
  42. package/src/javascripts/domains/forms/slice.ts +84 -0
  43. package/src/javascripts/domains/forms/utils.ts +15 -0
  44. package/src/javascripts/domains/i18n/actions.ts +24 -0
  45. package/src/javascripts/domains/i18n/{hooks.js → hooks.ts} +2 -2
  46. package/src/javascripts/domains/i18n/i18n.types.ts +6 -0
  47. package/src/javascripts/domains/i18n/selectors.ts +16 -0
  48. package/src/javascripts/domains/i18n/{reducer.js → slice.ts} +43 -37
  49. package/src/javascripts/domains/interrupt/{hooks.js → hooks.ts} +2 -2
  50. package/src/javascripts/domains/interrupt/{middleware.js → middleware.ts} +11 -8
  51. package/src/javascripts/domains/interrupt/selectors.ts +6 -0
  52. package/src/javascripts/domains/interrupt/slice.ts +40 -0
  53. package/src/javascripts/domains/options/middleware.js +9 -6
  54. package/src/javascripts/domains/redux/redux.types.ts +11 -0
  55. package/src/javascripts/domains/store/index.ts +53 -0
  56. package/src/javascripts/domains/store/slice.ts +639 -0
  57. package/src/javascripts/domains/store/store.types.ts +135 -0
  58. package/src/javascripts/domains/translations/components/chat-status.js +2 -2
  59. package/src/javascripts/domains/translations/components/options-button.js +1 -1
  60. package/src/javascripts/domains/translations/components/options-dialog/form.js +5 -5
  61. package/src/javascripts/domains/translations/components/options-dialog/index.js +2 -2
  62. package/src/javascripts/domains/translations/{hooks.js → hooks.ts} +28 -23
  63. package/src/javascripts/domains/translations/middleware.js +29 -27
  64. package/src/javascripts/domains/translations/selectors.js +4 -9
  65. package/src/javascripts/domains/translations/slice.ts +67 -0
  66. package/src/javascripts/domains/translations/translations.types.ts +12 -0
  67. package/src/javascripts/domains/visibility/{actions.js → actions.ts} +25 -19
  68. package/src/javascripts/domains/visibility/{hooks.js → hooks.ts} +13 -10
  69. package/src/javascripts/domains/visibility/{selectors.js → selectors.ts} +3 -6
  70. package/src/javascripts/domains/visibility/slice.ts +38 -0
  71. package/src/javascripts/domains/visibility/utils.js +0 -9
  72. package/src/javascripts/domains/visibility/visibility.types.ts +6 -0
  73. package/src/javascripts/index.ts +92 -0
  74. package/src/javascripts/lib/engine/index.js +15 -11
  75. package/src/javascripts/lib/external-api/initialize-api.js +1 -1
  76. package/src/javascripts/lib/id.js +5 -8
  77. package/src/javascripts/lib/mutex.js +3 -1
  78. package/src/javascripts/lib/store/providers/cookie-storage.js +1 -1
  79. package/src/javascripts/lib/store/providers/session-storage.js +1 -1
  80. package/src/javascripts/package/hooks.js +2 -2
  81. package/src/javascripts/package/utils.js +0 -1
  82. package/src/javascripts/schema.ts +1455 -0
  83. package/src/javascripts/style-guide/components/app.js +4 -4
  84. package/src/javascripts/style-guide/components/static-core.js +87 -65
  85. package/src/javascripts/style-guide/components/view.js +4 -4
  86. package/src/javascripts/style-guide/state-helpers/index.js +5 -5
  87. package/src/javascripts/style-guide/states.js +6 -4
  88. package/src/javascripts/style-guide.ts +5 -0
  89. package/src/javascripts/ui/components/app-options/index.js +2 -4
  90. package/src/javascripts/ui/components/conversation/component-filter.js +1 -1
  91. package/src/javascripts/ui/components/conversation/conversation.js +5 -5
  92. package/src/javascripts/ui/components/conversation/event/card-message.js +1 -1
  93. package/src/javascripts/ui/components/conversation/event/carousel-component/components/controls.js +1 -1
  94. package/src/javascripts/ui/components/conversation/event/carousel-message/components/slide.js +1 -1
  95. package/src/javascripts/ui/components/conversation/event/carousel-message/index.js +1 -1
  96. package/src/javascripts/ui/components/conversation/event/choice-prompt.js +2 -2
  97. package/src/javascripts/ui/components/conversation/event/conversation-suggestions.js +11 -14
  98. package/src/javascripts/ui/components/conversation/event/cta.js +1 -1
  99. package/src/javascripts/ui/components/conversation/event/divider/variants/default.js +1 -1
  100. package/src/javascripts/ui/components/conversation/event/divider/variants/new-translation.js +5 -2
  101. package/src/javascripts/ui/components/conversation/event/event-participant.js +2 -2
  102. package/src/javascripts/ui/components/conversation/event/hooks/use-formatted-date.js +2 -2
  103. package/src/javascripts/ui/components/conversation/event/image-lightbox.js +1 -1
  104. package/src/javascripts/ui/components/conversation/event/image.js +5 -7
  105. package/src/javascripts/ui/components/conversation/event/participant.js +1 -1
  106. package/src/javascripts/ui/components/conversation/event/splash.js +3 -3
  107. package/src/javascripts/ui/components/conversation/event/text.js +1 -1
  108. package/src/javascripts/ui/components/conversation/event/translation.js +2 -2
  109. package/src/javascripts/ui/components/conversation/event/upload.js +2 -2
  110. package/src/javascripts/ui/components/conversation/event/video.js +1 -1
  111. package/src/javascripts/ui/components/conversation/message-container.js +4 -4
  112. package/src/javascripts/ui/components/core/seamly-api-context.js +1 -1
  113. package/src/javascripts/ui/components/core/seamly-core.js +15 -14
  114. package/src/javascripts/ui/components/core/seamly-event-subscriber.js +96 -91
  115. package/src/javascripts/ui/components/core/seamly-file-upload.js +20 -24
  116. package/src/javascripts/ui/components/core/seamly-initializer.js +1 -1
  117. package/src/javascripts/ui/components/core/seamly-instance-functions-loader.js +5 -4
  118. package/src/javascripts/ui/components/core/seamly-new-notifications.js +2 -2
  119. package/src/javascripts/ui/components/core/seamly-read-state.js +10 -17
  120. package/src/javascripts/ui/components/entry/deprecated-toggle-button.js +3 -3
  121. package/src/javascripts/ui/components/entry/entry-container.js +4 -6
  122. package/src/javascripts/ui/components/entry/text-entry/hooks.js +3 -3
  123. package/src/javascripts/ui/components/entry/text-entry/index.js +3 -2
  124. package/src/javascripts/ui/components/entry/text-entry/text-entry-form.js +6 -10
  125. package/src/javascripts/ui/components/entry/upload/file-upload-form.js +2 -2
  126. package/src/javascripts/ui/components/entry/upload/index.js +10 -9
  127. package/src/javascripts/ui/components/entry/upload-toggle.js +2 -2
  128. package/src/javascripts/ui/components/faq/faq.js +6 -6
  129. package/src/javascripts/ui/components/form-controls/file-input.js +1 -1
  130. package/src/javascripts/ui/components/form-controls/form.js +1 -1
  131. package/src/javascripts/ui/components/form-controls/input.js +1 -1
  132. package/src/javascripts/ui/components/form-controls/select.js +1 -1
  133. package/src/javascripts/ui/components/layout/agent-info.js +4 -4
  134. package/src/javascripts/ui/components/layout/chat-frame.js +3 -3
  135. package/src/javascripts/ui/components/layout/chat.js +11 -12
  136. package/src/javascripts/ui/components/layout/deprecated-app-frame.js +10 -9
  137. package/src/javascripts/ui/components/layout/header.js +1 -1
  138. package/src/javascripts/ui/components/layout/interrupt.js +23 -24
  139. package/src/javascripts/ui/components/layout/pre-chat-messages.js +11 -11
  140. package/src/javascripts/ui/components/layout/privacy-disclaimer.js +2 -2
  141. package/src/javascripts/ui/components/options/options-button.js +12 -10
  142. package/src/javascripts/ui/components/options/transcript/index.js +2 -2
  143. package/src/javascripts/ui/components/options/transcript/transcript-form.js +1 -1
  144. package/src/javascripts/ui/components/suggestions/index.js +39 -27
  145. package/src/javascripts/ui/components/view/deprecated-view.js +19 -16
  146. package/src/javascripts/ui/components/view/index.js +12 -12
  147. package/src/javascripts/ui/components/view/inline-view.js +2 -2
  148. package/src/javascripts/ui/components/view/window-view/collapse-button.js +3 -3
  149. package/src/javascripts/ui/components/view/window-view/index.js +13 -13
  150. package/src/javascripts/ui/components/view/window-view/window-open-button.js +13 -13
  151. package/src/javascripts/ui/components/warnings/idle-detach-warning.js +1 -1
  152. package/src/javascripts/ui/components/warnings/resume-conversation-prompt.js +1 -1
  153. package/src/javascripts/ui/components/widgets/lightbox.js +2 -2
  154. package/src/javascripts/ui/components/widgets/upload-progress.js +1 -1
  155. package/src/javascripts/ui/hooks/component-helper-hooks.js +1 -1
  156. package/src/javascripts/ui/hooks/file-upload-hooks.js +4 -6
  157. package/src/javascripts/ui/hooks/focus-helper-hooks.js +14 -12
  158. package/src/javascripts/ui/hooks/live-region-hooks.js +2 -0
  159. package/src/javascripts/ui/hooks/seamly-api-hooks.js +8 -3
  160. package/src/javascripts/ui/hooks/seamly-entry-hooks.js +28 -25
  161. package/src/javascripts/ui/hooks/seamly-hooks.js +25 -25
  162. package/src/javascripts/ui/hooks/seamly-option-hooks.js +17 -19
  163. package/src/javascripts/ui/hooks/seamly-state-hooks.js +14 -13
  164. package/src/javascripts/ui/hooks/use-seamly-chat.js +15 -25
  165. package/src/javascripts/ui/hooks/use-seamly-commands.js +46 -63
  166. package/src/javascripts/ui/hooks/use-seamly-idle-detach-countdown.js +22 -24
  167. package/src/javascripts/ui/hooks/use-seamly-resume-conversation-prompt.js +8 -9
  168. package/src/javascripts/ui/hooks/use-single-file-upload.js +4 -6
  169. package/src/javascripts/ui/hooks/utility-hooks.js +4 -4
  170. package/src/javascripts/ui/utils/form-utils.js +0 -145
  171. package/src/javascripts/ui/utils/general-utils.js +3 -4
  172. package/src/javascripts/ui/utils/seamly-utils.ts +73 -0
  173. package/src/stylesheets/5-components/_suggestions.scss +3 -3
  174. package/webpack/config.common.js +16 -0
  175. package/webpack/config.dev.js +1 -0
  176. package/webpack/config.package.js +26 -5
  177. package/webpack/defaults.js +7 -2
  178. package/webpack/parts/babel-loader-browser-plugins.js +1 -0
  179. package/webpack/parts/dev-server.js +4 -3
  180. package/src/javascripts/domains/app/actions.js +0 -112
  181. package/src/javascripts/domains/app/index.js +0 -7
  182. package/src/javascripts/domains/app/reducer.js +0 -16
  183. package/src/javascripts/domains/app/selectors.js +0 -8
  184. package/src/javascripts/domains/app/utils.js +0 -4
  185. package/src/javascripts/domains/config/actions.js +0 -7
  186. package/src/javascripts/domains/config/hooks.js +0 -23
  187. package/src/javascripts/domains/config/index.js +0 -7
  188. package/src/javascripts/domains/config/reducer.js +0 -79
  189. package/src/javascripts/domains/config/selectors.js +0 -23
  190. package/src/javascripts/domains/config/utils.js +0 -4
  191. package/src/javascripts/domains/forms/actions.js +0 -21
  192. package/src/javascripts/domains/forms/context.js +0 -6
  193. package/src/javascripts/domains/forms/index.js +0 -8
  194. package/src/javascripts/domains/forms/reducer.js +0 -84
  195. package/src/javascripts/domains/forms/utils.js +0 -20
  196. package/src/javascripts/domains/i18n/actions.js +0 -20
  197. package/src/javascripts/domains/i18n/index.js +0 -7
  198. package/src/javascripts/domains/i18n/selectors.js +0 -15
  199. package/src/javascripts/domains/i18n/utils.js +0 -4
  200. package/src/javascripts/domains/interrupt/actions.js +0 -4
  201. package/src/javascripts/domains/interrupt/index.js +0 -9
  202. package/src/javascripts/domains/interrupt/reducer.js +0 -22
  203. package/src/javascripts/domains/interrupt/selectors.js +0 -6
  204. package/src/javascripts/domains/interrupt/utils.js +0 -4
  205. package/src/javascripts/domains/options/index.js +0 -1
  206. package/src/javascripts/domains/redux/context.js +0 -6
  207. package/src/javascripts/domains/redux/create-redux-store.js +0 -21
  208. package/src/javascripts/domains/redux/hooks.js +0 -80
  209. package/src/javascripts/domains/redux/index.js +0 -19
  210. package/src/javascripts/domains/redux/provider.js +0 -5
  211. package/src/javascripts/domains/redux/utils.js +0 -12
  212. package/src/javascripts/domains/store/index.js +0 -46
  213. package/src/javascripts/domains/store/state-reducer.js +0 -56
  214. package/src/javascripts/domains/translations/actions.js +0 -11
  215. package/src/javascripts/domains/translations/index.js +0 -10
  216. package/src/javascripts/domains/translations/reducer.js +0 -69
  217. package/src/javascripts/domains/translations/utils.js +0 -4
  218. package/src/javascripts/domains/visibility/index.js +0 -8
  219. package/src/javascripts/domains/visibility/reducer.js +0 -24
  220. package/src/javascripts/index.js +0 -153
  221. package/src/javascripts/lib/redux-helpers/index.js +0 -99
  222. package/src/javascripts/style-guide.js +0 -5
  223. package/src/javascripts/ui/hooks/use-seamly-dispatch.js +0 -3
  224. package/src/javascripts/ui/utils/seamly-utils.js +0 -833
@@ -1,20 +1,20 @@
1
- import { useCallback, useEffect, useMemo, useRef } from 'preact/hooks'
1
+ import FormProvider from 'domains/forms/provider'
2
+ import { useI18n } from 'domains/i18n/hooks'
2
3
  import { className } from 'lib/css'
4
+ import { useCallback, useEffect, useMemo, useRef } from 'preact/hooks'
5
+ import UploadProgress from 'ui/components/widgets/upload-progress'
3
6
  import {
4
- useSkiplink,
5
7
  useFileUploadMeta,
6
8
  useFileUploads,
7
- useSkiplinkTargetFocusing,
8
- useLiveRegion,
9
9
  useGeneratedId,
10
- useSeamlyEntry,
10
+ useLiveRegion,
11
+ useSkiplink,
12
+ useSkiplinkTargetFocusing,
11
13
  } from 'ui/hooks/seamly-hooks'
14
+ import { useSeamlyEntry } from 'ui/hooks/seamly-entry-hooks'
12
15
  import useSingleFileUpload from 'ui/hooks/use-single-file-upload'
13
- import { useI18n } from 'domains/i18n'
14
- import { formatBytes } from 'ui/utils/general-utils'
15
- import UploadProgress from 'ui/components/widgets/upload-progress'
16
- import { FormProvider } from 'domains/forms'
17
16
  import { getValidator } from 'ui/utils/form-utils'
17
+ import { formatBytes } from 'ui/utils/general-utils'
18
18
  import {
19
19
  fileListObjectIsNotEmpty,
20
20
  validateFileSize,
@@ -186,6 +186,7 @@ const Upload = () => {
186
186
  onClickCancel={handleOnClickCancel}
187
187
  />
188
188
  )}
189
+
189
190
  {!canUpload.current && (
190
191
  <>
191
192
  <span className={className('notification')} id={notificationId}>
@@ -7,11 +7,11 @@ import InOutTransition, {
7
7
  import {
8
8
  useFileUploadMeta,
9
9
  useSkiplinkTargetFocusing,
10
- useSeamlyEntry,
11
10
  useLiveRegion,
12
11
  useSeamlyCurrentAgent,
13
12
  } from 'ui/hooks/seamly-hooks'
14
- import { useI18n } from 'domains/i18n'
13
+ import { useSeamlyEntry } from 'ui/hooks/seamly-entry-hooks'
14
+ import { useI18n } from 'domains/i18n/hooks'
15
15
  import { entryTypes } from 'ui/utils/seamly-utils'
16
16
  import { runIfElementContainsOrHasFocus } from 'ui/utils/general-utils'
17
17
 
@@ -13,13 +13,13 @@ import { useSkiplinkTargetFocusing } from 'ui/hooks/focus-helper-hooks'
13
13
  import { useLiveRegion } from 'ui/hooks/live-region-hooks'
14
14
  import useSeamlyIdleDetachCountdown from 'ui/hooks/use-seamly-idle-detach-countdown'
15
15
  import useSeamlyResumeConversationPrompt from 'ui/hooks/use-seamly-resume-conversation-prompt'
16
- import { useI18n } from 'domains/i18n'
16
+ import { useI18n } from 'domains/i18n/hooks'
17
17
  import InOutTransition, {
18
18
  transitionStartStates,
19
19
  } from 'ui/components/widgets/in-out-transition'
20
- import { useTranslatedEventData } from 'domains/translations'
21
- import { useInterrupt } from 'domains/interrupt'
22
- import { useUserHasResponded } from 'domains/app'
20
+ import { useTranslatedEventData } from 'domains/translations/hooks'
21
+ import { useInterrupt } from 'domains/interrupt/hooks'
22
+ import { useUserHasResponded } from 'domains/app/hooks'
23
23
 
24
24
  const Faq = () => {
25
25
  const { t } = useI18n()
@@ -55,8 +55,8 @@ const Faq = () => {
55
55
  const prevHasFaqs = useRef(false)
56
56
 
57
57
  const { isInline } = useSeamlyLayoutMode()
58
- const hasResponded = useUserHasResponded()
59
- const hideForWindow = !isInline && hasResponded
58
+ const userHasResponded = useUserHasResponded()
59
+ const hideForWindow = !isInline && userHasResponded
60
60
  const prevHideForWindow = useRef(hideForWindow)
61
61
 
62
62
  const hasFaqs = !!faqs.length
@@ -1,7 +1,7 @@
1
1
  import { useCallback, useState } from 'preact/hooks'
2
2
  import { className } from 'lib/css'
3
3
  import { useGeneratedId } from 'ui/hooks/seamly-hooks'
4
- import { useFormControl, useFormContext } from 'domains/forms'
4
+ import { useFormControl, useFormContext } from 'domains/forms/hooks'
5
5
  import Icon from 'ui/components/layout/icon'
6
6
  import Error from './error'
7
7
 
@@ -1,4 +1,4 @@
1
- import { useForm } from 'domains/forms'
1
+ import { useForm } from 'domains/forms/hooks'
2
2
  import { className } from 'lib/css'
3
3
 
4
4
  function Form({
@@ -1,4 +1,4 @@
1
- import { useFormContext, useFormControl } from 'domains/forms'
1
+ import { useFormContext, useFormControl } from 'domains/forms/hooks'
2
2
  import FormControlWrapper from './wrapper'
3
3
 
4
4
  function Input({
@@ -1,4 +1,4 @@
1
- import { useFormContext, useFormControl } from 'domains/forms'
1
+ import { useFormContext, useFormControl } from 'domains/forms/hooks'
2
2
  import FormControlWrapper from './wrapper'
3
3
 
4
4
  const Select = ({
@@ -4,10 +4,10 @@ import {
4
4
  useSeamlyCurrentAgent,
5
5
  } from 'ui/hooks/seamly-hooks'
6
6
  import { className } from 'lib/css'
7
- import { useI18n } from 'domains/i18n'
8
- import { useInterrupt } from 'domains/interrupt'
9
- import { useStartChatIcon } from 'domains/config'
10
- import { useVisibility } from 'domains/visibility'
7
+ import { useI18n } from 'domains/i18n/hooks'
8
+ import { useInterrupt } from 'domains/interrupt/hooks'
9
+ import { useStartChatIcon } from 'domains/config/hooks'
10
+ import { useVisibility } from 'domains/visibility/hooks'
11
11
  import Icon from './icon'
12
12
 
13
13
  const AgentInfo = () => {
@@ -1,8 +1,8 @@
1
1
  import { className } from 'lib/css'
2
2
  import AppOptions from 'ui/components/app-options'
3
- import { ChatStatus as TranslationsChatStatus } from 'domains/translations'
4
- import { useInterrupt } from 'domains/interrupt'
5
- import { useVisibility } from 'domains/visibility'
3
+ import { useInterrupt } from 'domains/interrupt/hooks'
4
+ import { useVisibility } from 'domains/visibility/hooks'
5
+ import TranslationsChatStatus from 'domains/translations/components/chat-status'
6
6
 
7
7
  function ChatFrame({ children, interruptComponent: InterruptComponent }) {
8
8
  const { hasInterrupt, meta } = useInterrupt()
@@ -1,14 +1,13 @@
1
+ import { useUserHasResponded } from 'domains/app/hooks'
2
+ import { useConfig } from 'domains/config/hooks'
3
+ import { useI18n } from 'domains/i18n/hooks'
4
+ import { useVisibility } from 'domains/visibility/hooks'
1
5
  import { forwardRef } from 'preact/compat'
2
- import { className } from '../../../lib/css'
3
- import {
4
- useSeamlyAppContainerClassNames,
5
- useSeamlyLayoutMode,
6
- } from '../../hooks/seamly-hooks'
7
- import { useConfig } from '../../../domains/config'
8
- import { useUserHasResponded } from '../../../domains/app'
9
- import { useI18n } from '../../../domains/i18n'
10
- import { useVisibility, visibilityStates } from '../../../domains/visibility'
11
- import Suggestions from '../suggestions'
6
+ import { className } from 'lib/css'
7
+ import { useSeamlyLayoutMode } from 'ui/hooks/seamly-state-hooks'
8
+ import { useSeamlyAppContainerClassNames } from 'ui/hooks/component-helper-hooks'
9
+ import { visibilityStates } from 'domains/visibility/constants'
10
+ import Suggestions from 'ui/components/suggestions'
12
11
 
13
12
  const Chat = forwardRef(
14
13
  ({ children, className: givenClassName = '' }, forwardedRef) => {
@@ -16,7 +15,7 @@ const Chat = forwardRef(
16
15
  const { namespace, layoutMode } = useConfig()
17
16
  const { isInline } = useSeamlyLayoutMode()
18
17
  const appContainerClassNames = useSeamlyAppContainerClassNames()
19
- const userResponded = useUserHasResponded()
18
+ const userHasResponded = useUserHasResponded()
20
19
  const { t } = useI18n()
21
20
 
22
21
  const defaultClassNames = [
@@ -35,7 +34,7 @@ const Chat = forwardRef(
35
34
  classNames.push('chat--collapsed')
36
35
  }
37
36
 
38
- if (userResponded) {
37
+ if (userHasResponded) {
39
38
  classNames.push('chat--user-responded')
40
39
  }
41
40
 
@@ -1,15 +1,16 @@
1
- import { useCallback, useMemo } from 'preact/hooks'
1
+ import { useUserHasResponded } from 'domains/app/hooks'
2
+ import { useConfig } from 'domains/config/hooks'
3
+ import { useI18n } from 'domains/i18n/hooks'
4
+ import { visibilityStates } from 'domains/visibility/constants'
5
+ import { useVisibility } from 'domains/visibility/hooks'
2
6
  import { className } from 'lib/css'
7
+ import { useCallback, useMemo } from 'preact/hooks'
8
+ import Faq from 'ui/components/faq/faq'
3
9
  import {
4
10
  useSeamlyAppContainerClassNames,
5
- useSeamlyLayoutMode,
6
11
  useSeamlyContainerElement,
12
+ useSeamlyLayoutMode,
7
13
  } from 'ui/hooks/seamly-hooks'
8
- import Faq from 'ui/components/faq/faq'
9
- import { useConfig } from 'domains/config'
10
- import { useUserHasResponded } from 'domains/app'
11
- import { useI18n } from 'domains/i18n'
12
- import { useVisibility, visibilityStates } from 'domains/visibility'
13
14
 
14
15
  const DeprecatedAppFrame = ({ children }) => {
15
16
  const [, setSeamlyContainerElement] = useSeamlyContainerElement()
@@ -17,7 +18,7 @@ const DeprecatedAppFrame = ({ children }) => {
17
18
  const { zIndex, showFaq, layoutMode } = useConfig()
18
19
  const { isInline } = useSeamlyLayoutMode()
19
20
  const appContainerClassNames = useSeamlyAppContainerClassNames()
20
- const userResponded = useUserHasResponded()
21
+ const userHasResponded = useUserHasResponded()
21
22
  const { locale } = useI18n()
22
23
 
23
24
  const containerElementRef = useCallback(
@@ -45,7 +46,7 @@ const DeprecatedAppFrame = ({ children }) => {
45
46
  classNames.push('app--collapsed')
46
47
  }
47
48
 
48
- if (userResponded) {
49
+ if (userHasResponded) {
49
50
  classNames.push('app--user-responded')
50
51
  }
51
52
 
@@ -1,6 +1,6 @@
1
1
  import { useRef } from 'preact/hooks'
2
2
  import { className } from 'lib/css'
3
- import { useI18n } from 'domains/i18n'
3
+ import { useI18n } from 'domains/i18n/hooks'
4
4
  import { useSeamlyStateContext } from 'ui/hooks/seamly-hooks'
5
5
  import Icon from './icon'
6
6
 
@@ -6,7 +6,6 @@ import {
6
6
  useGeneratedId,
7
7
  useSkiplinkTargetFocusing,
8
8
  } from 'ui/hooks/seamly-hooks'
9
- import SeamlySessionExpiredError from 'api/errors/seamly-session-expired-error'
10
9
 
11
10
  const Interrupt = ({
12
11
  originalError,
@@ -20,7 +19,7 @@ const Interrupt = ({
20
19
  const headingId = useGeneratedId()
21
20
  const { sendPolite } = useLiveRegion()
22
21
  const focusSkiplinkTarget = useSkiplinkTargetFocusing()
23
- const isExpiredError = originalError instanceof SeamlySessionExpiredError
22
+ const isExpiredError = originalError.name === 'SeamlySessionExpiredError'
24
23
 
25
24
  useEffect(() => {
26
25
  if (isExpiredError) {
@@ -43,28 +42,28 @@ const Interrupt = ({
43
42
  focusSkiplinkTarget()
44
43
  }
45
44
 
46
- return (
47
- !isExpiredError && (
48
- <section className={className('interrupt')} aria-labelledby={headingId}>
49
- <div className={className('interrupt__body')}>
50
- <h2 id={headingId} className={className('interrupt__title')}>
51
- {title}
52
- </h2>
53
- <p className={className('interrupt__message')}>{message}</p>
54
- {buttonText && action && (
55
- <div className={className('interrupt__actions')}>
56
- <button
57
- type="button"
58
- className={className('button', 'button--primary')}
59
- onClick={onClickHandler}
60
- >
61
- {buttonText}
62
- </button>
63
- </div>
64
- )}
65
- </div>
66
- </section>
67
- )
45
+ return !isExpiredError ? (
46
+ <section className={className('interrupt')} aria-labelledby={headingId}>
47
+ <div className={className('interrupt__body')}>
48
+ <h2 id={headingId} className={className('interrupt__title')}>
49
+ {title}
50
+ </h2>
51
+ <p className={className('interrupt__message')}>{message}</p>
52
+ {buttonText && action && (
53
+ <div className={className('interrupt__actions')}>
54
+ <button
55
+ type="button"
56
+ className={className('button', 'button--primary')}
57
+ onClick={onClickHandler}
58
+ >
59
+ {buttonText}
60
+ </button>
61
+ </div>
62
+ )}
63
+ </div>
64
+ </section>
65
+ ) : (
66
+ <></>
68
67
  )
69
68
  }
70
69
 
@@ -1,15 +1,20 @@
1
- import { className } from '../../../lib/css'
2
- import { useInterrupt } from '../../../domains/interrupt'
3
- import { useConfig } from '../../../domains/config'
4
- import useEventComponentMapping from '../../hooks/use-event-component-mapping'
5
- import { useVisibility } from '../../../domains/visibility'
1
+ import { useConfig } from 'domains/config/hooks'
2
+ import { useInterrupt } from 'domains/interrupt/hooks'
3
+ import { useVisibility } from 'domains/visibility/hooks'
4
+ import { className } from 'lib/css'
5
+ import useEventComponentMapping from 'ui/hooks/use-event-component-mapping'
6
+
7
+ export function PreChatMessageEvent({ event }) {
8
+ const [Component] = useEventComponentMapping(event)
9
+ return <Component event={event} />
10
+ }
6
11
 
7
12
  export default function PreChatMessages() {
8
13
  const { preChatEvents, layoutMode } = useConfig()
9
14
  const { hasInterrupt } = useInterrupt()
10
15
  const { isOpen } = useVisibility()
11
16
 
12
- const isVisible = !(hasInterrupt || !preChatEvents.length || isOpen)
17
+ const isVisible = !(hasInterrupt || !preChatEvents?.length || isOpen)
13
18
 
14
19
  return (
15
20
  isVisible && (
@@ -32,8 +37,3 @@ export default function PreChatMessages() {
32
37
  )
33
38
  )
34
39
  }
35
-
36
- export function PreChatMessageEvent({ event }) {
37
- const [Component] = useEventComponentMapping(event)
38
- return <Component event={event} />
39
- }
@@ -1,6 +1,6 @@
1
1
  import { className } from 'lib/css'
2
- import { useI18n } from 'domains/i18n'
3
- import { useConfig } from 'domains/config'
2
+ import { useI18n } from 'domains/i18n/hooks'
3
+ import { useConfig } from 'domains/config/hooks'
4
4
 
5
5
  const PrivacyDisclaimer = () => {
6
6
  const { t } = useI18n()
@@ -2,12 +2,13 @@ import { createRef } from 'preact'
2
2
  import { useState, useRef, useEffect, useMemo } from 'preact/hooks'
3
3
  import { className } from 'lib/css'
4
4
  import { useSeamlyOptions, useOptionButton } from 'ui/hooks/seamly-hooks'
5
- import { useI18n } from 'domains/i18n'
5
+ import { useI18n } from 'domains/i18n/hooks'
6
6
  import Icon from 'ui/components/layout/icon'
7
7
  import InOutTransition, {
8
8
  transitionStartStates,
9
9
  } from 'ui/components/widgets/in-out-transition'
10
10
  import { getKey, keyNames, focusElement } from 'ui/utils/general-utils'
11
+ import { timeout } from 'ui/hooks/focus-helper-hooks'
11
12
  import Options from './options'
12
13
 
13
14
  const OptionsButton = () => {
@@ -41,15 +42,14 @@ const OptionsButton = () => {
41
42
 
42
43
  useEffect(() => {
43
44
  if (menuIsOpen && !prevMenuIsOpen.current) {
44
- requestAnimationFrame(() => {
45
- requestAnimationFrame(() => {
46
- const firstActiveOptionIndex = menuOptions.findIndex(
47
- (option) => option.available,
48
- )
49
- const focusIndex =
50
- firstActiveOptionIndex === -1 ? 0 : firstActiveOptionIndex
51
- focusElement(menuItemButtons.current[focusIndex])
52
- })
45
+ requestAnimationFrame(async () => {
46
+ await timeout(180) // Wait for next 3 frame ticks
47
+ const firstActiveOptionIndex = menuOptions.findIndex(
48
+ (option) => option.available,
49
+ )
50
+ const focusIndex =
51
+ firstActiveOptionIndex === -1 ? 0 : firstActiveOptionIndex
52
+ focusElement(menuItemButtons.current[focusIndex])
53
53
  })
54
54
  }
55
55
  prevMenuIsOpen.current = menuIsOpen
@@ -159,7 +159,9 @@ const OptionsButton = () => {
159
159
  <div
160
160
  className={className('options__container')}
161
161
  onKeyDown={onMainKeyDownHandler}
162
+ // eslint-disable-next-line react/no-unknown-property
162
163
  onfocusout={onFocusOutHandler}
164
+ // eslint-disable-next-line react/no-unknown-property
163
165
  onfocusin={onFocusInHandler}
164
166
  >
165
167
  <InOutTransition
@@ -1,5 +1,5 @@
1
1
  import { useCallback, useMemo, useState } from 'preact/hooks'
2
- import { useI18n } from 'domains/i18n'
2
+ import { useI18n } from 'domains/i18n/hooks'
3
3
  import OptionsFrame from 'ui/components/options/options-frame'
4
4
  import { className } from 'lib/css'
5
5
  import {
@@ -9,7 +9,7 @@ import {
9
9
  useSeamlyOptions,
10
10
  } from 'ui/hooks/seamly-hooks'
11
11
  import { actionTypes } from 'ui/utils/seamly-utils'
12
- import { FormProvider } from 'domains/forms'
12
+ import FormProvider from 'domains/forms/provider'
13
13
  import { getValidator } from 'ui/utils/form-utils'
14
14
  import { isEmailString, isNotEmptyString } from 'ui/utils/validations'
15
15
  import TranscriptForm from './transcript-form'
@@ -1,5 +1,5 @@
1
1
  import { className } from 'lib/css'
2
- import { useI18n } from 'domains/i18n'
2
+ import { useI18n } from 'domains/i18n/hooks'
3
3
  import Form from 'ui/components/form-controls/form'
4
4
  import Input from 'ui/components/form-controls/input'
5
5
 
@@ -1,28 +1,31 @@
1
- import { useEffect, useRef, useCallback, useMemo } from 'preact/hooks'
2
- import { className } from '../../../lib/css'
3
- import { useI18n } from '../../../domains/i18n'
4
- import { useSeamlyServiceData } from '../../hooks/seamly-state-hooks'
5
- import { useTranslatedEventData } from '../../../domains/translations'
6
- import { useInterrupt } from '../../../domains/interrupt'
7
- import { useGeneratedId } from '../../hooks/utility-hooks'
8
- import useSeamlyIdleDetachCountdown from '../../hooks/use-seamly-idle-detach-countdown'
9
- import useSeamlyResumeConversationPrompt from '../../hooks/use-seamly-resume-conversation-prompt'
10
- import useSeamlyCommands from '../../hooks/use-seamly-commands'
11
- import { useSkiplinkTargetFocusing } from '../../hooks/focus-helper-hooks'
12
- import { actionTypes } from '../../utils/seamly-utils'
13
- import { useUserHasResponded } from '../../../domains/app'
14
- import { useVisibility, visibilityStates } from '../../../domains/visibility'
1
+ import { useUserHasResponded } from 'domains/app/hooks'
2
+ import { useI18n } from 'domains/i18n/hooks'
3
+ import { useInterrupt } from 'domains/interrupt/hooks'
4
+ import { useTranslatedEventData } from 'domains/translations/hooks'
5
+ import { visibilityStates } from 'domains/visibility/constants'
6
+ import { useVisibility } from 'domains/visibility/hooks'
7
+ import { className } from 'lib/css'
8
+ import { useCallback, useEffect, useMemo, useRef } from 'preact/hooks'
9
+ import SuggestionsList from 'ui/components/suggestions/suggestions-list'
15
10
  import InOutTransition, {
16
11
  transitionStartStates,
17
- } from '../widgets/in-out-transition'
18
- import { useLiveRegion } from '../../hooks/live-region-hooks'
19
- import { runIfElementContainsOrHasFocus } from '../../utils/general-utils'
20
- import SuggestionsList from './suggestions-list'
21
- import { useConfig } from '../../../domains/config'
12
+ } from 'ui/components/widgets/in-out-transition'
13
+ import { useSkiplinkTargetFocusing } from 'ui/hooks/focus-helper-hooks'
14
+ import { useLiveRegion } from 'ui/hooks/live-region-hooks'
15
+ import {
16
+ useSeamlyLayoutMode,
17
+ useSeamlyServiceData,
18
+ } from 'ui/hooks/seamly-state-hooks'
19
+ import useSeamlyCommands from 'ui/hooks/use-seamly-commands'
20
+ import useSeamlyIdleDetachCountdown from 'ui/hooks/use-seamly-idle-detach-countdown'
21
+ import useSeamlyResumeConversationPrompt from 'ui/hooks/use-seamly-resume-conversation-prompt'
22
+ import { useGeneratedId } from 'ui/hooks/utility-hooks'
23
+ import { runIfElementContainsOrHasFocus } from 'ui/utils/general-utils'
24
+ import { actionTypes } from 'ui/utils/seamly-utils'
22
25
 
23
- const Suggestions = ({ isAside }) => {
26
+ const Suggestions = ({ isAside = false }) => {
24
27
  // generic hooks
25
- const { layoutMode } = useConfig()
28
+ const { isInline } = useSeamlyLayoutMode()
26
29
  const { t } = useI18n()
27
30
  const { sendAction, addMessageBubble } = useSeamlyCommands()
28
31
  const { isOpen, setVisibility } = useVisibility()
@@ -36,7 +39,7 @@ const Suggestions = ({ isAside }) => {
36
39
  const { hasCountdown, endCountdown } = useSeamlyIdleDetachCountdown()
37
40
  const { hasPrompt, continueChat } = useSeamlyResumeConversationPrompt()
38
41
  // data hooks
39
- const hasResponded = useUserHasResponded()
42
+ const userHasResponded = useUserHasResponded()
40
43
  const payload = useSeamlyServiceData('suggestion')
41
44
  const [eventBody] = useTranslatedEventData({ payload })
42
45
  const suggestions = useMemo(
@@ -49,10 +52,9 @@ const Suggestions = ({ isAside }) => {
49
52
 
50
53
  const previousRenderedSuggestions = useRef([])
51
54
  const hasSuggestions = !!suggestions.length
52
- const hideSuggestions =
53
- layoutMode === 'inline'
54
- ? (hasResponded || isOpen) && !isAside
55
- : hasResponded
55
+ const hideSuggestions = isInline
56
+ ? (userHasResponded || isOpen) && !isAside
57
+ : userHasResponded
56
58
  const prevHideSuggestions = useRef(hideSuggestions)
57
59
  const showSuggestionsContainer = hasSuggestions && !hideSuggestions
58
60
  const renderedSuggestions = hasSuggestions
@@ -60,6 +62,16 @@ const Suggestions = ({ isAside }) => {
60
62
  : previousRenderedSuggestions.current
61
63
  previousRenderedSuggestions.current = renderedSuggestions
62
64
 
65
+ const suggestionsClassNames = useMemo(() => {
66
+ const classNames = ['suggestions']
67
+
68
+ if (isAside) {
69
+ classNames.push('suggestions--aside')
70
+ }
71
+
72
+ return className(classNames)
73
+ }, [isAside])
74
+
63
75
  // click handler
64
76
  const handleClick = useCallback(
65
77
  ({ id, question }) => {
@@ -147,7 +159,7 @@ const Suggestions = ({ isAside }) => {
147
159
  transitionStartState={transitionStartStates.notRendered}
148
160
  >
149
161
  <ContainerElement
150
- className={className('suggestions')}
162
+ className={suggestionsClassNames}
151
163
  aria-labelledby={headingText ? sectionId : null}
152
164
  ref={containerRef}
153
165
  >
@@ -1,4 +1,4 @@
1
- import { useVisibility, useShowInlineView } from 'domains/visibility'
1
+ import { useVisibility, useShowInlineView } from 'domains/visibility/hooks'
2
2
  import DeprecatedAppFrame from '../layout/deprecated-app-frame'
3
3
  import ChatFrame from '../layout/chat-frame'
4
4
  import AgentInfo from '../layout/agent-info'
@@ -9,27 +9,30 @@ import Interrupt from '../layout/interrupt'
9
9
  import { useSeamlyChat } from '../../hooks/seamly-hooks'
10
10
  import DeprecatedToggleButton from '../entry/deprecated-toggle-button'
11
11
 
12
+ const ShowInlineView = ({ children }) => {
13
+ const { showInlineView, containerRef } = useShowInlineView()
14
+
15
+ return <div ref={containerRef}>{showInlineView && children}</div>
16
+ }
17
+
12
18
  const DeprecatedView = () => {
13
19
  const { isVisible } = useVisibility()
14
20
  const { openChat, closeChat } = useSeamlyChat()
15
- const { showInlineView, containerRef } = useShowInlineView()
16
21
 
17
22
  return (
18
23
  isVisible && (
19
- <div ref={containerRef}>
20
- {showInlineView && (
21
- <DeprecatedAppFrame>
22
- <DeprecatedToggleButton onOpenChat={openChat} />
23
- <Header onCloseChat={closeChat}>
24
- <AgentInfo />
25
- </Header>
26
- <ChatFrame interruptComponent={Interrupt}>
27
- <Conversation />
28
- <EntryContainer />
29
- </ChatFrame>
30
- </DeprecatedAppFrame>
31
- )}
32
- </div>
24
+ <ShowInlineView>
25
+ <DeprecatedAppFrame>
26
+ <DeprecatedToggleButton onOpenChat={openChat} />
27
+ <Header onCloseChat={closeChat}>
28
+ <AgentInfo />
29
+ </Header>
30
+ <ChatFrame interruptComponent={Interrupt}>
31
+ <Conversation />
32
+ <EntryContainer />
33
+ </ChatFrame>
34
+ </DeprecatedAppFrame>
35
+ </ShowInlineView>
33
36
  )
34
37
  )
35
38
  }
@@ -1,14 +1,14 @@
1
+ import { useUserHasResponded } from 'domains/app/hooks'
1
2
  import { useCallback, useMemo } from 'preact/hooks'
2
- import { useConfig } from '../../../domains/config'
3
- import AppView from './app-view'
4
- import InlineView from './inline-view'
5
- import WindowView from './window-view'
6
- import { useVisibility } from '../../../domains/visibility'
7
- import { className } from '../../../lib/css'
8
- import { useSeamlyAppContainerClassNames } from '../../hooks/component-helper-hooks'
9
- import { useUserHasResponded } from '../../../domains/app'
10
- import { useI18n } from '../../../domains/i18n'
11
- import { useSeamlyContainerElement } from '../../hooks/focus-helper-hooks'
3
+ import { useVisibility } from 'domains/visibility/hooks'
4
+ import { useSeamlyContainerElement } from 'ui/hooks/focus-helper-hooks'
5
+ import { useConfig } from 'domains/config/hooks'
6
+ import { useSeamlyAppContainerClassNames } from 'ui/hooks/component-helper-hooks'
7
+ import { useI18n } from 'domains/i18n/hooks'
8
+ import AppView from 'ui/components/view/app-view'
9
+ import InlineView from 'ui/components/view/inline-view'
10
+ import WindowView from 'ui/components/view/window-view'
11
+ import { className } from 'lib/css'
12
12
 
13
13
  const ViewComponentsMap = {
14
14
  app: AppView,
@@ -21,7 +21,7 @@ const View = ({ children }) => {
21
21
  const { namespace, layoutMode, zIndex } = useConfig()
22
22
  const { isOpen, isVisible } = useVisibility()
23
23
  const appContainerClassNames = useSeamlyAppContainerClassNames()
24
- const userResponded = useUserHasResponded()
24
+ const userHasResponded = useUserHasResponded()
25
25
  const { locale } = useI18n()
26
26
  const ViewComponent = ViewComponentsMap[layoutMode]
27
27
 
@@ -60,7 +60,7 @@ const View = ({ children }) => {
60
60
  classNames.push('app--collapsed')
61
61
  }
62
62
 
63
- if (userResponded) {
63
+ if (userHasResponded) {
64
64
  classNames.push('app--user-responded')
65
65
  }
66
66
 
@@ -1,6 +1,6 @@
1
1
  import { className } from 'lib/css'
2
- import { useVisibility, useShowInlineView } from 'domains/visibility'
3
- import { useInterrupt } from 'domains/interrupt'
2
+ import { useVisibility, useShowInlineView } from 'domains/visibility/hooks'
3
+ import { useInterrupt } from 'domains/interrupt/hooks'
4
4
  import Chat from '../layout/chat'
5
5
  import Interrupt from '../layout/interrupt'
6
6
  import Conversation from '../conversation/conversation'