@seamly/web-ui 20.7.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 (222) hide show
  1. package/CHANGELOG.md +212 -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 +24806 -19703
  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 +32726 -26838
  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 +8649 -7863
  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/utils.js +1 -2
  19. package/build/dist/lib/utils.min.js +1 -1
  20. package/package.json +19 -9
  21. package/src/icons/avatar_agent-32.svg +7 -0
  22. package/src/icons/avatar_bot-32.svg +6 -1
  23. package/src/javascripts/api/index.js +1 -1
  24. package/src/javascripts/{config.js → config.ts} +3 -1
  25. package/src/javascripts/config.types.ts +95 -0
  26. package/src/javascripts/domains/app/actions.ts +83 -0
  27. package/src/javascripts/domains/app/app.types.ts +3 -0
  28. package/src/javascripts/domains/app/hooks.js +3 -5
  29. package/src/javascripts/domains/app/selectors.ts +6 -0
  30. package/src/javascripts/domains/app/slice.ts +30 -0
  31. package/src/javascripts/domains/config/actions.ts +45 -0
  32. package/src/javascripts/domains/config/hooks.ts +19 -0
  33. package/src/javascripts/domains/config/selectors.ts +24 -0
  34. package/src/javascripts/domains/config/slice.ts +111 -0
  35. package/src/javascripts/domains/errors/index.js +13 -9
  36. package/src/javascripts/domains/forms/context.ts +14 -0
  37. package/src/javascripts/domains/forms/forms.types.ts +24 -0
  38. package/src/javascripts/domains/forms/{hooks.js → hooks.ts} +23 -26
  39. package/src/javascripts/domains/forms/{provider.js → provider.tsx} +20 -14
  40. package/src/javascripts/domains/forms/{selectors.js → selectors.ts} +7 -8
  41. package/src/javascripts/domains/forms/slice.ts +84 -0
  42. package/src/javascripts/domains/forms/utils.ts +15 -0
  43. package/src/javascripts/domains/i18n/actions.ts +24 -0
  44. package/src/javascripts/domains/i18n/{hooks.js → hooks.ts} +2 -2
  45. package/src/javascripts/domains/i18n/i18n.types.ts +6 -0
  46. package/src/javascripts/domains/i18n/selectors.ts +16 -0
  47. package/src/javascripts/domains/i18n/{reducer.js → slice.ts} +43 -37
  48. package/src/javascripts/domains/interrupt/{hooks.js → hooks.ts} +2 -2
  49. package/src/javascripts/domains/interrupt/{middleware.js → middleware.ts} +11 -8
  50. package/src/javascripts/domains/interrupt/selectors.ts +6 -0
  51. package/src/javascripts/domains/interrupt/slice.ts +40 -0
  52. package/src/javascripts/domains/options/middleware.js +9 -6
  53. package/src/javascripts/domains/redux/redux.types.ts +11 -0
  54. package/src/javascripts/domains/store/index.ts +53 -0
  55. package/src/javascripts/domains/store/slice.ts +639 -0
  56. package/src/javascripts/domains/store/store.types.ts +135 -0
  57. package/src/javascripts/domains/translations/components/chat-status.js +2 -2
  58. package/src/javascripts/domains/translations/components/options-button.js +1 -1
  59. package/src/javascripts/domains/translations/components/options-dialog/form.js +5 -5
  60. package/src/javascripts/domains/translations/components/options-dialog/index.js +2 -2
  61. package/src/javascripts/domains/translations/{hooks.js → hooks.ts} +28 -23
  62. package/src/javascripts/domains/translations/middleware.js +29 -27
  63. package/src/javascripts/domains/translations/selectors.js +4 -9
  64. package/src/javascripts/domains/translations/slice.ts +67 -0
  65. package/src/javascripts/domains/translations/translations.types.ts +12 -0
  66. package/src/javascripts/domains/visibility/{actions.js → actions.ts} +25 -19
  67. package/src/javascripts/domains/visibility/{hooks.js → hooks.ts} +13 -10
  68. package/src/javascripts/domains/visibility/{selectors.js → selectors.ts} +3 -6
  69. package/src/javascripts/domains/visibility/slice.ts +38 -0
  70. package/src/javascripts/domains/visibility/utils.js +0 -9
  71. package/src/javascripts/domains/visibility/visibility.types.ts +6 -0
  72. package/src/javascripts/index.ts +92 -0
  73. package/src/javascripts/lib/engine/index.js +15 -11
  74. package/src/javascripts/lib/external-api/initialize-api.js +1 -1
  75. package/src/javascripts/lib/id.js +5 -8
  76. package/src/javascripts/lib/mutex.js +3 -1
  77. package/src/javascripts/lib/store/providers/cookie-storage.js +1 -1
  78. package/src/javascripts/lib/store/providers/session-storage.js +1 -1
  79. package/src/javascripts/package/hooks.js +2 -2
  80. package/src/javascripts/package/utils.js +0 -1
  81. package/src/javascripts/schema.ts +1455 -0
  82. package/src/javascripts/style-guide/components/app.js +4 -4
  83. package/src/javascripts/style-guide/components/static-core.js +87 -65
  84. package/src/javascripts/style-guide/components/view.js +4 -4
  85. package/src/javascripts/style-guide/state-helpers/index.js +5 -5
  86. package/src/javascripts/style-guide/states.js +6 -4
  87. package/src/javascripts/style-guide.ts +5 -0
  88. package/src/javascripts/ui/components/app-options/index.js +2 -4
  89. package/src/javascripts/ui/components/conversation/component-filter.js +1 -1
  90. package/src/javascripts/ui/components/conversation/conversation.js +5 -5
  91. package/src/javascripts/ui/components/conversation/event/card-message.js +1 -1
  92. package/src/javascripts/ui/components/conversation/event/carousel-component/components/controls.js +1 -1
  93. package/src/javascripts/ui/components/conversation/event/carousel-message/components/slide.js +1 -1
  94. package/src/javascripts/ui/components/conversation/event/carousel-message/index.js +1 -1
  95. package/src/javascripts/ui/components/conversation/event/choice-prompt.js +2 -2
  96. package/src/javascripts/ui/components/conversation/event/conversation-suggestions.js +11 -14
  97. package/src/javascripts/ui/components/conversation/event/cta.js +1 -1
  98. package/src/javascripts/ui/components/conversation/event/divider/variants/default.js +1 -1
  99. package/src/javascripts/ui/components/conversation/event/divider/variants/new-translation.js +5 -2
  100. package/src/javascripts/ui/components/conversation/event/event-participant.js +2 -2
  101. package/src/javascripts/ui/components/conversation/event/hooks/use-formatted-date.js +2 -2
  102. package/src/javascripts/ui/components/conversation/event/image-lightbox.js +1 -1
  103. package/src/javascripts/ui/components/conversation/event/image.js +5 -7
  104. package/src/javascripts/ui/components/conversation/event/participant.js +1 -1
  105. package/src/javascripts/ui/components/conversation/event/splash.js +3 -3
  106. package/src/javascripts/ui/components/conversation/event/text.js +1 -1
  107. package/src/javascripts/ui/components/conversation/event/translation.js +2 -2
  108. package/src/javascripts/ui/components/conversation/event/upload.js +2 -2
  109. package/src/javascripts/ui/components/conversation/event/video.js +1 -1
  110. package/src/javascripts/ui/components/conversation/message-container.js +4 -4
  111. package/src/javascripts/ui/components/core/seamly-api-context.js +1 -1
  112. package/src/javascripts/ui/components/core/seamly-core.js +15 -14
  113. package/src/javascripts/ui/components/core/seamly-event-subscriber.js +96 -91
  114. package/src/javascripts/ui/components/core/seamly-file-upload.js +20 -24
  115. package/src/javascripts/ui/components/core/seamly-initializer.js +1 -1
  116. package/src/javascripts/ui/components/core/seamly-instance-functions-loader.js +5 -4
  117. package/src/javascripts/ui/components/core/seamly-new-notifications.js +2 -2
  118. package/src/javascripts/ui/components/core/seamly-read-state.js +10 -17
  119. package/src/javascripts/ui/components/entry/deprecated-toggle-button.js +3 -3
  120. package/src/javascripts/ui/components/entry/entry-container.js +4 -6
  121. package/src/javascripts/ui/components/entry/text-entry/hooks.js +3 -3
  122. package/src/javascripts/ui/components/entry/text-entry/index.js +3 -2
  123. package/src/javascripts/ui/components/entry/text-entry/text-entry-form.js +6 -10
  124. package/src/javascripts/ui/components/entry/upload/file-upload-form.js +2 -2
  125. package/src/javascripts/ui/components/entry/upload/index.js +10 -9
  126. package/src/javascripts/ui/components/entry/upload-toggle.js +2 -2
  127. package/src/javascripts/ui/components/faq/faq.js +6 -6
  128. package/src/javascripts/ui/components/form-controls/file-input.js +1 -1
  129. package/src/javascripts/ui/components/form-controls/form.js +1 -1
  130. package/src/javascripts/ui/components/form-controls/input.js +1 -1
  131. package/src/javascripts/ui/components/form-controls/select.js +1 -1
  132. package/src/javascripts/ui/components/layout/agent-info.js +4 -4
  133. package/src/javascripts/ui/components/layout/chat-frame.js +3 -3
  134. package/src/javascripts/ui/components/layout/chat.js +11 -12
  135. package/src/javascripts/ui/components/layout/deprecated-app-frame.js +10 -9
  136. package/src/javascripts/ui/components/layout/header.js +1 -1
  137. package/src/javascripts/ui/components/layout/interrupt.js +23 -24
  138. package/src/javascripts/ui/components/layout/pre-chat-messages.js +11 -11
  139. package/src/javascripts/ui/components/layout/privacy-disclaimer.js +2 -2
  140. package/src/javascripts/ui/components/options/options-button.js +12 -10
  141. package/src/javascripts/ui/components/options/transcript/index.js +2 -2
  142. package/src/javascripts/ui/components/options/transcript/transcript-form.js +1 -1
  143. package/src/javascripts/ui/components/suggestions/index.js +9 -8
  144. package/src/javascripts/ui/components/view/deprecated-view.js +19 -16
  145. package/src/javascripts/ui/components/view/index.js +12 -12
  146. package/src/javascripts/ui/components/view/inline-view.js +2 -2
  147. package/src/javascripts/ui/components/view/window-view/collapse-button.js +3 -3
  148. package/src/javascripts/ui/components/view/window-view/index.js +13 -13
  149. package/src/javascripts/ui/components/view/window-view/window-open-button.js +13 -13
  150. package/src/javascripts/ui/components/warnings/idle-detach-warning.js +1 -1
  151. package/src/javascripts/ui/components/warnings/resume-conversation-prompt.js +1 -1
  152. package/src/javascripts/ui/components/widgets/lightbox.js +2 -2
  153. package/src/javascripts/ui/components/widgets/upload-progress.js +1 -1
  154. package/src/javascripts/ui/hooks/component-helper-hooks.js +1 -1
  155. package/src/javascripts/ui/hooks/file-upload-hooks.js +4 -6
  156. package/src/javascripts/ui/hooks/focus-helper-hooks.js +14 -12
  157. package/src/javascripts/ui/hooks/live-region-hooks.js +2 -0
  158. package/src/javascripts/ui/hooks/seamly-api-hooks.js +8 -3
  159. package/src/javascripts/ui/hooks/seamly-entry-hooks.js +28 -25
  160. package/src/javascripts/ui/hooks/seamly-hooks.js +25 -25
  161. package/src/javascripts/ui/hooks/seamly-option-hooks.js +17 -19
  162. package/src/javascripts/ui/hooks/seamly-state-hooks.js +14 -13
  163. package/src/javascripts/ui/hooks/use-seamly-chat.js +15 -25
  164. package/src/javascripts/ui/hooks/use-seamly-commands.js +46 -46
  165. package/src/javascripts/ui/hooks/use-seamly-idle-detach-countdown.js +22 -24
  166. package/src/javascripts/ui/hooks/use-seamly-resume-conversation-prompt.js +8 -9
  167. package/src/javascripts/ui/hooks/use-single-file-upload.js +4 -6
  168. package/src/javascripts/ui/hooks/utility-hooks.js +4 -4
  169. package/src/javascripts/ui/utils/form-utils.js +0 -145
  170. package/src/javascripts/ui/utils/general-utils.js +3 -4
  171. package/src/javascripts/ui/utils/seamly-utils.ts +73 -0
  172. package/webpack/config.common.js +16 -0
  173. package/webpack/config.dev.js +1 -0
  174. package/webpack/config.package.js +26 -5
  175. package/webpack/defaults.js +7 -2
  176. package/webpack/parts/babel-loader-browser-plugins.js +1 -0
  177. package/webpack/parts/dev-server.js +4 -3
  178. package/src/javascripts/domains/app/actions.js +0 -112
  179. package/src/javascripts/domains/app/index.js +0 -7
  180. package/src/javascripts/domains/app/reducer.js +0 -16
  181. package/src/javascripts/domains/app/selectors.js +0 -8
  182. package/src/javascripts/domains/app/utils.js +0 -4
  183. package/src/javascripts/domains/config/actions.js +0 -7
  184. package/src/javascripts/domains/config/hooks.js +0 -23
  185. package/src/javascripts/domains/config/index.js +0 -7
  186. package/src/javascripts/domains/config/reducer.js +0 -79
  187. package/src/javascripts/domains/config/selectors.js +0 -23
  188. package/src/javascripts/domains/config/utils.js +0 -4
  189. package/src/javascripts/domains/forms/actions.js +0 -21
  190. package/src/javascripts/domains/forms/context.js +0 -6
  191. package/src/javascripts/domains/forms/index.js +0 -8
  192. package/src/javascripts/domains/forms/reducer.js +0 -84
  193. package/src/javascripts/domains/forms/utils.js +0 -20
  194. package/src/javascripts/domains/i18n/actions.js +0 -20
  195. package/src/javascripts/domains/i18n/index.js +0 -7
  196. package/src/javascripts/domains/i18n/selectors.js +0 -15
  197. package/src/javascripts/domains/i18n/utils.js +0 -4
  198. package/src/javascripts/domains/interrupt/actions.js +0 -4
  199. package/src/javascripts/domains/interrupt/index.js +0 -9
  200. package/src/javascripts/domains/interrupt/reducer.js +0 -22
  201. package/src/javascripts/domains/interrupt/selectors.js +0 -6
  202. package/src/javascripts/domains/interrupt/utils.js +0 -4
  203. package/src/javascripts/domains/options/index.js +0 -1
  204. package/src/javascripts/domains/redux/context.js +0 -6
  205. package/src/javascripts/domains/redux/create-redux-store.js +0 -21
  206. package/src/javascripts/domains/redux/hooks.js +0 -80
  207. package/src/javascripts/domains/redux/index.js +0 -19
  208. package/src/javascripts/domains/redux/provider.js +0 -5
  209. package/src/javascripts/domains/redux/utils.js +0 -12
  210. package/src/javascripts/domains/store/index.js +0 -46
  211. package/src/javascripts/domains/store/state-reducer.js +0 -56
  212. package/src/javascripts/domains/translations/actions.js +0 -11
  213. package/src/javascripts/domains/translations/index.js +0 -10
  214. package/src/javascripts/domains/translations/reducer.js +0 -69
  215. package/src/javascripts/domains/translations/utils.js +0 -4
  216. package/src/javascripts/domains/visibility/index.js +0 -8
  217. package/src/javascripts/domains/visibility/reducer.js +0 -24
  218. package/src/javascripts/index.js +0 -153
  219. package/src/javascripts/lib/redux-helpers/index.js +0 -99
  220. package/src/javascripts/style-guide.js +0 -5
  221. package/src/javascripts/ui/hooks/use-seamly-dispatch.js +0 -3
  222. package/src/javascripts/ui/utils/seamly-utils.js +0 -832
