@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
@@ -1,60 +1,88 @@
1
- import { useRef, useEffect } from 'preact/hooks'
1
+ import { VNode } from 'preact'
2
+ import { FC } from 'preact/compat'
3
+ import { MutableRef, useCallback, useEffect } from 'preact/hooks'
2
4
  import Icon from 'ui/components/layout/icon'
3
5
  import {
4
6
  useGeneratedId,
5
7
  useOptionButton,
6
8
  useSeamlyOptions,
7
9
  } from 'ui/hooks/seamly-hooks'
8
- import { className } from 'lib/css'
10
+ import useClickOutside from 'ui/hooks/use-click-outside'
9
11
  import { focusElement } from 'ui/utils/general-utils'
12
+ import { className } from 'lib/css'
13
+
14
+ export type FramePosition = {
15
+ vertical: 'top' | 'bottom'
16
+ horizontal: 'left' | 'right'
17
+ }
10
18
 
11
- const OptionsFrame = ({
19
+ type OptionsFrameProps = {
20
+ className?: string
21
+ onCancel?: () => void
22
+ headingText: string
23
+ description?: VNode
24
+ descriptionId?: string
25
+ cancelButtonText?: string
26
+ cancelButtonRef?: MutableRef<HTMLElement>
27
+ disableButtonFocusing?: boolean
28
+ position: FramePosition
29
+ }
30
+
31
+ const OptionsFrame: FC<OptionsFrameProps> = ({
12
32
  className: givenClassName,
13
33
  children,
14
34
  onCancel,
15
35
  headingText,
36
+ description,
37
+ descriptionId,
16
38
  cancelButtonText,
17
- disableButtonFocusing,
18
39
  cancelButtonRef,
19
- position = 'right',
40
+ disableButtonFocusing,
41
+ position = {
42
+ horizontal: 'left',
43
+ vertical: 'top',
44
+ },
20
45
  }) => {
21
- const container = useRef(null)
22
46
  const mainHeadingId = useGeneratedId()
23
47
  // @todo Lift this from the "options frame" into something reusable
24
48
  // when you're not using options
25
49
  const { hideOption } = useSeamlyOptions()
26
50
  const { focusButton } = useOptionButton()
27
51
 
28
- useEffect(() => {
29
- focusElement(container.current)
30
- }, [])
31
-
32
- const closePanel = () => {
52
+ const closePanel = useCallback(() => {
33
53
  hideOption()
34
54
  if (!disableButtonFocusing) {
35
55
  focusButton()
36
56
  }
37
- }
57
+ }, [disableButtonFocusing, focusButton, hideOption])
38
58
 
39
- const onCancelHandler = () => {
59
+ const onCancelHandler = useCallback(() => {
40
60
  if (onCancel) {
41
61
  onCancel()
42
62
  }
43
63
  closePanel()
44
- }
64
+ }, [closePanel, onCancel])
65
+
66
+ const container = useClickOutside(onCancelHandler)
67
+
68
+ useEffect(() => {
69
+ focusElement(container.current)
70
+ }, [container])
45
71
 
46
72
  return (
47
73
  <section
48
74
  className={className(
49
75
  'options',
50
76
  {
51
- 'options--right': position !== 'left',
52
- 'options--left': position === 'left',
77
+ 'options--right': position.horizontal === 'right',
78
+ 'options--left': position.horizontal === 'left',
79
+ 'options--top': position.vertical === 'top',
80
+ 'options--bottom': position.vertical === 'bottom',
53
81
  },
54
82
  givenClassName,
55
83
  )}
56
84
  aria-labelledby={mainHeadingId}
57
- tabIndex="-1"
85
+ tabIndex={-1}
58
86
  ref={container}
59
87
  >
60
88
  <div className={className('options__body')}>
@@ -72,9 +100,15 @@ const OptionsFrame = ({
72
100
  }
73
101
  }}
74
102
  >
75
- <Icon name="close" size="16" />
103
+ <Icon name="close" size="16" alt="" />
76
104
  <span>{cancelButtonText}</span>
77
105
  </button>
106
+
107
+ {description ? (
108
+ <p className={className('options__description')} id={descriptionId}>
109
+ {description}
110
+ </p>
111
+ ) : null}
78
112
  <div className={className('options__wrapper')}>{children}</div>
79
113
  </div>
80
114
  </section>
@@ -1,17 +1,16 @@
1
1
  import { useCallback, useMemo, useState } from 'preact/hooks'
2
- import { useI18n } from 'domains/i18n/hooks'
3
2
  import OptionsFrame from 'ui/components/options/options-frame'
4
- import { className } from 'lib/css'
5
3
  import {
6
4
  useGeneratedId,
7
5
  useOptionButton,
8
6
  useSeamlyCommands,
9
7
  useSeamlyOptions,
10
8
  } from 'ui/hooks/seamly-hooks'
11
- import { actionTypes } from 'ui/utils/seamly-utils'
12
- import FormProvider from 'domains/forms/provider'
13
9
  import { getValidator } from 'ui/utils/form-utils'
10
+ import { actionTypes } from 'ui/utils/seamly-utils'
14
11
  import { isEmailString, isNotEmptyString } from 'ui/utils/validations'
12
+ import FormProvider from 'domains/forms/provider'
13
+ import { useI18n } from 'domains/i18n/hooks'
15
14
  import TranscriptForm from './transcript-form'
16
15
 
17
16
  const formId = 'sendTranscript'
@@ -67,13 +66,13 @@ const Transcript = () => {
67
66
  className={errorClass}
68
67
  headingText={t('options.sendTranscript.title')}
69
68
  cancelButtonText={t('options.cancelButtonText')}
69
+ description={t('options.sendTranscript.description')}
70
+ descriptionId={transcriptDescriptionId}
71
+ position={{
72
+ vertical: 'top',
73
+ horizontal: 'right',
74
+ }}
70
75
  >
71
- <p
72
- className={className('options__description')}
73
- id={transcriptDescriptionId}
74
- >
75
- {t('options.sendTranscript.description')}
76
- </p>
77
76
  <FormProvider
78
77
  formId={formId}
79
78
  onSubmit={handleSubmit}
@@ -1,7 +1,7 @@
1
- import { className } from 'lib/css'
2
- import { useI18n } from 'domains/i18n/hooks'
3
1
  import Form from 'ui/components/form-controls/form'
4
2
  import Input from 'ui/components/form-controls/input'
3
+ import { useI18n } from 'domains/i18n/hooks'
4
+ import { className } from 'lib/css'
5
5
 
6
6
  export default function TranscriptForm({ controlName, describedById }) {
7
7
  const { t } = useI18n()
@@ -1,11 +1,3 @@
1
- import { useUserHasResponded } from 'domains/app/hooks'
2
- import { useConfig } from 'domains/config/hooks'
3
- import { useI18n } from 'domains/i18n/hooks'
4
- import { useInterrupt } from 'domains/interrupt/hooks'
5
- import { useTranslatedEventData } from 'domains/translations/hooks'
6
- import { visibilityStates } from 'domains/visibility/constants'
7
- import { useVisibility } from 'domains/visibility/hooks'
8
- import { className } from 'lib/css'
9
1
  import { useCallback, useEffect, useMemo, useRef } from 'preact/hooks'
10
2
  import SuggestionsList from 'ui/components/suggestions/suggestions-list'
11
3
  import InOutTransition, {
@@ -23,6 +15,14 @@ import useSeamlyResumeConversationPrompt from 'ui/hooks/use-seamly-resume-conver
23
15
  import { useGeneratedId } from 'ui/hooks/utility-hooks'
24
16
  import { runIfElementContainsOrHasFocus } from 'ui/utils/general-utils'
25
17
  import { actionTypes } from 'ui/utils/seamly-utils'
18
+ import { useUserHasResponded } from 'domains/app/hooks'
19
+ import { useConfig } from 'domains/config/hooks'
20
+ import { useI18n } from 'domains/i18n/hooks'
21
+ import { useInterrupt } from 'domains/interrupt/hooks'
22
+ import { useTranslatedEventData } from 'domains/translations/hooks'
23
+ import { visibilityStates } from 'domains/visibility/constants'
24
+ import { useVisibility } from 'domains/visibility/hooks'
25
+ import { className } from 'lib/css'
26
26
 
27
27
  const Suggestions = ({ isAside = false }) => {
28
28
  // generic hooks
@@ -1,4 +1,4 @@
1
- import { useMemo, useCallback } from 'preact/hooks'
1
+ import { useCallback, useMemo } from 'preact/hooks'
2
2
  import { className } from '../../../lib/css'
3
3
  import Icon from '../layout/icon'
4
4
 
@@ -1,41 +1,40 @@
1
1
  import { useCallback } from 'preact/hooks'
2
2
  import ChatStatus from 'ui/components/chat-status'
3
+ import { useSkiplinkTargetFocusing } from 'ui/hooks/focus-helper-hooks'
3
4
  import { useI18n } from 'domains/i18n/hooks'
4
- import { useSkiplinkTargetFocusing } from 'ui/hooks/seamly-hooks'
5
+ import { useInterrupt } from 'domains/interrupt/hooks'
5
6
  import {
6
- useTranslationsContainer,
7
- useTranslations,
8
7
  useLocaleNativeName,
8
+ useTranslations,
9
+ useTranslationsContainer,
9
10
  } from 'domains/translations/hooks'
10
- import { useInterrupt } from 'domains/interrupt/hooks'
11
11
 
12
- export default function TranslationsChatStatus() {
12
+ export default function TranslationChatStatus() {
13
13
  const { t } = useI18n()
14
14
  const { id } = useTranslationsContainer()
15
15
  const { hasInterrupt } = useInterrupt()
16
-
17
- const { isActive, disableTranslations, currentLocale } = useTranslations()
16
+ const { disableTranslations, currentLocale } = useTranslations()
18
17
  const localeNativeName = useLocaleNativeName(currentLocale)
19
-
20
18
  const focusSkiplinkTarget = useSkiplinkTargetFocusing()
21
19
 
20
+ const label = t('translations.status.label', { language: localeNativeName })
21
+
22
22
  const handleClickStop = useCallback(() => {
23
23
  disableTranslations()
24
24
  focusSkiplinkTarget()
25
25
  }, [disableTranslations, focusSkiplinkTarget])
26
26
 
27
- if (!isActive || hasInterrupt) {
27
+ if (hasInterrupt) {
28
28
  return null
29
29
  }
30
30
 
31
31
  return (
32
32
  <ChatStatus
33
- type="translations"
33
+ handleClose={handleClickStop}
34
+ title={label}
34
35
  id={id}
35
- label={t('translations.status.label', { language: localeNativeName })}
36
- onButtonClick={handleClickStop}
37
- buttonText={t('translations.status.stopText')}
38
- srButtonText={t('translations.status.srStopText')}
36
+ closeButtonText={t('translations.status.stopText')}
37
+ srCloseButtonText={t('translations.status.srStopText')}
39
38
  />
40
39
  )
41
40
  }
@@ -0,0 +1,36 @@
1
+ import ChatStatus from 'ui/components/chat-status'
2
+ import ChatStatusAction from 'ui/components/chat-status/chat-status-action'
3
+ import {
4
+ useTranslationProposal,
5
+ useTranslationsContainer,
6
+ } from 'domains/translations/hooks'
7
+
8
+ export default function TranslationProposal() {
9
+ const {
10
+ showProposal,
11
+ translationProposal,
12
+ dismissTranslationProposal,
13
+ activateTranslationProposal,
14
+ } = useTranslationProposal()
15
+
16
+ const { id } = useTranslationsContainer()
17
+
18
+ if (!showProposal) {
19
+ return null
20
+ }
21
+
22
+ return (
23
+ <ChatStatus
24
+ handleClose={dismissTranslationProposal}
25
+ srCloseButtonText={translationProposal.srDismissButtonText}
26
+ id={id}
27
+ title={translationProposal.titleLabel}
28
+ >
29
+ <ChatStatusAction
30
+ handleClick={activateTranslationProposal}
31
+ icon="newTranslation"
32
+ title={translationProposal.buttonLabel}
33
+ />
34
+ </ChatStatus>
35
+ )
36
+ }
@@ -1,18 +1,13 @@
1
- import Chat from '../layout/chat'
2
- import Interrupt from '../layout/interrupt'
3
1
  import Conversation from '../conversation/conversation'
4
- import EntryContainer from '../entry/entry-container'
2
+ import Chat from '../layout/chat'
5
3
  import ChatFrame from '../layout/chat-frame'
6
- import useSeamlyChat from '../../hooks/use-seamly-chat'
4
+ import Interrupt from '../layout/interrupt'
7
5
 
8
6
  const AppView = () => {
9
- useSeamlyChat()
10
-
11
7
  return (
12
8
  <Chat>
13
9
  <ChatFrame interruptComponent={Interrupt}>
14
10
  <Conversation />
15
- <EntryContainer />
16
11
  </ChatFrame>
17
12
  </Chat>
18
13
  )
@@ -1,13 +1,12 @@
1
- import { useVisibility, useShowInlineView } from 'domains/visibility/hooks'
2
- import DeprecatedAppFrame from '../layout/deprecated-app-frame'
3
- import ChatFrame from '../layout/chat-frame'
1
+ import ChatFrame from 'ui/components/layout/deprecated-chat-frame'
2
+ import { useShowInlineView, useVisibility } from 'domains/visibility/hooks'
3
+ import { useSeamlyChat } from '../../hooks/seamly-hooks'
4
+ import Conversation from '../conversation/conversation'
5
+ import DeprecatedToggleButton from '../entry/deprecated-toggle-button'
4
6
  import AgentInfo from '../layout/agent-info'
7
+ import DeprecatedAppFrame from '../layout/deprecated-app-frame'
5
8
  import Header from '../layout/header'
6
- import Conversation from '../conversation/conversation'
7
- import EntryContainer from '../entry/entry-container'
8
9
  import Interrupt from '../layout/interrupt'
9
- import { useSeamlyChat } from '../../hooks/seamly-hooks'
10
- import DeprecatedToggleButton from '../entry/deprecated-toggle-button'
11
10
 
12
11
  const ShowInlineView = ({ children }) => {
13
12
  const { showInlineView, containerRef } = useShowInlineView()
@@ -16,8 +15,8 @@ const ShowInlineView = ({ children }) => {
16
15
  }
17
16
 
18
17
  const DeprecatedView = () => {
19
- const { isVisible } = useVisibility()
20
- const { openChat, closeChat } = useSeamlyChat()
18
+ useSeamlyChat()
19
+ const { isVisible, openChat, closeChat } = useVisibility()
21
20
 
22
21
  return (
23
22
  isVisible && (
@@ -29,7 +28,6 @@ const DeprecatedView = () => {
29
28
  </Header>
30
29
  <ChatFrame interruptComponent={Interrupt}>
31
30
  <Conversation />
32
- <EntryContainer />
33
31
  </ChatFrame>
34
32
  </DeprecatedAppFrame>
35
33
  </ShowInlineView>
@@ -1,13 +1,13 @@
1
- import { useUserHasResponded } from 'domains/app/hooks'
2
1
  import { useCallback, useMemo } from 'preact/hooks'
3
- import { useVisibility } from 'domains/visibility/hooks'
4
- import { useSeamlyContainerElement } from 'ui/hooks/focus-helper-hooks'
5
- import { useConfig } from 'domains/config/hooks'
6
- import { useSeamlyAppContainerClassNames } from 'ui/hooks/component-helper-hooks'
7
- import { useI18n } from 'domains/i18n/hooks'
8
2
  import AppView from 'ui/components/view/app-view'
9
3
  import InlineView from 'ui/components/view/inline-view'
10
4
  import WindowView from 'ui/components/view/window-view'
5
+ import { useSeamlyAppContainerClassNames } from 'ui/hooks/component-helper-hooks'
6
+ import { useSeamlyContainerElement } from 'ui/hooks/focus-helper-hooks'
7
+ import { useUserHasResponded } from 'domains/app/hooks'
8
+ import { useConfig } from 'domains/config/hooks'
9
+ import { useI18n } from 'domains/i18n/hooks'
10
+ import { useVisibility } from 'domains/visibility/hooks'
11
11
  import { className } from 'lib/css'
12
12
 
13
13
  const ViewComponentsMap = {
@@ -1,12 +1,10 @@
1
- import { className } from 'lib/css'
2
- import { useVisibility, useShowInlineView } from 'domains/visibility/hooks'
3
1
  import { useInterrupt } from 'domains/interrupt/hooks'
4
- import Chat from '../layout/chat'
5
- import Interrupt from '../layout/interrupt'
2
+ import { useShowInlineView, useVisibility } from 'domains/visibility/hooks'
3
+ import { className } from 'lib/css'
6
4
  import Conversation from '../conversation/conversation'
7
- import EntryContainer from '../entry/entry-container'
5
+ import Chat from '../layout/chat'
8
6
  import ChatFrame from '../layout/chat-frame'
9
- import useSeamlyChat from '../../hooks/use-seamly-chat'
7
+ import Interrupt from '../layout/interrupt'
10
8
  import PreChatMessages from '../layout/pre-chat-messages'
11
9
  import Suggestions from '../suggestions'
12
10
  import InOutTransition, {
@@ -14,7 +12,6 @@ import InOutTransition, {
14
12
  } from '../widgets/in-out-transition'
15
13
 
16
14
  const InlineView = () => {
17
- useSeamlyChat()
18
15
  const { showInlineView, containerRef } = useShowInlineView()
19
16
 
20
17
  const { isOpen } = useVisibility()
@@ -49,7 +46,6 @@ const InlineView = () => {
49
46
  {showInlineView && (
50
47
  <ChatFrame interruptComponent={Interrupt}>
51
48
  {isOpen && <Conversation />}
52
- <EntryContainer />
53
49
  </ChatFrame>
54
50
  )}
55
51
  </Chat>
@@ -1,7 +1,7 @@
1
+ import { useCallback } from 'preact/hooks'
2
+ import Icon from 'ui/components/layout/icon'
1
3
  import { useI18n } from 'domains/i18n/hooks'
2
4
  import { className } from 'lib/css'
3
- import Icon from 'ui/components/layout/icon'
4
- import { useCallback } from 'preact/hooks'
5
5
 
6
6
  const CollapseButton = ({ onClick }) => {
7
7
  const { t } = useI18n()
@@ -1,25 +1,21 @@
1
- import { useUserHasResponded } from 'domains/app/hooks'
2
1
  import { useMemo } from 'preact/hooks'
2
+ import Conversation from 'ui/components/conversation/conversation'
3
+ import Text from 'ui/components/conversation/event/text'
4
+ import Chat from 'ui/components/layout/chat'
5
+ import ChatFrame from 'ui/components/layout/chat-frame'
6
+ import Interrupt from 'ui/components/layout/interrupt'
7
+ import PreChatMessages from 'ui/components/layout/pre-chat-messages'
8
+ import InOutTransition, {
9
+ transitionStartStates,
10
+ } from 'ui/components/widgets/in-out-transition'
11
+ import { useUserHasResponded } from 'domains/app/hooks'
3
12
  import { useI18n } from 'domains/i18n/hooks'
4
13
  import { useVisibility } from 'domains/visibility/hooks'
5
14
  import { className } from 'lib/css'
6
- import { useSeamlyChat } from '../../../hooks/seamly-hooks'
7
- import Conversation from '../../conversation/conversation'
8
- import Text from '../../conversation/event/text'
9
- import EntryContainer from '../../entry/entry-container'
10
- import Chat from '../../layout/chat'
11
- import ChatFrame from '../../layout/chat-frame'
12
- import Interrupt from '../../layout/interrupt'
13
- import PreChatMessages from '../../layout/pre-chat-messages'
14
- import InOutTransition, {
15
- transitionStartStates,
16
- } from '../../widgets/in-out-transition'
17
- import CollapseButton from './collapse-button'
18
15
  import WindowOpenButton from './window-open-button'
19
16
 
20
17
  const WindowView = () => {
21
- const { openChat, closeChat } = useSeamlyChat()
22
- const { isOpen } = useVisibility()
18
+ const { isOpen, openChat } = useVisibility()
23
19
  const userHasResponded = useUserHasResponded()
24
20
  const { t } = useI18n()
25
21
  const continueChatText = t('window.chat.continue')
@@ -68,10 +64,8 @@ const WindowView = () => {
68
64
  transitionStartState={transitionStartStates.notRendered}
69
65
  >
70
66
  <Chat>
71
- {isOpen && <CollapseButton onClick={closeChat} />}
72
67
  <ChatFrame interruptComponent={Interrupt}>
73
68
  <Conversation />
74
- <EntryContainer />
75
69
  </ChatFrame>
76
70
  </Chat>
77
71
  </InOutTransition>
@@ -1,10 +1,5 @@
1
- import { useStartChatIcon } from 'domains/config/hooks'
2
- import { useI18n } from 'domains/i18n/hooks'
3
- import { useInterrupt } from 'domains/interrupt/hooks'
4
- import { useVisibility } from 'domains/visibility/hooks'
5
- import { className } from 'lib/css'
6
- import Icon from 'ui/components/layout/icon'
7
1
  import { useCallback } from 'preact/hooks'
2
+ import Icon from 'ui/components/layout/icon'
8
3
  import InOutTransition, {
9
4
  transitionStartStates,
10
5
  } from 'ui/components/widgets/in-out-transition'
@@ -14,6 +9,11 @@ import {
14
9
  useSeamlyCurrentAgent,
15
10
  useSeamlyUnreadCount,
16
11
  } from 'ui/hooks/seamly-state-hooks'
12
+ import { useStartChatIcon } from 'domains/config/hooks'
13
+ import { useI18n } from 'domains/i18n/hooks'
14
+ import { useInterrupt } from 'domains/interrupt/hooks'
15
+ import { useVisibility } from 'domains/visibility/hooks'
16
+ import { className } from 'lib/css'
17
17
 
18
18
  const ButtonIcon = () => {
19
19
  const startChatIcon = useStartChatIcon()
@@ -1,9 +1,9 @@
1
- import { className } from 'lib/css'
2
- import { useI18n } from 'domains/i18n/hooks'
3
- import useSeamlyIdleDetachCountdown from 'ui/hooks/use-seamly-idle-detach-countdown'
4
1
  import { useSkiplinkTargetFocusing } from 'ui/hooks/focus-helper-hooks'
5
2
  import useSeamlyActivityEventHandler from 'ui/hooks/use-seamly-activity-event-handler'
6
3
  import useSeamlyCommands from 'ui/hooks/use-seamly-commands'
4
+ import useSeamlyIdleDetachCountdown from 'ui/hooks/use-seamly-idle-detach-countdown'
5
+ import { useI18n } from 'domains/i18n/hooks'
6
+ import { className } from 'lib/css'
7
7
  import Prompt from './prompt'
8
8
 
9
9
  const IdleDetachWarning = () => {
@@ -1,5 +1,5 @@
1
+ import { useGeneratedId, useSkiplink } from 'ui/hooks/seamly-hooks'
1
2
  import { className } from 'lib/css'
2
- import { useSkiplink, useGeneratedId } from 'ui/hooks/seamly-hooks'
3
3
 
4
4
  const Prompt = ({ baseClassName, children, title }) => {
5
5
  const skiplinkTargetId = useSkiplink()
@@ -1,8 +1,8 @@
1
- import { className } from 'lib/css'
2
- import { useI18n } from 'domains/i18n/hooks'
3
- import useSeamlyResumeConversationPrompt from 'ui/hooks/use-seamly-resume-conversation-prompt'
4
- import useSeamlyActivityEventHandler from 'ui/hooks/use-seamly-activity-event-handler'
5
1
  import { useSeamlyCurrentAgent } from 'ui/hooks/seamly-state-hooks'
2
+ import useSeamlyActivityEventHandler from 'ui/hooks/use-seamly-activity-event-handler'
3
+ import useSeamlyResumeConversationPrompt from 'ui/hooks/use-seamly-resume-conversation-prompt'
4
+ import { useI18n } from 'domains/i18n/hooks'
5
+ import { className } from 'lib/css'
6
6
  import Prompt from './prompt'
7
7
 
8
8
  const ResumeConversationPrompt = () => {
@@ -1,8 +1,8 @@
1
- import { toChildArray, cloneElement } from 'preact'
2
- import { useRef, useState, useEffect } from 'preact/hooks'
1
+ import { cloneElement, toChildArray } from 'preact'
2
+ import { useEffect, useRef, useState } from 'preact/hooks'
3
+ import { defaultTransitionTimeMs } from 'config'
3
4
  import { useStableCallback } from 'ui/hooks/seamly-hooks'
4
5
  import { className } from 'lib/css'
5
- import { defaultTransitionTimeMs } from 'config'
6
6
 
7
7
  const transitionClasses = {
8
8
  visible: className('transition--visible'),
@@ -21,13 +21,13 @@ export const transitionStartStates = {
21
21
  const InOutTransition = ({
22
22
  children,
23
23
  isActive,
24
- timeout,
24
+ timeout = defaultTransitionTimeMs,
25
25
  transitionStartState = transitionStartStates.notRendered,
26
- onInTransitionComplete,
27
- onOutTransitionComplete,
26
+ onInTransitionComplete = () => {},
27
+ onOutTransitionComplete = () => {},
28
28
  }) => {
29
29
  const prevIsActive = useRef(false)
30
- const timeoutVal = timeout ? parseInt(timeout, 10) : defaultTransitionTimeMs
30
+ const timeoutVal = parseInt(timeout, 10)
31
31
 
32
32
  const onInTransitionCompleteHandler = useStableCallback(
33
33
  onInTransitionComplete,
@@ -98,17 +98,19 @@ const InOutTransition = ({
98
98
  ])
99
99
 
100
100
  return (
101
- renderChildren &&
102
- toChildArray(children).map((child) => {
103
- const { className: childClassName = '' } = child.props
104
- const cleanClasses = childClassName
105
- .split(' ')
106
- .filter((cl) => !transitionClassesArray.includes(cl))
107
-
108
- return cloneElement(child, {
109
- className: [...cleanClasses, ...activeTransitionClasses].join(' '),
110
- })
111
- })
101
+ <>
102
+ {renderChildren &&
103
+ toChildArray(children).map((child) => {
104
+ const { className: childClassName = '' } = child.props
105
+ const cleanClasses = childClassName
106
+ .split(' ')
107
+ .filter((cl) => !transitionClassesArray.includes(cl))
108
+
109
+ return cloneElement(child, {
110
+ className: [...cleanClasses, ...activeTransitionClasses].join(' '),
111
+ })
112
+ })}
113
+ </>
112
114
  )
113
115
  }
114
116
 
@@ -1,12 +1,12 @@
1
1
  import { useRef } from 'preact/hooks'
2
- import { useI18n } from 'domains/i18n/hooks'
2
+ import Icon from 'ui/components/layout/icon'
3
3
  import {
4
4
  useSeamlyActivityEventHandler,
5
5
  useSeamlyAppContainerClassNames,
6
6
  } from 'ui/hooks/seamly-hooks'
7
- import { className } from 'lib/css'
8
- import Icon from 'ui/components/layout/icon'
9
7
  import { useConfig } from 'domains/config/hooks'
8
+ import { useI18n } from 'domains/i18n/hooks'
9
+ import { className } from 'lib/css'
10
10
  import Modal from './modal'
11
11
 
12
12
  const Lightbox = ({ url, description, onClose: onCloseHandler }) => {
@@ -1,8 +1,8 @@
1
1
  import { render, toChildArray } from 'preact'
2
+ import { useEffect, useLayoutEffect, useRef, useState } from 'preact/hooks'
2
3
  import { createFocusTrap } from 'focus-trap'
3
- import { useLayoutEffect, useEffect, useRef, useState } from 'preact/hooks'
4
- import { createAriaHider } from 'ui/utils/general-utils'
5
4
  import { useGeneratedId } from 'ui/hooks/seamly-hooks'
5
+ import { createAriaHider } from 'ui/utils/general-utils'
6
6
 
7
7
  const Modal = ({
8
8
  children,
@@ -1,7 +1,7 @@
1
- import { className } from 'lib/css'
1
+ import Error from 'ui/components/form-controls/error'
2
2
  import { useFileUploads } from 'ui/hooks/seamly-hooks'
3
3
  import { useI18n } from 'domains/i18n/hooks'
4
- import Error from 'ui/components/form-controls/error'
4
+ import { className } from 'lib/css'
5
5
 
6
6
  const UploadProgress = () => {
7
7
  const { t } = useI18n()
@@ -1,7 +1,7 @@
1
- import { clearAllUploads } from 'domains/store/slice'
2
1
  import { useCallback, useContext } from 'preact/hooks'
3
2
  import { useDispatch } from 'react-redux'
4
3
  import SeamlyFileUploadContext from 'ui/components/core/seamly-file-upload-context'
4
+ import { clearAllUploads } from 'domains/store/slice'
5
5
  import { useSeamlyStateContext } from './seamly-state-hooks'
6
6
 
7
7
  const useSeamlyFileUploadContext = () => useContext(SeamlyFileUploadContext)