@product7/feedback-sdk 1.6.4 → 1.6.6

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 CHANGED
@@ -439,6 +439,10 @@ messenger.mount();
439
439
  | `welcomeMessage` | string | 'How can we help?' | Welcome message on home view |
440
440
  | `enableHelp` | boolean | true | Show help articles section |
441
441
  | `enableChangelog` | boolean | true | Show changelog section |
442
+ | `enableNews` | boolean | - | Alias for `enableChangelog` |
443
+ | `autoLoadData` | boolean | true | Auto-fetch conversations/help/changelog |
444
+ | `initialView` | string | 'home' | Initial view on mount |
445
+ | `previewData` | object | null | Seed deterministic local data |
442
446
  | `logoUrl` | string | - | Custom logo URL |
443
447
  | `primaryColor` | string | '#155EEF' | Primary accent color |
444
448
  | `onSendMessage` | function | null | Callback when message is sent |
package/dist/README.md CHANGED
@@ -439,6 +439,10 @@ messenger.mount();
439
439
  | `welcomeMessage` | string | 'How can we help?' | Welcome message on home view |
440
440
  | `enableHelp` | boolean | true | Show help articles section |
441
441
  | `enableChangelog` | boolean | true | Show changelog section |
442
+ | `enableNews` | boolean | - | Alias for `enableChangelog` |
443
+ | `autoLoadData` | boolean | true | Auto-fetch conversations/help/changelog |
444
+ | `initialView` | string | 'home' | Initial view on mount |
445
+ | `previewData` | object | null | Seed deterministic local data |
442
446
  | `logoUrl` | string | - | Custom logo URL |
443
447
  | `primaryColor` | string | '#155EEF' | Primary accent color |
444
448
  | `onSendMessage` | function | null | Callback when message is sent |
@@ -2203,6 +2203,13 @@
2203
2203
  }
2204
2204
 
