@seamly/web-ui 18.1.1 → 18.3.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 (165) hide show
  1. package/build/dist/lib/index.debug.js +286 -99
  2. package/build/dist/lib/index.debug.min.js +1 -1
  3. package/build/dist/lib/index.debug.min.js.LICENSE.txt +84 -16
  4. package/build/dist/lib/index.js +4104 -3887
  5. package/build/dist/lib/index.min.js +1 -1
  6. package/build/dist/lib/standalone.js +4351 -4084
  7. package/build/dist/lib/standalone.min.js +1 -1
  8. package/build/dist/lib/style-guide.js +746 -641
  9. package/build/dist/lib/style-guide.min.js +1 -1
  10. package/build/dist/lib/styles.css +1 -1
  11. package/build/dist/lib/utils.js +0 -1
  12. package/build/dist/lib/utils.min.js +1 -1
  13. package/build/dist/translations/de-informal.js +0 -1
  14. package/build/dist/translations/de-informal.min.js +1 -1
  15. package/build/dist/translations/en.js +0 -1
  16. package/build/dist/translations/en.min.js +1 -1
  17. package/build/dist/translations/es-informal.js +0 -1
  18. package/build/dist/translations/es-informal.min.js +1 -1
  19. package/build/dist/translations/nl-formal.js +0 -1
  20. package/build/dist/translations/nl-formal.min.js +1 -1
  21. package/build/dist/translations/nl-informal.js +0 -1
  22. package/build/dist/translations/nl-informal.min.js +1 -1
  23. package/package.json +4 -2
  24. package/src/javascripts/api/index.js +9 -9
  25. package/src/javascripts/api/producer.js +8 -8
  26. package/src/javascripts/config.js +9 -11
  27. package/src/javascripts/domains/app/actions.js +25 -0
  28. package/src/javascripts/domains/app/index.js +3 -0
  29. package/src/javascripts/domains/config/actions.js +6 -0
  30. package/src/javascripts/domains/config/hooks.js +6 -0
  31. package/src/javascripts/domains/config/index.js +8 -0
  32. package/src/javascripts/domains/config/middleware.js +26 -0
  33. package/src/javascripts/domains/config/reducer.js +74 -0
  34. package/src/javascripts/domains/config/selectors.js +23 -0
  35. package/src/javascripts/domains/forms/actions.js +1 -1
  36. package/src/javascripts/domains/forms/hooks.js +10 -14
  37. package/src/javascripts/domains/forms/provider.js +4 -6
  38. package/src/javascripts/domains/forms/selectors.js +3 -3
  39. package/src/javascripts/domains/i18n/index.js +9 -5
  40. package/src/javascripts/domains/interrupt/actions.js +6 -0
  41. package/src/javascripts/domains/interrupt/hooks.js +29 -0
  42. package/src/javascripts/domains/interrupt/index.js +9 -0
  43. package/src/javascripts/domains/interrupt/middleware.js +30 -0
  44. package/src/javascripts/domains/interrupt/reducer.js +22 -0
  45. package/src/javascripts/domains/interrupt/selectors.js +5 -0
  46. package/src/javascripts/domains/options/index.js +1 -0
  47. package/src/javascripts/domains/options/middleware.js +35 -0
  48. package/src/javascripts/domains/redux/create-redux-store.js +14 -6
  49. package/src/javascripts/domains/redux/hooks.js +2 -2
  50. package/src/javascripts/domains/redux/index.js +2 -1
  51. package/src/javascripts/domains/redux/provider.js +5 -0
  52. package/src/javascripts/domains/store/index.js +38 -0
  53. package/src/javascripts/{ui → domains}/store/state-reducer.js +4 -7
  54. package/src/javascripts/domains/translations/actions.js +3 -3
  55. package/src/javascripts/domains/translations/components/chat-status.js +6 -12
  56. package/src/javascripts/domains/translations/components/options-button.js +3 -3
  57. package/src/javascripts/domains/translations/components/options-dialog/form.js +2 -2
  58. package/src/javascripts/domains/translations/components/options-dialog/index.js +2 -5
  59. package/src/javascripts/domains/translations/hooks.js +1 -1
  60. package/src/javascripts/domains/translations/reducer.js +2 -2
  61. package/src/javascripts/domains/translations/selectors.js +2 -2
  62. package/src/javascripts/index.js +17 -5
  63. package/src/javascripts/lib/css.js +5 -5
  64. package/src/javascripts/lib/engine/index.js +38 -11
  65. package/src/javascripts/lib/external-api/index.js +6 -6
  66. package/src/javascripts/lib/i18n.js +2 -2
  67. package/src/javascripts/lib/parse-body.js +1 -1
  68. package/src/javascripts/lib/redux-helpers/index.js +18 -4
  69. package/src/javascripts/lib/split-url-params.js +2 -2
  70. package/src/javascripts/lib/store/providers/app-storage.js +1 -1
  71. package/src/javascripts/lib/store/providers/cookie-storage.js +1 -1
  72. package/src/javascripts/package/utils.js +0 -1
  73. package/src/javascripts/style-guide/components/app.js +5 -12
  74. package/src/javascripts/style-guide/components/links.js +6 -6
  75. package/src/javascripts/style-guide/components/static-core.js +23 -7
  76. package/src/javascripts/style-guide/state-helpers/index.js +1 -1
  77. package/src/javascripts/style-guide/states.js +27 -67
  78. package/src/javascripts/style-guide/style-guide-engine.js +1 -1
  79. package/src/javascripts/ui/components/chat-app.js +2 -2
  80. package/src/javascripts/ui/components/conversation/component-filter.js +2 -2
  81. package/src/javascripts/ui/components/conversation/conversation.js +2 -2
  82. package/src/javascripts/ui/components/conversation/event/card-component.js +29 -4
  83. package/src/javascripts/ui/components/conversation/event/carousel-component/components/pagination.js +2 -2
  84. package/src/javascripts/ui/components/conversation/event/carousel-component/index.js +4 -3
  85. package/src/javascripts/ui/components/conversation/event/carousel-message/components/slide.js +2 -1
  86. package/src/javascripts/ui/components/conversation/event/carousel-message/index.js +2 -2
  87. package/src/javascripts/ui/components/conversation/event/choice-prompt.js +11 -6
  88. package/src/javascripts/ui/components/conversation/event/cta.js +1 -6
  89. package/src/javascripts/ui/components/conversation/event/divider/variants/new-translation.js +1 -1
  90. package/src/javascripts/ui/components/conversation/event/event-participant.js +3 -5
  91. package/src/javascripts/ui/components/conversation/event/hooks/use-event-link-click-handler.js +2 -2
  92. package/src/javascripts/ui/components/conversation/event/hooks/use-formatted-date.js +3 -3
  93. package/src/javascripts/ui/components/conversation/event/hooks/use-text-rendering.js +3 -3
  94. package/src/javascripts/ui/components/conversation/event/participant.js +2 -2
  95. package/src/javascripts/ui/components/conversation/event/upload.js +12 -27
  96. package/src/javascripts/ui/components/conversation/message-container.js +4 -6
  97. package/src/javascripts/ui/components/core/seamly-activity-monitor.js +4 -5
  98. package/src/javascripts/ui/components/core/seamly-core.js +6 -7
  99. package/src/javascripts/ui/components/core/seamly-event-subscriber.js +16 -17
  100. package/src/javascripts/ui/components/core/seamly-file-upload.js +5 -6
  101. package/src/javascripts/ui/components/core/seamly-idle-detach-counter.js +2 -6
  102. package/src/javascripts/ui/components/core/seamly-initializer.js +7 -60
  103. package/src/javascripts/ui/components/core/seamly-instance-functions-loader.js +10 -10
  104. package/src/javascripts/ui/components/core/seamly-live-region.js +1 -1
  105. package/src/javascripts/ui/components/core/seamly-new-notifications.js +1 -1
  106. package/src/javascripts/ui/components/core/seamly-read-state.js +2 -2
  107. package/src/javascripts/ui/components/entry/entry-container.js +7 -10
  108. package/src/javascripts/ui/components/entry/toggle-button.js +24 -10
  109. package/src/javascripts/ui/components/entry/upload/index.js +4 -11
  110. package/src/javascripts/ui/components/faq/faq.js +4 -4
  111. package/src/javascripts/ui/components/form-controls/error.js +22 -0
  112. package/src/javascripts/ui/components/form-controls/file-input.js +3 -9
  113. package/src/javascripts/ui/components/form-controls/select.js +1 -1
  114. package/src/javascripts/ui/components/form-controls/wrapper.js +2 -9
  115. package/src/javascripts/ui/components/layout/agent-info.js +4 -4
  116. package/src/javascripts/ui/components/layout/app-frame.js +5 -5
  117. package/src/javascripts/ui/components/layout/chat-frame.js +3 -5
  118. package/src/javascripts/ui/components/layout/header.js +4 -18
  119. package/src/javascripts/ui/components/layout/privacy-disclaimer.js +2 -2
  120. package/src/javascripts/ui/components/options/cobrowsing.js +3 -7
  121. package/src/javascripts/ui/components/options/options-button.js +9 -13
  122. package/src/javascripts/ui/components/options/options-frame.js +1 -1
  123. package/src/javascripts/ui/components/options/transcript/index.js +2 -2
  124. package/src/javascripts/ui/components/options/transcript/transcript-form.js +1 -1
  125. package/src/javascripts/ui/components/warnings/cobrowsing-active-frame.js +3 -6
  126. package/src/javascripts/ui/components/warnings/idle-detach-warning.js +2 -6
  127. package/src/javascripts/ui/components/widgets/in-out-transition.js +2 -2
  128. package/src/javascripts/ui/components/widgets/lightbox.js +4 -4
  129. package/src/javascripts/ui/components/widgets/modal.js +3 -3
  130. package/src/javascripts/ui/components/widgets/upload-progress.js +2 -13
  131. package/src/javascripts/ui/hooks/component-helper-hooks.js +4 -15
  132. package/src/javascripts/ui/hooks/file-upload-hooks.js +3 -3
  133. package/src/javascripts/ui/hooks/focus-helper-hooks.js +4 -4
  134. package/src/javascripts/ui/hooks/live-region-hooks.js +2 -2
  135. package/src/javascripts/ui/hooks/seamly-entry-hooks.js +7 -6
  136. package/src/javascripts/ui/hooks/seamly-hooks.js +3 -9
  137. package/src/javascripts/ui/hooks/seamly-option-hooks.js +4 -4
  138. package/src/javascripts/ui/hooks/seamly-state-hooks.js +8 -16
  139. package/src/javascripts/ui/hooks/use-event-component-mapping.js +1 -1
  140. package/src/javascripts/ui/hooks/use-seamly-chat.js +1 -0
  141. package/src/javascripts/ui/hooks/use-seamly-commands.js +27 -49
  142. package/src/javascripts/ui/hooks/use-seamly-idle-detach-countdown.js +3 -3
  143. package/src/javascripts/ui/hooks/use-seamly-stored-visibility.js +3 -3
  144. package/src/javascripts/ui/hooks/use-seamly-visibility.js +3 -3
  145. package/src/javascripts/ui/hooks/utility-hooks.js +2 -2
  146. package/src/javascripts/ui/utils/form-utils.js +3 -3
  147. package/src/javascripts/ui/utils/general-utils.js +17 -11
  148. package/src/javascripts/ui/utils/seamly-utils.js +15 -83
  149. package/src/javascripts/ui/utils/validations.js +10 -7
  150. package/src/stylesheets/5-components/_card.scss +0 -1
  151. package/src/stylesheets/5-components/_choice-prompt.scss +5 -0
  152. package/src/stylesheets/5-components/_message.scss +10 -0
  153. package/src/stylesheets/5-components/_options.scss +3 -2
  154. package/translations/de-informal.js +0 -2
  155. package/translations/en.js +0 -2
  156. package/translations/es-informal.js +0 -2
  157. package/translations/nl-formal.js +0 -2
  158. package/translations/nl-informal.js +0 -2
  159. package/webpack/config.common.js +3 -3
  160. package/webpack/config.package.js +4 -4
  161. package/webpack/config.site.js +8 -6
  162. package/CHANGELOG.md +0 -551
  163. package/src/javascripts/ui/components/core/seamly-api.js +0 -44
  164. package/src/javascripts/ui/hooks/use-seamly-interrupt.js +0 -62
  165. package/src/javascripts/ui/store/index.js +0 -37
