@product7/feedback-sdk 1.5.0 → 1.5.2
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/dist/feedback-sdk.js +144 -3
- package/dist/feedback-sdk.js.map +1 -1
- package/dist/feedback-sdk.min.js +1 -1
- package/dist/feedback-sdk.min.js.map +1 -1
- package/package.json +1 -1
- package/src/api/services/SurveyService.js +28 -0
- package/src/core/FeedbackSDK.js +82 -3
- package/src/widgets/SurveyWidget.js +34 -0
- package/types/index.d.ts +2 -0
package/package.json
CHANGED
|
@@ -15,11 +15,20 @@ export class SurveyService {
|
|
|
15
15
|
return { success: true, data: MOCK_SURVEYS };
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
const respondent = this._getRespondentContext(context);
|
|
19
|
+
|
|
18
20
|
const params = {
|
|
19
21
|
url:
|
|
20
22
|
context.url ||
|
|
21
23
|
(typeof window !== 'undefined' ? window.location.href : ''),
|
|
22
24
|
...getDeviceInfo(),
|
|
25
|
+
...(respondent.respondent_id && {
|
|
26
|
+
respondent_id: respondent.respondent_id,
|
|
27
|
+
}),
|
|
28
|
+
...(respondent.email && { email: respondent.email }),
|
|
29
|
+
...(context.includeEligibility !== undefined && {
|
|
30
|
+
include_eligibility: context.includeEligibility,
|
|
31
|
+
}),
|
|
23
32
|
...(context.userProperties && {
|
|
24
33
|
user_properties: context.userProperties,
|
|
25
34
|
}),
|
|
@@ -37,6 +46,19 @@ export class SurveyService {
|
|
|
37
46
|
});
|
|
38
47
|
}
|
|
39
48
|
|
|
49
|
+
_getRespondentContext(context = {}) {
|
|
50
|
+
const userContext =
|
|
51
|
+
typeof this.api.getUserContext === 'function'
|
|
52
|
+
? this.api.getUserContext() || {}
|
|
53
|
+
: {};
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
respondent_id:
|
|
57
|
+
context.respondentId || context.userId || userContext.user_id || null,
|
|
58
|
+
email: context.email || userContext.email || null,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
40
62
|
async submitSurveyResponse(surveyId, responseData) {
|
|
41
63
|
if (!surveyId) throw new APIError(400, 'Survey ID is required');
|
|
42
64
|
|
|
@@ -55,10 +77,16 @@ export class SurveyService {
|
|
|
55
77
|
};
|
|
56
78
|
}
|
|
57
79
|
|
|
80
|
+
const respondent = this._getRespondentContext(responseData);
|
|
81
|
+
|
|
58
82
|
const payload = {
|
|
59
83
|
rating: responseData.rating,
|
|
60
84
|
feedback: responseData.feedback || '',
|
|
61
85
|
answers: responseData.answers || {},
|
|
86
|
+
...(respondent.respondent_id && {
|
|
87
|
+
respondent_id: respondent.respondent_id,
|
|
88
|
+
}),
|
|
89
|
+
...(respondent.email && { email: respondent.email }),
|
|
62
90
|
};
|
|
63
91
|
|
|
64
92
|
return this.api._handleAuthRetry(async () => {
|
package/src/core/FeedbackSDK.js
CHANGED
|
@@ -94,7 +94,11 @@ export class FeedbackSDK {
|
|
|
94
94
|
|
|
95
95
|
try {
|
|
96
96
|
const result = await this.apiService.getActiveSurveys(context);
|
|
97
|
-
|
|
97
|
+
const surveys = result.data || [];
|
|
98
|
+
if (context.includeIneligible) {
|
|
99
|
+
return surveys;
|
|
100
|
+
}
|
|
101
|
+
return surveys.filter((survey) => this._isSurveyEligible(survey));
|
|
98
102
|
} catch (error) {
|
|
99
103
|
this.eventBus.emit('sdk:error', { error });
|
|
100
104
|
throw new SDKError(
|
|
@@ -111,7 +115,12 @@ export class FeedbackSDK {
|
|
|
111
115
|
);
|
|
112
116
|
}
|
|
113
117
|
|
|
114
|
-
const
|
|
118
|
+
const { context = {}, ...displayOptions } = options;
|
|
119
|
+
const surveys = await this.getActiveSurveys({
|
|
120
|
+
...context,
|
|
121
|
+
includeEligibility: true,
|
|
122
|
+
includeIneligible: true,
|
|
123
|
+
});
|
|
115
124
|
const surveyConfig = surveys.find((s) => s.id === surveyId);
|
|
116
125
|
|
|
117
126
|
if (!surveyConfig) {
|
|
@@ -120,6 +129,15 @@ export class FeedbackSDK {
|
|
|
120
129
|
);
|
|
121
130
|
}
|
|
122
131
|
|
|
132
|
+
if (!this._isSurveyEligible(surveyConfig)) {
|
|
133
|
+
this.eventBus.emit('survey:suppressed', {
|
|
134
|
+
surveyId,
|
|
135
|
+
reason: this._getSurveyIneligibilityReason(surveyConfig),
|
|
136
|
+
survey: surveyConfig,
|
|
137
|
+
});
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
|
|
123
141
|
return this.showSurvey({
|
|
124
142
|
surveyId: surveyConfig.id,
|
|
125
143
|
surveyType: surveyConfig.type,
|
|
@@ -128,7 +146,7 @@ export class FeedbackSDK {
|
|
|
128
146
|
lowLabel: surveyConfig.low_label,
|
|
129
147
|
highLabel: surveyConfig.high_label,
|
|
130
148
|
customQuestions: surveyConfig.questions,
|
|
131
|
-
...
|
|
149
|
+
...displayOptions,
|
|
132
150
|
});
|
|
133
151
|
}
|
|
134
152
|
|
|
@@ -139,6 +157,15 @@ export class FeedbackSDK {
|
|
|
139
157
|
);
|
|
140
158
|
}
|
|
141
159
|
|
|
160
|
+
if (!this._isSurveyEligible(options)) {
|
|
161
|
+
this.eventBus.emit('survey:suppressed', {
|
|
162
|
+
surveyId: options.surveyId || options.id || null,
|
|
163
|
+
reason: this._getSurveyIneligibilityReason(options),
|
|
164
|
+
survey: options,
|
|
165
|
+
});
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
|
|
142
169
|
const surveyWidget = this.createWidget('survey', {
|
|
143
170
|
surveyId: options.surveyId,
|
|
144
171
|
surveyType: options.surveyType || options.type || 'nps',
|
|
@@ -149,6 +176,8 @@ export class FeedbackSDK {
|
|
|
149
176
|
lowLabel: options.lowLabel,
|
|
150
177
|
highLabel: options.highLabel,
|
|
151
178
|
customQuestions: options.customQuestions,
|
|
179
|
+
respondentId: options.respondentId,
|
|
180
|
+
email: options.email,
|
|
152
181
|
onSubmit: options.onSubmit,
|
|
153
182
|
onDismiss: options.onDismiss,
|
|
154
183
|
});
|
|
@@ -159,6 +188,56 @@ export class FeedbackSDK {
|
|
|
159
188
|
return surveyWidget;
|
|
160
189
|
}
|
|
161
190
|
|
|
191
|
+
_isSurveyEligible(survey = {}) {
|
|
192
|
+
const shouldShow = this._getSurveyField(survey, ['shouldShow', 'should_show']);
|
|
193
|
+
if (typeof shouldShow === 'boolean') {
|
|
194
|
+
return shouldShow;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const eligible = this._getSurveyField(survey, [
|
|
198
|
+
'eligible',
|
|
199
|
+
'isEligible',
|
|
200
|
+
'is_eligible',
|
|
201
|
+
]);
|
|
202
|
+
if (typeof eligible === 'boolean') {
|
|
203
|
+
return eligible;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const isAnswered = this._getSurveyField(survey, ['isAnswered', 'is_answered']);
|
|
207
|
+
if (typeof isAnswered === 'boolean') {
|
|
208
|
+
return !isAnswered;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
_getSurveyIneligibilityReason(survey = {}) {
|
|
215
|
+
const explicitReason = this._getSurveyField(survey, [
|
|
216
|
+
'reason',
|
|
217
|
+
'suppressionReason',
|
|
218
|
+
'suppression_reason',
|
|
219
|
+
]);
|
|
220
|
+
if (explicitReason) {
|
|
221
|
+
return explicitReason;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const isAnswered = this._getSurveyField(survey, ['isAnswered', 'is_answered']);
|
|
225
|
+
if (isAnswered === true) {
|
|
226
|
+
return 'already_answered';
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return 'ineligible';
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
_getSurveyField(survey, fields) {
|
|
233
|
+
for (const field of fields) {
|
|
234
|
+
if (survey[field] !== undefined && survey[field] !== null) {
|
|
235
|
+
return survey[field];
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
|
|
162
241
|
showChangelog(options = {}) {
|
|
163
242
|
if (!this.initialized) {
|
|
164
243
|
throw new SDKError(
|
|
@@ -13,6 +13,8 @@ export class SurveyWidget extends BaseWidget {
|
|
|
13
13
|
lowLabel: options.lowLabel || null,
|
|
14
14
|
highLabel: options.highLabel || null,
|
|
15
15
|
customQuestions: options.customQuestions || [],
|
|
16
|
+
respondentId: options.respondentId || null,
|
|
17
|
+
email: options.email || null,
|
|
16
18
|
onSubmit: options.onSubmit || null,
|
|
17
19
|
onDismiss: options.onDismiss || null,
|
|
18
20
|
};
|
|
@@ -381,10 +383,14 @@ export class SurveyWidget extends BaseWidget {
|
|
|
381
383
|
return;
|
|
382
384
|
}
|
|
383
385
|
|
|
386
|
+
const respondent = this._getRespondentContext();
|
|
387
|
+
|
|
384
388
|
const responseData = {
|
|
385
389
|
rating: this.surveyState.score,
|
|
386
390
|
feedback: this.surveyState.feedback,
|
|
387
391
|
answers: this.surveyState.customAnswers,
|
|
392
|
+
...(respondent.respondentId && { respondentId: respondent.respondentId }),
|
|
393
|
+
...(respondent.email && { email: respondent.email }),
|
|
388
394
|
};
|
|
389
395
|
|
|
390
396
|
const response = {
|
|
@@ -413,6 +419,34 @@ export class SurveyWidget extends BaseWidget {
|
|
|
413
419
|
this._showSuccessNotification();
|
|
414
420
|
}
|
|
415
421
|
|
|
422
|
+
_getRespondentContext() {
|
|
423
|
+
const sdkUserContext =
|
|
424
|
+
typeof this.sdk.getUserContext === 'function'
|
|
425
|
+
? this.sdk.getUserContext() || {}
|
|
426
|
+
: {};
|
|
427
|
+
const apiUserContext =
|
|
428
|
+
this.apiService &&
|
|
429
|
+
typeof this.apiService.getUserContext === 'function'
|
|
430
|
+
? this.apiService.getUserContext() || {}
|
|
431
|
+
: {};
|
|
432
|
+
const localUserContext = this.options.userContext || {};
|
|
433
|
+
|
|
434
|
+
return {
|
|
435
|
+
respondentId:
|
|
436
|
+
this.surveyOptions.respondentId ||
|
|
437
|
+
localUserContext.user_id ||
|
|
438
|
+
sdkUserContext.user_id ||
|
|
439
|
+
apiUserContext.user_id ||
|
|
440
|
+
null,
|
|
441
|
+
email:
|
|
442
|
+
this.surveyOptions.email ||
|
|
443
|
+
localUserContext.email ||
|
|
444
|
+
sdkUserContext.email ||
|
|
445
|
+
apiUserContext.email ||
|
|
446
|
+
null,
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
|
|
416
450
|
async _handleDismiss() {
|
|
417
451
|
if (this.surveyOptions.surveyId) {
|
|
418
452
|
try {
|
package/types/index.d.ts
CHANGED
|
@@ -78,6 +78,8 @@ declare module '@product7/feedback-sdk' {
|
|
|
78
78
|
lowLabel?: string | null;
|
|
79
79
|
highLabel?: string | null;
|
|
80
80
|
customQuestions?: SurveyQuestion[];
|
|
81
|
+
respondentId?: string | null;
|
|
82
|
+
email?: string | null;
|
|
81
83
|
theme?: 'light' | 'dark';
|
|
82
84
|
onSubmit?: (response: SurveyWidgetResponse) => void;
|
|
83
85
|
onDismiss?: () => void;
|