@kindly/react-chat 2.42.1 → 2.43.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kindly/react-chat",
3
- "version": "2.42.1",
3
+ "version": "2.43.0",
4
4
  "description": "Kindly Chat react component",
5
5
  "repository": "https://github.com/kindly-ai/kindly-chat/tree/main/packages/react-chat",
6
6
  "main": "dist/index.js",
@@ -69,15 +69,15 @@
69
69
  "@babel/plugin-transform-runtime": "^7.21.0",
70
70
  "@babel/preset-env": "^7.20.2",
71
71
  "@babel/preset-react": "^7.18.6",
72
- "@storybook/addon-a11y": "^7.0.4",
73
- "@storybook/addon-actions": "^7.0.4",
74
- "@storybook/addon-essentials": "^7.0.4",
75
- "@storybook/addon-interactions": "^7.0.4",
76
- "@storybook/addon-links": "^7.0.4",
77
- "@storybook/addon-mdx-gfm": "^7.0.4",
72
+ "@storybook/addon-a11y": "^7.0.11",
73
+ "@storybook/addon-actions": "^7.0.11",
74
+ "@storybook/addon-essentials": "^7.0.11",
75
+ "@storybook/addon-interactions": "^7.0.11",
76
+ "@storybook/addon-links": "^7.0.11",
77
+ "@storybook/addon-mdx-gfm": "^7.0.11",
78
78
  "@storybook/jest": "^0.1.0",
79
- "@storybook/react": "^7.0.4",
80
- "@storybook/react-webpack5": "^7.0.4",
79
+ "@storybook/react": "^7.0.11",
80
+ "@storybook/react-webpack5": "^7.0.11",
81
81
  "@storybook/test-runner": "^0.10.0",
82
82
  "@storybook/testing-library": "^0.1.0",
83
83
  "@testing-library/jest-dom": "^5.16.5",
@@ -112,7 +112,7 @@
112
112
  "react-svg-loader": "^3.0.3",
113
113
  "react-test-renderer": "16.14.0",
114
114
  "resolve-url-loader": "^5.0.0",
115
- "storybook": "^7.0.4",
115
+ "storybook": "^7.0.11",
116
116
  "storybook-addon-mock": "^4.0.0",
117
117
  "url-loader": "^4.1.1",
118
118
  "wait-on": "^6.0.1",
@@ -130,5 +130,5 @@
130
130
  "pusher-js": "8.0.1"
131
131
  }
132
132
  },
133
- "gitHead": "b2f0e79ce5be18782b4c66075d1b9830205d4de9"
133
+ "gitHead": "28c0dccea41ef182224bdbabcd66c85444e81220"
134
134
  }
