@seamly/web-ui 20.7.0 → 20.8.0-beta.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 (226) hide show
  1. package/build/dist/lib/hooks.js +1 -1
  2. package/build/dist/lib/hooks.min.js +1 -1
  3. package/build/dist/lib/index.debug.js +945 -790
  4. package/build/dist/lib/index.debug.min.js +1 -1
  5. package/build/dist/lib/index.debug.min.js.LICENSE.txt +187 -131
  6. package/build/dist/lib/index.js +24800 -19606
  7. package/build/dist/lib/index.min.js +1 -1
  8. package/build/dist/lib/index.min.js.LICENSE.txt +38 -4
  9. package/build/dist/lib/standalone.js +32920 -26742
  10. package/build/dist/lib/standalone.min.js +1 -1
  11. package/build/dist/lib/standalone.min.js.LICENSE.txt +39 -0
  12. package/build/dist/lib/storage.js +2 -2
  13. package/build/dist/lib/storage.min.js +1 -1
  14. package/build/dist/lib/style-guide.js +8780 -7907
  15. package/build/dist/lib/style-guide.min.js +2 -1
  16. package/build/dist/lib/style-guide.min.js.LICENSE.txt +38 -0
  17. package/build/dist/lib/styles.css +1 -1
  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 +96 -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 +113 -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} +40 -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 +642 -0
  56. package/src/javascripts/domains/store/store.types.ts +146 -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.ts +114 -0
  62. package/src/javascripts/domains/translations/middleware.js +29 -27
  63. package/src/javascripts/domains/translations/selectors.ts +12 -0
  64. package/src/javascripts/domains/translations/slice.ts +120 -0
  65. package/src/javascripts/domains/translations/translations.types.ts +19 -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 +1448 -0
  82. package/src/javascripts/style-guide/components/app.js +6 -6
  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 +67 -7
  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 +11 -7
  91. package/src/javascripts/ui/components/conversation/event/card-message.js +2 -2
  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 +2 -2
  95. package/src/javascripts/ui/components/conversation/event/choice-prompt.js +3 -3
  96. package/src/javascripts/ui/components/conversation/event/conversation-suggestions.js +19 -15
  97. package/src/javascripts/ui/components/conversation/event/cta.js +2 -2
  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 +44 -5
  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 +6 -8
  104. package/src/javascripts/ui/components/conversation/event/participant.js +2 -2
  105. package/src/javascripts/ui/components/conversation/event/splash.js +4 -4
  106. package/src/javascripts/ui/components/conversation/event/text.js +2 -2
  107. package/src/javascripts/ui/components/conversation/event/translation.js +3 -3
  108. package/src/javascripts/ui/components/conversation/event/upload.js +3 -3
  109. package/src/javascripts/ui/components/conversation/event/video.js +2 -2
  110. package/src/javascripts/ui/components/conversation/message-container.js +4 -26
  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 +98 -92
  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 +9 -7
  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 +14 -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 +14 -10
  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 +20 -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/src/stylesheets/5-components/_message-carousel.scss +10 -8
  173. package/webpack/config.common.js +16 -0
  174. package/webpack/config.dev.js +1 -0
  175. package/webpack/config.package.js +26 -5
  176. package/webpack/defaults.js +7 -2
  177. package/webpack/parts/babel-loader-browser-plugins.js +1 -0
  178. package/webpack/parts/dev-server.js +4 -3
  179. package/CHANGELOG.md +0 -791
  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/hooks.js +0 -103
  216. package/src/javascripts/domains/translations/index.js +0 -10
  217. package/src/javascripts/domains/translations/reducer.js +0 -69
  218. package/src/javascripts/domains/translations/selectors.js +0 -16
  219. package/src/javascripts/domains/translations/utils.js +0 -4
  220. package/src/javascripts/domains/visibility/index.js +0 -8
  221. package/src/javascripts/domains/visibility/reducer.js +0 -24
  222. package/src/javascripts/index.js +0 -153
  223. package/src/javascripts/lib/redux-helpers/index.js +0 -99
  224. package/src/javascripts/style-guide.js +0 -5
  225. package/src/javascripts/ui/hooks/use-seamly-dispatch.js +0 -3
  226. package/src/javascripts/ui/utils/seamly-utils.js +0 -832
