@seamly/web-ui 21.0.7 → 22.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/dist/lib/components.js +9354 -7909
- package/build/dist/lib/components.js.map +1 -0
- package/build/dist/lib/components.min.js +2 -1
- package/build/dist/lib/components.min.js.LICENSE.txt +2 -2
- package/build/dist/lib/components.min.js.map +1 -0
- package/build/dist/lib/config.js +2 -1
- package/build/dist/lib/config.js.map +1 -0
- package/build/dist/lib/config.min.js +2 -1
- package/build/dist/lib/config.min.js.map +1 -0
- package/build/dist/lib/contexts.js +2 -1
- package/build/dist/lib/contexts.js.map +1 -0
- package/build/dist/lib/contexts.min.js +2 -1
- package/build/dist/lib/contexts.min.js.map +1 -0
- package/build/dist/lib/deprecated-view.css +1 -1
- package/build/dist/lib/deprecated-view.js +1 -1
- package/build/dist/lib/hooks.js +7006 -5903
- package/build/dist/lib/hooks.js.map +1 -0
- package/build/dist/lib/hooks.min.js +2 -1
- package/build/dist/lib/hooks.min.js.map +1 -0
- package/build/dist/lib/index.debug.js +965 -384
- package/build/dist/lib/index.debug.js.map +1 -0
- package/build/dist/lib/index.debug.min.js +2 -1
- package/build/dist/lib/index.debug.min.js.LICENSE.txt +336 -108
- package/build/dist/lib/index.debug.min.js.map +1 -0
- package/build/dist/lib/index.js +2991 -5664
- package/build/dist/lib/index.js.map +1 -0
- package/build/dist/lib/index.min.js +2 -1
- package/build/dist/lib/index.min.js.LICENSE.txt +2 -2
- package/build/dist/lib/index.min.js.map +1 -0
- package/build/dist/lib/sounds/beep.mp3 +0 -0
- package/build/dist/lib/standalone.js +9461 -12461
- package/build/dist/lib/standalone.js.map +1 -0
- package/build/dist/lib/standalone.min.js +2 -1
- package/build/dist/lib/standalone.min.js.LICENSE.txt +1 -1
- package/build/dist/lib/standalone.min.js.map +1 -0
- package/build/dist/lib/storage.js +2 -1
- package/build/dist/lib/storage.js.map +1 -0
- package/build/dist/lib/storage.min.js +2 -1
- package/build/dist/lib/storage.min.js.map +1 -0
- package/build/dist/lib/style-guide.js +1831 -6023
- package/build/dist/lib/style-guide.js.map +1 -0
- package/build/dist/lib/style-guide.min.js +2 -1
- package/build/dist/lib/style-guide.min.js.LICENSE.txt +2 -2
- package/build/dist/lib/style-guide.min.js.map +1 -0
- package/build/dist/lib/styles-default-implementation.css +1 -1
- package/build/dist/lib/styles-default-implementation.js +1 -1
- package/build/dist/lib/styles.css +1 -1
- package/build/dist/lib/styles.js +1 -1
- package/build/dist/lib/utils.js +11598 -14588
- package/build/dist/lib/utils.js.map +1 -0
- package/build/dist/lib/utils.min.js +2 -1
- package/build/dist/lib/utils.min.js.LICENSE.txt +1 -6
- package/build/dist/lib/utils.min.js.map +1 -0
- package/package.json +58 -48
- package/src/javascripts/api/conversation-connector.ts +2 -0
- package/src/javascripts/api/errors/seamly-api-error.ts +15 -0
- package/src/javascripts/api/index.ts +168 -94
- package/src/javascripts/config.ts +1 -1
- package/src/javascripts/config.types.ts +18 -11
- package/src/javascripts/domains/config/selectors.ts +1 -1
- package/src/javascripts/domains/config/slice.ts +12 -0
- package/src/javascripts/domains/forms/forms.types.ts +1 -0
- package/src/javascripts/domains/forms/hooks.ts +10 -2
- package/src/javascripts/domains/i18n/slice.ts +2 -0
- package/src/javascripts/domains/interrupt/hooks.ts +15 -7
- package/src/javascripts/domains/interrupt/middleware.ts +7 -14
- package/src/javascripts/domains/interrupt/selectors.ts +4 -0
- package/src/javascripts/domains/interrupt/slice.ts +2 -2
- package/src/javascripts/domains/store/selectors.ts +23 -10
- package/src/javascripts/domains/store/slice.ts +63 -11
- package/src/javascripts/domains/store/store.types.ts +39 -1
- package/src/javascripts/domains/translations/components/options-button.tsx +1 -4
- package/src/javascripts/domains/translations/components/translation-status.tsx +4 -3
- package/src/javascripts/domains/translations/hooks.ts +11 -4
- package/src/javascripts/domains/translations/slice.ts +2 -0
- package/src/javascripts/index.ts +2 -0
- package/src/javascripts/lib/url-helpers.ts +24 -0
- package/src/javascripts/schema.ts +10 -0
- package/src/javascripts/style-guide/states.js +65 -0
- package/src/javascripts/ui/components/app-options/index.js +4 -3
- package/src/javascripts/ui/components/conversation/conversation.tsx +2 -0
- package/src/javascripts/ui/components/conversation/event/chat-scroll/chat-scroll-provider.tsx +2 -0
- package/src/javascripts/ui/components/conversation/event/choice-prompt.js +1 -1
- package/src/javascripts/ui/components/conversation/event/text.js +1 -1
- package/src/javascripts/ui/components/conversation/event/upload.js +50 -9
- package/src/javascripts/ui/components/conversation/use-chat-scroll.ts +3 -2
- package/src/javascripts/ui/components/core/seamly-event-subscriber.ts +16 -14
- package/src/javascripts/ui/components/core/seamly-file-upload.tsx +156 -0
- package/src/javascripts/ui/components/core/seamly-instance-functions-loader.js +5 -5
- package/src/javascripts/ui/components/entry/abort-transaction-button/abort-transaction-button.tsx +45 -0
- package/src/javascripts/ui/components/entry/deprecated-toggle-button.js +4 -3
- package/src/javascripts/ui/components/entry/text-entry/hooks.ts +108 -0
- package/src/javascripts/ui/components/entry/text-entry/index.js +7 -4
- package/src/javascripts/ui/components/entry/text-entry/{text-entry-form.js → text-entry-form.tsx} +8 -22
- package/src/javascripts/ui/components/faq/faq.js +5 -4
- package/src/javascripts/ui/components/form-controls/{input.js → input.tsx} +13 -2
- package/src/javascripts/ui/components/form-controls/{wrapper.js → wrapper.tsx} +8 -4
- package/src/javascripts/ui/components/layout/agent-info.js +4 -3
- package/src/javascripts/ui/components/layout/chat-frame.js +7 -8
- package/src/javascripts/ui/components/layout/deprecated-chat-frame.js +7 -8
- package/src/javascripts/ui/components/layout/interrupt.js +6 -15
- package/src/javascripts/ui/components/layout/pre-chat-messages.js +4 -3
- package/src/javascripts/ui/components/suggestions/index.js +5 -4
- package/src/javascripts/ui/components/translation-chat-status/index.tsx +4 -3
- package/src/javascripts/ui/components/view/app-view.js +1 -2
- package/src/javascripts/ui/components/view/deprecated-view.js +1 -2
- package/src/javascripts/ui/components/view/{index.js → index.tsx} +53 -4
- package/src/javascripts/ui/components/view/inline-view.js +1 -11
- package/src/javascripts/ui/components/view/window-view/{index.js → index.tsx} +15 -11
- package/src/javascripts/ui/components/view/window-view/window-open-button.js +4 -3
- package/src/javascripts/ui/components/widgets/{in-out-transition.js → in-out-transition.tsx} +67 -28
- package/src/javascripts/ui/hooks/sounds/beep.mp3 +0 -0
- package/src/javascripts/ui/hooks/use-click-outside.ts +5 -3
- package/src/javascripts/ui/hooks/use-notifications.ts +114 -0
- package/src/javascripts/ui/hooks/{use-seamly-chat.js → use-seamly-chat.ts} +5 -1
- package/src/javascripts/ui/hooks/use-session-expired-command.ts +17 -0
- package/src/javascripts/ui/hooks/use-timeout.ts +20 -0
- package/src/stylesheets/3-chat/_chat.scss +3 -5
- package/src/stylesheets/4-base/_formelements.scss +0 -36
- package/src/stylesheets/5-components/_abort-transaction.scss +10 -0
- package/src/stylesheets/5-components/_buttons.scss +18 -3
- package/src/stylesheets/5-components/_character-limit.scss +2 -2
- package/src/stylesheets/5-components/_chat-status.scss +26 -37
- package/src/stylesheets/5-components/_choice-prompt.scss +9 -10
- package/src/stylesheets/5-components/_conversation.scss +9 -62
- package/src/stylesheets/5-components/_disclaimer.scss +11 -3
- package/src/stylesheets/5-components/_error.scss +3 -2
- package/src/stylesheets/5-components/_idle.scss +3 -8
- package/src/stylesheets/5-components/_input.scss +34 -13
- package/src/stylesheets/5-components/_interrupt.scss +3 -10
- package/src/stylesheets/5-components/_loader.scss +1 -2
- package/src/stylesheets/5-components/_message-author.scss +2 -4
- package/src/stylesheets/5-components/_message-body.scss +33 -10
- package/src/stylesheets/5-components/_message-card.scss +2 -10
- package/src/stylesheets/5-components/_message-carousel.scss +4 -4
- package/src/stylesheets/5-components/_message-cta.scss +0 -6
- package/src/stylesheets/5-components/_message.scss +1 -0
- package/src/stylesheets/5-components/_modal.scss +2 -5
- package/src/stylesheets/5-components/_options.scss +17 -22
- package/src/stylesheets/5-components/_pre-chat-messages.scss +3 -1
- package/src/stylesheets/5-components/_prompt.scss +3 -7
- package/src/stylesheets/5-components/_skip-link.scss +2 -1
- package/src/stylesheets/5-components/_suggestions.scss +2 -2
- package/src/stylesheets/5-components/_translation-options.scss +5 -2
- package/src/stylesheets/5-components/_unread-messages.scss +33 -0
- package/src/stylesheets/5-components/_upload.scss +20 -27
- package/src/stylesheets/6-default-implementation/_hover.scss +14 -17
- package/src/stylesheets/7-deprecated/1-settings/_config.scss +17 -0
- package/src/stylesheets/7-deprecated/3-app/_app.scss +2 -1
- package/src/stylesheets/7-deprecated/5-components/_card.scss +1 -0
- package/src/stylesheets/7-deprecated/5-components/_chat-status.scss +66 -20
- package/src/stylesheets/7-deprecated/5-components/_conversation.scss +1 -4
- package/src/stylesheets/7-deprecated/5-components/_input.scss +6 -1
- package/src/stylesheets/7-deprecated/5-components/_interrupt.scss +1 -4
- package/src/stylesheets/7-deprecated/5-components/_message.scss +49 -12
- package/src/stylesheets/7-deprecated/5-components/_translation-options.scss +30 -37
- package/src/stylesheets/7-deprecated/5-components/_unread-messages.scss +38 -0
- package/src/stylesheets/deprecated-view.scss +1 -0
- package/src/stylesheets/styles.scss +2 -0
- package/webpack/config.common.js +6 -1
- package/webpack/config.package.js +18 -0
- package/webpack/defaults.js +1 -1
- package/src/javascripts/ui/components/core/seamly-file-upload.js +0 -86
- package/src/javascripts/ui/components/entry/text-entry/hooks.js +0 -46
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seamly/web-ui",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "22.0.0-beta.1",
|
|
4
4
|
"main": "build/dist/lib/index.js",
|
|
5
5
|
"types": "build/src/javascripts/index.d.ts",
|
|
6
6
|
"module": "",
|
|
@@ -22,79 +22,89 @@
|
|
|
22
22
|
"webpack/*"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@reduxjs/toolkit": "^1.
|
|
25
|
+
"@reduxjs/toolkit": "^1.9.3",
|
|
26
26
|
"@ultraq/icu-message-formatter": "^0.12.0",
|
|
27
|
+
"core-js": "^3.30.0",
|
|
27
28
|
"deep-keys": "^0.5.0",
|
|
28
|
-
"focus-trap": "^7.
|
|
29
|
-
"include-media": "^
|
|
29
|
+
"focus-trap": "^7.4.0",
|
|
30
|
+
"include-media": "^2.0.0",
|
|
30
31
|
"js-cookie": "^3.0.1",
|
|
31
32
|
"minivents": "^2.2.1",
|
|
32
|
-
"phoenix": "1.
|
|
33
|
-
"react-redux": "^8.0.
|
|
34
|
-
"superagent": "^8.0.3"
|
|
33
|
+
"phoenix": "^1.7.2",
|
|
34
|
+
"react-redux": "^8.0.5"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@babel/core": "^7.
|
|
38
|
-
"@babel/plugin-proposal-object-rest-spread": "^7.
|
|
37
|
+
"@babel/core": "^7.21.4",
|
|
38
|
+
"@babel/plugin-proposal-object-rest-spread": "^7.20.7",
|
|
39
39
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
40
|
-
"@babel/plugin-transform-classes": "^7.
|
|
41
|
-
"@babel/plugin-transform-react-jsx": "^7.
|
|
42
|
-
"@babel/plugin-transform-runtime": "^7.
|
|
43
|
-
"@babel/preset-env": "^7.
|
|
40
|
+
"@babel/plugin-transform-classes": "^7.21.0",
|
|
41
|
+
"@babel/plugin-transform-react-jsx": "^7.21.0",
|
|
42
|
+
"@babel/plugin-transform-runtime": "^7.21.4",
|
|
43
|
+
"@babel/preset-env": "^7.21.4",
|
|
44
44
|
"@babel/preset-react": "^7.18.6",
|
|
45
|
-
"@babel/preset-typescript": "^7.
|
|
46
|
-
"@babel/runtime-corejs3": "^7.
|
|
47
|
-
"@playwright/test": "^1.
|
|
45
|
+
"@babel/preset-typescript": "^7.21.4",
|
|
46
|
+
"@babel/runtime-corejs3": "^7.21.0",
|
|
47
|
+
"@playwright/test": "^1.32.2",
|
|
48
48
|
"@seamly/doc-site": "^2.0.0",
|
|
49
49
|
"@seamly/eslint-config": "^2.3.0",
|
|
50
50
|
"@seamly/prettier-config": "^2.2.0",
|
|
51
51
|
"@seamly/stylelint-config": "^2.0.0",
|
|
52
52
|
"@testing-library/jest-dom": "^5.16.5",
|
|
53
|
-
"@testing-library/preact": "^3.2.
|
|
54
|
-
"@trivago/prettier-plugin-sort-imports": "^
|
|
55
|
-
"@types/
|
|
56
|
-
"@types/
|
|
57
|
-
"@
|
|
58
|
-
"@typescript-eslint/
|
|
59
|
-
"
|
|
60
|
-
"babel-
|
|
53
|
+
"@testing-library/preact": "^3.2.3",
|
|
54
|
+
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
|
|
55
|
+
"@types/core-js": "^2.5.5",
|
|
56
|
+
"@types/jest": "^29.5.0",
|
|
57
|
+
"@types/phoenix": "^1.5.5",
|
|
58
|
+
"@typescript-eslint/eslint-plugin": "^5.57.1",
|
|
59
|
+
"@typescript-eslint/parser": "^5.57.1",
|
|
60
|
+
"babel-jest": "^29.5.0",
|
|
61
|
+
"babel-loader": "^9.1.2",
|
|
61
62
|
"babel-plugin-istanbul": "^6.1.1",
|
|
62
63
|
"babel-plugin-react-remove-properties": "^0.3.0",
|
|
63
64
|
"copy-webpack-plugin": "^11.0.0",
|
|
64
65
|
"debug": "^4.3.4",
|
|
65
|
-
"eslint": "^8.
|
|
66
|
+
"eslint": "^8.37.0",
|
|
67
|
+
"eslint-config-prettier": "^8.8.0",
|
|
66
68
|
"eslint-import-resolver-alias": "^1.1.2",
|
|
67
|
-
"eslint-import-resolver-typescript": "^3.5.
|
|
68
|
-
"eslint-plugin-
|
|
69
|
-
"eslint-plugin-
|
|
69
|
+
"eslint-import-resolver-typescript": "^3.5.5",
|
|
70
|
+
"eslint-plugin-filenames": "^1.3.2",
|
|
71
|
+
"eslint-plugin-import": "^2.27.5",
|
|
72
|
+
"eslint-plugin-jest": "^27.2.1",
|
|
73
|
+
"eslint-plugin-prettier": "^4.2.1",
|
|
74
|
+
"eslint-plugin-react": "^7.32.2",
|
|
75
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
|
70
76
|
"file-loader": "^6.2.0",
|
|
71
|
-
"
|
|
72
|
-
"
|
|
77
|
+
"fork-ts-checker-webpack-plugin": "^8.0.0",
|
|
78
|
+
"glob": "^9.3.4",
|
|
79
|
+
"husky": "^8.0.3",
|
|
73
80
|
"ignore-loader": "^0.1.2",
|
|
74
|
-
"
|
|
75
|
-
"jest
|
|
76
|
-
"
|
|
81
|
+
"isomorphic-unfetch": "^4.0.2",
|
|
82
|
+
"jest": "^29.5.0",
|
|
83
|
+
"jest-environment-jsdom": "^29.5.0",
|
|
84
|
+
"jest-watch-typeahead": "^2.2.2",
|
|
85
|
+
"mini-css-extract-plugin": "^2.7.5",
|
|
77
86
|
"nyc": "^15.1.0",
|
|
78
|
-
"playwright-test-coverage": "^1.2.
|
|
79
|
-
"postcss": "8",
|
|
80
|
-
"preact": "^10.
|
|
81
|
-
"
|
|
87
|
+
"playwright-test-coverage": "^1.2.12",
|
|
88
|
+
"postcss": "^8.4.21",
|
|
89
|
+
"preact": "^10.13.2",
|
|
90
|
+
"preact-render-to-string": "^6.0.2",
|
|
91
|
+
"prettier": "^2.8.7",
|
|
82
92
|
"raw-loader": "^4.0.2",
|
|
83
|
-
"rimraf": "^
|
|
84
|
-
"start-server-and-test": "^
|
|
85
|
-
"style-loader": "^3.3.
|
|
86
|
-
"stylelint": "^
|
|
87
|
-
"ts-loader": "^9.4.
|
|
88
|
-
"typescript": "^
|
|
93
|
+
"rimraf": "^4.4.1",
|
|
94
|
+
"start-server-and-test": "^2.0.0",
|
|
95
|
+
"style-loader": "^3.3.2",
|
|
96
|
+
"stylelint": "^15.4.0",
|
|
97
|
+
"ts-loader": "^9.4.2",
|
|
98
|
+
"typescript": "^5.0.3",
|
|
89
99
|
"url-loader": "^4.1.1",
|
|
90
|
-
"webpack": "^5.
|
|
91
|
-
"webpack-bundle-analyzer": "^4.
|
|
92
|
-
"webpack-cli": "^
|
|
93
|
-
"webpack-dev-server": "^4.
|
|
100
|
+
"webpack": "^5.78.0",
|
|
101
|
+
"webpack-bundle-analyzer": "^4.8.0",
|
|
102
|
+
"webpack-cli": "^5.0.1",
|
|
103
|
+
"webpack-dev-server": "^4.13.2",
|
|
94
104
|
"webpack-merge": "^5.8.0"
|
|
95
105
|
},
|
|
96
106
|
"peerDependencies": {
|
|
97
|
-
"preact": "^10.
|
|
107
|
+
"preact": "^10.13.2"
|
|
98
108
|
},
|
|
99
109
|
"scripts": {
|
|
100
110
|
"build:clean": "rimraf build; mkdir -p build",
|
|
@@ -11,6 +11,7 @@ type CurrentConnectionState =
|
|
|
11
11
|
| 'join_channel_succeeded' // Joined channel succesfully.
|
|
12
12
|
| 'join_channel_erred' // Error on joining channel. This is usefull when you want to restart a chat sessions.
|
|
13
13
|
| 'attach_channel_succeeded' // Attached channel to system.
|
|
14
|
+
| 'attach_channel_erred' // Error attaching channel.
|
|
14
15
|
|
|
15
16
|
type ConnectionState = {
|
|
16
17
|
connected: boolean
|
|
@@ -98,6 +99,7 @@ export default class ConversationConnector {
|
|
|
98
99
|
|
|
99
100
|
this.channel.onError((msg) => {
|
|
100
101
|
log('[CHANNEL][ERROR]', msg)
|
|
102
|
+
|
|
101
103
|
this.#emitConnectionState({
|
|
102
104
|
connected: false,
|
|
103
105
|
ready: false,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
// eslint-disable-next-line no-undef
|
|
3
|
+
interface ApiErrorOptions extends ErrorOptions {
|
|
4
|
+
status?: number
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export default class ApiError extends Error {
|
|
8
|
+
status: number
|
|
9
|
+
|
|
10
|
+
constructor(message: string, options?: ApiErrorOptions) {
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
super(message, { cause: options?.cause })
|
|
13
|
+
this.status = options?.status
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { ApiConfig,
|
|
1
|
+
import type { ApiConfig, Context, LayoutMode } from 'config.types'
|
|
2
2
|
import { components, operations } from 'schema'
|
|
3
|
-
import superagent from 'superagent'
|
|
4
3
|
import { apiVersion } from 'config'
|
|
4
|
+
import ApiError from 'api/errors/seamly-api-error'
|
|
5
5
|
import SeamlyConfigurationError from 'api/errors/seamly-configuration-error'
|
|
6
6
|
import SeamlyGeneralError from 'api/errors/seamly-general-error'
|
|
7
7
|
import SeamlySessionExpiredError from 'api/errors/seamly-session-expired-error'
|
|
@@ -20,7 +20,7 @@ declare let PACKAGE_VERSION: string
|
|
|
20
20
|
const log = debug('seamly')
|
|
21
21
|
|
|
22
22
|
const DOMAIN = 'api.seamly-app.com'
|
|
23
|
-
const TRANSLATIONS_VERSION =
|
|
23
|
+
const TRANSLATIONS_VERSION = 4
|
|
24
24
|
|
|
25
25
|
function buildPayload(command, payload) {
|
|
26
26
|
if (command !== 'message') {
|
|
@@ -37,6 +37,26 @@ function buildPayload(command, payload) {
|
|
|
37
37
|
return { type, body, transactionId }
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
const fetchApi = async (
|
|
41
|
+
input: string,
|
|
42
|
+
// eslint-disable-next-line no-undef
|
|
43
|
+
init: RequestInit,
|
|
44
|
+
): Promise<Response> => {
|
|
45
|
+
const url = new URL(input)
|
|
46
|
+
url.searchParams.set('v', apiVersion)
|
|
47
|
+
|
|
48
|
+
const response = await fetch(url.href, { mode: 'cors', ...init })
|
|
49
|
+
|
|
50
|
+
if (!response.ok) {
|
|
51
|
+
throw new ApiError(
|
|
52
|
+
response.statusText || `Request failed with status: ${response.status}`,
|
|
53
|
+
{ status: response.status },
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return response
|
|
58
|
+
}
|
|
59
|
+
|
|
40
60
|
/**
|
|
41
61
|
* Tries to get the time zone key directly from the operating system for those
|
|
42
62
|
* environments that support the ECMAScript Internationalization API.
|
|
@@ -80,11 +100,16 @@ type InitialConversation = Omit<
|
|
|
80
100
|
>
|
|
81
101
|
export type ConversationHistoryResponse = Omit<
|
|
82
102
|
components['schemas']['ConversationHistoryResponse']['history'],
|
|
83
|
-
'messages' | 'ui.resumeConversationPrompt'
|
|
103
|
+
'messages' | 'ui.resumeConversationPrompt' | 'activeServiceSettings'
|
|
84
104
|
> & {
|
|
85
105
|
resumeConversationPrompt: components['schemas']['ConversationHistoryResponse']['history']['ui']['resumeConversationPrompt']
|
|
86
106
|
translationProposal: components['schemas']['ConversationHistoryResponse']['history']['ui']['translationProposal']
|
|
87
107
|
events: ChannelEvent[]
|
|
108
|
+
activeServiceSettings: components['schemas']['ConversationHistoryResponse']['history']['activeServiceSettings'] & {
|
|
109
|
+
proactiveMessages?: {
|
|
110
|
+
enabled: boolean
|
|
111
|
+
}
|
|
112
|
+
}
|
|
88
113
|
}
|
|
89
114
|
|
|
90
115
|
export class API {
|
|
@@ -94,6 +119,8 @@ export class API {
|
|
|
94
119
|
|
|
95
120
|
#externalId: string
|
|
96
121
|
|
|
122
|
+
#conversationAuthToken?: string
|
|
123
|
+
|
|
97
124
|
#layoutMode: LayoutMode
|
|
98
125
|
|
|
99
126
|
#config: ApiConfig & {
|
|
@@ -116,7 +143,7 @@ export class API {
|
|
|
116
143
|
|
|
117
144
|
locale: string
|
|
118
145
|
|
|
119
|
-
conversation
|
|
146
|
+
conversation: ConversationConnector = new ConversationConnector()
|
|
120
147
|
|
|
121
148
|
constructor({
|
|
122
149
|
layoutMode,
|
|
@@ -238,18 +265,29 @@ export class API {
|
|
|
238
265
|
|
|
239
266
|
async #createConversation(): Promise<InitialConversation> {
|
|
240
267
|
try {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
268
|
+
if (typeof this.#config?.getConversationAuthToken === 'function') {
|
|
269
|
+
this.#conversationAuthToken =
|
|
270
|
+
await this.#config.getConversationAuthToken()
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const response = await fetchApi(
|
|
274
|
+
`${this.#getUrlPrefix('http')}${this.URLS.conversations}`,
|
|
275
|
+
{
|
|
276
|
+
method: 'POST',
|
|
277
|
+
credentials: 'include',
|
|
278
|
+
headers: {
|
|
279
|
+
'Content-Type': 'application/json',
|
|
280
|
+
},
|
|
281
|
+
body: JSON.stringify({
|
|
282
|
+
externalId: this.#conversationAuthToken
|
|
283
|
+
? undefined
|
|
284
|
+
: this.#externalId,
|
|
285
|
+
token: this.#conversationAuthToken,
|
|
286
|
+
}),
|
|
287
|
+
},
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
const body = await response.json()
|
|
253
291
|
|
|
254
292
|
const { conversation } = body
|
|
255
293
|
const initialState = { ...conversation }
|
|
@@ -268,57 +306,73 @@ export class API {
|
|
|
268
306
|
throw new SeamlyGeneralError(error)
|
|
269
307
|
}
|
|
270
308
|
|
|
309
|
+
if (error.status === 400) {
|
|
310
|
+
throw new SeamlyUnauthorizedError(error)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (error.status === 404) {
|
|
314
|
+
throw new SeamlyConfigurationError(error)
|
|
315
|
+
}
|
|
316
|
+
|
|
271
317
|
throw error
|
|
272
318
|
}
|
|
273
319
|
}
|
|
274
320
|
|
|
275
|
-
getConfig()
|
|
276
|
-
|
|
277
|
-
|
|
321
|
+
async getConfig() {
|
|
322
|
+
try {
|
|
323
|
+
const response = await fetchApi(
|
|
278
324
|
`${this.#getUrlPrefix('http')}/client/${
|
|
279
325
|
this.connectionInfo.apiKey
|
|
280
326
|
}/configs`,
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
327
|
+
{
|
|
328
|
+
method: 'POST',
|
|
329
|
+
headers: {
|
|
330
|
+
'Content-Type': 'application/json',
|
|
331
|
+
},
|
|
332
|
+
body: JSON.stringify({
|
|
333
|
+
context: {
|
|
334
|
+
...this.#config.context,
|
|
335
|
+
environment:
|
|
336
|
+
this.#config.sendEnvironment === true
|
|
337
|
+
? this.#getEnvironment()
|
|
338
|
+
: this.#config.sendEnvironment,
|
|
339
|
+
},
|
|
340
|
+
}),
|
|
291
341
|
},
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
}
|
|
342
|
+
)
|
|
343
|
+
const body = await response.json()
|
|
344
|
+
this.#updateUrls(body)
|
|
345
|
+
this.configReady = true
|
|
346
|
+
return body.config
|
|
347
|
+
} catch (error) {
|
|
348
|
+
if (error.status === 404) {
|
|
349
|
+
throw new SeamlyConfigurationError(error)
|
|
350
|
+
}
|
|
302
351
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
352
|
+
if (error.status >= 500) {
|
|
353
|
+
throw new SeamlyGeneralError(error)
|
|
354
|
+
}
|
|
306
355
|
|
|
307
|
-
|
|
308
|
-
|
|
356
|
+
throw error
|
|
357
|
+
}
|
|
309
358
|
}
|
|
310
359
|
|
|
311
|
-
async getConversation(): Promise<ConversationHistoryResponse> {
|
|
360
|
+
async getConversation(): Promise<ConversationHistoryResponse | null> {
|
|
312
361
|
if (!this.hasConversation()) {
|
|
313
362
|
return null
|
|
314
363
|
}
|
|
315
364
|
|
|
316
365
|
try {
|
|
317
|
-
const
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
366
|
+
const response = await fetchApi(
|
|
367
|
+
`${this.#getUrlPrefix('http')}${this.URLS.history}`,
|
|
368
|
+
{
|
|
369
|
+
method: 'GET',
|
|
370
|
+
headers: {
|
|
371
|
+
Authorization: `Bearer ${this.#getAccessToken()}`,
|
|
372
|
+
},
|
|
373
|
+
},
|
|
374
|
+
)
|
|
375
|
+
const body = await response.json()
|
|
322
376
|
this.#updateUrls(body)
|
|
323
377
|
|
|
324
378
|
const {
|
|
@@ -408,58 +462,76 @@ export class API {
|
|
|
408
462
|
const formData = new FormData()
|
|
409
463
|
formData.append('upload', file)
|
|
410
464
|
|
|
411
|
-
const
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
.send(formData)
|
|
465
|
+
const xhr = new XMLHttpRequest()
|
|
466
|
+
xhr.open('POST', `${this.#getUrlPrefix('http')}${this.URLS.uploads}`)
|
|
467
|
+
xhr.setRequestHeader('Authorization', `Bearer ${this.#getAccessToken()}`)
|
|
415
468
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
469
|
+
xhr.upload.onprogress = (event) => {
|
|
470
|
+
if (typeof progressCallback === 'function') {
|
|
471
|
+
const percent = Math.ceil((event.loaded / event.total) * 100)
|
|
419
472
|
progressCallback(percent)
|
|
420
473
|
}
|
|
421
|
-
}
|
|
474
|
+
}
|
|
422
475
|
|
|
423
|
-
|
|
424
|
-
|
|
476
|
+
xhr.onloadend = () => {
|
|
477
|
+
// status is set to 0 when upload is aborted.
|
|
478
|
+
if (xhr.status === 0) return
|
|
479
|
+
|
|
480
|
+
if (xhr.status === 200 || xhr.status === 201) {
|
|
425
481
|
if (successCallback) {
|
|
426
|
-
|
|
482
|
+
try {
|
|
483
|
+
successCallback(JSON.parse(xhr.response))
|
|
484
|
+
} catch (_) {
|
|
485
|
+
successCallback(xhr.response)
|
|
486
|
+
}
|
|
487
|
+
return
|
|
427
488
|
}
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
if (errorCallback) {
|
|
492
|
+
try {
|
|
493
|
+
errorCallback(JSON.parse(xhr.response))
|
|
494
|
+
} catch (_) {
|
|
495
|
+
errorCallback(xhr.response)
|
|
434
496
|
}
|
|
435
|
-
}
|
|
497
|
+
} else {
|
|
498
|
+
throw new Error(xhr.response)
|
|
499
|
+
}
|
|
500
|
+
}
|
|
436
501
|
|
|
437
|
-
|
|
502
|
+
xhr.send(formData)
|
|
503
|
+
return xhr
|
|
438
504
|
}
|
|
439
505
|
|
|
440
|
-
getConversationIntitialState() {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
if (error.status === 401) {
|
|
452
|
-
throw new SeamlyUnauthorizedError(error)
|
|
453
|
-
}
|
|
454
|
-
if (error.status === 404) {
|
|
455
|
-
throw new SeamlySessionExpiredError(error)
|
|
456
|
-
}
|
|
457
|
-
if (error.status >= 500) {
|
|
458
|
-
throw new SeamlyGeneralError(error)
|
|
459
|
-
}
|
|
506
|
+
async getConversationIntitialState() {
|
|
507
|
+
try {
|
|
508
|
+
const response = await fetchApi(
|
|
509
|
+
`${this.#getUrlPrefix('http')}${this.getConversationUrl()}`,
|
|
510
|
+
{
|
|
511
|
+
method: 'GET',
|
|
512
|
+
headers: {
|
|
513
|
+
Authorization: `Bearer ${this.#getAccessToken()}`,
|
|
514
|
+
},
|
|
515
|
+
},
|
|
516
|
+
)
|
|
460
517
|
|
|
461
|
-
|
|
462
|
-
|
|
518
|
+
const body = await response.json()
|
|
519
|
+
|
|
520
|
+
this.#updateUrls(body)
|
|
521
|
+
this.userResponded = body.conversation.userResponded
|
|
522
|
+
return omit(body.conversation, ['accessToken', 'channelTopic'])
|
|
523
|
+
} catch (error) {
|
|
524
|
+
if (error.status === 401) {
|
|
525
|
+
throw new SeamlyUnauthorizedError(error)
|
|
526
|
+
}
|
|
527
|
+
if (error.status === 404) {
|
|
528
|
+
throw new SeamlySessionExpiredError(error)
|
|
529
|
+
}
|
|
530
|
+
if (error.status >= 500) {
|
|
531
|
+
throw new SeamlyGeneralError(error)
|
|
532
|
+
}
|
|
533
|
+
throw error
|
|
534
|
+
}
|
|
463
535
|
}
|
|
464
536
|
|
|
465
537
|
async getTranslations(locale: string): Promise<Record<string, string>> {
|
|
@@ -471,9 +543,11 @@ export class API {
|
|
|
471
543
|
const url = `${this.#getUrlPrefix('http')}${this.URLS.translations}`
|
|
472
544
|
.replace('{version}', String(TRANSLATIONS_VERSION))
|
|
473
545
|
.replace('{locale}', this.#getLocale(locale))
|
|
474
|
-
const request = superagent.get(url)
|
|
475
546
|
|
|
476
|
-
const
|
|
547
|
+
const response = await fetchApi(url, {
|
|
548
|
+
method: 'GET',
|
|
549
|
+
})
|
|
550
|
+
const body = await response.json()
|
|
477
551
|
return body.translations
|
|
478
552
|
} catch (error) {
|
|
479
553
|
if (error.status >= 500) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { operations } from 'schema'
|
|
1
2
|
import { FunctionComponent } from 'preact'
|
|
2
3
|
import type { ChannelEvent } from 'domains/store/store.types'
|
|
3
4
|
|
|
@@ -8,6 +9,7 @@ export type ApiConfig = {
|
|
|
8
9
|
sendEnvironment?: boolean
|
|
9
10
|
storageProvider?: unknown
|
|
10
11
|
externalId?: string
|
|
12
|
+
getConversationAuthToken?: Function
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
export type LayoutMode = 'inline' | 'window' | 'app' | null
|
|
@@ -47,13 +49,11 @@ export type Context = {
|
|
|
47
49
|
variables?: Record<string, unknown>
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
export type
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
export type UserParticipant =
|
|
55
|
-
avatar: string
|
|
56
|
-
}
|
|
52
|
+
export type ConfigResponse =
|
|
53
|
+
operations['getAccountConfig']['responses']['201']['content']['application/json']['config']
|
|
54
|
+
|
|
55
|
+
export type AgentParticipant = ConfigResponse['agentParticipant']
|
|
56
|
+
export type UserParticipant = ConfigResponse['userParticipant']
|
|
57
57
|
|
|
58
58
|
export type VisibilityCallbackOptions = {
|
|
59
59
|
hasConversation: boolean
|
|
@@ -67,7 +67,14 @@ export type VisibilityCallback = (
|
|
|
67
67
|
_options: VisibilityCallbackOptions,
|
|
68
68
|
) => VisibilityOptions
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
type PreChatTransitionOptions =
|
|
71
|
+
| {
|
|
72
|
+
enterDelay: number
|
|
73
|
+
exitAfter: number
|
|
74
|
+
}
|
|
75
|
+
| boolean
|
|
76
|
+
|
|
77
|
+
export type Config = Omit<ConfigResponse, 'preChat'> & {
|
|
71
78
|
parentElement?: HTMLElement
|
|
72
79
|
namespace?: string
|
|
73
80
|
customComponents?: {
|
|
@@ -85,14 +92,14 @@ export type Config = {
|
|
|
85
92
|
zIndex?: number
|
|
86
93
|
showFaq?: boolean
|
|
87
94
|
showSuggestions?: boolean
|
|
95
|
+
continueChat?: PreChatTransitionOptions
|
|
96
|
+
preChat?: PreChatTransitionOptions
|
|
88
97
|
context?: Context
|
|
89
98
|
messages?: Messages
|
|
90
99
|
defaults?: {
|
|
91
100
|
visible: VisibilityOptions
|
|
92
101
|
}
|
|
93
102
|
preChatEvents?: ChannelEvent[]
|
|
94
|
-
agentParticipant?: AgentParticipant
|
|
95
|
-
userParticipant?: UserParticipant
|
|
96
|
-
startChatIcon?: string
|
|
97
103
|
visible?: VisibilityOptions
|
|
104
|
+
notificationAudioURL?: string | undefined | boolean
|
|
98
105
|
}
|
|
@@ -10,7 +10,7 @@ export const selectConfig = createSelector(
|
|
|
10
10
|
visible: (config?.layoutMode === 'inline'
|
|
11
11
|
? visibilityStates.open
|
|
12
12
|
: visibilityStates.minimized) as VisibilityOptions,
|
|
13
|
-
appContainerClassNames: config
|
|
13
|
+
appContainerClassNames: config?.appContainerClassNames || [],
|
|
14
14
|
...config,
|
|
15
15
|
}
|
|
16
16
|
if (typeof newConfig.appContainerClassNames === 'function') {
|
|
@@ -12,11 +12,20 @@ export const initialConfigState: Config = {
|
|
|
12
12
|
key: '',
|
|
13
13
|
secure: true,
|
|
14
14
|
},
|
|
15
|
+
notificationAudioURL: undefined,
|
|
15
16
|
hideOnNoUserResponse: false,
|
|
16
17
|
connectWhenInView: true,
|
|
17
18
|
showDisclaimer: false,
|
|
18
19
|
showFaq: false,
|
|
19
20
|
showSuggestions: true,
|
|
21
|
+
preChat: {
|
|
22
|
+
enterDelay: 1000,
|
|
23
|
+
exitAfter: 4000,
|
|
24
|
+
},
|
|
25
|
+
continueChat: {
|
|
26
|
+
enterDelay: 0,
|
|
27
|
+
exitAfter: 2000,
|
|
28
|
+
},
|
|
20
29
|
customComponents: {},
|
|
21
30
|
defaults: {
|
|
22
31
|
visible: null,
|
|
@@ -30,6 +39,8 @@ const configKeys: (keyof Config)[] = [
|
|
|
30
39
|
'showDisclaimer',
|
|
31
40
|
'showFaq',
|
|
32
41
|
'showSuggestions',
|
|
42
|
+
'continueChat',
|
|
43
|
+
'preChat',
|
|
33
44
|
'namespace',
|
|
34
45
|
'customComponents',
|
|
35
46
|
'defaults',
|
|
@@ -45,6 +56,7 @@ const configKeys: (keyof Config)[] = [
|
|
|
45
56
|
'agentParticipant',
|
|
46
57
|
'userParticipant',
|
|
47
58
|
'startChatIcon',
|
|
59
|
+
'notificationAudioURL',
|
|
48
60
|
]
|
|
49
61
|
|
|
50
62
|
const updateState = (state, config: Config): Config => {
|