@product7/feedback-sdk 1.4.3 → 1.4.4

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": "@product7/feedback-sdk",
3
- "version": "1.4.3",
3
+ "version": "1.4.4",
4
4
  "description": "JavaScript SDK for integrating Product7 feedback widgets into any website",
5
5
  "main": "dist/feedback-sdk.js",
6
6
  "module": "src/index.js",
@@ -31,7 +31,12 @@ export class MessengerWidget extends BaseWidget {
31
31
  enableHelp: options.enableHelp !== false,
32
32
  enableChangelog: options.enableChangelog !== false,
33
33
  featuredContent: options.featuredContent || null,
34
+ feedbackUrl: options.feedbackUrl || null,
35
+ changelogUrl: options.changelogUrl || null,
36
+ helpUrl: options.helpUrl || null,
37
+ roadmapUrl: options.roadmapUrl || null,
34
38
  onSendMessage: options.onSendMessage || null,
39
+ onFeedbackClick: options.onFeedbackClick || null,
35
40
  onArticleClick: options.onArticleClick || null,
36
41
  onChangelogClick: options.onChangelogClick || null,
37
42
  };
@@ -43,6 +48,12 @@ export class MessengerWidget extends BaseWidget {
43
48
  enableHelp: this.messengerOptions.enableHelp,
44
49
  enableChangelog: this.messengerOptions.enableChangelog,
45
50
  userContext: this.sdk?.apiService?.getUserContext() || null,
51
+ urls: {
52
+ feedback: this.messengerOptions.feedbackUrl,
53
+ changelog: this.messengerOptions.changelogUrl,
54
+ help: this.messengerOptions.helpUrl,
55
+ roadmap: this.messengerOptions.roadmapUrl,
56
+ },
46
57
  });
47
58
 
48
59
  this.launcher = null;
@@ -89,6 +100,7 @@ export class MessengerWidget extends BaseWidget {
89
100
  onSelectConversation: this._handleSelectConversation.bind(this),
90
101
  onStartNewConversation: this._handleNewConversationClick.bind(this),
91
102
  onIdentifyContact: this._handleIdentifyContact.bind(this),
103
+ onFeedbackClick: this.messengerOptions.onFeedbackClick,
92
104
  onArticleClick: this.messengerOptions.onArticleClick,
93
105
  onChangelogClick: this.messengerOptions.onChangelogClick,
94
106
  });