@@ -1,13 +1,21 @@
1
- import { combineReducers, createStore } from 'redux'
1
+ import { combineReducers, createStore, applyMiddleware, compose } from 'redux'
2
2
 
3
- let enhancer
3
+ let composeEnhancers = compose
4
4
  if (process.env.NODE_ENV === 'development') {
5
5
  /* eslint-disable no-underscore-dangle */
6
- enhancer =
7
- typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION__?.()
6
+ composeEnhancers =
7
+ window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || composeEnhancers
8
8
  /* eslint-enable no-underscore-dangle */
9
9
  }
10
10
 
11
- export default function createReduxStore(reducers = {}, initialState = {}) {
12
- return createStore(combineReducers(reducers), initialState, enhancer)
11
+ export default function createReduxStore({
12
+ reducers = {},
13
+ initialState = {},
14
+ middlewares = [],
15
+ } = {}) {
16
+ return createStore(
17
+ combineReducers(reducers),
18
+ initialState,
19
+ composeEnhancers(applyMiddleware(...middlewares)),
20
+ )
13
21
  }
@@ -19,7 +19,7 @@ export function useStoreDispatch() {
19
19
  export function useSelector(selector, deps = []) {
20
20
  const store = useStoreContext()
21
21
  // we need a force-update because we're manually updating a ref instead of a useState
22
- const [, forceUpdate] = useReducer(x => x + 1, 0)
22
+ const [, forceUpdate] = useReducer((x) => x + 1, 0)
23
23
  // we're keeping the value to compare against
24
24
  const valueRef = useRef()
25
25
 
@@ -74,6 +74,6 @@ export const useSelectorWithProps = function useSelectorWithProps(
74
74
  // equalityFn = arrayContentEquals,
75
75
  ) {
76
76
  // eslint-disable-next-line react-hooks/exhaustive-deps
77
- const wrappedMapper = useCallback(state => selector(state, props), inputs)
77
+ const wrappedMapper = useCallback((state) => selector(state, props), inputs)
78
78
  return useSelector(wrappedMapper, inputs)
79
79
  }
@@ -1,4 +1,5 @@
1
- import StoreContext, { Provider as StoreProvider } from './context'
1
+ import StoreContext from './context'
2
+ import StoreProvider from './provider'
2
3
  import createReduxStore from './create-redux-store'
3
4
  import {
4
5
  useStoreContext,
@@ -0,0 +1,5 @@
1
+ import { Provider } from './context'
2
+
3
+ export default function StoreProvider({ store, children }) {
4
+ return <Provider value={store}>{children}</Provider>
5
+ }
@@ -0,0 +1,38 @@
1
+ import thunkMiddleware from 'redux-thunk'
2
+ import { createReduxStore } from '../redux'
3
+ import {
4
+ createMiddleware as createConfigMiddleware,
5
+ Reducer as configReducer,
6
+ } from '../config'
7
+ import { Reducer as formReducer } from '../forms'
8
+ import { Reducer as translationsReducer } from '../translations'
9
+ import { Reducer as i18nReducer } from '../i18n'
10
+ import {
11
+ Reducer as interruptReducer,
12
+ createMiddleware as createInterruptMiddleware,
13
+ } from '../interrupt'
14
+ import { createMiddleware as createOptionsMiddleware } from '../options'
15
+ import stateReducer from './state-reducer'
16
+
17
+ export function createStore({ initialState, api } = {}) {
18
+ const store = createReduxStore({
19
+ reducers: {
20
+ state: stateReducer,
21
+ [String(configReducer)]: configReducer,
22
+ [String(formReducer)]: formReducer,
23
+ [String(translationsReducer)]: translationsReducer,
24
+ [String(i18nReducer)]: i18nReducer,
25
+ [String(interruptReducer)]: interruptReducer,
26
+ },
27
+ initialState,
28
+ middlewares: [
29
+ thunkMiddleware.withExtraArgument({
30
+ api,
31
+ }),
32
+ createConfigMiddleware(),
33
+ createInterruptMiddleware(),
34
+ createOptionsMiddleware({ api }),
35
+ ],
36
+ })
37
+ return store
38
+ }
@@ -1,13 +1,14 @@
1
+ // Legacy state reducer. Do not add new features here but extract/create new reducers as needed
2
+
1
3
  import { randomId } from '../../lib/id'
2
4
  import {
3
5
  entryTypes,
4
6
  seamlyStateReducer,
5
7
  visibilityStates,
6
- } from '../utils/seamly-utils'
8
+ } from '../../ui/utils/seamly-utils'
7
9
 
8
10
  const initialState = {
9
11
  events: [],
10
- config: { hideOnNoUserResponse: false },
11
12
  initialState: {},
12
13
  unreadEvents: 0,
13
14
  isLoading: false,
@@ -25,15 +26,11 @@ const initialState = {
25
26
  title: null,
26
27
  subTitle: '',
27
28
  },
28
- interrupt: {
29
- hasInterrupt: false,
30
- meta: {},
31
- },
32
29
  historyLoaded: false,
33
30
  skiplinkTargetId: randomId(),
34
31
  optionsButtonId: randomId(),
35
32
  cobrowsingContainerId: randomId(),
36
- showDisclaimer: false,
33
+ headerCollapseButtonId: randomId(),
37
34
  serviceData: {},
38
35
  options: {
39
36
  features: {},
@@ -3,11 +3,11 @@ import { createDomain } from '../../lib/redux-helpers'
3
3
  const { createActions } = createDomain('translations')
4
4
 
5
5
  export const [enable, disable] = createActions('translate', {
6
- enable: locale => ({ locale }),
6
+ enable: (locale) => ({ locale }),
7
7
  disable: () => ({}),
8
8
  })
9
9
 
10
10
  export const [enableEvent, disableEvent] = createActions('event', {
11
- enable: payloadId => ({ payloadId }),
12
- disable: payloadId => ({ payloadId }),
11
+ enable: (payloadId) => ({ payloadId }),
12
+ disable: (payloadId) => ({ payloadId }),
13
13
  })
@@ -1,27 +1,21 @@
1
1
  import { useCallback, useMemo } from 'preact/hooks'
2
2
  import ChatStatus from '../../../ui/components/chat-status'
3
3
  import { useI18n } from '../../i18n'
4
- import {
5
- useSeamlyInterrupt,
6
- useSkiplinkTargetFocusing,
7
- } from '../../../ui/hooks/seamly-hooks'
4
+ import { useSkiplinkTargetFocusing } from '../../../ui/hooks/seamly-hooks'
8
5
  import { useTranslationsContainer, useTranslations } from '../hooks'
6
+ import { useInterrupt } from '../../interrupt'
9
7
 
10
8
  export default function TranslationsChatStatus() {
11
9
  const { t } = useI18n()
12
10
  const { id } = useTranslationsContainer()
13
- const { hasInterrupt } = useSeamlyInterrupt()
11
+ const { hasInterrupt } = useInterrupt()
14
12
 
15
- const {
16
- isActive,
17
- disableTranslations,
18
- languages,
19
- currentLocale,
20
- } = useTranslations()
13
+ const { isActive, disableTranslations, languages, currentLocale } =
14
+ useTranslations()
21
15
  const focusSkiplinkTarget = useSkiplinkTargetFocusing()
22
16
 
23
17
  const languageName = useMemo(() => {
24
- return languages?.find(lang => lang.locale === currentLocale)?.nativeName
18
+ return languages?.find((lang) => lang.locale === currentLocale)?.nativeName
25
19
  }, [languages, currentLocale])
26
20
 
27
21
  const handleClickStop = useCallback(() => {
@@ -15,7 +15,7 @@ export default function TranslationsOptionButton() {
15
15
  const toggleButton = useRef(null)
16
16
  const toggleButtonId = useGeneratedId()
17
17
 
18
- const onMainKeyDownHandler = e => {
18
+ const onMainKeyDownHandler = (e) => {
19
19
  if (!menuIsOpen) {
20
20
  return
21
21
  }
@@ -31,9 +31,9 @@ export default function TranslationsOptionButton() {
31
31
  }
32
32
 
33
33
  const handleToggleClick = () => {
34
- setMenuIsOpen(o => !o)
34
+ setMenuIsOpen((o) => !o)
35
35
  }
36
- const handleToggleKeyDown = e => {
36
+ const handleToggleKeyDown = (e) => {
37
37
  if (getKey(e) === keyNames.ArrowDown) {
38
38
  setMenuIsOpen(true)
39
39
  e.preventDefault()
@@ -10,13 +10,13 @@ function TranslationsOptionsDialogForm({ controlName, descriptionId }) {
10
10
  const { isActive, languages, currentLocale } = useTranslations()
11
11
 
12
12
  const languageName = useMemo(() => {
13
- return languages?.find(lang => lang.locale === currentLocale)?.nativeName
13
+ return languages?.find((lang) => lang.locale === currentLocale)?.nativeName
14
14
  }, [languages, currentLocale])
15
15
 
16
16
  const options = useMemo(() => {
17
17
  return [
18
18
  { value: '', label: t('translations.settings.defaultOptionLabel') },
19
- ...languages.map(language => ({
19
+ ...languages.map((language) => ({
20
20
  value: language.locale,
21
21
  label: language.nativeName,
22
22
  })),
@@ -14,11 +14,8 @@ export const inputName = 'locale'
14
14
  function TranslationsOptionsDialog({ onClose }) {
15
15
  const { t } = useI18n()
16
16
 
17
- const {
18
- isActive,
19
- enableTranslations,
20
- disableTranslations,
21
- } = useTranslations()
17
+ const { isActive, enableTranslations, disableTranslations } =
18
+ useTranslations()
22
19
 
23
20
  const descriptionId = useGeneratedId()
24
21
  const { focusContainer } = useTranslationsContainer()
@@ -12,7 +12,7 @@ export function useTranslations() {
12
12
  const { sendAction } = useSeamlyCommands()
13
13
  const dispatch = useStoreDispatch()
14
14
  const enableTranslations = useStableCallback(
15
- locale => {
15
+ (locale) => {
16
16
  sendAction({
17
17
  type: actionTypes.setTranslation,
18
18
  body: { enabled: true, locale },
@@ -42,7 +42,7 @@ export default createReducer(
42
42
  currentLocale: locale,
43
43
  }
44
44
  },
45
- [Actions.disable]: state => {
45
+ [Actions.disable]: (state) => {
46
46
  return {
47
47
  ...state,
48
48
  isActive: false,
@@ -56,7 +56,7 @@ export default createReducer(
56
56
  return {
57
57
  ...state,
58
58
  originalPayloadIds: state.originalPayloadIds.filter(
59
- id => id !== payloadId,
59
+ (id) => id !== payloadId,
60
60
  ),
61
61
  }
62
62
  },
@@ -2,11 +2,11 @@ import { createSelector } from 'reselect'
2
2
  import { getPropSelector } from '../redux/utils'
3
3
  import Reducer from './reducer'
4
4
 
5
- export const getState = state => state[String(Reducer)]
5
+ export const getState = (state) => state[String(Reducer)]
6
6
 
7
7
  export const getOriginalPayloadIds = createSelector(
8
8
  getState,
9
- state => state.originalPayloadIds,
9
+ (state) => state.originalPayloadIds,
10
10
  )
11
11
 
12
12
  export const getIsPayloadTranslated = createSelector(
@@ -41,9 +41,6 @@ export { eventTypes } from './ui/utils/seamly-utils'
41
41
  // Used by: StyleGuide
42
42
  export { default as ExternalApi } from './lib/external-api'
43
43
 
44
- // Used by: StyleGuide
45
- export { getSeamlyConfig } from './ui/utils/seamly-utils'
46
-
47
44
  // Used by: StyleGuide
48
45
  export { getUrlParams } from './ui/utils/general-utils'
49
46
 
@@ -78,7 +75,7 @@ export { SeamlyEventBusContext } from './ui/components/core/seamly-api-context'
78
75
  export { SeamlyLiveRegionContext } from './ui/components/core/seamly-live-region-context'
79
76
 
80
77
  // Used by: StyleGuide
81
- export { default as StoreProvider } from './ui/store'
78
+ export { StoreProvider } from './domains/redux'
82
79
 
83
80
  // Used by: Client
84
81
  export { useChoicePrompt } from './ui/components/conversation/event/choice-prompt'
@@ -93,7 +90,7 @@ export { useSeamlyChat } from './ui/hooks/seamly-hooks'
93
90
  export { useSeamlyCommands } from './ui/hooks/seamly-hooks'
94
91
 
95
92
  // Used by: Client
96
- export { useSeamlyConfig } from './ui/hooks/seamly-hooks'
93
+ export { useConfig as useSeamlyConfig } from './domains/config'
97
94
 
98
95
  // Used by: Client
99
96
  export { useEvents } from './ui/hooks/seamly-hooks'
@@ -139,3 +136,18 @@ export { default as View } from './ui/components/layout/view'
139
136
  // Used by: Client
140
137
  // Used by: StyleGuide
141
138
  export { visibilityStates } from './ui/utils/seamly-utils'
139
+
140
+ // Used by: StyleGuide
141
+ export { default as SeamlyGeneralError } from './api/errors/seamly-general-error'
142
+
143
+ // Used by: StyleGuide
144
+ export { default as SeamlyConfigurationError } from './api/errors/seamly-configuration-error'
145
+
146
+ // Used by: StyleGuide
147
+ export { default as SeamlySessionExpiredError } from './api/errors/seamly-session-expired-error'
148
+
149
+ // Used by: StyleGuide
150
+ export { default as SeamlyOfflineError } from './api/errors/seamly-offline-error'
151
+
152
+ // Used by: StyleGuide
153
+ export { default as SeamlyUnauthorizedError } from './api/errors/seamly-unauthorized-error'
@@ -10,7 +10,7 @@ import { CSS_NAME } from '../config'
10
10
  export const className = (...classes) =>
11
11
  classes
12
12
  .flat()
13
- .map(c => {
13
+ .map((c) => {
14
14
  if (typeof c === 'object') {
15
15
  return Object.entries(c)
16
16
  .map(([key, value]) => (value ? key : ''))
@@ -18,9 +18,9 @@ export const className = (...classes) =>
18
18
  }
19
19
  return c
20
20
  })
21
- .filter(c => typeof c === 'string')
22
- .map(c => c.split(' '))
21
+ .filter((c) => typeof c === 'string')
22
+ .map((c) => c.split(' '))
23
23
  .flat()
24
- .filter(c => c.length)
25
- .map(c => [CSS_NAME, c].join('-'))
24
+ .filter((c) => c.length)
25
+ .map((c) => [CSS_NAME, c].join('-'))
26
26
  .join(' ')
@@ -1,18 +1,28 @@
1
1
  import { render, h } from 'preact'
2
2
  import Events from 'minivents'
3
-
4
3
  import ChatApp from '../../ui/components/chat-app'
5
4
  import SeamlyCore from '../../ui/components/core/seamly-core'
5
+ import { API } from '../../api'
6
+ import { createStore } from '../../domains/store'
7
+ import { Actions as AppActions } from '../../domains/app'
6
8
 
7
9
  export default class Engine {
8
10
  constructor(config, externalApi) {
9
- const { customComponents, parentElement, showFaq, ...restConfig } = config
10
- this.config = { ...restConfig, showFaq: showFaq !== false }
11
- this.namespace = config.namespace || ''
11
+ const { namespace = '', parentElement, showFaq, ...restConfig } = config
12
+ this.config = {
13
+ ...restConfig,
14
+ showFaq: showFaq !== false,
15
+ namespace,
16
+ }
17
+ this.namespace = namespace
12
18
  this.parentElement = parentElement
13
- this.customComponents = customComponents
14
19
  this.externalApi = externalApi
15
20
 
21
+ this.api = new API({
22
+ namespace: config.namespace,
23
+ config: config.api,
24
+ })
25
+
16
26
  this.eventBus = new Events()
17
27
  this.functions = {}
18
28
  this.registerFunctions({
@@ -28,8 +38,8 @@ export default class Engine {
28
38
  )
29
39
  }
30
40
 
31
- render() {
32
- const { view: View, ...restComponents } = this.customComponents || {}
41
+ async render() {
42
+ const { view: View, ...restComponents } = this.config.customComponents || {}
33
43
 
34
44
  const renderConfig = {
35
45
  ...this.config,
@@ -38,16 +48,32 @@ export default class Engine {
38
48
  : undefined,
39
49
  }
40
50
 
51
+ const store = createStore({
52
+ api: this.api,
53
+ })
54
+
55
+ await store.dispatch(AppActions.initialize(renderConfig))
56
+
41
57
  if (View) {
42
58
  render(
43
- <SeamlyCore config={renderConfig} eventBus={this.eventBus}>
59
+ <SeamlyCore
60
+ config={renderConfig}
61
+ eventBus={this.eventBus}
62
+ store={store}
63
+ api={this.api}
64
+ >
44
65
  <View />
45
66
  </SeamlyCore>,
46
67
  this.parentElement,
47
68
  )
48
69
  } else {
49
70
  render(
50
- <ChatApp config={renderConfig} eventBus={this.eventBus} />,
71
+ <ChatApp
72
+ config={renderConfig}
73
+ eventBus={this.eventBus}
74
+ store={store}
75
+ api={this.api}
76
+ />,
51
77
  this.parentElement,
52
78
  )
53
79
  }
@@ -56,6 +82,7 @@ export default class Engine {
56
82
  destroy() {
57
83
  render(null, this.parentElement)
58
84
  this.eventBus.off()
85
+ this.api.disconnect()
59
86
  delete this.functions
60
87
  }
61
88
 
@@ -74,7 +101,7 @@ export default class Engine {
74
101
  unregisterFunction(functionName, fn) {
75
102
  const functions = this.functions[functionName]
76
103
  if (functions && functions.length) {
77
- this.functions[functionName] = functions.filter(fn2 => fn2 !== fn)
104
+ this.functions[functionName] = functions.filter((fn2) => fn2 !== fn)
78
105
  }
79
106
  }
80
107
 
@@ -83,7 +110,7 @@ export default class Engine {
83
110
  if (!functions || !functions.length) {
84
111
  return false
85
112
  }
86
- functions.forEach(fn => {
113
+ functions.forEach((fn) => {
87
114
  try {
88
115
  fn(...args)
89
116
  } catch (e) {
@@ -1,8 +1,8 @@
1
1
  import Engine from '../engine'
2
2
 
3
- const isActionObject = actionObj =>
3
+ const isActionObject = (actionObj) =>
4
4
  typeof actionObj === 'object' && 'action' in actionObj
5
- const fixActionObjectArgs = actionObj => ({
5
+ const fixActionObjectArgs = (actionObj) => ({
6
6
  ...actionObj,
7
7
  args: Array.isArray(actionObj.args) ? actionObj.args : [actionObj.args],
8
8
  })
@@ -29,7 +29,7 @@ class ExternalApi {
29
29
  handleActions() {
30
30
  const actions = this._waitingActions
31
31
  this._waitingActions = []
32
- actions.forEach(actionObj => {
32
+ actions.forEach((actionObj) => {
33
33
  switch (actionObj.action) {
34
34
  case 'init':
35
35
  this.handleInit(actionObj)
@@ -55,7 +55,7 @@ class ExternalApi {
55
55
  return
56
56
  }
57
57
  const { parentElement, namespace } = config
58
- Object.values(this._instances).forEach(instance => {
58
+ Object.values(this._instances).forEach((instance) => {
59
59
  if (
60
60
  instance.parentElement === parentElement ||
61
61
  instance.namespace === namespace
@@ -72,7 +72,7 @@ class ExternalApi {
72
72
  if (actionObj.instance !== undefined) {
73
73
  this.destroy(actionObj.instance)
74
74
  } else {
75
- Object.values(this._instances).forEach(instance => {
75
+ Object.values(this._instances).forEach((instance) => {
76
76
  this.destroy(instance)
77
77
  })
78
78
  }
@@ -90,7 +90,7 @@ class ExternalApi {
90
90
 
91
91
  // results will be an array containing the results of wether an instance has
92
92
  // handled the action or not
93
- const results = instances.map(instance => {
93
+ const results = instances.map((instance) => {
94
94
  return !namespace || instance.namespace === namespace
95
95
  ? instance.execFunction(action, ...args)
96
96
  : false
@@ -1,12 +1,12 @@
1
1
  import deepKeys from 'deep-keys'
2
2
  import en from '@seamly/web-ui/translations/en'
3
3
 
4
- export const translate = translations => {
4
+ export const translate = (translations) => {
5
5
  let translationSet
6
6
  if (translations) {
7
7
  const standardKeys = deepKeys(en)
8
8
  const customKeys = deepKeys(translations)
9
- standardKeys.forEach(key => {
9
+ standardKeys.forEach((key) => {
10
10
  if (customKeys.indexOf(key) === -1) {
11
11
  console.error('Seamly: Missing translation key:', key)
12
12
  }
@@ -1,6 +1,6 @@
1
1
  import marked from 'marked'
2
2
 
3
- export default body => {
3
+ export default (body) => {
4
4
  try {
5
5
  return marked(body)
6
6
  } catch (e) {
@@ -5,7 +5,10 @@ export function prefixType(prefix, fn, delimiter = '/') {
5
5
  return (type, ...args) => fn(prefix + delimiter + type, ...args)
6
6
  }
7
7
 
8
- export function createAction(type, identityReducer = payload => ({ payload })) {
8
+ export function createAction(
9
+ type,
10
+ identityReducer = (payload) => ({ payload }),
11
+ ) {
9
12
  const action = (...params) => ({ type, ...identityReducer(...params) })
10
13
  action.toString = () => type.toString()
11
14
  return action
@@ -14,7 +17,7 @@ export function createAction(type, identityReducer = payload => ({ payload })) {
14
17
  export function createActions(baseType, ...args) {
15
18
  const handlers = []
16
19
  // eslint-disable-next-line consistent-return
17
- args.forEach(arg => {
20
+ args.forEach((arg) => {
18
21
  const argType = typeof arg
19
22
  if (argType === 'string') {
20
23
  return handlers.push([arg])
@@ -22,17 +25,28 @@ export function createActions(baseType, ...args) {
22
25
  if (argType !== 'object' || arg instanceof Array) {
23
26
  return undefined
24
27
  }
25
- Object.keys(arg).forEach(key => handlers.push([key, arg[key]]))
28
+ Object.keys(arg).forEach((key) => handlers.push([key, arg[key]]))
26
29
  })
27
30
  const create = prefixType(baseType, createAction, SLICE_DELIMITER)
28
31
 
29
- return handlers.map(handler => create(...handler))
32
+ return handlers.map((handler) => create(...handler))
33
+ }
34
+
35
+ export function createThunk(type, thunkCreator) {
36
+ const fn = (...args) => {
37
+ const thunk = thunkCreator(...args)
38
+ thunk.type = type
39
+ return thunk
40
+ }
41
+ fn.toString = () => type
42
+ return fn
30
43
  }
31
44
 
32
45
  export function createDomain(domain) {
33
46
  return {
34
47
  createAction: prefixType(domain, createAction, DOMAIN_DELIMITER),
35
48
  createActions: prefixType(domain, createActions, DOMAIN_DELIMITER),
49
+ createThunk: prefixType(domain, createThunk, DOMAIN_DELIMITER),
36
50
  }
37
51
  }
38
52
 
@@ -1,4 +1,4 @@
1
- const splitUrlParams = url => {
1
+ const splitUrlParams = (url) => {
2
2
  const searchIndex = url.indexOf('?')
3
3
 
4
4
  if (searchIndex < 0) {
@@ -9,7 +9,7 @@ const splitUrlParams = url => {
9
9
  const params = url
10
10
  .slice(searchIndex + 1)
11
11
  .split('&')
12
- .reduce(function(acc, hash) {
12
+ .reduce(function (acc, hash) {
13
13
  const [key, val] = hash.split('=')
14
14
  return {
15
15
  ...acc,
@@ -16,7 +16,7 @@ export default function appStore() {
16
16
  }
17
17
  return window.seamlyBridgeData
18
18
  },
19
- set: newData => {
19
+ set: (newData) => {
20
20
  // iOS
21
21
  if (
22
22
  window.webkit &&
@@ -1,7 +1,7 @@
1
1
  import cookies from 'js-cookie'
2
2
 
3
3
  export default function cookieStore(attributes = {}) {
4
- return function(key) {
4
+ return function (key) {
5
5
  const KEY = 'cvco.' + key
6
6
 
7
7
  return {
@@ -4,7 +4,6 @@ export {
4
4
  Engine,
5
5
  eventTypes,
6
6
  ExternalApi,
7
- getSeamlyConfig,
8
7
  getUrlParams,
9
8
  getUrlSearchString,
10
9
  randomId,