@product7/product7-js 0.1.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/README.md +1025 -0
- package/dist/README.md +1025 -0
- package/dist/product7-js.js +14658 -0
- package/dist/product7-js.js.map +1 -0
- package/dist/product7-js.min.js +2 -0
- package/dist/product7-js.min.js.map +1 -0
- package/package.json +114 -0
- package/src/api/mock-data/index.js +360 -0
- package/src/api/services/ChangelogService.js +28 -0
- package/src/api/services/FeedbackService.js +44 -0
- package/src/api/services/HelpService.js +50 -0
- package/src/api/services/MessengerService.js +279 -0
- package/src/api/services/SurveyService.js +127 -0
- package/src/api/utils/helpers.js +30 -0
- package/src/core/APIService.js +303 -0
- package/src/core/BaseAPIService.js +298 -0
- package/src/core/EventBus.js +54 -0
- package/src/core/Product7.js +812 -0
- package/src/core/WebSocketService.js +275 -0
- package/src/docs/api.md +226 -0
- package/src/docs/example.md +461 -0
- package/src/docs/framework-integrations.md +714 -0
- package/src/docs/installation.md +281 -0
- package/src/index.js +894 -0
- package/src/styles/base.js +50 -0
- package/src/styles/changelog.js +665 -0
- package/src/styles/components.js +553 -0
- package/src/styles/design-tokens.js +124 -0
- package/src/styles/feedback.js +325 -0
- package/src/styles/messenger-components.js +632 -0
- package/src/styles/messenger-core.js +233 -0
- package/src/styles/messenger-features.js +169 -0
- package/src/styles/messenger-views.js +877 -0
- package/src/styles/messenger.js +17 -0
- package/src/styles/messengerCustomStyles.js +114 -0
- package/src/styles/styles.js +26 -0
- package/src/styles/survey.js +894 -0
- package/src/utils/errors.js +142 -0
- package/src/utils/helpers.js +219 -0
- package/src/widgets/BaseWidget.js +548 -0
- package/src/widgets/ButtonWidget.js +104 -0
- package/src/widgets/ChangelogWidget.js +615 -0
- package/src/widgets/InlineWidget.js +148 -0
- package/src/widgets/MessengerWidget.js +979 -0
- package/src/widgets/SurveyWidget.js +1325 -0
- package/src/widgets/TabWidget.js +45 -0
- package/src/widgets/WidgetFactory.js +70 -0
- package/src/widgets/messenger/MessengerState.js +323 -0
- package/src/widgets/messenger/components/MessengerLauncher.js +124 -0
- package/src/widgets/messenger/components/MessengerPanel.js +111 -0
- package/src/widgets/messenger/components/NavigationTabs.js +130 -0
- package/src/widgets/messenger/views/ChangelogView.js +167 -0
- package/src/widgets/messenger/views/ChatView.js +592 -0
- package/src/widgets/messenger/views/ConversationsView.js +244 -0
- package/src/widgets/messenger/views/HelpView.js +239 -0
- package/src/widgets/messenger/views/HomeView.js +300 -0
- package/src/widgets/messenger/views/PreChatFormView.js +109 -0
- package/types/index.d.ts +341 -0
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
## Basic Usage
|
|
4
|
+
|
|
5
|
+
### Simple Setup
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
import Product7 from '@product7/product7-js';
|
|
9
|
+
|
|
10
|
+
const sdk = new Product7({
|
|
11
|
+
workspace: 'my-workspace',
|
|
12
|
+
metadata: {
|
|
13
|
+
user_id: 'user_123',
|
|
14
|
+
email: 'user@example.com',
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
await sdk.init();
|
|
19
|
+
|
|
20
|
+
const widget = sdk.createWidget('button');
|
|
21
|
+
widget.mount();
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## User Context
|
|
27
|
+
|
|
28
|
+
### Basic User Context
|
|
29
|
+
|
|
30
|
+
```javascript
|
|
31
|
+
const sdk = new Product7({
|
|
32
|
+
workspace: 'my-workspace',
|
|
33
|
+
metadata: {
|
|
34
|
+
user_id: 'user_123',
|
|
35
|
+
email: 'user@example.com',
|
|
36
|
+
name: 'John Doe',
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### With Custom Fields
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
metadata: {
|
|
45
|
+
user_id: 'user_123',
|
|
46
|
+
email: 'user@example.com',
|
|
47
|
+
name: 'John Doe',
|
|
48
|
+
custom_fields: {
|
|
49
|
+
role: 'admin',
|
|
50
|
+
plan: 'pro',
|
|
51
|
+
signup_date: '2024-01-01'
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### With Company Data
|
|
57
|
+
|
|
58
|
+
```javascript
|
|
59
|
+
metadata: {
|
|
60
|
+
user_id: 'user_123',
|
|
61
|
+
email: 'user@example.com',
|
|
62
|
+
name: 'John Doe',
|
|
63
|
+
company: {
|
|
64
|
+
id: 'company_456',
|
|
65
|
+
name: 'Acme Corp',
|
|
66
|
+
monthly_spend: 1000
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Extract from Auth
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
const authData = {
|
|
75
|
+
sub: 'user_123',
|
|
76
|
+
email: 'user@example.com',
|
|
77
|
+
name: 'John Doe',
|
|
78
|
+
role: 'admin',
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const metadata = Product7.extractMetadataFromAuth(authData);
|
|
82
|
+
|
|
83
|
+
const sdk = new Product7({
|
|
84
|
+
workspace: 'my-workspace',
|
|
85
|
+
metadata,
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Widget Customization
|
|
92
|
+
|
|
93
|
+
### Different Positions
|
|
94
|
+
|
|
95
|
+
```javascript
|
|
96
|
+
// Bottom right (default)
|
|
97
|
+
const widget1 = sdk.createWidget('button', {
|
|
98
|
+
position: 'bottom-right',
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Bottom left
|
|
102
|
+
const widget2 = sdk.createWidget('button', {
|
|
103
|
+
position: 'bottom-left',
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Top right
|
|
107
|
+
const widget3 = sdk.createWidget('button', {
|
|
108
|
+
position: 'top-right',
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Top left
|
|
112
|
+
const widget4 = sdk.createWidget('button', {
|
|
113
|
+
position: 'top-left',
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Dark Theme
|
|
118
|
+
|
|
119
|
+
```javascript
|
|
120
|
+
const widget = sdk.createWidget('button', {
|
|
121
|
+
theme: 'dark',
|
|
122
|
+
});
|
|
123
|
+
widget.mount();
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Custom Board
|
|
127
|
+
|
|
128
|
+
```javascript
|
|
129
|
+
const widget = sdk.createWidget('button', {
|
|
130
|
+
boardName: 'feature-requests',
|
|
131
|
+
});
|
|
132
|
+
widget.mount();
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Multiple Widgets
|
|
136
|
+
|
|
137
|
+
```javascript
|
|
138
|
+
// Feedback button
|
|
139
|
+
const feedbackWidget = sdk.createWidget('button', {
|
|
140
|
+
position: 'bottom-right',
|
|
141
|
+
boardName: 'general',
|
|
142
|
+
});
|
|
143
|
+
feedbackWidget.mount();
|
|
144
|
+
|
|
145
|
+
// Bug report button
|
|
146
|
+
const bugWidget = sdk.createWidget('button', {
|
|
147
|
+
position: 'bottom-left',
|
|
148
|
+
boardName: 'bug-reports',
|
|
149
|
+
});
|
|
150
|
+
bugWidget.updateText('Report Bug');
|
|
151
|
+
bugWidget.mount();
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Update Widget
|
|
155
|
+
|
|
156
|
+
```javascript
|
|
157
|
+
const widget = sdk.createWidget('button');
|
|
158
|
+
widget.mount();
|
|
159
|
+
|
|
160
|
+
// Update text
|
|
161
|
+
widget.updateText('Send Feedback');
|
|
162
|
+
|
|
163
|
+
// Update position
|
|
164
|
+
widget.updatePosition('top-right');
|
|
165
|
+
|
|
166
|
+
// Show/hide
|
|
167
|
+
widget.hide();
|
|
168
|
+
widget.show();
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Event Handling
|
|
174
|
+
|
|
175
|
+
### Track Submissions
|
|
176
|
+
|
|
177
|
+
```javascript
|
|
178
|
+
sdk.on('feedback:submitted', ({ widget, feedback }) => {
|
|
179
|
+
console.log('Feedback submitted:', feedback.id);
|
|
180
|
+
|
|
181
|
+
// Track in analytics
|
|
182
|
+
analytics.track('Feedback Submitted', {
|
|
183
|
+
feedbackId: feedback.id,
|
|
184
|
+
board: feedback.board,
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Handle Errors
|
|
190
|
+
|
|
191
|
+
```javascript
|
|
192
|
+
sdk.on('feedback:error', ({ widget, error }) => {
|
|
193
|
+
console.error('Submission failed:', error.message);
|
|
194
|
+
|
|
195
|
+
// Show custom error notification
|
|
196
|
+
toast.error('Failed to submit feedback. Please try again.');
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Widget Lifecycle
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
sdk.on('widget:mounted', ({ widget }) => {
|
|
204
|
+
console.log('Widget mounted:', widget.id);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
sdk.on('widget:destroyed', ({ widget }) => {
|
|
208
|
+
console.log('Widget destroyed:', widget.id);
|
|
209
|
+
});
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Multiple Events
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
sdk
|
|
216
|
+
.on('feedback:submitted', handleSubmit)
|
|
217
|
+
.on('feedback:error', handleError)
|
|
218
|
+
.on('config:updated', handleConfigUpdate);
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### One-time Events
|
|
222
|
+
|
|
223
|
+
```javascript
|
|
224
|
+
sdk.once('sdk:initialized', (data) => {
|
|
225
|
+
console.log('SDK ready!', data.config);
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Authentication Flows
|
|
232
|
+
|
|
233
|
+
### On Login
|
|
234
|
+
|
|
235
|
+
```javascript
|
|
236
|
+
async function handleLogin(authResponse) {
|
|
237
|
+
const metadata = Product7.extractMetadataFromAuth(authResponse);
|
|
238
|
+
await sdk.reinitialize(metadata);
|
|
239
|
+
|
|
240
|
+
// Create widget after login
|
|
241
|
+
const widget = sdk.createWidget('button');
|
|
242
|
+
widget.mount();
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### On Logout
|
|
247
|
+
|
|
248
|
+
```javascript
|
|
249
|
+
function handleLogout() {
|
|
250
|
+
sdk.apiService.clearSession();
|
|
251
|
+
sdk.destroyAllWidgets();
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Check Session
|
|
256
|
+
|
|
257
|
+
```javascript
|
|
258
|
+
if (!sdk.apiService.isSessionValid()) {
|
|
259
|
+
await sdk.init();
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Configuration Updates
|
|
266
|
+
|
|
267
|
+
### Update Theme
|
|
268
|
+
|
|
269
|
+
```javascript
|
|
270
|
+
sdk.updateConfig({ theme: 'dark' });
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Update Multiple Options
|
|
274
|
+
|
|
275
|
+
```javascript
|
|
276
|
+
sdk.updateConfig({
|
|
277
|
+
theme: 'dark',
|
|
278
|
+
position: 'top-right',
|
|
279
|
+
showBackdrop: false,
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Update User Context
|
|
284
|
+
|
|
285
|
+
```javascript
|
|
286
|
+
sdk.setMetadata({
|
|
287
|
+
user_id: 'user_456',
|
|
288
|
+
email: 'newuser@example.com',
|
|
289
|
+
name: 'Jane Smith',
|
|
290
|
+
});
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## Programmatic Control
|
|
296
|
+
|
|
297
|
+
### Open Panel Programmatically
|
|
298
|
+
|
|
299
|
+
```javascript
|
|
300
|
+
const widget = sdk.createWidget('button');
|
|
301
|
+
widget.mount();
|
|
302
|
+
|
|
303
|
+
// Open panel from code
|
|
304
|
+
setTimeout(() => {
|
|
305
|
+
widget.openPanel();
|
|
306
|
+
}, 3000);
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Close Panel
|
|
310
|
+
|
|
311
|
+
```javascript
|
|
312
|
+
widget.closePanel();
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Trigger from Custom Button
|
|
316
|
+
|
|
317
|
+
```javascript
|
|
318
|
+
const customButton = document.getElementById('feedback-btn');
|
|
319
|
+
customButton.addEventListener('click', () => {
|
|
320
|
+
const widget = sdk.getWidget('widget_123');
|
|
321
|
+
if (widget) {
|
|
322
|
+
widget.openPanel();
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## Error Handling
|
|
330
|
+
|
|
331
|
+
### Try-Catch Pattern
|
|
332
|
+
|
|
333
|
+
```javascript
|
|
334
|
+
try {
|
|
335
|
+
await sdk.init();
|
|
336
|
+
const widget = sdk.createWidget('button');
|
|
337
|
+
widget.mount();
|
|
338
|
+
} catch (error) {
|
|
339
|
+
if (error instanceof ConfigError) {
|
|
340
|
+
console.error('Config error:', error.message);
|
|
341
|
+
} else if (error instanceof APIError) {
|
|
342
|
+
console.error('API error:', error.status);
|
|
343
|
+
} else {
|
|
344
|
+
console.error('Unexpected error:', error);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### Handle API Errors
|
|
350
|
+
|
|
351
|
+
```javascript
|
|
352
|
+
try {
|
|
353
|
+
await sdk.apiService.submitFeedback(data);
|
|
354
|
+
} catch (error) {
|
|
355
|
+
if (error.isNetworkError()) {
|
|
356
|
+
alert('No internet connection');
|
|
357
|
+
} else if (error.isClientError()) {
|
|
358
|
+
alert('Invalid data. Please check your input.');
|
|
359
|
+
} else if (error.isServerError()) {
|
|
360
|
+
alert('Server error. Please try again later.');
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## Advanced Usage
|
|
368
|
+
|
|
369
|
+
### Custom Widget Creation
|
|
370
|
+
|
|
371
|
+
```javascript
|
|
372
|
+
import { BaseWidget, WidgetFactory } from '@product7/product7-js';
|
|
373
|
+
|
|
374
|
+
class CustomWidget extends BaseWidget {
|
|
375
|
+
constructor(options) {
|
|
376
|
+
super({ ...options, type: 'custom' });
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
_render() {
|
|
380
|
+
const element = document.createElement('div');
|
|
381
|
+
element.innerHTML = '<button>Custom Feedback</button>';
|
|
382
|
+
return element;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
_attachEvents() {
|
|
386
|
+
this.element
|
|
387
|
+
.querySelector('button')
|
|
388
|
+
.addEventListener('click', this.openPanel);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
WidgetFactory.register('custom', CustomWidget);
|
|
393
|
+
|
|
394
|
+
const widget = sdk.createWidget('custom');
|
|
395
|
+
widget.mount();
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### Conditional Widget Loading
|
|
399
|
+
|
|
400
|
+
```javascript
|
|
401
|
+
// Only show feedback for authenticated users
|
|
402
|
+
if (user.isAuthenticated) {
|
|
403
|
+
const sdk = new Product7({
|
|
404
|
+
workspace: 'my-workspace',
|
|
405
|
+
metadata: {
|
|
406
|
+
user_id: user.id,
|
|
407
|
+
email: user.email,
|
|
408
|
+
},
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
await sdk.init();
|
|
412
|
+
const widget = sdk.createWidget('button');
|
|
413
|
+
widget.mount();
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### Environment-based Configuration
|
|
418
|
+
|
|
419
|
+
```javascript
|
|
420
|
+
const config = {
|
|
421
|
+
workspace: 'my-workspace',
|
|
422
|
+
metadata: getMetadata(),
|
|
423
|
+
apiUrl:
|
|
424
|
+
process.env.NODE_ENV === 'production'
|
|
425
|
+
? 'https://api.product7.io/api/v1'
|
|
426
|
+
: 'https://staging.api.product7.io/api/v1',
|
|
427
|
+
debug: process.env.NODE_ENV === 'development',
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
const sdk = new Product7(config);
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
## Testing
|
|
436
|
+
|
|
437
|
+
### Mock SDK
|
|
438
|
+
|
|
439
|
+
```javascript
|
|
440
|
+
// In tests
|
|
441
|
+
jest.mock('@product7/product7-js');
|
|
442
|
+
|
|
443
|
+
test('should initialize SDK', async () => {
|
|
444
|
+
const sdk = new Product7({
|
|
445
|
+
workspace: 'test',
|
|
446
|
+
metadata: { user_id: '123' },
|
|
447
|
+
});
|
|
448
|
+
await sdk.init();
|
|
449
|
+
expect(sdk.initialized).toBe(true);
|
|
450
|
+
});
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### Check Widget Exists
|
|
454
|
+
|
|
455
|
+
```javascript
|
|
456
|
+
const widget = sdk.createWidget('button');
|
|
457
|
+
widget.mount();
|
|
458
|
+
|
|
459
|
+
const found = sdk.getWidget(widget.id);
|
|
460
|
+
expect(found).toBeDefined();
|
|
461
|
+
```
|