@@ -1,30 +1,30 @@
1
- import { useCallback, useContext } from 'preact/hooks'
2
- import { SeamlyEventBusContext } from 'ui/components/core/seamly-api-context'
3
- import { randomId } from 'lib/id'
4
1
  import { userParticipantId } from 'config'
5
- import { actionTypes, seamlyActions } from 'ui/utils/seamly-utils'
6
- import { Actions as InterruptActions } from 'domains/interrupt'
7
- import { useConfig } from 'domains/config'
8
- import * as AppActions from 'domains/app/actions'
9
2
  import { useUserHasResponded } from 'domains/app/hooks'
10
- import { useVisibility, visibilityStates } from 'domains/visibility'
11
- import { useStableCallback } from './utility-hooks'
12
- import useSeamlyDispatchContext from './use-seamly-dispatch'
13
- import { useSeamlyUnreadCount } from './seamly-state-hooks'
3
+ import * as AppActions from 'domains/app/actions'
4
+ import { setHasResponded } from 'domains/app/slice'
5
+ import { useConfig } from 'domains/config/hooks'
6
+ import { setInterrupt } from 'domains/interrupt/slice'
7
+ import { addEvent, setInitialState } from 'domains/store/slice'
8
+ import { visibilityStates } from 'domains/visibility/constants'
9
+ import { useVisibility } from 'domains/visibility/hooks'
10
+
11
+ import { randomId } from 'lib/id'
12
+ import { useCallback, useContext } from 'preact/hooks'
13
+ import { useDispatch } from 'react-redux'
14
+ import { SeamlyEventBusContext } from 'ui/components/core/seamly-api-context'
15
+ import { actionTypes } from 'ui/utils/seamly-utils'
14
16
  import {
15
17
  useSeamlyApiContext,
16
18
  useSeamlyHasConversation,
17
19
  } from './seamly-api-hooks'
