@telia-ace/widget-conversation 1.0.14 → 1.0.17
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/README.md +123 -106
- package/dist/conversation.js +453 -614
- package/dist/conversation.js.map +1 -1
- package/dist/index.js +0 -3
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +28 -42
- package/dist/ui/conversation/conversation-styles.d.ts +1 -0
- package/dist/ui/conversation/message-list-items/button-list.d.ts +8 -0
- package/dist/ui/conversation/{message-types/custom-message-list-item.d.ts → message-list-items/custom.d.ts} +2 -2
- package/dist/ui/conversation/message-list-items/html.d.ts +5 -0
- package/dist/ui/conversation/message-list-items/link-list.d.ts +8 -0
- package/dist/ui/conversation/message-list-items/separator.d.ts +2 -0
- package/dist/ui/conversation/message-list-items/text.d.ts +6 -0
- package/dist/ui/conversation/message-types/index.d.ts +0 -1
- package/dist/ui/conversation/message-types/message-list.d.ts +9 -0
- package/dist/utils/map-actions.d.ts +1 -0
- package/package.json +8 -8
- package/dist/ui/conversation/message-types/custom.d.ts +0 -9
package/README.md
CHANGED
|
@@ -2,21 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
The Widget Conversation API provides support for reading and writing to a conversational component inside a widget.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Sandbox
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
We do not recommend binding functions to the `
|
|
7
|
+
For demonstration purposes, we've set up a sandbox for the Widget Conversational API so that you can see it in action. Keep in mind that this is for demonstration purposes only and may not reflect best practice.
|
|
8
|
+
|
|
9
|
+
> We do not recommend binding functions to the `window` object.
|
|
10
10
|
|
|
11
11
|
[](https://codesandbox.io/s/elegant-jones-rnyrd?fontsize=14&hidenavigation=1&theme=dark)
|
|
12
12
|
|
|
13
13
|
## Accessing the API
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
In order to access the API you need to have a widget with a conversational component.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
### Creating the plugin
|
|
18
|
+
|
|
19
|
+
You need to register the conversational provider in the `providers`-property in the component. To access the global instance of `ConversationPlatform`, you pass in the current `Container` to the `getInstance()` method. It will return a `Promise` that is resolved to the `ConversationPlatform` instance. In the instance, register a provider and pass in name and handler by calling the `registerProvider()` function as shown below.
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
The handler function will be called once a conversational component for the specified provider is activated in the widget. Use the provider to interact with the conversation.
|
|
20
22
|
|
|
21
23
|
```ts
|
|
22
24
|
import { ConversationPlatform } from '@telia-ace/widget-conversation';
|
|
@@ -30,34 +32,39 @@ const MyPlugin = async (container) => {
|
|
|
30
32
|
};
|
|
31
33
|
```
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
When writing content to the conversation you will first need to create an `Agent` object and then use its `print()` function. Specify the type of entry to print and pass in the content.
|
|
35
|
+
You also need to register the provider inside the widget configuration:
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
```JSON
|
|
38
|
+
"my-conversation-component": {
|
|
39
|
+
"type": "conversation",
|
|
40
|
+
"properties": {
|
|
41
|
+
"providers": ["my-chat"],
|
|
42
|
+
// ...
|
|
43
|
+
},
|
|
44
|
+
"context": {}
|
|
45
|
+
},
|
|
46
|
+
```
|
|
38
47
|
|
|
39
|
-
|
|
48
|
+
### Creating an agent in the conversation
|
|
40
49
|
|
|
41
|
-
|
|
50
|
+
When using `createAgent` you can specify both a name and an avatar. These will then be displayed in the conversation alongside that agent's entries.
|
|
42
51
|
|
|
43
52
|
```ts
|
|
44
|
-
const agent = conversation.createAgent(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
entry.update({
|
|
48
|
-
// ...
|
|
53
|
+
const agent = conversation.createAgent({
|
|
54
|
+
name: 'Agent Smith',
|
|
55
|
+
avatar: 'https://www.site.com/avatar.jpg',
|
|
49
56
|
});
|
|
50
|
-
|
|
51
|
-
entry.remove();
|
|
52
57
|
```
|
|
53
58
|
|
|
54
|
-
|
|
59
|
+
## Writing to the conversation
|
|
60
|
+
|
|
61
|
+
### Posting, updating and removing content
|
|
55
62
|
|
|
56
|
-
|
|
63
|
+
When managing content in the conversation you'll first need to create an `Agent`-object and then use its `print()` function. There are serveral types of entries in order to accommedate different types of content.
|
|
57
64
|
|
|
58
|
-
|
|
65
|
+
The `print(content: object)` function let's you return a `ConversationEntry` message that can be used to update and/or remove the content from the conversation.
|
|
59
66
|
|
|
60
|
-
##### Example
|
|
67
|
+
##### Example of simple text message
|
|
61
68
|
|
|
62
69
|
```ts
|
|
63
70
|
// print user message
|
|
@@ -68,9 +75,22 @@ const agent = conversation.createAgent();
|
|
|
68
75
|
agent.print('Lorem ipsum');
|
|
69
76
|
```
|
|
70
77
|
|
|
71
|
-
|
|
78
|
+
##### Example of updating or removing content
|
|
72
79
|
|
|
73
|
-
|
|
80
|
+
```ts
|
|
81
|
+
const agent = conversation.createAgent();
|
|
82
|
+
const entry = agent.print('Hello world!');
|
|
83
|
+
|
|
84
|
+
entry.update({
|
|
85
|
+
// ...
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
entry.remove();
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Entry with list of actions
|
|
92
|
+
|
|
93
|
+
You can post an entry into the conversation with actions. You can specify a title, body and available actions. This is only supported for the `Agent` and will be displayed as a system message.
|
|
74
94
|
|
|
75
95
|
| Name | Type | Description |
|
|
76
96
|
| --------- | -------- | ------------------------------------------------------------- |
|
|
@@ -78,7 +98,7 @@ Example of how to render a list with actions. Is only supported on `Agent` and a
|
|
|
78
98
|
| `body` | `string` | Body content for the entry. Supports HTML. |
|
|
79
99
|
| `actions` | `object` | Key-value-pairs representing available actions for the entry. |
|
|
80
100
|
|
|
81
|
-
##### Example
|
|
101
|
+
##### Example of a list of actions
|
|
82
102
|
|
|
83
103
|
```ts
|
|
84
104
|
agent.print({
|
|
@@ -92,9 +112,9 @@ agent.print({
|
|
|
92
112
|
});
|
|
93
113
|
```
|
|
94
114
|
|
|
95
|
-
|
|
115
|
+
### Entry with a form
|
|
96
116
|
|
|
97
|
-
|
|
117
|
+
You can also post a message with a form attached. This uses the `FormBuilder`-method. This is handled by the `conversation.form` event. It is only supported for `Agent` and will be displayed as a system message.
|
|
98
118
|
|
|
99
119
|
| Name | Type | Description |
|
|
100
120
|
| ------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -103,7 +123,7 @@ Example of how to render a form that can be handled by the `conversation.form` e
|
|
|
103
123
|
| `form` | `(FormBuilder) => void` | A callback function for building the form. Refer to the [`@telia-ace/widget-forms`](https://www.npmjs.com/package/@telia-ace/widget-forms) package for more information about `FormBuilder`. |
|
|
104
124
|
| `key` | `string` | The key used to refer to the form when validating and submitting the form. |
|
|
105
125
|
|
|
106
|
-
##### Example
|
|
126
|
+
##### Example of an entry with a form
|
|
107
127
|
|
|
108
128
|
```ts
|
|
109
129
|
agent.print({
|
|
@@ -132,47 +152,13 @@ agent.print({
|
|
|
132
152
|
});
|
|
133
153
|
```
|
|
134
154
|
|
|
135
|
-
###
|
|
136
|
-
|
|
137
|
-
To create an agent with a name and avatar use the `createAgent` method on the conversation.
|
|
138
|
-
|
|
139
|
-
##### Example
|
|
155
|
+
### The loading and typing indicators
|
|
140
156
|
|
|
141
|
-
|
|
142
|
-
const agent = conversation.createAgent({
|
|
143
|
-
name: 'Mr. Agent',
|
|
144
|
-
avatar: 'https://www.site.com/avatar.jpg',
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
agent.print({
|
|
148
|
-
title: 'I found the following invoices associated to your account:',
|
|
149
|
-
actions: {
|
|
150
|
-
action1: 'Action 1',
|
|
151
|
-
action2: 'Action 2',
|
|
152
|
-
action3: 'Action 3',
|
|
153
|
-
},
|
|
154
|
-
});
|
|
155
|
-
```
|
|
157
|
+
When you need to fetch data from external resource you should use the `loading()` function on the `ConversationProvider` to inform the user that something is about to happen. Even in cases when the response is available immediately it gives a better user experience to present a loading indicator for a short while.
|
|
156
158
|
|
|
157
|
-
|
|
159
|
+
When you need to make the user aware that your agent is currently typing, you should use the `typing` function on `Agent`.
|
|
158
160
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
#### Example
|
|
162
|
-
|
|
163
|
-
```ts
|
|
164
|
-
conversation.print('Lorem ipsum');
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
### Loading/typing indicator
|
|
168
|
-
|
|
169
|
-
In many cases you will likely fetch data from an external resource before the content is written to the conversation. In this case you should use the `loading()` function on the `ConversationProvider` to inform the user that something is about to happen. Even in cases when the response is available immediately it gives a better user experience to present a loading indicator for a short while.
|
|
170
|
-
|
|
171
|
-
In cases where you want to notify the user that the agent is currently typing, you should use the `typing` function on `Agent`.
|
|
172
|
-
|
|
173
|
-
#### Example
|
|
174
|
-
|
|
175
|
-
##### Loading
|
|
161
|
+
#### Example of `loading`
|
|
176
162
|
|
|
177
163
|
```ts
|
|
178
164
|
const done = conversation.loading();
|
|
@@ -180,7 +166,7 @@ const done = conversation.loading();
|
|
|
180
166
|
done(); // remove loader
|
|
181
167
|
```
|
|
182
168
|
|
|
183
|
-
|
|
169
|
+
#### Example of `typing`
|
|
184
170
|
|
|
185
171
|
```ts
|
|
186
172
|
const done = agent.typing();
|
|
@@ -188,51 +174,34 @@ const done = agent.typing();
|
|
|
188
174
|
done(); // remove loader
|
|
189
175
|
```
|
|
190
176
|
|
|
191
|
-
##
|
|
192
|
-
|
|
193
|
-
The second parameter to your provider handler is a `ComponentNode` instance representing the conversational component. On it you can read the component's properties and react to action emitted by the component.
|
|
194
|
-
|
|
195
|
-
### Actions
|
|
196
|
-
|
|
197
|
-
The following actions are emitted from the conversational component.
|
|
198
|
-
|
|
199
|
-
**Important**: For default actions it is important to call `next()` unless you want to completely stop the execution flow for the particular action. Not doing so will stop any succeeding handlers and may unintentionally break functionality.
|
|
200
|
-
|
|
201
|
-
#### `conversation.user-typing`
|
|
202
|
-
|
|
203
|
-
Is emitted when the user´s typing indicator is changed.
|
|
204
|
-
|
|
205
|
-
| Name | Type | Description |
|
|
206
|
-
| ------------ | -------- | ---------------------------------------------- |
|
|
207
|
-
| `textLength` | `number` | The current text length of the user's message. |
|
|
208
|
-
|
|
209
|
-
#### `conversation.user-submit`
|
|
177
|
+
## Writing system messages
|
|
210
178
|
|
|
211
|
-
|
|
179
|
+
System message in the conversation are sent by using the `print` method on the `conversation`. The `print` method accepts the same arguments as on the `Agent`.
|
|
212
180
|
|
|
213
|
-
|
|
214
|
-
| ------ | -------- | ------------------- |
|
|
215
|
-
| `text` | `string` | The submitted text. |
|
|
181
|
+
#### Example
|
|
216
182
|
|
|
217
|
-
|
|
183
|
+
```ts
|
|
184
|
+
conversation.print('Hello world!');
|
|
185
|
+
```
|
|
218
186
|
|
|
219
|
-
|
|
187
|
+
## Reading from the conversation
|
|
220
188
|
|
|
221
|
-
|
|
222
|
-
| ------ | -------- | ---------------------------- |
|
|
223
|
-
| `text` | `string` | Key of the submitted action. |
|
|
189
|
+
The second parameter to your provider handler is a `ComponentNode` instance representing the conversational component. From it you can read the component's properties and react to action emitted by the component.
|
|
224
190
|
|
|
225
|
-
|
|
191
|
+
The following actions are emitted from the conversational component:
|
|
226
192
|
|
|
227
|
-
|
|
193
|
+
> For default actions it is necessary to call `next()` unless you want to completely stop the execution flow for the particular action. Not doing so will stop any succeeding handlers and may unintentionally break functionality.
|
|
228
194
|
|
|
229
|
-
| Name
|
|
230
|
-
|
|
|
231
|
-
| `
|
|
232
|
-
| `
|
|
233
|
-
| `
|
|
195
|
+
| Action | Name | Type | Description |
|
|
196
|
+
| -------------------------- | ------------ | ---------- | --------------------------------------------------------- |
|
|
197
|
+
| `conversation.user-typing` | `textLength` | `number` | The current text length of the user's message. |
|
|
198
|
+
| `conversation.user-submit` | `text` | `string` | The submitted text. |
|
|
199
|
+
| `conversation.action` | `text` | `string` | Key of the submitted action. |
|
|
200
|
+
| `conversation.form` | `data` | `FormData` | The form data. |
|
|
201
|
+
| `conversation.form` | `formKey` | `string` | The unique key for the form. |
|
|
202
|
+
| `conversation.form` | `actionKey` | `string` | The key of the form component responsible for the change. |
|
|
234
203
|
|
|
235
|
-
|
|
204
|
+
If you want to subscribe to any of the `conversation.form`-actions you have access to the `ComponentNodeController`. Example below:
|
|
236
205
|
|
|
237
206
|
```ts
|
|
238
207
|
component.actions.watch('conversation.form', (input, next) => {
|
|
@@ -242,7 +211,7 @@ component.actions.watch('conversation.form', (input, next) => {
|
|
|
242
211
|
|
|
243
212
|
### Submitting forms
|
|
244
213
|
|
|
245
|
-
|
|
214
|
+
If you want to listen for form events you should subscribe to the `conversation.form` event. By passing a `key` to the form, you are able to target the form in this listener.
|
|
246
215
|
|
|
247
216
|
```ts
|
|
248
217
|
component.actions.watch('conversation.form', (input, next) => {
|
|
@@ -254,3 +223,51 @@ component.actions.watch('conversation.form', (input, next) => {
|
|
|
254
223
|
return next(input);
|
|
255
224
|
});
|
|
256
225
|
```
|
|
226
|
+
|
|
227
|
+
### Adding custom list items
|
|
228
|
+
|
|
229
|
+
You can add custom list items to the conversation. To do so you have to register your own custom React component, which will be mapped to a key also provided by you.
|
|
230
|
+
|
|
231
|
+
#### Example of custom list items
|
|
232
|
+
|
|
233
|
+
```ts
|
|
234
|
+
import { registerCustomMessageComponent } from '@telia-ace/widget-conversation';
|
|
235
|
+
|
|
236
|
+
registerCustomMessageComponent(container, 'my-custom-list-item', import('./my-custom-list-item'));
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Once the component has been registered it will be available to be used as any other item in the `print` method on the Conversation API.
|
|
240
|
+
|
|
241
|
+
## Custom secondary action
|
|
242
|
+
|
|
243
|
+
You can add a secondary action button that's displayed next to the user input field. This button can run any event that you write. You need to add the `secondaryAction` property to the conversation component in the configuration. It accepts an object with the following properties:
|
|
244
|
+
|
|
245
|
+
| Name | Type | Description |
|
|
246
|
+
| -------- | -------- | ------------------------------------------------------------------- |
|
|
247
|
+
| `action` | `string` | An action that will be dispatched when the button is pressed |
|
|
248
|
+
| `label` | `string` | Will be used as a "title" and aria-label on the HTML button element |
|
|
249
|
+
| `icon` | `string` | An icon to be displayed, defaults to "browse" icon if left empty |
|
|
250
|
+
|
|
251
|
+
```json
|
|
252
|
+
"conversation": {
|
|
253
|
+
"type": "conversation",
|
|
254
|
+
"properties": {
|
|
255
|
+
"secondaryAction": {
|
|
256
|
+
"action": "my-secondary-action",
|
|
257
|
+
"label": "Label for the secondary action",
|
|
258
|
+
"icon": "my-icon"
|
|
259
|
+
}
|
|
260
|
+
// ...other properties
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
When you have added this property to the component, you can create an event for it in your code:
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
component.actions.watch('conversation.action', (input, next) => {
|
|
269
|
+
if (input === 'my-secondary-action') {
|
|
270
|
+
// handle action
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
```
|