@@ -1,8 +1,8 @@
1
- import { useCallback, useEffect, useState } from 'preact/hooks'
2
1
  import { getUrlParams, getUrlSearchString, randomId } from '@seamly/web-ui'
3
- import { getStateObj, getDeprecatedStateObj } from 'style-guide/states'
4
- import StyleGuideView from './view'
5
- import StyleGuideLinks from './links'
2
+ import { useCallback, useEffect, useState } from 'preact/hooks'
3
+ import StyleGuideLinks from 'style-guide/components/links'
4
+ import StyleGuideView from 'style-guide/components/view'
5
+ import { getDeprecatedStateObj, getStateObj } from 'style-guide/states'
6
6
 
7
7
  const StyleGuideApp = ({
8
8
  config,
@@ -50,8 +50,7 @@ const StyleGuideApp = ({
50
50
  const { headingText } = mainState[feature]
51
51
  setSelectedStateDescription(headingText)
52
52
  const bareState = mainState[feature][layoutMode]
53
- const { overrideMessages, showFaq } = bareState.config
54
-
53
+ const { overrideMessages, showFaq, showSuggestions } = bareState.config
55
54
  const agent = participants.find(
56
55
  (participant) => participant.id === 'agent',
57
56
  )
@@ -66,6 +65,7 @@ const StyleGuideApp = ({
66
65
  layoutMode: bareState.config.layoutMode,
67
66
  ...(overrideMessages ? { messages: overrideMessages } : {}),
68
67
  showFaq,
68
+ showSuggestions,
69
69
  },
70
70
  headerTitles: {
71
71
  ...bareState.headerTitles,
@@ -1,101 +1,123 @@
1
- import { useMemo, useRef } from 'preact/hooks'
2
- import thunkMiddleware from 'redux-thunk'
3
-
1
+ import { configureStore } from '@reduxjs/toolkit'
4
2
  import {
5
- SeamlyEventBusContext,
3
+ ComponentFilter,
6
4
  SeamlyApiContext,
5
+ SeamlyEventBusContext,
7
6
  SeamlyLiveRegionContext,
8
- StoreProvider,
9
- ComponentFilter,
10
- createReduxStore,
7
+ SeamlyStoreProvider,
11
8
  } from '@seamly/web-ui'
12
- import stateReducer from 'domains/store/state-reducer'
13
- import { Reducer as formReducer } from 'domains/forms'
14
- import { Reducer as translationsReducer } from 'domains/translations'
15
- import { Reducer as i18nReducer, Actions as I18nActions } from 'domains/i18n'
16
- import { Reducer as interruptReducer } from 'domains/interrupt'
17
- import { Reducer as appReducer } from 'domains/app'
18
- import {
19
- Reducer as configReducer,
20
- Actions as ConfigActions,
21
- } from 'domains/config'
22
- import { Reducer as visibilityReducer } from 'domains/visibility'
23
- import { seamlyActions } from '../../ui/utils/seamly-utils'
24
-
25
- const { SET_PARTICIPANT } = seamlyActions
9
+ import appReducer from 'domains/app/slice'
10
+ import configReducer, {
11
+ setPreChatEvents,
12
+ setConfig,
13
+ } from 'domains/config/slice'
14
+ import formsReducer from 'domains/forms/slice'
15
+ import i18nReducer, {
16
+ setInitialLocale,
17
+ setTranslations,
18
+ } from 'domains/i18n/slice'
19
+ import interruptReducer from 'domains/interrupt/slice'
20
+ import stateReducer, { setParticipant } from 'domains/store/slice'
21
+ import translationReducer from 'domains/translations/slice'
22
+ import visibilityReducer from 'domains/visibility/slice'
23
+ import { useMemo, useRef } from 'preact/hooks'
26
24
 
27
25
  const bareApi = {
28
- send: () => {},
26
+ send: () => {
27
+ // do nothing
28
+ },
29
29
  reset: () => {
30
30
  return Promise.resolve({})
31
31
  },
32
- store: { get: () => {}, set: () => {} },
32
+ store: {
33
+ get: () => {
34
+ // do nothing
35
+ },
36
+ set: () => {
37
+ // do nothing
38
+ },
39
+ },
33
40
  hasConversation: () => false,
34
41
  }
35
42
 
36
- const SeamlyTestCore = ({
43
+ const SeamlyStaticCore = ({
37
44
  state,
38
45
  translations,
39
46
  participants = [],
40
47
  children,
41
48
  }) => {
42
- const liveMsgRef = useRef(() => {})
43
- const eventBusRef = useRef({ emit: () => {} })
49
+ const liveMsgRef = useRef(() => {
50
+ // do nothing
51
+ })
52
+ const eventBusRef = useRef({
53
+ emit: () => {
54
+ // do nothing
55
+ },
56
+ })
44
57
 
45
58
  const store = useMemo(() => {
46
59
  const {
47
- translations: translationsSlice,
48
- interrupt: interruptSlice,
49
- config: configSlice = {},
50
- visibility: visibilitySlice,
51
- ...restState
60
+ translations: initialTranslations,
61
+ interrupt: initialInterrupt,
62
+ config: initialConfig = {},
63
+ visibility: initialVisibility,
64
+ ...initialState
52
65
  } = state || {}
53
- const newStore = createReduxStore({
54
- reducers: {
66
+
67
+ const newStore = configureStore({
68
+ reducer: {
55
69
  state: stateReducer,
56
- [String(appReducer)]: appReducer,
57
- [String(configReducer)]: configReducer,
58
- [String(formReducer)]: formReducer,
59
- [String(translationsReducer)]: translationsReducer,
60
- [String(i18nReducer)]: i18nReducer,
61
- [String(interruptReducer)]: interruptReducer,
62
- [String(visibilityReducer)]: visibilityReducer,
70
+ app: appReducer,
71
+ config: configReducer,
72
+ i18n: i18nReducer,
73
+ translations: translationReducer,
74
+ visibility: visibilityReducer,
75
+ forms: formsReducer,
76
+ interrupt: interruptReducer,
63
77
  },
64
- initialState: {
65
- state: restState,
66
- [String(translationsReducer)]: translationsSlice,
67
- [String(interruptReducer)]: interruptSlice,
68
- [String(visibilityReducer)]: visibilitySlice,
78
+ preloadedState: {
79
+ state: initialState,
80
+ config: initialConfig,
81
+ translations: initialTranslations,
82
+ interrupt: initialInterrupt,
83
+ visibility: initialVisibility,
69
84
  },
70
- middlewares: [
71
- thunkMiddleware.withExtraArgument({
72
- api: bareApi,
73
- eventBus: eventBusRef.current,
85
+ middleware: (getDefaultMiddleWare) =>
86
+ getDefaultMiddleWare({
87
+ thunk: {
88
+ extraArgument: {
89
+ api: bareApi,
90
+ eventBus: eventBusRef.current,
91
+ },
92
+ },
93
+ serializableCheck: false,
74
94
  }),
75
- ],
76
95
  })
77
- newStore.dispatch(ConfigActions.initialize(configSlice))
78
- if (configSlice.preChatEvents) {
79
- newStore.dispatch(
80
- ConfigActions.setPreChatEvents(configSlice.preChatEvents),
81
- )
96
+
97
+ const { config } = newStore.getState()
98
+
99
+ newStore.dispatch(setConfig(config))
100
+ if (config.preChatEvents) {
101
+ newStore.dispatch(setPreChatEvents(config.preChatEvents))
82
102
  }
83
- newStore.dispatch(I18nActions.setLocale.fulfilled('en-GB', translations))
103
+ newStore.dispatch(setInitialLocale('en-GB'))
104
+ newStore.dispatch(setTranslations(translations))
84
105
 
85
106
  participants.forEach((participant) => {
86
- newStore.dispatch({
87
- type: SET_PARTICIPANT,
88
- participant,
89
- fromClient: participant.id === 'user',
90
- })
107
+ newStore.dispatch(
108
+ setParticipant({
109
+ participant,
110
+ fromClient: participant.id === 'user',
111
+ }),
112
+ )
91
113
  })
92
114
 
93
115
  return newStore
94
- }, [state, translations, participants])
116
+ }, [participants, state, translations])
95
117
 
96
118
  return (
97
119
  state && (
98
- <StoreProvider store={store}>
120
+ <SeamlyStoreProvider store={store}>
99
121
  <SeamlyEventBusContext.Provider value={eventBusRef.current}>
100
122
  <SeamlyLiveRegionContext.Provider value={liveMsgRef.current}>
101
123
  <SeamlyApiContext.Provider value={bareApi}>
@@ -103,9 +125,9 @@ const SeamlyTestCore = ({
103
125
  </SeamlyApiContext.Provider>
104
126
  </SeamlyLiveRegionContext.Provider>
105
127
  </SeamlyEventBusContext.Provider>
106
- </StoreProvider>
128
+ </SeamlyStoreProvider>
107
129
  )
108
130
  )
109
131
  }
110
132
 
111
- export default SeamlyTestCore
133
+ export default SeamlyStaticCore
@@ -1,5 +1,6 @@
1
1
  import { useState, useEffect } from 'preact/hooks'
2
2
  import { View } from '@seamly/web-ui'
3
+ import { timeout } from 'ui/hooks/focus-helper-hooks'
3
4
  import StyleGuideStaticCore from './static-core'
4
5
 
5
6
  const StyleGuideView = ({
@@ -18,10 +19,9 @@ const StyleGuideView = ({
18
19
  // renders showing up.
19
20
  useEffect(() => {
20
21
  setRenderView(false)
21
- requestAnimationFrame(() => {
22
- requestAnimationFrame(() => {
23
- setRenderView(true)
24
- })
22
+ requestAnimationFrame(async () => {
23
+ await timeout(60)
24
+ setRenderView(true)
25
25
  })
26
26
  }, [state])
27
27
 
@@ -33,24 +33,24 @@ export function addTranslationData(event) {
33
33
  data: {
34
34
  ...event.payload.body,
35
35
  text: event.payload.body.text
36
- ? 'NL - ' + event.payload.body.text
36
+ ? `NL - ${event.payload.body.text}`
37
37
  : undefined,
38
38
  description: event.payload.body.description
39
- ? 'NL - ' + event.payload.body.description
39
+ ? `NL - ${event.payload.body.description}`
40
40
  : undefined,
41
41
  buttonText: event.payload.body.buttonText
42
- ? 'NL - ' + event.payload.body.buttonText
42
+ ? `NL - ${event.payload.body.buttonText}`
43
43
  : undefined,
44
44
  choices: event.payload.body.choices
45
45
  ? event.payload.body.choices.map((choice) => ({
46
46
  ...choice,
47
- text: 'NL - ' + choice.text,
47
+ text: `NL - ${choice.text}`,
48
48
  }))
49
49
  : undefined,
50
50
  prompt: event.payload.body.prompt
51
51
  ? {
52
52
  ...event.payload.body.prompt,
53
- text: 'NL - ' + event.payload.body.prompt.text,
53
+ text: `NL - ${event.payload.body.prompt.text}`,
54
54
  }
55
55
  : undefined,
56
56
  },
@@ -1,8 +1,8 @@
1
1
  import {
2
- visibilityStates,
3
2
  randomId,
4
- SeamlyOfflineError,
5
3
  SeamlyGeneralError,
4
+ SeamlyOfflineError,
5
+ visibilityStates,
6
6
  } from '@seamly/web-ui'
7
7
  import { addTranslationData } from './state-helpers'
8
8
 
@@ -14,6 +14,7 @@ const baseState = {
14
14
  hideOnNoUserResponse: false,
15
15
  showFaq: false,
16
16
  showDisclaimer: false,
17
+ showSuggestions: true,
17
18
  },
18
19
  initialState: {},
19
20
  unreadEvents: 0,
@@ -126,6 +127,32 @@ const newTranslationDividerStart = {
126
127
  type: 'divider',
127
128
  },
128
129
  }
130
+
131
+ const newTranslationDividerStartTwo = {
132
+ type: 'info',
133
+ payload: {
134
+ body: {
135
+ language: 'Nederlands',
136
+ subtype: 'new_translation',
137
+ text: '[NL] Automatic translation to Dutch started. Please note that automatic translations may contain errors.',
138
+ translationEnabled: true,
139
+ translationLocale: 'nl',
140
+ },
141
+ fromClient: false,
142
+ fromHistory: true,
143
+ id: randomId(),
144
+ occurredAt: 1625658300534259,
145
+ participant: null,
146
+ service: {
147
+ meta: {},
148
+ name: null,
149
+ serviceSessionId: null,
150
+ },
151
+ transactionId: null,
152
+ translatedBody: null,
153
+ type: 'divider',
154
+ },
155
+ }
129
156
  const newTranslationDividerStop = {
130
157
  type: 'info',
131
158
  payload: {
@@ -713,7 +740,9 @@ const uploadBusy = {
713
740
  complete: false,
714
741
  error: '',
715
742
  uploadHandle: {
716
- abort: () => {},
743
+ abort: () => {
744
+ // do nothing
745
+ },
717
746
  },
718
747
  }
719
748
 
@@ -725,7 +754,7 @@ const uploadError = {
725
754
  complete: false,
726
755
  error: 'Something went wrong with the upload',
727
756
  uploadHandle: {
728
- abort: () => {},
757
+ abort: () => undefined,
729
758
  },
730
759
  }
731
760
 
@@ -734,7 +763,7 @@ const translationsSlice = {
734
763
  currentLocale: undefined,
735
764
  isAvailable: false,
736
765
  languages: [],
737
- originalPayloadIds: [],
766
+ translatedEventGroups: {},
738
767
  containerId: randomId(),
739
768
  }
740
769
 
@@ -1734,7 +1763,7 @@ const standardState = {
1734
1763
  userMessage,
1735
1764
  textMessageBoldItalicUnderline,
1736
1765
  newTopicDivider,
1737
- newTranslationDividerStart,
1766
+ newTranslationDividerStartTwo,
1738
1767
  newTranslationDividerStop,
1739
1768
  imageMessage,
1740
1769
  fileDownloadAgentMessage,
@@ -1750,13 +1779,44 @@ const standardState = {
1750
1779
  choicePromptMessage,
1751
1780
  ctaMessage,
1752
1781
  newTranslationDividerStop,
1753
- newTranslationDividerStart,
1754
1782
  ].map(addTranslationData),
1755
1783
  translations: {
1756
1784
  ...translationsSlice,
1757
1785
  currentLocale: 'nl',
1758
1786
  isActive: true,
1759
1787
  isAvailable: true,
1788
+ translatedEventGroups: {
1789
+ [newTranslationDividerStart.payload.id]: [
1790
+ infoMessage,
1791
+ shortTextMessage,
1792
+ {
1793
+ ...choicePromptMessage,
1794
+ payload: {
1795
+ ...choicePromptMessage.payload,
1796
+ id: `${choicePromptMessage.payload.id}XXX`,
1797
+ },
1798
+ },
1799
+ longTextMessage,
1800
+ userMessage,
1801
+ textMessageBoldItalicUnderline,
1802
+ newTopicDivider,
1803
+ ].map((p) => p.payload.id),
1804
+ [newTranslationDividerStartTwo.payload.id]: [
1805
+ imageMessage,
1806
+ fileDownloadAgentMessage,
1807
+ deletedFileDownloadAgentMessage,
1808
+ userMessageLong,
1809
+ videoMessage,
1810
+ textMessageWithLinks,
1811
+ textMessageWithLongLink,
1812
+ imageMessageWithLightbox,
1813
+ fileDownloadUserMessage,
1814
+ emptyUrlFileDownloadUserMessage,
1815
+ textMesageWithBullets,
1816
+ choicePromptMessage,
1817
+ ctaMessage,
1818
+ ].map((p) => p.payload.id),
1819
+ },
1760
1820
  languages: [
1761
1821
  { locale: 'nl', nativeName: 'Dutch' },
1762
1822
  { locale: 'en', nativeName: 'English' },
@@ -0,0 +1,5 @@
1
+ import initializeStyleGuideExternalApi from 'style-guide/register-style-guide-api'
2
+
3
+ export default initializeStyleGuideExternalApi
4
+
5
+ export { default as SeamlyStaticCore } from 'style-guide/components/static-core'
@@ -1,10 +1,8 @@
1
1
  import { useSeamlyOptions } from 'ui/hooks/seamly-hooks'
2
2
  import { className } from 'lib/css'
3
3
  import OptionsButton from 'ui/components/options/options-button'
4
- import {
5
- useTranslations,
6
- OptionsButton as TranslationsOptionsButton,
7
- } from 'domains/translations'
4
+ import { useTranslations } from 'domains/translations/hooks'
5
+ import TranslationsOptionsButton from 'domains/translations/components/options-button'
8
6
 
9
7
  export default function AppOptions() {
10
8
  const { menuOptions, allowOptionSelection } = useSeamlyOptions()
@@ -1,5 +1,5 @@
1
1
  import { useMemo } from 'preact/hooks'
2
- import { useConfig } from 'domains/config'
2
+ import { useConfig } from 'domains/config/hooks'
3
3
  import ComponentContext from './component-context'
4
4
  import ChoicePrompt from './event/choice-prompt'
5
5
  import Text from './event/text'
@@ -1,17 +1,18 @@
1
- import { useRef, useEffect } from 'preact/hooks'
1
+ import { useI18n } from 'domains/i18n/hooks'
2
+ import { useVisibility } from 'domains/visibility/hooks'
2
3
  import { className } from 'lib/css'
3
- import { useI18n } from 'domains/i18n'
4
+ import { useLayoutEffect, useRef } from 'preact/hooks'
5
+ import PrivacyDisclaimer from 'ui/components/layout/privacy-disclaimer'
6
+ import { timeout } from 'ui/hooks/focus-helper-hooks'
4
7
  import {
5
8
  useSeamlyIsLoading,
6
9
  useSkiplink,
7
10
  useSkiplinkTargetFocusing,
8
11
  } from 'ui/hooks/seamly-hooks'
9
12
  import { useEvents, useLoadedImageEventIds } from 'ui/hooks/seamly-state-hooks'
10
- import PrivacyDisclaimer from 'ui/components/layout/privacy-disclaimer'
11
- import { useVisibility } from 'domains/visibility'
13
+ import ComponentFilter from './component-filter'
12
14
  import Event from './event/event'
13
15
  import Loader from './loader'
14
- import ComponentFilter from './component-filter'
15
16
 
16
17
  const Events = () => {
17
18
  const events = useEvents()
@@ -51,10 +52,13 @@ const Conversation = () => {
51
52
  const focusSkiplinkTarget = useSkiplinkTargetFocusing()
52
53
  const loadedImageEventIds = useLoadedImageEventIds()
53
54
 
54
- useEffect(() => {
55
+ useLayoutEffect(() => {
55
56
  const containerElement = chatBodyContainer.current
56
57
  if (containerElement) {
57
- containerElement.scrollTop = containerElement.scrollHeight
58
+ requestAnimationFrame(async () => {
59
+ await timeout(30) // Wait for next frame tick
60
+ containerElement.scrollTop = containerElement.scrollHeight
61
+ })
58
62
  }
59
63
  }, [events, isLoading, isOpen, loadedImageEventIds])
60
64
 
@@ -1,10 +1,10 @@
1
1
  import { useGeneratedId } from 'ui/hooks/seamly-hooks'
2
2
  import MessageContainer from 'ui/components/conversation/message-container'
3
- import { useTranslatedEventData } from 'domains/translations'
3
+ import { useTranslatedEventData } from 'domains/translations/hooks'
4
4
  import CardComponent from './card-component'
5
5
 
6
6
  const CardMessage = ({ event }) => {
7
- const [body] = useTranslatedEventData(event)
7
+ const { body } = useTranslatedEventData(event)
8
8
  const descriptionId = useGeneratedId()
9
9
 
10
10
  return (
@@ -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 Icon from 'ui/components/layout/icon'
4
4
 
5
5
  export default function CarouselControls({
@@ -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 CardComponent from 'ui/components/conversation/event/card-component'
4
4
 
5
5
  export default function CarouselMessageSlide({
@@ -1,12 +1,12 @@
1
1
  import MessageContainer from 'ui/components/conversation/message-container'
2
2
  import CarouselComponent from 'ui/components/conversation/event/carousel-component'
3
- import { useTranslatedEventData } from 'domains/translations'
3
+ import { useTranslatedEventData } from 'domains/translations/hooks'
4
4
  import CarouselMessageSlide from './components/slide'
5
5
 
6
6
  const getItemKey = (item, idx, prefix = '') => `${prefix}${item.title}:${idx}`
7
7
  const getItemLabel = (item) => item.title
8
8
  const CarouselMessage = ({ event }) => {
9
- const [body] = useTranslatedEventData(event)
9
+ const { body } = useTranslatedEventData(event)
10
10
  const slides = body.cards
11
11
 
12
12
  return (
@@ -9,8 +9,8 @@ import {
9
9
  import { className } from 'lib/css'
10
10
  import { actionTypes } from 'ui/utils/seamly-utils'
11
11
  import Icon from 'ui/components/layout/icon'
12
- import { useI18n } from 'domains/i18n'
13
- import { useTranslatedEventData } from 'domains/translations'
12
+ import { useI18n } from 'domains/i18n/hooks'
13
+ import { useTranslatedEventData } from 'domains/translations/hooks'
14
14
  import MessageContainer from 'ui/components/conversation/message-container'
15
15
 
16
16
  export const useChoicePrompt = (event) => {
@@ -19,7 +19,7 @@ export const useChoicePrompt = (event) => {
19
19
  const { sendAction, addMessageBubble, addDivider } = useSeamlyCommands()
20
20
  const { activeServiceSessionId } = useSeamlyServiceInfo()
21
21
  const lastEventId = useLastMessageEventId()
22
- const [body] = useTranslatedEventData(event)
22
+ const { body } = useTranslatedEventData(event)
23
23
  const { service } = payload
24
24
 
25
25
  const subEvent = useMemo(() => {
@@ -1,21 +1,19 @@
1
- import { useCallback, useMemo, useState } from 'preact/hooks'
1
+ import { useUserHasResponded } from 'domains/app/hooks'
2
+ import { setHasResponded } from 'domains/app/slice'
3
+ import { useConfig } from 'domains/config/hooks'
4
+ import { useI18n } from 'domains/i18n/hooks'
5
+ import { useTranslatedEventData } from 'domains/translations/hooks'
2
6
  import { className } from 'lib/css'
3
- import {
4
- useEvents,
5
- useSeamlyCommands,
6
- useSeamlyDispatchContext,
7
- } from 'ui/hooks/seamly-hooks'
8
- import { useI18n } from 'domains/i18n'
9
- import { useTranslatedEventData } from 'domains/translations'
10
- import { useUserHasResponded } from 'domains/app'
11
- import { setHasResponded } from 'domains/app/actions'
12
- import { actionTypes } from 'ui/utils/seamly-utils'
7
+ import { useCallback, useMemo, useState } from 'preact/hooks'
8
+ import { useDispatch } from 'react-redux'
13
9
  import MessageContainer from 'ui/components/conversation/message-container'
14
10
  import SuggestionsList from 'ui/components/suggestions/suggestions-list'
11
+ import { useEvents, useSeamlyCommands } from 'ui/hooks/seamly-hooks'
12
+ import { actionTypes } from 'ui/utils/seamly-utils'
15
13
 
16
14
  export const useSuggestions = (event) => {
17
15
  const { payload } = event
18
- const [suggestions] = useTranslatedEventData(event)
16
+ const { body: suggestions } = useTranslatedEventData(event)
19
17
 
20
18
  return {
21
19
  suggestions,
@@ -25,10 +23,11 @@ export const useSuggestions = (event) => {
25
23
 
26
24
  const ConversationSuggestions = ({ event, ...props }) => {
27
25
  const [isExpanded, setIsExpanded] = useState(true)
28
- const dispatch = useSeamlyDispatchContext()
29
- const userResponded = useUserHasResponded()
26
+ const dispatch = useDispatch()
27
+ const userHasResponded = useUserHasResponded()
30
28
  const { sendAction, addMessageBubble } = useSeamlyCommands()
31
29
  const { suggestions, payload } = useSuggestions(event)
30
+ const { showSuggestions } = useConfig()
32
31
  const events = useEvents()
33
32
 
34
33
  const { t } = useI18n()
@@ -66,7 +65,12 @@ const ConversationSuggestions = ({ event, ...props }) => {
66
65
  [dispatch, sendAction, payload.id, addMessageBubble],
67
66
  )
68
67
 
69
- if (!isExpanded || userResponded || !hasLastTransactionEvent) {
68
+ if (
69
+ !isExpanded ||
70
+ userHasResponded ||
71
+ !hasLastTransactionEvent ||
72
+ !showSuggestions
73
+ ) {
70
74
  return null
71
75
  }
72
76
 
@@ -3,11 +3,11 @@ import { className } from 'lib/css'
3
3
  import { useGeneratedId, useSeamlyCommands } from 'ui/hooks/seamly-hooks'
4
4
  import { actionTypes } from 'ui/utils/seamly-utils'
5
5
  import MessageContainer from 'ui/components/conversation/message-container'
6
- import { useTranslatedEventData } from 'domains/translations'
6
+ import { useTranslatedEventData } from 'domains/translations/hooks'
7
7
  import useEventLinkClickHandler from './hooks/use-event-link-click-handler'
8
8
 
9
9
  const Cta = ({ event }) => {
10
- const [body] = useTranslatedEventData(event)
10
+ const { body } = useTranslatedEventData(event)
11
11
  const eventClick = useEventLinkClickHandler(event.payload.id)
12
12
  const { emitEvent } = useSeamlyCommands()
13
13
 
@@ -1,5 +1,5 @@
1
1
  import { dividerKeys } from 'ui/utils/seamly-utils'
2
- import { useI18n } from 'domains/i18n'
2
+ import { useI18n } from 'domains/i18n/hooks'
3
3
  import EventDivider from 'ui/components/conversation/event-divider'
4
4
 
5
5
  const dividerTypes = {