@seamly/web-ui 20.8.1 → 21.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/build/dist/lib/deprecated-view.js +1 -1
  2. package/build/dist/lib/index.debug.js +585 -584
  3. package/build/dist/lib/index.debug.min.js +1 -1
  4. package/build/dist/lib/index.debug.min.js.LICENSE.txt +110 -110
  5. package/build/dist/lib/index.js +20269 -26441
  6. package/build/dist/lib/index.min.js +1 -1
  7. package/build/dist/lib/index.min.js.LICENSE.txt +6 -1
  8. package/build/dist/lib/standalone.js +27728 -34583
  9. package/build/dist/lib/standalone.min.js +1 -1
  10. package/build/dist/lib/standalone.min.js.LICENSE.txt +1 -1
  11. package/build/dist/lib/storage.js +6 -15
  12. package/build/dist/lib/style-guide.js +9660 -8970
  13. package/build/dist/lib/style-guide.min.js +1 -1
  14. package/build/dist/lib/styles-default-implementation.js +1 -1
  15. package/build/dist/lib/styles.js +1 -1
  16. package/build/dist/lib/utils.js +85 -3
  17. package/build/dist/lib/utils.min.js +1 -1
  18. package/package.json +54 -52
  19. package/src/icons/icon_check-16.svg +14 -0
  20. package/src/icons/icon_check-32.svg +14 -0
  21. package/src/javascripts/api/conversation-connector.ts +149 -0
  22. package/src/javascripts/api/errors/seamly-base-error.js +19 -0
  23. package/src/javascripts/api/errors/seamly-unavailable-error.js +5 -7
  24. package/src/javascripts/api/{index.js → index.ts} +163 -116
  25. package/src/javascripts/config.types.ts +5 -4
  26. package/src/javascripts/domains/app/actions.ts +47 -46
  27. package/src/javascripts/domains/app/hooks.js +1 -1
  28. package/src/javascripts/domains/config/actions.ts +2 -8
  29. package/src/javascripts/domains/config/hooks.ts +1 -1
  30. package/src/javascripts/domains/config/selectors.ts +6 -6
  31. package/src/javascripts/domains/config/slice.ts +3 -3
  32. package/src/javascripts/domains/errors/index.ts +66 -0
  33. package/src/javascripts/domains/forms/context.ts +1 -1
  34. package/src/javascripts/domains/forms/forms.types.ts +3 -3
  35. package/src/javascripts/domains/forms/hooks.ts +10 -10
  36. package/src/javascripts/domains/forms/provider.tsx +9 -9
  37. package/src/javascripts/domains/i18n/actions.ts +11 -5
  38. package/src/javascripts/domains/i18n/hooks.ts +11 -8
  39. package/src/javascripts/domains/i18n/selectors.ts +10 -4
  40. package/src/javascripts/domains/i18n/slice.ts +0 -1
  41. package/src/javascripts/domains/interrupt/hooks.ts +1 -1
  42. package/src/javascripts/domains/interrupt/middleware.ts +1 -1
  43. package/src/javascripts/domains/store/index.ts +1 -1
  44. package/src/javascripts/domains/store/selectors.ts +16 -0
  45. package/src/javascripts/domains/store/slice.ts +47 -41
  46. package/src/javascripts/domains/store/store.types.ts +38 -10
  47. package/src/javascripts/domains/translations/components/{options-button.js → options-button.tsx} +30 -20
  48. package/src/javascripts/domains/translations/components/options-dialog/index.tsx +33 -0
  49. package/src/javascripts/domains/translations/components/options-dialog/translation-option.tsx +37 -0
  50. package/src/javascripts/domains/translations/components/options-dialog/translation-options.tsx +85 -0
  51. package/src/javascripts/domains/translations/components/translation-status.tsx +15 -0
  52. package/src/javascripts/domains/translations/hooks.ts +77 -11
  53. package/src/javascripts/domains/translations/slice.ts +20 -9
  54. package/src/javascripts/domains/translations/translations.types.ts +4 -2
  55. package/src/javascripts/domains/visibility/actions.ts +6 -10
  56. package/src/javascripts/domains/visibility/hooks.ts +33 -14
  57. package/src/javascripts/domains/visibility/selectors.ts +3 -2
  58. package/src/javascripts/domains/visibility/slice.ts +2 -6
  59. package/src/javascripts/index.ts +19 -21
  60. package/src/javascripts/lib/engine/{index.js → index.tsx} +25 -7
  61. package/src/javascripts/lib/url-helpers.ts +112 -0
  62. package/src/javascripts/package/utils.js +5 -2
  63. package/src/javascripts/schema.ts +28 -0
  64. package/src/javascripts/style-guide/components/app.js +16 -12
  65. package/src/javascripts/style-guide/components/links.js +6 -6
  66. package/src/javascripts/style-guide/components/static-core.js +6 -3
  67. package/src/javascripts/style-guide/components/view.js +1 -1
  68. package/src/javascripts/style-guide/states.js +129 -31
  69. package/src/javascripts/style-guide/style-guide-engine.js +1 -1
  70. package/src/javascripts/ui/components/app-options/index.js +25 -6
  71. package/src/javascripts/ui/components/chat-app.js +1 -1
  72. package/src/javascripts/ui/components/chat-status/chat-status-action.tsx +30 -0
  73. package/src/javascripts/ui/components/chat-status/index.tsx +61 -0
  74. package/src/javascripts/ui/components/conversation/component-filter.js +9 -9
  75. package/src/javascripts/ui/components/conversation/{conversation.js → conversation.tsx} +32 -41
  76. package/src/javascripts/ui/components/conversation/event/card-component.js +2 -2
  77. package/src/javascripts/ui/components/conversation/event/card-message.js +1 -1
  78. package/src/javascripts/ui/components/conversation/event/carousel-component/components/controls.js +2 -2
  79. package/src/javascripts/ui/components/conversation/event/carousel-component/index.js +4 -4
  80. package/src/javascripts/ui/components/conversation/event/carousel-message/components/slide.js +2 -2
  81. package/src/javascripts/ui/components/conversation/event/carousel-message/index.js +1 -1
  82. package/src/javascripts/ui/components/conversation/event/chat-scroll/chat-scroll-context.ts +12 -0
  83. package/src/javascripts/ui/components/conversation/event/chat-scroll/chat-scroll-provider.tsx +46 -0
  84. package/src/javascripts/ui/components/conversation/event/chat-scroll/unread-messages-button.tsx +27 -0
  85. package/src/javascripts/ui/components/conversation/event/choice-prompt.js +12 -8
  86. package/src/javascripts/ui/components/conversation/event/conversation-suggestions.js +6 -6
  87. package/src/javascripts/ui/components/conversation/event/cta.js +2 -2
  88. package/src/javascripts/ui/components/conversation/event/divider/index.js +0 -1
  89. package/src/javascripts/ui/components/conversation/event/divider/variants/default.js +1 -1
  90. package/src/javascripts/ui/components/conversation/event/divider/variants/new-translation.js +17 -22
  91. package/src/javascripts/ui/components/conversation/event/divider/variants/time-indicator.js +2 -2
  92. package/src/javascripts/ui/components/conversation/event/event-participant.js +1 -1
  93. package/src/javascripts/ui/components/conversation/event/event.tsx +66 -0
  94. package/src/javascripts/ui/components/conversation/event/hooks/use-event-link-click-handler.js +1 -1
  95. package/src/javascripts/ui/components/conversation/event/hooks/use-formatted-date.js +1 -1
  96. package/src/javascripts/ui/components/conversation/event/image-lightbox.js +1 -1
  97. package/src/javascripts/ui/components/conversation/event/image.js +2 -2
  98. package/src/javascripts/ui/components/conversation/event/splash.js +1 -1
  99. package/src/javascripts/ui/components/conversation/event/translation.js +1 -1
  100. package/src/javascripts/ui/components/conversation/event/upload.js +2 -2
  101. package/src/javascripts/ui/components/conversation/event/video.js +2 -2
  102. package/src/javascripts/ui/components/conversation/event-divider.js +1 -1
  103. package/src/javascripts/ui/components/conversation/message-container.js +1 -1
  104. package/src/javascripts/ui/components/conversation/use-chat-scroll.ts +108 -0
  105. package/src/javascripts/ui/components/core/{seamly-activity-monitor.js → seamly-activity-monitor.tsx} +12 -5
  106. package/src/javascripts/ui/components/core/seamly-api-context.ts +7 -0
  107. package/src/javascripts/ui/components/core/seamly-chat.tsx +8 -0
  108. package/src/javascripts/ui/components/core/{seamly-core.js → seamly-core.tsx} +27 -14
  109. package/src/javascripts/ui/components/core/seamly-event-subscriber.ts +340 -0
  110. package/src/javascripts/ui/components/core/seamly-file-upload.js +2 -2
  111. package/src/javascripts/ui/components/core/seamly-idle-detach-counter.js +1 -1
  112. package/src/javascripts/ui/components/core/seamly-instance-functions-loader.js +24 -11
  113. package/src/javascripts/ui/components/core/seamly-live-region.js +4 -4
  114. package/src/javascripts/ui/components/core/seamly-new-notifications.js +3 -3
  115. package/src/javascripts/ui/components/core/seamly-read-state.js +2 -33
  116. package/src/javascripts/ui/components/entry/deprecated-toggle-button.js +4 -4
  117. package/src/javascripts/ui/components/entry/entry-container.js +8 -8
  118. package/src/javascripts/ui/components/entry/text-entry/hooks.js +3 -3
  119. package/src/javascripts/ui/components/entry/text-entry/index.js +3 -3
  120. package/src/javascripts/ui/components/entry/text-entry/text-entry-form.js +4 -4
  121. package/src/javascripts/ui/components/entry/upload/file-upload-form.js +3 -3
  122. package/src/javascripts/ui/components/entry/upload/index.js +5 -5
  123. package/src/javascripts/ui/components/entry/upload-toggle.js +6 -6
  124. package/src/javascripts/ui/components/faq/faq.js +14 -14
  125. package/src/javascripts/ui/components/form-controls/error.js +2 -2
  126. package/src/javascripts/ui/components/form-controls/file-input.js +3 -3
  127. package/src/javascripts/ui/components/layout/agent-info.js +3 -3
  128. package/src/javascripts/ui/components/layout/chat-frame.js +20 -12
  129. package/src/javascripts/ui/components/layout/chat.js +5 -5
  130. package/src/javascripts/ui/components/layout/deprecated-app-frame.js +6 -6
  131. package/src/javascripts/ui/components/layout/deprecated-chat-frame.js +34 -0
  132. package/src/javascripts/ui/components/layout/header.js +2 -2
  133. package/src/javascripts/ui/components/layout/icon.js +11 -9
  134. package/src/javascripts/ui/components/layout/interrupt.js +7 -5
  135. package/src/javascripts/ui/components/layout/pre-chat-messages.js +1 -1
  136. package/src/javascripts/ui/components/layout/privacy-disclaimer.js +2 -2
  137. package/src/javascripts/ui/components/options/options-button.js +5 -5
  138. package/src/javascripts/ui/components/options/{options-frame.js → options-frame.tsx} +52 -18
  139. package/src/javascripts/ui/components/options/transcript/index.js +9 -10
  140. package/src/javascripts/ui/components/options/transcript/transcript-form.js +2 -2
  141. package/src/javascripts/ui/components/suggestions/index.js +8 -8
  142. package/src/javascripts/ui/components/suggestions/suggestions-item.js +1 -1
  143. package/src/javascripts/{domains/translations/components/chat-status.js → ui/components/translation-chat-status/index.tsx} +13 -14
  144. package/src/javascripts/ui/components/translation-proposal/index.tsx +36 -0
  145. package/src/javascripts/ui/components/view/app-view.js +2 -7
  146. package/src/javascripts/ui/components/view/deprecated-view.js +8 -10
  147. package/src/javascripts/ui/components/view/index.js +6 -6
  148. package/src/javascripts/ui/components/view/inline-view.js +4 -8
  149. package/src/javascripts/ui/components/view/window-view/collapse-button.js +2 -2
  150. package/src/javascripts/ui/components/view/window-view/index.js +11 -17
  151. package/src/javascripts/ui/components/view/window-view/window-open-button.js +6 -6
  152. package/src/javascripts/ui/components/warnings/idle-detach-warning.js +3 -3
  153. package/src/javascripts/ui/components/warnings/prompt.js +1 -1
  154. package/src/javascripts/ui/components/warnings/resume-conversation-prompt.js +4 -4
  155. package/src/javascripts/ui/components/widgets/in-out-transition.js +20 -18
  156. package/src/javascripts/ui/components/widgets/lightbox.js +3 -3
  157. package/src/javascripts/ui/components/widgets/modal.js +2 -2
  158. package/src/javascripts/ui/components/widgets/upload-progress.js +2 -2
  159. package/src/javascripts/ui/hooks/file-upload-hooks.js +1 -1
  160. package/src/javascripts/ui/hooks/focus-helper-hooks.js +1 -1
  161. package/src/javascripts/ui/hooks/seamly-entry-hooks.js +6 -6
  162. package/src/javascripts/ui/hooks/seamly-hooks.js +11 -10
  163. package/src/javascripts/ui/hooks/seamly-option-hooks.js +6 -6
  164. package/src/javascripts/ui/hooks/{seamly-state-hooks.js → seamly-state-hooks.ts} +9 -6
  165. package/src/javascripts/ui/hooks/use-click-outside.ts +29 -0
  166. package/src/javascripts/ui/hooks/use-event-component-mapping.js +11 -10
  167. package/src/javascripts/ui/hooks/use-interval.js +1 -1
  168. package/src/javascripts/ui/hooks/use-seamly-actions.ts +29 -29
  169. package/src/javascripts/ui/hooks/use-seamly-chat.js +13 -23
  170. package/src/javascripts/ui/hooks/use-seamly-commands.js +20 -15
  171. package/src/javascripts/ui/hooks/use-seamly-idle-detach-countdown.js +8 -8
  172. package/src/javascripts/ui/hooks/use-seamly-resume-conversation-prompt.js +2 -2
  173. package/src/javascripts/ui/hooks/use-single-file-upload.js +1 -1
  174. package/src/javascripts/ui/hooks/utility-hooks.js +1 -1
  175. package/src/javascripts/ui/utils/general-utils.js +0 -23
  176. package/src/javascripts/ui/utils/seamly-utils.ts +10 -1
  177. package/src/javascripts/ui/utils/seamly-utils.types.ts +9 -0
  178. package/src/stylesheets/1-settings/_config.scss +1 -1
  179. package/src/stylesheets/3-chat/_chat.scss +23 -5
  180. package/src/stylesheets/5-components/_chat-status.scss +72 -16
  181. package/src/stylesheets/5-components/_conversation.scss +35 -1
  182. package/src/stylesheets/5-components/_disclaimer.scss +0 -5
  183. package/src/stylesheets/5-components/_options.scss +16 -2
  184. package/src/stylesheets/5-components/_translation-options.scss +39 -0
  185. package/src/stylesheets/6-default-implementation/_scrollbar.scss +1 -1
  186. package/src/stylesheets/7-deprecated/3-app/_app.scss +19 -4
  187. package/src/stylesheets/7-deprecated/5-components/_chat-status.scss +5 -0
  188. package/src/stylesheets/7-deprecated/5-components/_options.scss +1 -0
  189. package/src/stylesheets/7-deprecated/5-components/_translation-options.scss +39 -0
  190. package/src/stylesheets/deprecated-view.scss +1 -0
  191. package/src/stylesheets/styles.scss +1 -0
  192. package/webpack/config.common.js +4 -4
  193. package/webpack/config.package.js +10 -16
  194. package/webpack/config.site.js +4 -1
  195. package/webpack/config.test.js +2 -1
  196. package/build/dist/lib/deprecated-view.css +0 -1
  197. package/build/dist/lib/styles-default-implementation.css +0 -1
  198. package/build/dist/lib/styles.css +0 -1
  199. package/src/.DS_Store +0 -0
  200. package/src/javascripts/api/event-producer.js +0 -20
  201. package/src/javascripts/api/producer.js +0 -136
  202. package/src/javascripts/domains/errors/index.js +0 -37
  203. package/src/javascripts/domains/translations/components/options-dialog/form.js +0 -70
  204. package/src/javascripts/domains/translations/components/options-dialog/index.js +0 -87
  205. package/src/javascripts/ui/components/chat-status/index.js +0 -38
  206. package/src/javascripts/ui/components/conversation/event/event.js +0 -36
  207. package/src/javascripts/ui/components/core/seamly-api-context.js +0 -5
  208. package/src/javascripts/ui/components/core/seamly-event-subscriber.js +0 -279