2205
2205
  _render() {
2206
+ const buttonText =
2207
+ this.options.buttonText ||
2208
+ this.options.triggerText ||
2209
+ this.options.label ||
2210
+ this.options.text ||
2211
+ 'Feedback';
2212
+
2206
2213
  const button = document.createElement('div');
2207
2214
  button.className = `feedback-widget-button position-${this.options.position}`;
2208
2215
  button.innerHTML = `
@@ -2210,7 +2217,7 @@
2210
2217
  <svg class="feedback-icon" width="20" height="20" viewBox="0 0 256 256" fill="currentColor">
2211
2218
  <path d="M216,80H184V48a16,16,0,0,0-16-16H40A16,16,0,0,0,24,48V176a8,8,0,0,0,13,6.22L72,154V184a16,16,0,0,0,16,16h93.59L219,230.22a8,8,0,0,0,5,1.78,8,8,0,0,0,8-8V96A16,16,0,0,0,216,80ZM66.55,137.78,40,159.25V48H168v88H71.58A8,8,0,0,0,66.55,137.78ZM216,207.25l-26.55-21.47a8,8,0,0,0-5-1.78H88V152h80a16,16,0,0,0,16-16V96h32Z"/>
2212
2219
  </svg>
2213
- <span class="feedback-text">Feedback</span>
2220
+ <span class="feedback-text">${buttonText}</span>
2214
2221
 
2215
2222
  <div class="feedback-minimize-icon">
2216
2223
  <svg viewBox="0 0 256 256">
@@ -5895,6 +5902,11 @@
5895
5902
  constructor(options) {
5896
5903
  super({ ...options, type: 'messenger' });
5897
5904
 
5905
+ const resolvedEnableChangelog =
5906
+ typeof options.enableChangelog === 'boolean'
5907
+ ? options.enableChangelog
5908
+ : options.enableNews !== false;
5909
+
5898
5910
  this.messengerOptions = {
5899
5911
  position: options.position || 'bottom-right',
5900
5912
  theme: options.theme || 'light',
@@ -5907,7 +5919,10 @@
5907
5919
  greetingMessage: options.greetingMessage || 'Hi there 👋',
5908
5920
  welcomeMessage: options.welcomeMessage || 'How can we help?',
5909
5921
  enableHelp: options.enableHelp !== false,
5910
- enableChangelog: options.enableChangelog !== false,
5922
+ enableChangelog: resolvedEnableChangelog,
5923
+ autoLoadData: options.autoLoadData !== false,
5924
+ initialView: options.initialView || 'home',
5925
+ previewData: options.previewData || null,
5911
5926
  featuredContent: options.featuredContent || null,
5912
5927
  feedbackUrl: options.feedbackUrl || null,
5913
5928
  changelogUrl: options.changelogUrl || null,
@@ -6375,6 +6390,51 @@
6375
6390
  };
6376
6391
  }
6377
6392
 
6393
+ _applyPreviewData() {
6394
+ const data = this.messengerOptions.previewData;
6395
+ if (!data || typeof data !== 'object') {
6396
+ return;
6397
+ }
6398
+
6399
+ if (Array.isArray(data.conversations)) {
6400
+ this.messengerState.setConversations(data.conversations);
6401
+ }
6402
+
6403
+ if (Array.isArray(data.helpArticles)) {
6404
+ this.messengerState.setHelpArticles(data.helpArticles);
6405
+ }
6406
+
6407
+ if (Array.isArray(data.homeChangelogItems)) {
6408
+ this.messengerState.setHomeChangelogItems(data.homeChangelogItems);
6409
+ }
6410
+
6411
+ if (Array.isArray(data.changelogItems)) {
6412
+ this.messengerState.setChangelogItems(data.changelogItems);
6413
+ }
6414
+
6415
+ if (typeof data.unreadCount === 'number') {
6416
+ this.setUnreadCount(data.unreadCount);
6417
+ }
6418
+
6419
+ if (data.availability && typeof data.availability === 'object') {
6420
+ const availability = data.availability;
6421
+ this.messengerState.agentsOnline = Boolean(
6422
+ availability.agentsOnline ?? availability.agents_online
6423
+ );
6424
+ this.messengerState.onlineCount =
6425
+ availability.onlineCount ?? availability.online_count ?? 0;
6426
+ this.messengerState.responseTime =
6427
+ availability.responseTime ??
6428
+ availability.response_time ??
6429
+ this.messengerState.responseTime;
6430
+ this.messengerState._notify('availabilityUpdate', availability);
6431
+ }
6432
+
6433
+ if (typeof data.currentView === 'string') {
6434
+ this.messengerState.setView(data.currentView);
6435
+ }
6436
+ }
6437
+
6378
6438
  async loadInitialData() {
6379
6439
  try {
6380
6440
  const conversations = await this._fetchConversations();
@@ -6701,17 +6761,28 @@
6701
6761
  }
6702
6762
 
6703
6763
  async onMount() {
6704
- this.loadInitialData();
6764
+ this._applyPreviewData();
6705
6765
 
6706
- if (this.apiService?.sessionToken) {
6707
- this._initWebSocket();
6708
- }
6766
+ if (this.messengerOptions.autoLoadData) {
6767
+ this.loadInitialData();
6709
6768
 
6710
- this.checkAgentAvailability();
6769
+ if (this.apiService?.sessionToken) {
6770
+ this._initWebSocket();
6771
+ }
6711
6772
 
6712
- this._availabilityInterval = setInterval(() => {
6713
6773
  this.checkAgentAvailability();
6714
- }, 60000);
6774
+
6775
+ this._availabilityInterval = setInterval(() => {
6776
+ this.checkAgentAvailability();
6777
+ }, 60000);
6778
+ }
6779
+
6780
+ if (
6781
+ this.messengerOptions.initialView &&
6782
+ this.messengerOptions.initialView !== this.messengerState.currentView
6783
+ ) {
6784
+ this.messengerState.setView(this.messengerOptions.initialView);
6785
+ }
6715
6786
  }
6716
6787
 
6717
6788
  onDestroy() {
@@ -8087,12 +8158,15 @@
8087
8158
  }
8088
8159
 
8089
8160
  const widgetId = generateId('widget');
8161
+ const widgetConfig = this._getWidgetTypeConfig(type);
8162
+ const explicitOptions = this._omitUndefined(options);
8090
8163
  const widgetOptions = {
8091
8164
  id: widgetId,
8092
8165
  sdk: this,
8093
8166
  apiService: this.apiService,
8094
8167
  ...this.config,
8095
- ...options,
8168
+ ...widgetConfig,
8169
+ ...explicitOptions,
8096
8170
  };
8097
8171
 
8098
8172
  try {
@@ -8204,13 +8278,22 @@
8204
8278
  }
8205
8279
 
8206
8280
  const normalizedOptions = this._normalizeSurveyConfig(options);
8281
+ const surveyConfigDefaults = this._getWidgetTypeConfig('survey');
8207
8282
 
8208
8283
  const surveyWidget = this.createWidget('survey', {
8209
8284
  surveyId: normalizedOptions.surveyId,
8210
8285
  surveyType:
8211
8286
  normalizedOptions.surveyType || normalizedOptions.type || 'nps',
8212
- position: normalizedOptions.position || 'bottom-right',
8213
- theme: normalizedOptions.theme || this.config.theme || 'light',
8287
+ position:
8288
+ normalizedOptions.position ??
8289
+ surveyConfigDefaults.position ??
8290
+ this.config.position ??
8291
+ 'bottom-right',
8292
+ theme:
8293
+ normalizedOptions.theme ??
8294
+ surveyConfigDefaults.theme ??
8295
+ this.config.theme ??
8296
+ 'light',
8214
8297
  title: normalizedOptions.title,
8215
8298
  description: normalizedOptions.description,
8216
8299
  lowLabel: normalizedOptions.lowLabel,
@@ -8413,6 +8496,58 @@
8413
8496
  return null;
8414
8497
  }
8415
8498
 
8499
+ _getWidgetTypeConfig(type) {
8500
+ const widgetsConfig = this._isPlainObject(this.config?.widgets)
8501
+ ? this.config.widgets
8502
+ : {};
8503
+
8504
+ const legacyTypeConfig = this._isPlainObject(this.config?.[type])
8505
+ ? this.config[type]
8506
+ : {};
8507
+
8508
+ const namespacedTypeConfig = this._isPlainObject(widgetsConfig?.[type])
8509
+ ? widgetsConfig[type]
8510
+ : {};
8511
+
8512
+ const mergedTypeConfig = deepMerge(legacyTypeConfig, namespacedTypeConfig);
8513
+ return this._toCamelCaseObject(mergedTypeConfig);
8514
+ }
8515
+
8516
+ _isPlainObject(value) {
8517
+ return Object.prototype.toString.call(value) === '[object Object]';
8518
+ }
8519
+
8520
+ _toCamelCaseKey(key) {
8521
+ return key.replace(/_([a-z])/g, (_, char) => char.toUpperCase());
8522
+ }
8523
+
8524
+ _toCamelCaseObject(value) {
8525
+ if (Array.isArray(value)) {
8526
+ return value.map((item) => this._toCamelCaseObject(item));
8527
+ }
8528
+
8529
+ if (!this._isPlainObject(value)) {
8530
+ return value;
8531
+ }
8532
+
8533
+ const normalized = {};
8534
+ for (const [key, nestedValue] of Object.entries(value)) {
8535
+ normalized[this._toCamelCaseKey(key)] =
8536
+ this._toCamelCaseObject(nestedValue);
8537
+ }
8538
+ return normalized;
8539
+ }
8540
+
8541
+ _omitUndefined(value) {
8542
+ if (!this._isPlainObject(value)) {
8543
+ return value;
8544
+ }
8545
+
8546
+ return Object.fromEntries(
8547
+ Object.entries(value).filter(([, nestedValue]) => nestedValue !== undefined)
8548
+ );
8549
+ }
8550
+
8416
8551
  showChangelog(options = {}) {
8417
8552
  if (!this.initialized) {
8418
8553
  throw new SDKError(
@@ -8420,16 +8555,22 @@
8420
8555
  );
8421
8556
  }
8422
8557
 
8558
+ const defaults = {
8559
+ position: this.config.position || 'bottom-right',
8560
+ theme: this.config.theme || 'light',
8561
+ title: "What's New",
8562
+ triggerText: "What's New",
8563
+ showBadge: true,
8564
+ viewButtonText: 'View Update',
8565
+ };
8566
+
8567
+ const configDefaults = this._getWidgetTypeConfig('changelog');
8568
+ const explicitOptions = this._omitUndefined(options);
8569
+
8423
8570
  const changelogWidget = this.createWidget('changelog', {
8424
- position: options.position || 'bottom-right',
8425
- theme: options.theme || this.config.theme || 'light',
8426
- title: options.title || "What's New",
8427
- triggerText: options.triggerText || "What's New",
8428
- showBadge: options.showBadge !== false,
8429
- viewButtonText: options.viewButtonText || 'View Update',
8430
- changelogBaseUrl: options.changelogBaseUrl,
8431
- openInNewTab: options.openInNewTab,
8432
- onViewUpdate: options.onViewUpdate,
8571
+ ...defaults,
8572
+ ...configDefaults,
8573
+ ...explicitOptions,
8433
8574
  });
8434
8575
 
8435
8576
  changelogWidget.mount();