18
-
19
- const { ADD_EVENT, SET_INITIAL_STATE } = seamlyActions
20
+ import { useSeamlyUnreadCount } from './seamly-state-hooks'
20
21
 
21
22
  const useSeamlyCommands = () => {
22
23
  const api = useSeamlyApiContext()
23
24
  const appConfig = useConfig()
24
- const dispatch = useSeamlyDispatchContext()
25
+ const dispatch = useDispatch()
25
26
  const eventBus = useContext(SeamlyEventBusContext)
26
-
27
- const hasResponded = useUserHasResponded()
27
+ const userHasResponded = useUserHasResponded()
28
28
  const hasConversation = useSeamlyHasConversation()
29
29
  const { visible: visibility, setVisibility } = useVisibility()
30
30
  const unreadMessageCount = useSeamlyUnreadCount()
@@ -36,34 +36,34 @@ const useSeamlyCommands = () => {
36
36
  [eventBus],
37
37
  )
38
38
 
39
- const start = useStableCallback(() => {
39
+ const start = useCallback(() => {
40
40
  api.sendContext(appConfig.context || {})
41
41
  emitEvent('ui.beforeStart', {
42
42
  visibility,
43
- hasConversation,
44
- hasResponded,
43
+ hasConversation: hasConversation(),
44
+ hasResponded: userHasResponded,
45
45
  unreadMessageCount,
46
46
  })
47
47
 
48
48
  api.send('start')
49
49
  emitEvent('ui.start', {
50
50
  visibility,
51
- hasConversation,
52
- hasResponded,
51
+ hasConversation: hasConversation(),
52
+ hasResponded: userHasResponded,
53
53
  unreadMessageCount,
54
54
  })
55
55
  }, [
56
56
  api,
57
- appConfig,
57
+ appConfig.context,
58
58
  emitEvent,
59
- hasResponded,
60
59
  hasConversation,
61
- visibility,
60
+ userHasResponded,
62
61
  unreadMessageCount,
62
+ visibility,
63
63
  ])
64
64
 
65
65
  const reset = useCallback(async () => {
66
- dispatch(AppActions.reset())
66
+ dispatch(AppActions.resetApp())
67
67
  }, [dispatch])
68
68
 
69
69
  const getMessageBase = useCallback(
@@ -106,35 +106,30 @@ const useSeamlyCommands = () => {
106
106
 
107
107
  api.send('message', message)
108
108
  emitEvent('message', message)
109
- dispatch({
110
- type: ADD_EVENT,
111
- event: {
109
+ dispatch(
110
+ addEvent({
112
111
  type: 'message',
113
112
  payload: {
114
113
  ...message,
115
114
  optimisticallyInjected: true,
116
115
  },
117
- },
118
- })
116
+ }),
117
+ )
119
118
  },
120
119
  [api, dispatch, emitEvent, getTextMessageBase],
121
120
  )
122
121
 
123
122
  const addMessageBubble = useCallback(
124
123
  (text) => {
125
- dispatch({
126
- type: ADD_EVENT,
127
- event: { type: 'message', payload: getTextMessageBase(text) },
128
- })
124
+ dispatch(addEvent({ type: 'message', payload: getTextMessageBase(text) }))
129
125
  },
130
126
  [dispatch, getTextMessageBase],
131
127
  )
132
128
 
133
129
  const addUploadBubble = useCallback(
134
130
  (id, transactionId, occurredAt, contentType, filename, filesize, url) => {
135
- dispatch({
136
- type: ADD_EVENT,
137
- event: {
131
+ dispatch(
132
+ addEvent({
138
133
  type: 'message',
139
134
  payload: {
140
135
  type: 'upload',
@@ -146,8 +141,8 @@ const useSeamlyCommands = () => {
146
141
  meta: {},
147
142
  body: { contentType, filename, filesize, url },
148
143
  },
149
- },
150
- })
144
+ }),
145
+ )
151
146
  },
152
147
  [dispatch],
153
148
  )
@@ -163,10 +158,7 @@ const useSeamlyCommands = () => {
163
158
  type: 'divider',
164
159
  }
165
160
 
166
- dispatch({
167
- type: ADD_EVENT,
168
- event: { type: 'info', payload },
169
- })
161
+ dispatch(addEvent({ type: 'info', payload }))
170
162
  },
171
163
  [dispatch],
172
164
  )
@@ -203,15 +195,23 @@ const useSeamlyCommands = () => {
203
195
  .connect()
204
196
  .then((initialState) => {
205
197
  if (initialState) {
206
- dispatch({ type: SET_INITIAL_STATE, initialState })
198
+ dispatch(setInitialState(initialState))
207
199
  if (initialState.userResponded) {
208
- dispatch(AppActions.setHasResponded(initialState.userResponded))
200
+ dispatch(setHasResponded(initialState.userResponded))
209
201
  setVisibility(visibilityStates.open)
210
202
  }
211
203
  }
212
204
  })
213
205
  .catch((error) => {
214
- dispatch(InterruptActions.set(error))
206
+ dispatch(
207
+ setInterrupt({
208
+ name: error.name,
209
+ message: error.message,
210
+ langKey: error.langKey,
211
+ originalEvent: error.originalEvent,
212
+ originalError: error.originalError,
213
+ }),
214
+ )
215
215
  })
216
216
  }, [api, dispatch, setVisibility])
217
217
 
@@ -1,26 +1,25 @@
1
+ import { screenReaderDebounceDelaySeconds } from 'config'
2
+ import { useI18n } from 'domains/i18n/hooks'
3
+ import { useVisibility } from 'domains/visibility/hooks'
4
+ import {
5
+ clearIdleDetachCountdown,
6
+ decrementIdleDetachCountdownCounter,
7
+ initIdleDetachCountdown,
8
+ stopIdleDetachCountdownCounter,
9
+ } from 'domains/store/slice'
1
10
  import { useCallback, useRef } from 'preact/hooks'
2
- import { useI18n } from 'domains/i18n'
11
+ import { useDispatch } from 'react-redux'
3
12
  import {
4
13
  getTimeFromSeconds,
5
14
  millisecondsToSeconds,
6
15
  } from 'ui/utils/general-utils'
7
- import { actionTypes, seamlyActions } from 'ui/utils/seamly-utils'
8
- import { screenReaderDebounceDelaySeconds } from 'config'
9
- import { useVisibility } from 'domains/visibility'
16
+ import { actionTypes } from 'ui/utils/seamly-utils'
10
17
  import { useLiveRegion } from './live-region-hooks'
11
- import useSeamlyCommands from './use-seamly-commands'
12
18
  import { useSeamlyStateContext } from './seamly-state-hooks'
13
- import useSeamlyDispatchContext from './use-seamly-dispatch'
14
-
15
- const {
16
- CLEAR_IDLE_DETACH_COUNTDOWN,
17
- INIT_IDLE_DETACH_COUNTDOWN,
18
- DECREMENT_IDLE_DETACH_COUNTDOWN_COUNTER,
19
- STOP_IDLE_DETACH_COUNTDOWN_COUNTER,
20
- } = seamlyActions
19
+ import useSeamlyCommands from './use-seamly-commands'
21
20
 
22
21
  const useSeamlyIdleDetachCountdown = () => {
23
- const dispatch = useSeamlyDispatchContext()
22
+ const dispatch = useDispatch()
24
23
 
25
24
  const { idleDetachCountdown } = useSeamlyStateContext()
26
25
 
@@ -65,11 +64,12 @@ const useSeamlyIdleDetachCountdown = () => {
65
64
  const delaySeconds = millisecondsToSeconds(milliseconds)
66
65
  const delayTime = getTimeFromSeconds(delaySeconds)
67
66
 
68
- dispatch({
69
- type: INIT_IDLE_DETACH_COUNTDOWN,
70
- delaySeconds,
71
- delayTime,
72
- })
67
+ dispatch(
68
+ initIdleDetachCountdown({
69
+ delaySeconds,
70
+ delayTime,
71
+ }),
72
+ )
73
73
  emitEvent('idleTimer.start')
74
74
  sendAssertiveIfOpen(
75
75
  `${t('idleDetachWarning.countdownTitle')} ${t(
@@ -98,7 +98,7 @@ const useSeamlyIdleDetachCountdown = () => {
98
98
  emitEvent('idleTimer.stop')
99
99
  }
100
100
 
101
- dispatch({ type: CLEAR_IDLE_DETACH_COUNTDOWN })
101
+ dispatch(clearIdleDetachCountdown())
102
102
  },
103
103
  [dispatch, sendAction, emitEvent, sendAssertiveIfOpen, t],
104
104
  )
@@ -120,9 +120,7 @@ const useSeamlyIdleDetachCountdown = () => {
120
120
  )
121
121
  }
122
122
 
123
- dispatch({
124
- type: DECREMENT_IDLE_DETACH_COUNTDOWN_COUNTER,
125
- })
123
+ dispatch(decrementIdleDetachCountdownCounter())
126
124
  }, [dispatch, sendAssertiveIfOpen, t])
127
125
 
128
126
  const stopCountdown = useCallback(() => {
@@ -131,7 +129,7 @@ const useSeamlyIdleDetachCountdown = () => {
131
129
  return
132
130
  }
133
131
 
134
- dispatch({ type: STOP_IDLE_DETACH_COUNTDOWN_COUNTER })
132
+ dispatch(stopIdleDetachCountdownCounter())
135
133
 
136
134
  if (remaining) {
137
135
  emitEvent('idleTimer.stop')
@@ -1,14 +1,13 @@
1
- import { useI18n } from 'domains/i18n'
2
- import { actionTypes, dismissTypes, seamlyActions } from 'ui/utils/seamly-utils'
3
- import useSeamlyDispatchContext from './use-seamly-dispatch'
1
+ import { useI18n } from 'domains/i18n/hooks'
2
+ import { clearResumeConversationPrompt } from 'domains/store/slice'
3
+ import { useDispatch } from 'react-redux'
4
+ import { actionTypes, dismissTypes } from 'ui/utils/seamly-utils'
5
+ import { useLiveRegion } from './live-region-hooks'
4
6
  import { useSeamlyStateContext } from './seamly-state-hooks'
5
7
  import useSeamlyCommands from './use-seamly-commands'
6
- import { useLiveRegion } from './live-region-hooks'
7
-
8
- const { CLEAR_RESUME_CONVERSATION_PROMPT } = seamlyActions
9
8
 
10
9
  const useSeamlyResumeConversationPrompt = () => {
11
- const dispatch = useSeamlyDispatchContext()
10
+ const dispatch = useDispatch()
12
11
  const hasPrompt = useSeamlyStateContext().resumeConversationPrompt
13
12
  const { sendAction } = useSeamlyCommands()
14
13
  const { t } = useI18n()
@@ -19,13 +18,13 @@ const useSeamlyResumeConversationPrompt = () => {
19
18
  type: actionTypes.dismiss,
20
19
  body: { type: dismissTypes.resumeConversationPrompt },
21
20
  })
22
- dispatch({ type: CLEAR_RESUME_CONVERSATION_PROMPT })
21
+ dispatch(clearResumeConversationPrompt())
23
22
  }
24
23
 
25
24
  const restartChat = () => {
26
25
  sendAssertive(t('resumeConversationPrompt.srNotifyRestartText'))
27
26
  sendAction({ type: actionTypes.detachService })
28
- dispatch({ type: CLEAR_RESUME_CONVERSATION_PROMPT })
27
+ dispatch(clearResumeConversationPrompt())
29
28
  }
30
29
 
31
30
  return { continueChat, hasPrompt, restartChat }
@@ -1,12 +1,10 @@
1
- import { Selectors } from 'domains/forms'
2
- import { useSelectorWithProps } from 'domains/redux'
1
+ import { getControlValueByName } from 'domains/forms/selectors'
2
+ import { useSelector } from 'react-redux'
3
3
  import { useFileUploads } from './seamly-hooks'
4
4
 
5
5
  const useSingleFileUpload = (formId, name) => {
6
- const fileList = useSelectorWithProps(
7
- Selectors.getControlValueByName,
8
- { formId, name },
9
- [formId, name],
6
+ const fileList = useSelector((store) =>
7
+ getControlValueByName(store, { formId, name }),
10
8
  )
11
9
  // This hook acts as a helper as the data model is built to handle multiple
12
10
  // file uploads but currently Seamly only supports single file uploads.
@@ -1,17 +1,17 @@
1
+ import { randomId } from 'lib/id'
1
2
  import {
2
3
  useCallback,
4
+ useMemo,
3
5
  useReducer,
4
6
  useRef,
5
7
  useState,
6
- useMemo,
7
8
  } from 'preact/hooks'
8
- import { randomId } from 'lib/id'
9
9
 
10
10
  export const useForceUpdate = () => {
11
11
  // This is an escape hatch mentioned in the React docs:
12
12
  // https://reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate
13
13
  /* eslint-disable-next-line no-unused-vars */
14
- const [ignored, forceUpdate] = useReducer((x) => x + 1, 0)
14
+ const [_, forceUpdate] = useReducer((x) => x + 1, 0)
15
15
 
16
16
  return useCallback(() => {
17
17
  setTimeout(() => {
@@ -26,7 +26,7 @@ export const useGeneratedId = () => {
26
26
  }
27
27
 
28
28
  export const useStableCallback = (callback) => {
29
- const callbackRef = useRef()
29
+ const callbackRef = useRef(null)
30
30
  callbackRef.current = callback
31
31
  const isFunction = typeof callback === 'function'
32
32
  return useMemo(() => {
@@ -1,150 +1,5 @@
1
- export const formActions = {
2
- REGISTER_FORM: 'REGISTER_FORM',
3
- DE_REGISTER_FORM: 'DE_REGISTER_FORM',
4
- REGISTER: 'REGISTER',
5
- DE_REGISTER: 'DEREGISTER',
6
- SET_VALUE: 'SET_VALUE',
7
- SET_VALIDITY: 'SET_VALIDITY',
8
- SET_STATE: 'SET_STATE',
9
- SET_SUBMITTED: 'SET_SUBMITTED',
10
- SET_PERSIST_FORM_DATA: 'SET_PERSIST_FORM_DATA',
11
- }
12
-
13
- const {
14
- REGISTER_FORM,
15
- DE_REGISTER_FORM,
16
- REGISTER,
17
- DE_REGISTER,
18
- SET_VALUE,
19
- SET_VALIDITY,
20
- SET_STATE,
21
- SET_SUBMITTED,
22
- SET_PERSIST_FORM_DATA,
23
- } = formActions
24
-
25
1
  export const getValidator = (fn, errorText, compareValue = null) => ({
26
2
  fn,
27
3
  errorText,
28
4
  compareValue,
29
5
  })
30
-
31
- export const formReducer = (state, action) => {
32
- const {
33
- formId,
34
- name,
35
- controlId,
36
- value,
37
- data,
38
- validity,
39
- errorText,
40
- hasSubmitted,
41
- persistData,
42
- } = action
43
-
44
- const setControls = (controls) => ({
45
- ...state,
46
- [formId]: {
47
- ...state[formId],
48
- controls: {
49
- ...state[formId].controls,
50
- ...controls,
51
- },
52
- },
53
- })
54
-
55
- switch (action.type) {
56
- case REGISTER_FORM:
57
- return {
58
- [formId]: {
59
- controls: {},
60
- validity: true,
61
- hasSubmitted: false,
62
- persistData: false,
63
- },
64
- ...state,
65
- }
66
- case DE_REGISTER_FORM:
67
- const removedFormState = { ...state }
68
- delete removedFormState[formId]
69
- return removedFormState
70
- case REGISTER:
71
- const {
72
- value: existingValue,
73
- validity: existingValidity,
74
- errorText: existingErrorText,
75
- } = state[formId].controls[name] || {}
76
-
77
- return setControls({
78
- [name]: {
79
- controlId,
80
- value: existingValue || value,
81
- validity: existingValidity !== false,
82
- errorText: existingErrorText || '',
83
- },
84
- })
85
- case DE_REGISTER:
86
- const relatedForm = state[formId]
87
- if (!relatedForm) {
88
- return state
89
- }
90
- const newControls = { ...relatedForm.controls }
91
- delete newControls[action.name]
92
- return { ...state, [formId]: { ...relatedForm, controls: newControls } }
93
- case SET_VALUE:
94
- return setControls({
95
- [name]: {
96
- ...state[formId].controls[name],
97
- value,
98
- },
99
- })
100
- case SET_VALIDITY:
101
- const newControlValidities = {
102
- ...state[formId].controls,
103
- [name]: {
104
- ...state[formId].controls[name],
105
- validity,
106
- errorText,
107
- },
108
- }
109
- return {
110
- ...state,
111
- [formId]: {
112
- ...state[formId],
113
- controls: newControlValidities,
114
- validity: Object.keys(newControlValidities)
115
- .map((key) => newControlValidities[key].validity)
116
- .every((v) => v),
117
- },
118
- }
119
- case SET_STATE:
120
- return {
121
- ...state,
122
- [formId]: {
123
- ...state[formId],
124
- controls: Object.keys(data).reduce(
125
- (acc, key) => {
126
- return {
127
- ...acc,
128
- [key]: {
129
- ...state[formId].controls[key],
130
- value: data[key],
131
- validity: true,
132
- errorText: '',
133
- },
134
- }
135
- },
136
- { ...state.controls },
137
- ),
138
- },
139
- }
140
- case SET_SUBMITTED:
141
- return { ...state, [formId]: { ...state[formId], hasSubmitted } }
142
- case SET_PERSIST_FORM_DATA:
143
- return {
144
- ...state,
145
- [formId]: { ...state[formId], persistData },
146
- }
147
- default:
148
- return state
149
- }
150
- }
@@ -1,13 +1,12 @@
1
1
  export const debounce = (func, wait) => {
2
2
  let timeout
3
3
  return function (...args) {
4
- const context = this
5
4
  let isCancelled = false
6
5
  clearTimeout(timeout)
7
6
  timeout = setTimeout(() => {
8
7
  timeout = null
9
8
  if (!isCancelled) {
10
- func.apply(context, args)
9
+ func.apply(this, args)
11
10
  }
12
11
  isCancelled = false
13
12
  }, wait)
@@ -15,7 +14,7 @@ export const debounce = (func, wait) => {
15
14
  return (runInstant) => {
16
15
  isCancelled = true
17
16
  if (runInstant) {
18
- func.apply(context, args)
17
+ func.apply(this, args)
19
18
  }
20
19
  }
21
20
  }
@@ -103,7 +102,7 @@ export const formatBytes = (bytes, decimals = 2) => {
103
102
 
104
103
  const i = Math.floor(Math.log(bytes) / Math.log(k))
105
104
 
106
- return parseFloat((bytes / k ** i).toFixed(dm)) + ' ' + sizes[i]
105
+ return `${parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`
107
106
  }
108
107
 
109
108
  export const getUrlParams = () => {
@@ -0,0 +1,73 @@
1
+ export const eventTypes = {
2
+ info: 'info',
3
+ message: 'message',
4
+ participant: 'participant',
5
+ system: 'system',
6
+ } as const
7
+
8
+ export const payloadTypes = {
9
+ choicePrompt: 'choice_prompt',
10
+ text: 'text',
11
+ image: 'image',
12
+ video: 'video',
13
+ participant: 'participant',
14
+ divider: 'divider',
15
+ translation: 'translation',
16
+ message: 'message',
17
+ countdown: 'countdown',
18
+ upload: 'upload',
19
+ cta: 'cta',
20
+ splash: 'splash',
21
+ }
22
+
23
+ export const entryTypes = {
24
+ text: 'text',
25
+ upload: 'upload',
26
+ }
27
+
28
+ export const readStates = {
29
+ received: 'received',
30
+ read: 'read',
31
+ }
32
+
33
+ export const actionTypes = {
34
+ pickChoice: 'pick_choice',
35
+ navigate: 'navigate',
36
+ custom: 'custom',
37
+ typing: 'typing',
38
+ read: 'read',
39
+ detachService: 'detach_service',
40
+ interactivityUpdate: 'interactivity_update',
41
+ dismiss: 'dismiss',
42
+ sendTranscript: 'send_transcript',
43
+ setTopic: 'set_topic',
44
+ setTranslation: 'set_translation',
45
+ clickCta: 'click_cta',
46
+ clickCard: 'click_card',
47
+ }
48
+
49
+ export const dismissTypes = {
50
+ resumeConversationPrompt: 'resume_conversation_prompt',
51
+ }
52
+
53
+ export const ariaLiveLevels = {
54
+ assertive: 'assertive',
55
+ polite: 'polite',
56
+ }
57
+
58
+ export const dividerKeys = {
59
+ new_topic: 'newTopic',
60
+ new_translation: 'newTranslation',
61
+ }
62
+
63
+ export const featureKeys = {
64
+ sendTranscript: 'sendTranscript',
65
+ typingPeekahead: 'typingPeekahead',
66
+ uploads: 'uploads',
67
+ }
68
+
69
+ export const cardTypes = {
70
+ ask: 'ask',
71
+ navigate: 'navigate',
72
+ topic: 'topic',
73
+ }
@@ -51,6 +51,7 @@ module.exports = (env = {}, argv = {}, configOverrides = {}) => {
51
51
  publicPath: PUBLIC_PATH,
52
52
  },
53
53
  resolve: {
54
+ extensions: ['.js', '.ts', '.tsx'],
54
55
  modules: [path.resolve(__dirname, '../src/javascripts'), 'node_modules'],
55
56
  alias: {
56
57
  ...ALIASSES,
@@ -116,6 +117,21 @@ module.exports = (env = {}, argv = {}, configOverrides = {}) => {
116
117
  exclude: /(doc-site[\\\/]+|node_modules|bower_components)/,
117
118
  use: ['style-loader', ...site.scssLoaders({ browsers: BROWSERS })],
118
119
  },
120
+ {
121
+ test: /\.tsx?$/,
122
+ loader: 'ts-loader',
123
+ exclude: /node_modules|\.d\.ts$/,
124
+ options: {
125
+ compilerOptions: {
126
+ outDir: 'build',
127
+ noEmit: false,
128
+ },
129
+ },
130
+ },
131
+ {
132
+ test: /\.d\.ts$/,
133
+ loader: 'ignore-loader',
134
+ },
119
135
  ],
120
136
  },
121
137
  }
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-var-requires */
1
2
  const webpackMerge = require('webpack-merge').merge
2
3
  const site = require('@seamly/doc-site/lib/config/site')
3
4
  const defaultConfig = require('./defaults')