@@ -544,12 +556,16 @@ export class MessengerWidget extends BaseWidget {
544
556
  const response = await this.apiService.getHelpCollections();
545
557
  if (response.success && response.data) {
546
558
  const collections = response.data.collections || response.data;
559
+ const helpBase = (this.messengerOptions.helpUrl || '').replace(/\/$/, '');
560
+
547
561
  return collections.map((collection) => ({
548
562
  id: collection.id,
549
563
  title: collection.title,
550
564
  description: collection.description || '',
551
565
  articleCount: collection.article_count || 0,
552
- url: collection.url_slug ? `/help-docs/collections/${collection.url_slug}` : null,
566
+ url: collection.url_slug && helpBase
567
+ ? `${helpBase}/collections/${collection.url_slug}`
568
+ : helpBase || null,
553
569
  }));
554
570
  }
555
571
  return [];
@@ -654,7 +670,7 @@ export class MessengerWidget extends BaseWidget {
654
670
  try {
655
671
  await this.apiService.sendTypingIndicator(conversationId, isTyping);
656
672
  } catch (error) {
657
- // Silent fail
673
+ // silent fail
658
674
  }
659
675
  }
660
676
 
@@ -762,6 +778,7 @@ export class MessengerWidget extends BaseWidget {
762
778
 
763
779
  if (response.success && response.data) {
764
780
  const changelogs = Array.isArray(response.data) ? response.data : [];
781
+ const changelogBase = (this.messengerOptions.changelogUrl || '').replace(/\/$/, '');
765
782
 
766
783
  const mappedItems = changelogs.map((item) => ({
767
784
  id: item.id,
@@ -770,7 +787,9 @@ export class MessengerWidget extends BaseWidget {
770
787
  tags: item.labels ? item.labels.map((label) => label.name) : [],
771
788
  coverImage: item.cover_image || null,
772
789
  publishedAt: item.published_at,
773
- url: item.slug ? `/changelog/${item.slug}` : null,
790
+ url: item.slug && changelogBase
791
+ ? `${changelogBase}/${item.slug}`
792
+ : changelogBase || null,
774
793
  }));
775
794
 
776
795
  return {
@@ -829,4 +848,4 @@ export class MessengerWidget extends BaseWidget {
829
848
  this.onDestroy();
830
849
  super.destroy();
831
850
  }
832
- }
851
+ }
@@ -34,6 +34,13 @@ export class MessengerState {
34
34
  this.isLoading = false;
35
35
  this.isLoadingMessages = false;
36
36
 
37
+ this.urls = options.urls || {
38
+ feedback: null,
39
+ changelog: null,
40
+ help: null,
41
+ roadmap: null,
42
+ };
43
+
37
44
  this._listeners = new Set();
38
45
  }
39
46
 
@@ -195,4 +202,4 @@ export class MessengerState {
195
202
  this.helpSearchQuery = '';
196
203
  this._notify('reset', {});
197
204
  }
198
- }
205
+ }
@@ -23,14 +23,14 @@ export class ChangelogView {
23
23
 
24
24
  _updateContent() {
25
25
  this.element.innerHTML = `
26
- <div class="messenger-changelog-header">
27
- <h2>Latest Updates</h2>
28
- </div>
26
+ <div class="messenger-changelog-header">
27
+ <h2>Latest Updates</h2>
28
+ </div>
29
29
 
30
- <div class="messenger-changelog-body">
31
- <div class="messenger-changelog-list"></div>
32
- </div>
33
- `;
30
+ <div class="messenger-changelog-body">
31
+ <div class="messenger-changelog-list"></div>
32
+ </div>
33
+ `;
34
34
 
35
35
  this._updateChangelogList();
36
36
  this._attachEvents();
@@ -170,4 +170,4 @@ export class ChangelogView {
170
170
  this.element.parentNode.removeChild(this.element);
171
171
  }
172
172
  }
173
- }
173
+ }
@@ -23,30 +23,29 @@ export class HelpView {
23
23
 
24
24
  _updateContent() {
25
25
  const searchQuery = this.state.helpSearchQuery || '';
26
- const collections = this.state.helpArticles || [];
27
26
 
28
27
  this.element.innerHTML = `
29
- <div class="messenger-help-header">
30
- <div class="messenger-help-header-top">
31
- <h2>Help</h2>
32
- <button class="sdk-close-btn" aria-label="Close">
33
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256">
34
- <path d="M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z"></path>
35
- </svg>
36
- </button>
37
- </div>
38
- <input
39
- type="text"
40
- class="messenger-help-search-input"
41
- placeholder="Search for help..."
42
- value="${searchQuery}"
43
- />
44
- </div>
45
-
46
- <div class="messenger-help-body">
47
- <div class="messenger-help-collections"></div>
48
- </div>
49
- `;
28
+ <div class="messenger-help-header">
29
+ <div class="messenger-help-header-top">
30
+ <h2>Help</h2>
31
+ <button class="sdk-close-btn" aria-label="Close">
32
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256">
33
+ <path d="M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z"></path>
34
+ </svg>
35
+ </button>
36
+ </div>
37
+ <input
38
+ type="text"
39
+ class="messenger-help-search-input"
40
+ placeholder="Search for help..."
41
+ value="${searchQuery}"
42
+ />
43
+ </div>
44
+
45
+ <div class="messenger-help-body">
46
+ <div class="messenger-help-collections"></div>
47
+ </div>
48
+ `;
50
49
 
51
50
  this._updateCollectionsList();
52
51
  this._attachEvents();
@@ -179,4 +178,4 @@ export class HelpView {
179
178
  this.element.parentNode.removeChild(this.element);
180
179
  }
181
180
  }
182
- }
181
+ }
@@ -129,11 +129,6 @@ export class HomeView {
129
129
  `;
130
130
 
131
131
  if (openConversation) {
132
- const preview = openConversation.lastMessage
133
- ? openConversation.lastMessage.length > 40
134
- ? openConversation.lastMessage.substring(0, 40) + '...'
135
- : openConversation.lastMessage
136
- : 'Continue your conversation';
137
132
  return `
138
133
  <button class="messenger-home-message-btn messenger-home-continue-btn" data-conversation-id="${openConversation.id}">
139
134
  <div class="messenger-home-continue-info">
@@ -141,18 +136,19 @@ export class HomeView {
141
136
  </div>
142
137
  ${sendIcon}
143
138
  </button>
144
- <button class="messenger-home-message-btn" data-action="feedback">
139
+ <button class="messenger-home-message-btn messenger-feedback-btn" data-action="feedback">
145
140
  <span class="messenger-home-continue-label">Leave us feedback</span>
146
141
  ${caretIcon}
147
142
  </button>
148
143
  `;
149
144
  }
145
+
150
146
  return `
151
147
  <button class="messenger-home-message-btn">
152
148
  <span>Start a conversation</span>
153
149
  ${sendIcon}
154
150
  </button>
155
- <button class="messenger-home-message-btn" data-action="feedback">
151
+ <button class="messenger-home-message-btn messenger-feedback-btn" data-action="feedback">
156
152
  <span>Leave us feedback</span>
157
153
  ${caretIcon}
158
154
  </button>
@@ -234,7 +230,9 @@ export class HomeView {
234
230
  this.state.setOpen(false);
235
231
  });
236
232
 
237
- const msgBtn = this.element.querySelector('.messenger-home-message-btn');
233
+ const msgBtn = this.element.querySelector(
234
+ '.messenger-home-message-btn:not(.messenger-feedback-btn)'
235
+ );
238
236
  if (msgBtn) {
239
237
  msgBtn.addEventListener('click', () => {
240
238
  const convId = msgBtn.dataset.conversationId;
@@ -251,11 +249,35 @@ export class HomeView {
251
249
  });
252
250
  }
253
251
 
252
+ const feedbackBtn = this.element.querySelector('.messenger-feedback-btn');
253
+ if (feedbackBtn) {
254
+ feedbackBtn.addEventListener('click', () => {
255
+ const url = this.state.urls?.feedback;
256
+
257
+ if (this.options.onFeedbackClick) {
258
+ this.options.onFeedbackClick();
259
+ } else if (url) {
260
+ window.open(url, '_blank');
261
+ } else {
262
+ console.warn(
263
+ '[Messenger] No feedback destination configured. Set `feedbackUrl` in MessengerWidget options.'
264
+ );
265
+ }
266
+ });
267
+ }
268
+
254
269
  this.element
255
- .querySelectorAll('.messenger-home-changelog-item')
256
- .forEach((item) => {
257
- item.addEventListener('click', () => {
258
- this.state.setView('changelog');
270
+ .querySelectorAll('.messenger-home-changelog-card')
271
+ .forEach((card) => {
272
+ card.addEventListener('click', () => {
273
+ const item = this.state.homeChangelogItems.find(
274
+ (i) => i.id === card.dataset.changelogId
275
+ );
276
+ if (item?.url) {
277
+ window.open(item.url, '_blank');
278
+ } else {
279
+ this.state.setView('changelog');
280
+ }
259
281
  });
260
282
  });
261
283
 
@@ -292,4 +314,4 @@ export class HomeView {
292
314
  this.element.parentNode.removeChild(this.element);
293
315
  }
294
316
  }
295
- }
317
+ }