@@ -162,7 +162,7 @@ export default {
162
162
  text: {
163
163
  placeholder: {
164
164
  en: 'Ask me a question…',
165
- nb: 'Ask me a question…',
165
+ nb: 'Still meg et spørsmål…',
166
166
  },
167
167
  change_language_button: {
168
168
  en: 'Change language',
@@ -218,12 +218,6 @@ export default {
218
218
  nn: 'Tilbake til chat',
219
219
  sv: 'Tillbaka till chat',
220
220
  },
221
- change_language_text: {
222
- en: 'The chat will reset when you change the language',
223
- nb: 'Når du endrer språk, starter samtalen på nytt',
224
- nn: 'Når du endrer språk, starter samtalen på nytt',
225
- sv: 'När du ändrar språk, startar samtalet på nytt',
226
- },
227
221
  cancel_chat_text: {
228
222
  en: 'Would you like to cancel the chat?',
229
223
  nb: 'Vil du avslutte samtalen?',
@@ -296,6 +290,24 @@ export default {
296
290
  nn: 'Behold plassen i køen',
297
291
  sv: 'Behåll platsen i chattkön',
298
292
  },
293
+ gpt_search_result_text: {
294
+ nb: 'fant dette på nettsiden vår',
295
+ en: 'found this on our web page',
296
+ sv: 'hittade detta på vår hemsida',
297
+ nn: 'fann dette på nettsida vår',
298
+ },
299
+ gpt_search_text: {
300
+ nb: 'søker på nettsiden vår',
301
+ en: 'is searching our web page',
302
+ sv: 'söker på vår hemsida',
303
+ nn: 'søker på nettsida vår',
304
+ },
305
+ gpt_tooltip_disclaimer: {
306
+ nb: 'Dette svaret er generert basert på innhold fra nettsiden vår.',
307
+ en: 'This reply is generated based on content from our web page.',
308
+ sv: 'Detta svar är genererat baserat på innehållet från vår hemsida',
309
+ nn: 'Dette svaret er generert basert på innhald frå nettsida vår.',
310
+ },
299
311
  },
300
312
  nudges: {
301
313
  form_nudges: [
@@ -0,0 +1,174 @@
1
+ import { userEvent, within } from '@storybook/testing-library';
2
+ import React from 'react';
3
+
4
+ import KindlyChatButton from '../../../src/features/KindlyChatButton/KindlyChatButton';
5
+ import settingsJSON from '../../assets/settingsJson';
6
+ import withContainer from '../../decorators/withContainer';
7
+ import withMockProvider from '../../decorators/withProvider';
8
+
9
+ const defaultBotSettings = {
10
+ welcomePage: settingsJSON.welcome_page,
11
+ feedbackForm: settingsJSON.feedback_form,
12
+ maintenanceAlert: settingsJSON.maintenance_alert,
13
+ ...settingsJSON.settings,
14
+ ...settingsJSON,
15
+ };
16
+
17
+ function Template(args, context) {
18
+ return <KindlyChatButton {...args} {...context} />;
19
+ }
20
+
21
+ export default {
22
+ title: 'Screen/Chat/Composer',
23
+ component: KindlyChatButton,
24
+ decorators: [withContainer, withMockProvider],
25
+ argTypes: {
26
+ initialStateModifierFromArgs: {
27
+ table: {
28
+ disable: true,
29
+ },
30
+ },
31
+ },
32
+ };
33
+
34
+ const todayTime = new Date();
35
+ todayTime.setHours(13);
36
+ todayTime.setMinutes(37);
37
+ const created = todayTime.toISOString();
38
+
39
+ const defaultParameters = {
40
+ botSettings: defaultBotSettings,
41
+ initialStateModifier: {
42
+ chatbubble: {
43
+ active: true,
44
+ chatHasStarted: true,
45
+ currentLanguage: 'en',
46
+ },
47
+ messages: {
48
+ chatMessages: [
49
+ {
50
+ session_id: '1',
51
+ bot_id: 1234,
52
+ chat_id: '1',
53
+ chat_source: 'web',
54
+ chat_language_code: 'en',
55
+ from_bot: true,
56
+ sender: 'BOT',
57
+ message: 'Why did the calendar get in trouble at work?',
58
+ message_format: 'txt',
59
+ exchange_type: 'greeting',
60
+ exchange_id: '1',
61
+ reply_type: 'STANDARD',
62
+ created,
63
+ id: '1',
64
+ },
65
+ {
66
+ id: '2',
67
+ created,
68
+ message: 'Because it took a day off!',
69
+ status: null,
70
+ },
71
+ ],
72
+ messageSentTime: '2020-12-01T12:00:00.000Z',
73
+ lastMessageSeen: {
74
+ id: '2',
75
+ index: 2,
76
+ },
77
+ },
78
+ },
79
+ };
80
+
81
+ export const BelowInputLimit = Template.bind({});
82
+ BelowInputLimit.parameters = {
83
+ ...defaultParameters,
84
+ botSettings: {
85
+ ...defaultBotSettings,
86
+ chatbubble: {
87
+ ...defaultBotSettings.chatbubble,
88
+ input_limit_enabled: true,
89
+ input_limit: 120,
90
+ },
91
+ },
92
+ };
93
+ BelowInputLimit.args = {
94
+ inputLimit: 100,
95
+ initialStateModifierFromArgs: ({ inputLimit }) => ({
96
+ chatbubble: {
97
+ active: true,
98
+ chatHasStarted: true,
99
+ currentLanguage: 'en',
100
+ },
101
+ bot: {
102
+ inputLimit,
103
+ },
104
+ }),
105
+ };
106
+ BelowInputLimit.argTypes = {
107
+ inputLimit: {
108
+ control: { type: 'range', min: 60, max: 200, step: 20, defaultValue: 140 },
109
+ },
110
+ };
111
+
112
+ BelowInputLimit.play = async ({ canvasElement }) => {
113
+ const composer = await within(canvasElement).findByPlaceholderText(defaultBotSettings.text.placeholder.en);
114
+ await userEvent.type(composer, 'Once upon a time, there was a mischievous dragon named Lorem.');
115
+ };
116
+
117
+ export const AboveInputLimit = Template.bind({});
118
+ AboveInputLimit.parameters = {
119
+ ...defaultParameters,
120
+ botSettings: {
121
+ ...defaultBotSettings,
122
+ chatbubble: {
123
+ ...defaultBotSettings.chatbubble,
124
+ input_limit_enabled: true,
125
+ input_limit: 120,
126
+ },
127
+ },
128
+ };
129
+ AboveInputLimit.args = {
130
+ inputLimit: 100,
131
+ initialStateModifierFromArgs: ({ inputLimit }) => ({
132
+ chatbubble: {
133
+ active: true,
134
+ chatHasStarted: true,
135
+ currentLanguage: 'en',
136
+ },
137
+ bot: {
138
+ inputLimit,
139
+ },
140
+ }),
141
+ };
142
+ AboveInputLimit.argTypes = {
143
+ inputLimit: {
144
+ control: { type: 'range', min: 60, max: 200, step: 20, defaultValue: 140 },
145
+ },
146
+ };
147
+
148
+ AboveInputLimit.play = async ({ canvasElement }) => {
149
+ const composer = await within(canvasElement).findByPlaceholderText(defaultBotSettings.text.placeholder.en);
150
+ await userEvent.type(
151
+ composer,
152
+ 'Once upon a time, in a land far, far away, there was a mischievous dragon named Lorem who loved to eat apples and play pranks on the villagers.',
153
+ );
154
+ };
155
+
156
+ export const NoInputLimit = Template.bind({});
157
+ NoInputLimit.parameters = {
158
+ ...defaultParameters,
159
+ botSettings: {
160
+ ...defaultBotSettings,
161
+ chatbubble: {
162
+ ...defaultBotSettings.chatbubble,
163
+ input_limit_enabled: false,
164
+ input_limit: 100,
165
+ },
166
+ },
167
+ };
168
+ NoInputLimit.play = async ({ canvasElement }) => {
169
+ const composer = await within(canvasElement).findByPlaceholderText(defaultBotSettings.text.placeholder.en);
170
+ await userEvent.type(
171
+ composer,
172
+ 'Once upon a time, in a land far, far away, there was a mischievous dragon named Lorem who loved to eat apples and play pranks on the villagers. One day, a brave knight named Ipsum arrived in the village, seeking to slay the dragon and win the heart of the fair princess.',
173
+ );
174
+ };
@@ -0,0 +1,184 @@
1
+ import React from 'react';
2
+
3
+ import { DEFAULT_ALERT_TYPES } from '../../../src/constants';
4
+ import KindlyChatButton from '../../../src/features/KindlyChatButton/KindlyChatButton';
5
+ import { showInChatNotification } from '../../../src/state/actions';
6
+ import settingsJSON from '../../assets/settingsJson';
7
+ import withContainer from '../../decorators/withContainer';
8
+ import withMockProvider from '../../decorators/withProvider';
9
+
10
+ const defaultBotSettings = {
11
+ welcomePage: settingsJSON.welcome_page,
12
+ feedbackForm: settingsJSON.feedback_form,
13
+ maintenanceAlert: settingsJSON.maintenance_alert,
14
+ ...settingsJSON.settings,
15
+ ...settingsJSON,
16
+ };
17
+
18
+ function Template(args, context) {
19
+ return <KindlyChatButton {...args} {...context} />;
20
+ }
21
+
22
+ export default {
23
+ title: 'Screen/Chat/Notifications',
24
+ component: KindlyChatButton,
25
+ decorators: [withContainer, withMockProvider],
26
+ argTypes: {
27
+ initialStateModifierFromArgs: {
28
+ table: {
29
+ disable: true,
30
+ },
31
+ },
32
+ },
33
+ };
34
+
35
+ export const Maintenance = Template.bind({});
36
+ Maintenance.parameters = {
37
+ botSettings: defaultBotSettings,
38
+ initialStateModifier: {
39
+ chatbubble: {
40
+ active: true,
41
+ chatHasStarted: true,
42
+ currentLanguage: 'en',
43
+ },
44
+ bot: {
45
+ maintenanceAlert: {
46
+ alert_enabled: true,
47
+ link_text: { en: 'Click here to learn more', nb: '', nn: '', sv: '' },
48
+ link_location: { en: 'https://example.com', nb: '', nn: '', sv: '' },
49
+ text_content: { en: 'Maintenance!', nb: '', nn: '', sv: '' },
50
+ },
51
+ maintenanceAlertEnabled: true,
52
+ },
53
+ },
54
+ };
55
+
56
+ export const WithIcon = Template.bind({});
57
+ WithIcon.parameters = {
58
+ botSettings: defaultBotSettings,
59
+ initialStateModifier: {
60
+ chatbubble: {
61
+ active: true,
62
+ chatHasStarted: true,
63
+ currentLanguage: 'en',
64
+ },
65
+ },
66
+ };
67
+ WithIcon.play = async () => {
68
+ const notification = {
69
+ content: 'I detected english and switched language. Go to [settings](#settings/language-select) to switch back.',
70
+ icon: 'language',
71
+ };
72
+ window.store.dispatch(showInChatNotification(notification, Math.random()));
73
+ };
74
+
75
+ export const WithIconAndButton = Template.bind({});
76
+ WithIconAndButton.parameters = {
77
+ botSettings: defaultBotSettings,
78
+ initialStateModifier: {
79
+ chatbubble: {
80
+ active: true,
81
+ chatHasStarted: true,
82
+ currentLanguage: 'en',
83
+ },
84
+ },
85
+ };
86
+ WithIconAndButton.play = async () => {
87
+ const notification = {
88
+ content: 'I am a notification',
89
+ buttonHref: 'https://example.com',
90
+ buttonText: 'Click me',
91
+ icon: 'language',
92
+ };
93
+ window.store.dispatch(showInChatNotification(notification, Math.random()));
94
+ };
95
+
96
+ export const StackedNotifications = Template.bind({});
97
+ StackedNotifications.parameters = {
98
+ botSettings: defaultBotSettings,
99
+ initialStateModifier: {
100
+ chatbubble: {
101
+ active: true,
102
+ chatHasStarted: true,
103
+ currentLanguage: 'en',
104
+ },
105
+ },
106
+ };
107
+ StackedNotifications.play = async () => {
108
+ const notifications = [
109
+ {
110
+ content: 'I am a notification',
111
+ buttonHref: 'https://example.com',
112
+ buttonText: 'Click me',
113
+ },
114
+ {
115
+ content: 'With a long text that will wrap. I am a notification. I am long. Maybe too long?',
116
+ buttonHref: 'https://example.com',
117
+ buttonText: 'With a long text that will wrap. I am a notification. I am long. Maybe too long?',
118
+ },
119
+ {
120
+ content: 'Without a button',
121
+ },
122
+ ];
123
+ notifications.forEach((notification) => {
124
+ window.store.dispatch(showInChatNotification(notification, Math.random()));
125
+ });
126
+ let i = 0;
127
+ const { store } = window;
128
+ const interval = setInterval(() => {
129
+ store.dispatch(showInChatNotification(notifications[(i + 1) % notifications.length], Math.random()));
130
+ i += 1;
131
+ if (window.store !== store) {
132
+ clearInterval(interval);
133
+ }
134
+ }, [4000]);
135
+ };
136
+
137
+ export const OnWelcomePage = Template.bind({});
138
+ OnWelcomePage.parameters = {
139
+ botSettings: defaultBotSettings,
140
+ initialStateModifier: {
141
+ chatbubble: {
142
+ active: true,
143
+ chatHasStarted: false,
144
+ currentLanguage: 'en',
145
+ },
146
+ },
147
+ };
148
+
149
+ OnWelcomePage.play = async () => {
150
+ const notifications = [
151
+ {
152
+ content: 'I am a notification',
153
+ buttonHref: 'https://example.com',
154
+ buttonText: 'Click me',
155
+ },
156
+ ];
157
+ notifications.forEach((notification) => {
158
+ window.store.dispatch(showInChatNotification(notification, Math.random()));
159
+ });
160
+ };
161
+
162
+ export const QuickSetting = Template.bind({});
163
+ QuickSetting.parameters = {
164
+ botSettings: defaultBotSettings,
165
+ initialStateModifier: {
166
+ chatbubble: {
167
+ active: true,
168
+ chatHasStarted: true,
169
+ currentLanguage: 'en',
170
+ },
171
+ },
172
+ };
173
+
174
+ QuickSetting.play = async () => {
175
+ const notifications = [
176
+ {
177
+ content:
178
+ 'I detected [english](and) switched language. Go to [settings](#settings/language-select) to switch back.',
179
+ },
180
+ ];
181
+ notifications.forEach((notification) => {
182
+ window.store.dispatch(showInChatNotification(notification, DEFAULT_ALERT_TYPES.LANGUAGE_SWITCH));
183
+ });
184
+ };
@@ -0,0 +1,143 @@
1
+ import React from 'react';
2
+
3
+ import KindlyChatButton from '../../../src/features/KindlyChatButton/KindlyChatButton';
4
+ import settingsJSON from '../../assets/settingsJson';
5
+ import withContainer from '../../decorators/withContainer';
6
+ import withMockProvider from '../../decorators/withProvider';
7
+
8
+ const todayTime = new Date();
9
+ todayTime.setHours(13);
10
+ todayTime.setMinutes(37);
11
+ const created = todayTime.toISOString();
12
+
13
+ const defaultBotSettings = {
14
+ welcomePage: settingsJSON.welcome_page,
15
+ feedbackForm: settingsJSON.feedback_form,
16
+ maintenanceAlert: settingsJSON.maintenance_alert,
17
+ ...settingsJSON.settings,
18
+ ...settingsJSON,
19
+ };
20
+
21
+ const defaultParameters = {
22
+ botSettings: defaultBotSettings,
23
+ initialStateModifier: {
24
+ chatbubble: {
25
+ active: true,
26
+ chatHasStarted: true,
27
+ currentLanguage: 'en',
28
+ },
29
+ messages: {
30
+ chatMessages: [
31
+ {
32
+ session_id: '1',
33
+ bot_id: 1234,
34
+ chat_id: '1',
35
+ chat_source: 'web',
36
+ chat_language_code: 'en',
37
+ from_bot: true,
38
+ sender: 'BOT',
39
+ message:
40
+ "Hi! I'm Kindly's Chatbot. I can answer questions about Kindly and our services. How can I help you? 🙂\n<br>\n<br>Feel free to ask me a short and concise question!",
41
+ message_format: 'txt',
42
+ exchange_type: 'greeting',
43
+ exchange_id: '1',
44
+ reply_type: 'STANDARD',
45
+ created,
46
+ id: '1',
47
+ },
48
+ ],
49
+ messageSentTime: '2020-12-01T12:00:00.000Z',
50
+ lastMessageSeen: {
51
+ id: '3',
52
+ index: 3,
53
+ },
54
+ },
55
+ },
56
+ };
57
+
58
+ export default {
59
+ title: 'Screen/Chat/TypingIndicator',
60
+ component: KindlyChatButton,
61
+ decorators: [withContainer, withMockProvider],
62
+ argTypes: {
63
+ initialStateModifierFromArgs: {
64
+ table: {
65
+ disable: true,
66
+ },
67
+ },
68
+ },
69
+ };
70
+
71
+ function Template(args, context) {
72
+ return <KindlyChatButton {...args} {...context} />;
73
+ }
74
+
75
+ export const BotTypingIndicator = Template.bind({});
76
+
77
+ BotTypingIndicator.parameters = {
78
+ botSettings: defaultBotSettings,
79
+ initialStateModifier: {
80
+ chatbubble: {
81
+ active: true,
82
+ chatHasStarted: true,
83
+ currentLanguage: 'en',
84
+ },
85
+ messages: {
86
+ chatMessages: [
87
+ {
88
+ id: '2',
89
+ created,
90
+ message: 'What is the meaning of life?',
91
+ status: null,
92
+ },
93
+ ],
94
+ },
95
+ bot: {
96
+ isTyping: true,
97
+ },
98
+ },
99
+ };
100
+
101
+ export const MimirTypingIndicator = Template.bind({});
102
+
103
+ MimirTypingIndicator.parameters = {
104
+ botSettings: defaultBotSettings,
105
+ initialStateModifier: {
106
+ chatbubble: {
107
+ active: true,
108
+ chatHasStarted: true,
109
+ currentLanguage: 'en',
110
+ },
111
+ messages: {
112
+ chatMessages: [
113
+ {
114
+ id: '1',
115
+ created,
116
+ message: 'What is the meaning of life?',
117
+ status: null,
118
+ },
119
+ ],
120
+ },
121
+ },
122
+ };
123
+
124
+ MimirTypingIndicator.args = {
125
+ text: settingsJSON.text.gpt_search_text.en,
126
+ initialStateModifierFromArgs: ({ text }) => {
127
+ return {
128
+ ...defaultParameters.initialStateModifier,
129
+ bot: {
130
+ isMimirTyping: true,
131
+ text: {
132
+ gpt_search_text: {
133
+ en: text,
134
+ },
135
+ },
136
+ },
137
+ };
138
+ },
139
+ };
140
+
141
+ MimirTypingIndicator.argTypes = {
142
+ text: 'string',
143
+ };