@@ -185,6 +185,29 @@ export interface components {
185
185
  * @example false
186
186
  */
187
187
  resumeConversationPrompt?: boolean
188
+ /** @description Additional information to be able to show a translation proposal element. */
189
+ translationProposal?: {
190
+ /**
191
+ * @description Title of the activate button
192
+ * @example Activate
193
+ */
194
+ buttonLabel?: string
195
+ /**
196
+ * @description Proposed locale for translation
197
+ * @example en-GB
198
+ */
199
+ proposedLocale?: string
200
+ /**
201
+ * @description Screen reader text for dismiss button
202
+ * @example Dismiss translation proposal
203
+ */
204
+ srDismissButtonText?: string
205
+ /**
206
+ * @description Title of the shown translation proposal element
207
+ * @example Do you want to chat in English?
208
+ */
209
+ titleLabel?: string
210
+ } | null
188
211
  }
189
212
  }
190
213
  _links?: {
@@ -1084,6 +1107,11 @@ export interface operations {
1084
1107
  * @example https://seamly.ai/en/contact-us/
1085
1108
  */
1086
1109
  currentUrl?: string
1110
+ /**
1111
+ * @description The preferred locale of the user, for example the language of the browser UI.
1112
+ * @example en-US
1113
+ */
1114
+ preferredLocale?: string
1087
1115
  /**
1088
1116
  * @description The screen resolution of the user.
1089
1117
  * @example 2560x1440
@@ -1,5 +1,6 @@
1
- import { getUrlParams, getUrlSearchString, randomId } from '@seamly/web-ui'
1
+ import { randomId } from '@seamly/web-ui'
2
2
  import { useCallback, useEffect, useState } from 'preact/hooks'
3
+ import { getSearchParamsByKeys, getUrlSearchParams } from 'lib/url-helpers'
3
4
  import StyleGuideLinks from 'style-guide/components/links'
4
5
  import StyleGuideView from 'style-guide/components/view'
5
6
  import { getDeprecatedStateObj, getStateObj } from 'style-guide/states'
@@ -22,6 +23,7 @@ const StyleGuideApp = ({
22
23
  styleGuideConfig.showLayoutModes || ['inline', 'window'],
23
24
  customMessageEventBodies,
24
25
  )
26
+
25
27
  return Object.keys(mainStateObj).reduce(
26
28
  (acc, key) => ({
27
29
  ...acc,
@@ -47,6 +49,13 @@ const StyleGuideApp = ({
47
49
 
48
50
  const getState = useCallback(
49
51
  (layoutMode, feature) => {
52
+ const keys = getSearchParamsByKeys('apiKey', 'locale')
53
+ const combinedParams = new URLSearchParams({
54
+ ...keys,
55
+ layoutMode,
56
+ feature,
57
+ })
58
+ window.history.replaceState(null, null, `?${combinedParams}`)
50
59
  const { headingText } = mainState[feature]
51
60
  setSelectedStateDescription(headingText)
52
61
  const bareState = mainState[feature][layoutMode]
@@ -62,6 +71,10 @@ const StyleGuideApp = ({
62
71
  ...config,
63
72
  showDisclaimer:
64
73
  bareState.config.showDisclaimer || config.showDisclaimer,
74
+ context: {
75
+ ...config.context,
76
+ ...bareState.config?.context,
77
+ },
65
78
  layoutMode: bareState.config.layoutMode,
66
79
  ...(overrideMessages ? { messages: overrideMessages } : {}),
67
80
  showFaq,
@@ -95,17 +108,8 @@ const StyleGuideApp = ({
95
108
  }, [staticState, setStaticState, showStyleGuide])
96
109
 
97
110
  const loadFromUrl = useCallback(() => {
98
- const params = getUrlParams()
99
- if (Object.keys(params).length !== 2) {
100
- window.history.pushState(
101
- null,
102
- null,
103
- `${window.location.pathname}?${getUrlSearchString({
104
- layoutMode: 'inline',
105
- feature: 'base',
106
- })}`,
107
- )
108
- }
111
+ const params = getUrlSearchParams()
112
+
109
113
  const { layoutMode = 'inline', feature = 'base' } = params
110
114
  updateState(getState(layoutMode, feature))
111
115
  window.title = `Style`
@@ -1,4 +1,4 @@
1
- import { getUrlSearchString, getUrlParams } from '@seamly/web-ui'
1
+ import { getUrlSearchParams, getUrlSearchString } from 'lib/url-helpers'
2
2
  import { categories } from 'style-guide/states'
3
3
 
4
4
  const StyleGuideLinks = ({ setSelectedState, states, headingLevel }) => {
@@ -13,7 +13,7 @@ const StyleGuideLinks = ({ setSelectedState, states, headingLevel }) => {
13
13
  setSelectedState(actionObj)
14
14
  }
15
15
 
16
- const currentSearch = getUrlParams(window.location.search)
16
+ const currentSearch = getUrlSearchParams()
17
17
 
18
18
  return (
19
19
  <nav aria-label="Style guide navigation" className="nav--styleguide">
@@ -54,8 +54,8 @@ const StyleGuideLinks = ({ setSelectedState, states, headingLevel }) => {
54
54
  <li
55
55
  key={layoutMode}
56
56
  className={
57
- layoutMode === currentSearch.layoutMode &&
58
- feature === currentSearch.feature
57
+ layoutMode === currentSearch?.layoutMode &&
58
+ feature === currentSearch?.feature
59
59
  ? 'state__selected'
60
60
  : null
61
61
  }
@@ -69,8 +69,8 @@ const StyleGuideLinks = ({ setSelectedState, states, headingLevel }) => {
69
69
  feature,
70
70
  })}`}
71
71
  aria-current={
72
- layoutMode === currentSearch.layoutMode &&
73
- feature === currentSearch.feature
72
+ layoutMode === currentSearch?.layoutMode &&
73
+ feature === currentSearch?.feature
74
74
  ? 'page'
75
75
  : null
76
76
  }
@@ -6,10 +6,12 @@ import {
6
6
  SeamlyLiveRegionContext,
7
7
  SeamlyStoreProvider,
8
8
  } from '@seamly/web-ui'
9
+ import { useMemo, useRef } from 'preact/hooks'
10
+ import SeamlyChat from 'ui/components/core/seamly-chat'
9
11
  import appReducer from 'domains/app/slice'
10
12
  import configReducer, {
11
- setPreChatEvents,
12
13
  setConfig,
14
+ setPreChatEvents,
13
15
  } from 'domains/config/slice'
14
16
  import formsReducer from 'domains/forms/slice'
15
17
  import i18nReducer, {
@@ -20,7 +22,6 @@ import interruptReducer from 'domains/interrupt/slice'
20
22
  import stateReducer, { setParticipant } from 'domains/store/slice'
21
23
  import translationReducer from 'domains/translations/slice'
22
24
  import visibilityReducer from 'domains/visibility/slice'
23
- import { useMemo, useRef } from 'preact/hooks'
24
25
 
25
26
  const bareApi = {
26
27
  send: () => {
@@ -121,7 +122,9 @@ const SeamlyStaticCore = ({
121
122
  <SeamlyEventBusContext.Provider value={eventBusRef.current}>
122
123
  <SeamlyLiveRegionContext.Provider value={liveMsgRef.current}>
123
124
  <SeamlyApiContext.Provider value={bareApi}>
124
- <ComponentFilter>{children}</ComponentFilter>
125
+ <SeamlyChat>
126
+ <ComponentFilter>{children}</ComponentFilter>
127
+ </SeamlyChat>
125
128
  </SeamlyApiContext.Provider>
126
129
  </SeamlyLiveRegionContext.Provider>
127
130
  </SeamlyEventBusContext.Provider>
@@ -1,5 +1,5 @@
1
- import { useState, useEffect } from 'preact/hooks'
2
1
  import { View } from '@seamly/web-ui'
2
+ import { useEffect, useState } from 'preact/hooks'
3
3
  import { timeout } from 'ui/hooks/focus-helper-hooks'
4
4
  import StyleGuideStaticCore from './static-core'
5
5
 
@@ -1,7 +1,7 @@
1
1
  import {
2
- randomId,
3
2
  SeamlyGeneralError,
4
3
  SeamlyOfflineError,
4
+ randomId,
5
5
  visibilityStates,
6
6
  } from '@seamly/web-ui'
7
7
  import { addTranslationData } from './state-helpers'
@@ -107,8 +107,10 @@ const newTranslationDividerStart = {
107
107
  payload: {
108
108
  body: {
109
109
  language: 'Nederlands',
110
+ restartButtonText: null,
110
111
  subtype: 'new_translation',
111
112
  text: '[NL] Automatic translation to Dutch started. Please note that automatic translations may contain errors.',
113
+ title: '[NL] Translating to Dutch',
112
114
  translationEnabled: true,
113
115
  translationLocale: 'nl',
114
116
  },
@@ -158,8 +160,10 @@ const newTranslationDividerStop = {
158
160
  payload: {
159
161
  body: {
160
162
  language: 'Nederlands',
163
+ restartButtonText: '[NL] Start again',
161
164
  subtype: 'new_translation',
162
- text: '[NL] Automatic translation to Dutch ended.',
165
+ text: null,
166
+ title: '[NL] Automatic translation to Dutch ended',
163
167
  translationEnabled: false,
164
168
  translationLocale: 'nl',
165
169
  },
@@ -762,6 +766,7 @@ const translationsSlice = {
762
766
  isActive: false,
763
767
  currentLocale: undefined,
764
768
  isAvailable: false,
769
+ showTranslationProposal: false,
765
770
  languages: [],
766
771
  translatedEventGroups: {},
767
772
  containerId: randomId(),
@@ -1720,6 +1725,30 @@ const standardState = {
1720
1725
  languages: [
1721
1726
  { locale: 'nl', nativeName: 'Dutch' },
1722
1727
  { locale: 'en', nativeName: 'English' },
1728
+ { locale: 'ar', nativeName: 'Arabic' },
1729
+ { locale: 'bg', nativeName: 'Bulgarian' },
1730
+ { locale: 'zh', nativeName: 'Chinese' },
1731
+ { locale: 'cs', nativeName: 'Czech' },
1732
+ { locale: 'da', nativeName: 'Danish' },
1733
+ { locale: 'et', nativeName: 'Estonian' },
1734
+ { locale: 'fi', nativeName: 'Finnish' },
1735
+ { locale: 'fr', nativeName: 'French' },
1736
+ { locale: 'de-informal', nativeName: 'German' },
1737
+ { locale: 'el', nativeName: 'Greek' },
1738
+ { locale: 'hu', nativeName: 'Hungarian' },
1739
+ { locale: 'it', nativeName: 'Italian' },
1740
+ { locale: 'ja', nativeName: 'Japanese' },
1741
+ { locale: 'lv', nativeName: 'Latvian' },
1742
+ { locale: 'pl', nativeName: 'Polish' },
1743
+ { locale: 'ro', nativeName: 'Romanian' },
1744
+ { locale: 'ru', nativeName: 'Russian' },
1745
+ { locale: 'sk', nativeName: 'Slovak' },
1746
+ { locale: 'sl', nativeName: 'Slovenian' },
1747
+ { locale: 'es-informal', nativeName: 'Spanish' },
1748
+ { locale: 'sv', nativeName: 'Swedish' },
1749
+ { locale: 'ti', nativeName: 'Tigrinya' },
1750
+ { locale: 'tr', nativeName: 'Turkish' },
1751
+ { locale: 'uk', nativeName: 'Ukrainian' },
1723
1752
  ],
1724
1753
  },
1725
1754
  },
@@ -1823,6 +1852,63 @@ const standardState = {
1823
1852
  ],
1824
1853
  },
1825
1854
  },
1855
+ translationProposal: {
1856
+ category: categoryKeys.translations,
1857
+ headingText: 'Show translation proposal',
1858
+ description: '',
1859
+ ...baseState,
1860
+ events: [shortTextMessage, userMessage, userMessageLong],
1861
+ config: {
1862
+ ...baseState.config,
1863
+ showDisclaimer: true,
1864
+ context: {
1865
+ locale: 'nl-informal',
1866
+ },
1867
+ },
1868
+ translations: {
1869
+ ...translationsSlice,
1870
+ translationProposal: {
1871
+ buttonLabel: 'Activate',
1872
+ proposedLocale: 'en-GB',
1873
+ srDismissButtonText: 'Dismiss translation proposal',
1874
+ titleLabel: 'Do you want to chat in English?',
1875
+ },
1876
+ isAvailable: true,
1877
+ isActive: false,
1878
+ languages: [
1879
+ { locale: 'nl-informal', nativeName: 'Dutch' },
1880
+ { locale: 'en-GB', nativeName: 'English' },
1881
+ ],
1882
+ },
1883
+ },
1884
+ translationProposalWithoutTitle: {
1885
+ category: categoryKeys.translations,
1886
+ headingText: 'Show translation proposal without title',
1887
+ description: '',
1888
+ ...baseState,
1889
+ events: [shortTextMessage, userMessage, userMessageLong],
1890
+ config: {
1891
+ ...baseState.config,
1892
+ showDisclaimer: true,
1893
+ context: {
1894
+ locale: 'nl-informal',
1895
+ },
1896
+ },
1897
+ translations: {
1898
+ ...translationsSlice,
1899
+ translationProposal: {
1900
+ buttonLabel: 'Activate',
1901
+ proposedLocale: 'en-GB',
1902
+ srDismissButtonText: 'Dismiss translation proposal',
1903
+ },
1904
+ isAvailable: true,
1905
+ isActive: false,
1906
+ languages: [
1907
+ { locale: 'nl-informal', nativeName: 'Dutch' },
1908
+ { locale: 'en-GB', nativeName: 'English' },
1909
+ ],
1910
+ },
1911
+ },
1826
1912
  }
1827
1913
 
1828
1914
  const inlineInterface = {
@@ -1955,7 +2041,10 @@ const standardWindowStates = {
1955
2041
  description: '',
1956
2042
  window: {
1957
2043
  ...baseState,
1958
- config: { ...baseState.config, layoutMode: 'window' },
2044
+ config: {
2045
+ ...baseState.config,
2046
+ layoutMode: 'window',
2047
+ },
1959
2048
  visibility: {
1960
2049
  ...baseState.visibility,
1961
2050
  visibility: visibilityStates.minimized,
@@ -1968,7 +2057,10 @@ const standardWindowStates = {
1968
2057
  description: '',
1969
2058
  window: {
1970
2059
  ...baseState,
1971
- config: { ...baseState.config, layoutMode: 'window' },
2060
+ config: {
2061
+ ...baseState.config,
2062
+ layoutMode: 'window',
2063
+ },
1972
2064
  visibility: {
1973
2065
  ...baseState.visibility,
1974
2066
  visibility: visibilityStates.minimized,
@@ -2048,6 +2140,7 @@ const buildStandardState = (
2048
2140
  return Object.keys(intermediateState).reduce((acc, key) => {
2049
2141
  const { headingText, category, description, ...rest } =
2050
2142
  intermediateState[key]
2143
+
2051
2144
  return {
2052
2145
  ...acc,
2053
2146
  [key]: {
@@ -2057,7 +2150,10 @@ const buildStandardState = (
2057
2150
  ...layoutModes.reduce(
2058
2151
  (comb, layoutMode) => ({
2059
2152
  ...comb,
2060
- [layoutMode]: { ...rest, config: { ...rest.config, layoutMode } },
2153
+ [layoutMode]: {
2154
+ ...rest,
2155
+ config: { ...rest.config, layoutMode },
2156
+ },
2061
2157
  }),
2062
2158
  {},
2063
2159
  ),
@@ -2074,31 +2170,33 @@ export const getDeprecatedStateObj = (
2074
2170
  ...(layoutModes.indexOf('window') !== -1 ? standardWindowStates : {}),
2075
2171
  })
2076
2172
 
2077
- export const getStateObj = (layoutModes, customComponentEventBodies) => ({
2078
- ...buildStandardState(layoutModes, customComponentEventBodies, true),
2079
- ...(layoutModes.indexOf('window') !== -1
2080
- ? {
2081
- ...standardWindowStates,
2082
- minimizedWindowPrechat: {
2083
- category: categoryKeys.minimizedWindow,
2084
- headingText: 'Minimized with pre-chat messages',
2085
- description: '',
2086
- window: {
2087
- ...baseState,
2088
- config: {
2089
- ...baseState.config,
2090
- layoutMode: 'window',
2091
- preChatEvents: [splashMessage],
2092
- },
2093
- visibility: {
2094
- ...baseState.visibility,
2095
- visibility: visibilityStates.minimized,
2173
+ export const getStateObj = (layoutModes, customComponentEventBodies) => {
2174
+ return {
2175
+ ...buildStandardState(layoutModes, customComponentEventBodies, true),
2176
+ ...(layoutModes.indexOf('window') !== -1
2177
+ ? {
2178
+ ...standardWindowStates,
2179
+ minimizedWindowPrechat: {
2180
+ category: categoryKeys.minimizedWindow,
2181
+ headingText: 'Minimized with pre-chat messages',
2182
+ description: '',
2183
+ window: {
2184
+ ...baseState,
2185
+ config: {
2186
+ ...baseState.config,
2187
+ layoutMode: 'window',
2188
+ preChatEvents: [splashMessage],
2189
+ },
2190
+ visibility: {
2191
+ ...baseState.visibility,
2192
+ visibility: visibilityStates.minimized,
2193
+ },
2194
+ participantInfo,
2195
+ headerTitles,
2096
2196
  },
2097
- participantInfo,
2098
- headerTitles,
2099
2197
  },
2100
- },
2101
- }
2102
- : {}),
2103
- ...inlineInterface,
2104
- })
2198
+ }
2199
+ : {}),
2200
+ ...inlineInterface,
2201
+ }
2202
+ }
@@ -1,5 +1,5 @@
1
- import { render } from 'preact'
2
1
  import { API, Engine } from '@seamly/web-ui'
2
+ import { render } from 'preact'
3
3
  import StyleGuideApp from './components/app'
4
4
 
5
5
  class SeamlyStyleGuideInstance extends Engine {
@@ -1,19 +1,35 @@
1
- import { useSeamlyOptions } from 'ui/hooks/seamly-hooks'
2
- import { className } from 'lib/css'
1
+ import Icon from 'ui/components/layout/icon'
3
2
  import OptionsButton from 'ui/components/options/options-button'
4
- import { useTranslations } from 'domains/translations/hooks'
3
+ import { useSeamlyOptions } from 'ui/hooks/seamly-hooks'
4
+ import { useI18n } from 'domains/i18n/hooks'
5
+ import { useInterrupt } from 'domains/interrupt/hooks'
5
6
  import TranslationsOptionsButton from 'domains/translations/components/options-button'
7
+ import {
8
+ useLocaleNativeName,
9
+ useTranslations,
10
+ } from 'domains/translations/hooks'
11
+ import { className } from 'lib/css'
6
12
 
7
13
  export default function AppOptions() {
8
14
  const { menuOptions, allowOptionSelection } = useSeamlyOptions()
9
15
  const { isAvailable: isTranslationsAvailable } = useTranslations()
16
+ const { hasInterrupt } = useInterrupt()
17
+ const { t, locale } = useI18n()
18
+ const localeNativeName = useLocaleNativeName(locale)
19
+
10
20
  if (
11
- !isTranslationsAvailable &&
12
- (!allowOptionSelection || !menuOptions.length)
21
+ (!isTranslationsAvailable &&
22
+ (!allowOptionSelection || !menuOptions.length)) ||
23
+ hasInterrupt
13
24
  ) {
14
25
  return null
15
26
  }
16
27
 
28
+ const openButtonText = t('translations.settings.openButtonText', {
29
+ hasLanguage: !!localeNativeName,
30
+ language: localeNativeName,
31
+ })
32
+
17
33
  return (
18
34
  <div className={className('chat__options')}>
19
35
  {isTranslationsAvailable && (
@@ -23,7 +39,10 @@ export default function AppOptions() {
23
39
  'chat__options-item--left',
24
40
  )}
25
41
  >
26
- <TranslationsOptionsButton />
42
+ <TranslationsOptionsButton classNames={['button--secondary']}>
43
+ <Icon alt={openButtonText} name="newTranslation" size="16" />
44
+ <span className={className('button__text')}>{openButtonText}</span>
45
+ </TranslationsOptionsButton>
27
46
  </div>
28
47
  )}
29
48
  {allowOptionSelection && (
@@ -1,5 +1,5 @@
1
- import View from './view'
2
1
  import SeamlyCore from './core/seamly-core'
2
+ import View from './view'
3
3
 
4
4
  const ChatApp = (props) => {
5
5
  return (
@@ -0,0 +1,30 @@
1
+ import Icon from 'ui/components/layout/icon'
2
+ import { className } from 'lib/css'
3
+
4
+ type ChatStatusActionProps = {
5
+ handleClick: () => void
6
+ icon: string
7
+ title: string
8
+ srButtonText?: string
9
+ }
10
+
11
+ const ChatStatusAction = ({
12
+ handleClick,
13
+ icon,
14
+ title,
15
+ srButtonText,
16
+ }: ChatStatusActionProps) => (
17
+ <button
18
+ type="button"
19
+ onClick={handleClick}
20
+ className={className('button', 'button--primary', 'chat-status__button')}
21
+ >
22
+ <Icon name={icon} size="16" alt="" />
23
+ {title}
24
+ {srButtonText && (
25
+ <span className={className('visually-hidden')}>{srButtonText}</span>
26
+ )}
27
+ </button>
28
+ )
29
+
30
+ export default ChatStatusAction
@@ -0,0 +1,61 @@
1
+ import { FC } from 'preact/compat'
2
+ import Icon from 'ui/components/layout/icon'
3
+ import { useGeneratedId } from 'ui/hooks/utility-hooks'
4
+ import { className } from 'lib/css'
5
+
6
+ type ChatStatusProps = {
7
+ handleClose: () => void
8
+ title: string
9
+ closeButtonText?: string
10
+ srCloseButtonText?: string
11
+ id: string
12
+ }
13
+
14
+ const ChatStatus: FC<ChatStatusProps> = ({
15
+ children,
16
+ handleClose,
17
+ title,
18
+ closeButtonText,
19
+ srCloseButtonText,
20
+ id,
21
+ }) => {
22
+ const headingId = useGeneratedId()
23
+
24
+ return (
25
+ <section
26
+ tabIndex={-1}
27
+ id={id}
28
+ aria-labelledby={title ? headingId : undefined}
29
+ className={className('chat-status', !title && 'chat-status--condensed')}
30
+ >
31
+ <div className={className('chat-status__body')}>
32
+ {title ? (
33
+ <h2 className={className('chat-status__title')} id={headingId}>
34
+ {title}
35
+ </h2>
36
+ ) : null}
37
+ {children}
38
+ </div>
39
+ {typeof handleClose === 'function' && (
40
+ <button
41
+ type="button"
42
+ onClick={handleClose}
43
+ className={className(
44
+ 'button',
45
+ 'button--tertiary',
46
+ 'chat-status__close',
47
+ )}
48
+ >
49
+ {closeButtonText || <Icon name="close" size="16" alt="" />}
50
+ {srCloseButtonText && (
51
+ <span className={className('visually-hidden')}>
52
+ {srCloseButtonText}
53
+ </span>
54
+ )}
55
+ </button>
56
+ )}
57
+ </section>
58
+ )
59
+ }
60
+
61
+ export default ChatStatus
@@ -1,20 +1,20 @@
1
1
  import { useMemo } from 'preact/hooks'
2
2
  import { useConfig } from 'domains/config/hooks'
3
3
  import ComponentContext from './component-context'
4
+ import CardMessage from './event/card-message'
5
+ import CarouselMessage from './event/carousel-message'
4
6
  import ChoicePrompt from './event/choice-prompt'
5
- import Text from './event/text'
6
- import Image from './event/image'
7
- import Video from './event/video'
7
+ import ConversationSuggestions from './event/conversation-suggestions'
8
+ import Cta from './event/cta'
8
9
  import Divider from './event/divider'
9
- import Translation from './event/translation'
10
+ import TimeIndicator from './event/divider/variants/time-indicator'
11
+ import Image from './event/image'
10
12
  import Participant from './event/participant'
11
13
  import Splash from './event/splash'
14
+ import Text from './event/text'
15
+ import Translation from './event/translation'
12
16
  import Upload from './event/upload'
13
- import Cta from './event/cta'
14
- import TimeIndicator from './event/divider/variants/time-indicator'
15
- import CarouselMessage from './event/carousel-message'
16
- import CardMessage from './event/card-message'
17
- import ConversationSuggestions from './event/conversation-suggestions'
17
+ import Video from './event/video'
18
18
 
19
19
  const eventTypeMapping = {
20
20
  message: {