@product7/product7-js 0.5.9 → 0.6.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.
@@ -4292,13 +4292,13 @@
4292
4292
  }
4293
4293
 
4294
4294
  .liveChat-launcher-right {
4295
- bottom: var(--spacing-5);
4296
- right: var(--spacing-5);
4295
+ bottom: var(--liveChat-v-padding, var(--spacing-5));
4296
+ right: var(--liveChat-h-padding, var(--spacing-5));
4297
4297
  }
4298
4298
 
4299
4299
  .liveChat-launcher-left {
4300
- bottom: var(--spacing-5);
4301
- left: var(--spacing-5);
4300
+ bottom: var(--liveChat-v-padding, var(--spacing-5));
4301
+ left: var(--liveChat-h-padding, var(--spacing-5));
4302
4302
  }
4303
4303
 
4304
4304
  .liveChat-launcher-btn {
@@ -4378,14 +4378,14 @@
4378
4378
  }
4379
4379
 
4380
4380
  .liveChat-panel-right {
4381
- bottom: 90px;
4382
- right: var(--spacing-5);
4381
+ bottom: calc(var(--liveChat-v-padding, var(--spacing-5)) + 70px);
4382
+ right: var(--liveChat-h-padding, var(--spacing-5));
4383
4383
  transform-origin: bottom right;
4384
4384
  }
4385
4385
 
4386
4386
  .liveChat-panel-left {
4387
- bottom: 90px;
4388
- left: var(--spacing-5);
4387
+ bottom: calc(var(--liveChat-v-padding, var(--spacing-5)) + 70px);
4388
+ left: var(--liveChat-h-padding, var(--spacing-5));
4389
4389
  transform-origin: bottom left;
4390
4390
  }
4391
4391
 
@@ -8256,7 +8256,7 @@
8256
8256
  const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
8257
8257
  let wsURL = this.baseURL.replace(/^https?:/, wsProtocol);
8258
8258
  wsURL = wsURL.replace('/api/v1', '');
8259
- wsURL = `${wsURL}/api/v1/widget/liveChat/ws?token=${encodeURIComponent(this.sessionToken)}`;
8259
+ wsURL = `${wsURL}/api/v1/widget/livechat/ws?token=${encodeURIComponent(this.sessionToken)}`;
8260
8260
 
8261
8261
  try {
8262
8262
  this.ws = new WebSocket(wsURL);
@@ -8755,6 +8755,8 @@
8755
8755
  this.teamAvatars = options.teamAvatars || [];
8756
8756
  this.greetingMessage = options.greetingMessage || 'Hi there 👋';
8757
8757
  this.welcomeMessage = options.welcomeMessage || 'How can we help?';
8758
+ this.startButtonText = options.startButtonText || 'Send us a message';
8759
+ this.showAvatars = options.showAvatars !== false;
8758
8760
 
8759
8761
  this.metadata = options.metadata || null;
8760
8762
  this.isIdentified = false;
@@ -8762,6 +8764,13 @@
8762
8764
 
8763
8765
  this.enableHelp = options.enableHelp !== false;
8764
8766
  this.enableChangelog = options.enableChangelog !== false;
8767
+ this.homeModuleEnabled = options.homeModuleEnabled !== false;
8768
+ this.messagesModuleEnabled = options.messagesModuleEnabled !== false;
8769
+
8770
+ this.requireEmailBeforeChat = options.requireEmailBeforeChat || false;
8771
+ this.allowAttachments = options.allowAttachments !== false;
8772
+ this.allowEmoji = options.allowEmoji !== false;
8773
+ this.showReplyTime = options.showReplyTime !== false;
8765
8774
 
8766
8775
  this.agentsOnline = false;
8767
8776
  this.onlineCount = 0;
@@ -8769,6 +8778,10 @@
8769
8778
  this.responseTime =
8770
8779
  options.responseTime || 'We typically reply within a few minutes';
8771
8780
 
8781
+ this.businessHoursState = options.businessHoursState || null;
8782
+ this.nextOpenAt = options.nextOpenAt || null;
8783
+ this.holidayName = options.holidayName || null;
8784
+
8772
8785
  this.typingUsers = {};
8773
8786
 
8774
8787
  this.isLoading = false;
@@ -9202,6 +9215,9 @@
9202
9215
  this._unsubscribe = this.state.subscribe((type) => {
9203
9216
  if (type === 'viewChange' || type === 'unreadCountChange') {
9204
9217
  this._updateActiveTab();
9218
+ } else if (type === 'settingsUpdate') {
9219
+ this._updateContent();
9220
+ this._updateActiveTab();
9205
9221
  }
9206
9222
  });
9207
9223
 
@@ -9209,15 +9225,20 @@
9209
9225
  }
9210
9226
 
9211
9227
  _getTabs() {
9212
- const tabs = [
9213
- { id: 'home', label: 'Home', icon: 'ph:house-simple' },
9214
- {
9228
+ const tabs = [];
9229
+
9230
+ if (this.state.homeModuleEnabled !== false) {
9231
+ tabs.push({ id: 'home', label: 'Home', icon: 'ph:house-simple' });
9232
+ }
9233
+
9234
+ if (this.state.messagesModuleEnabled !== false) {
9235
+ tabs.push({
9215
9236
  id: 'messages',
9216
9237
  label: 'Messages',
9217
9238
  icon: 'ph:chats',
9218
9239
  badge: this.state.unreadCount,
9219
- },
9220
- ];
9240
+ });
9241
+ }
9221
9242
 
9222
9243
  if (this.state.enableHelp) {
9223
9244
  tabs.push({ id: 'help', label: 'Help', icon: 'ph:books' });
@@ -9675,6 +9696,8 @@
9675
9696
  data.conversationId === this.state.activeConversationId
9676
9697
  ) {
9677
9698
  this._updateContent();
9699
+ } else if (type === 'settingsUpdate') {
9700
+ this._updateContent();
9678
9701
  }
9679
9702
  });
9680
9703
 
@@ -9721,7 +9744,7 @@
9721
9744
  </div>
9722
9745
  <div class="liveChat-chat-header-info">
9723
9746
  <span class="liveChat-chat-title">${this._escapeHtml(teamName)}</span>
9724
- <span class="liveChat-chat-subtitle">${isClosed ? 'Conversation resolved' : this.state.responseTime || 'Typically replies within minutes'}</span>
9747
+ ${isClosed || this.state.showReplyTime !== false ? `<span class="liveChat-chat-subtitle">${isClosed ? 'Conversation resolved' : this.state.responseTime || 'Typically replies within minutes'}</span>` : ''}
9725
9748
  </div>
9726
9749
  <div class="liveChat-chat-header-actions">
9727
9750
  <div class="liveChat-chat-menu-wrapper">
@@ -9783,18 +9806,14 @@
9783
9806
  </div>
9784
9807
  <div class="liveChat-compose-bottom">
9785
9808
  <div class="liveChat-compose-actions">
9786
- <button class="sdk-btn-icon liveChat-compose-attach" aria-label="Attach file">
9787
- <iconify-icon icon="ph:paperclip" width="20" height="20"></iconify-icon>
9788
- </button>
9789
- <button class="sdk-btn-icon liveChat-emoji-btn" aria-label="Emoji">
9790
- <iconify-icon icon="ph:smiley" width="20" height="20"></iconify-icon>
9791
- </button>
9809
+ ${this.state.allowAttachments !== false ? `<button class="sdk-btn-icon liveChat-compose-attach" aria-label="Attach file"><iconify-icon icon="ph:paperclip" width="20" height="20"></iconify-icon></button>` : ''}
9810
+ ${this.state.allowEmoji !== false ? `<button class="sdk-btn-icon liveChat-emoji-btn" aria-label="Emoji"><iconify-icon icon="ph:smiley" width="20" height="20"></iconify-icon></button>` : ''}
9792
9811
  </div>
9793
9812
  <button class="liveChat-compose-send" aria-label="Send" disabled>
9794
9813
  <iconify-icon icon="ph:paper-plane-right" width="20" height="20"></iconify-icon>
9795
9814
  </button>
9796
9815
  </div>
9797
- <input type="file" class="liveChat-compose-file-input" multiple accept="image/*,.pdf,.doc,.docx,.xls,.xlsx,.txt,.zip" />
9816
+ ${this.state.allowAttachments !== false ? `<input type="file" class="liveChat-compose-file-input" multiple accept="image/*,.pdf,.doc,.docx,.xls,.xlsx,.txt,.zip" />` : ''}
9798
9817
  </div>
9799
9818
  `
9800
9819
  }
@@ -11034,7 +11053,8 @@
11034
11053
  if (
11035
11054
  type === 'homeChangelogUpdate' ||
11036
11055
  type === 'conversationsUpdate' ||
11037
- type === 'availabilityUpdate'
11056
+ type === 'availabilityUpdate' ||
11057
+ type === 'settingsUpdate'
11038
11058
  ) {
11039
11059
  this._updateContent();
11040
11060
  }
@@ -11044,7 +11064,7 @@
11044
11064
  }
11045
11065
 
11046
11066
  _updateContent() {
11047
- const avatarsHtml = this._renderAvatarStack();
11067
+ const avatarsHtml = this.state.showAvatars ? this._renderAvatarStack() : '';
11048
11068
  const recentChangelogHtml = this._renderRecentChangelog();
11049
11069
 
11050
11070
  this.element.innerHTML = `
@@ -11095,9 +11115,31 @@
11095
11115
  }
11096
11116
 
11097
11117
  _renderAvailabilityStatus() {
11098
- const isOnline = this.state.agentsOnline;
11118
+ const businessState = this.state.businessHoursState;
11119
+
11120
+ if (businessState === 'offline') {
11121
+ let offlineText = 'We\'re currently closed';
11122
+ if (this.state.holidayName) {
11123
+ offlineText = `Closed for ${this.state.holidayName}`;
11124
+ } else if (this.state.nextOpenAt) {
11125
+ const opens = new Date(this.state.nextOpenAt);
11126
+ const now = new Date();
11127
+ const diffHours = Math.round((opens - now) / 3600000);
11128
+ if (diffHours < 24) {
11129
+ offlineText = `Opens in ${diffHours}h`;
11130
+ } else {
11131
+ offlineText = `Opens ${opens.toLocaleDateString('en-US', { weekday: 'short', hour: 'numeric', hour12: true })}`;
11132
+ }
11133
+ }
11134
+ return `
11135
+ <div class="liveChat-home-availability">
11136
+ <span class="liveChat-availability-dot liveChat-availability-away"></span>
11137
+ <span class="liveChat-availability-text">${offlineText}</span>
11138
+ </div>
11139
+ `;
11140
+ }
11099
11141
 
11100
- if (isOnline) {
11142
+ if (this.state.agentsOnline) {
11101
11143
  return `
11102
11144
  <div class="liveChat-home-availability">
11103
11145
  <span class="liveChat-availability-dot liveChat-availability-online"></span>
@@ -11133,7 +11175,7 @@
11133
11175
  ${recentCardHtml}
11134
11176
  <button class="liveChat-home-message-btn">
11135
11177
  <div class="liveChat-home-continue-info">
11136
- <span class="liveChat-home-continue-label">Send us a message</span>
11178
+ <span class="liveChat-home-continue-label">${this.state.startButtonText}</span>
11137
11179
  <span class="liveChat-home-message-subtext">${responseTime}</span>
11138
11180
  </div>
11139
11181
  ${sendIcon}
@@ -11619,6 +11661,15 @@
11619
11661
  const container = document.createElement('div');
11620
11662
  container.className = `liveChat-widget theme-${this.liveChatOptions.theme}`;
11621
11663
  container.style.zIndex = '999999';
11664
+ container.style.setProperty(
11665
+ '--liveChat-h-padding',
11666
+ `${this.liveChatOptions.horizontalPadding ?? 20}px`
11667
+ );
11668
+ container.style.setProperty(
11669
+ '--liveChat-v-padding',
11670
+ `${this.liveChatOptions.verticalPadding ?? 20}px`
11671
+ );
11672
+ this._widgetContainer = container;
11622
11673
 
11623
11674
  applyliveChatCustomStyles({
11624
11675
  primaryColor: this.liveChatOptions.primaryColor,
@@ -11715,7 +11766,10 @@
11715
11766
 
11716
11767
  async _handleStartConversation(messageContent, pendingAttachments) {
11717
11768
  try {
11718
- if (!this.LiveChatState.isIdentified) {
11769
+ if (
11770
+ this.LiveChatState.requireEmailBeforeChat &&
11771
+ !this.LiveChatState.isIdentified
11772
+ ) {
11719
11773
  this.LiveChatState.pendingMessage = {
11720
11774
  content: messageContent,
11721
11775
  attachments: pendingAttachments,
@@ -12321,8 +12375,9 @@
12321
12375
  if (!response?.status || !response?.data) return;
12322
12376
 
12323
12377
  const s = response.data;
12378
+ let stylesChanged = false;
12324
12379
 
12325
- // Only apply values that were NOT explicitly passed in options
12380
+ // Team info
12326
12381
  if (s.team_name && !this._hasExplicitOption('teamName')) {
12327
12382
  this.liveChatOptions.teamName = s.team_name;
12328
12383
  this.LiveChatState.teamName = s.team_name;
@@ -12333,12 +12388,165 @@
12333
12388
  if (s.greeting_message && !this._hasExplicitOption('greetingMessage')) {
12334
12389
  this.LiveChatState.greetingMessage = s.greeting_message;
12335
12390
  }
12391
+ if (s.welcome_message && !this._hasExplicitOption('welcomeMessage')) {
12392
+ this.LiveChatState.welcomeMessage = s.welcome_message;
12393
+ }
12336
12394
  if (s.response_time && !this._hasExplicitOption('responseTime')) {
12337
12395
  this.LiveChatState.responseTime = s.response_time;
12338
12396
  }
12397
+ if (
12398
+ Array.isArray(s.team_avatars) &&
12399
+ s.team_avatars.length > 0 &&
12400
+ !this._hasExplicitOption('teamAvatars')
12401
+ ) {
12402
+ this.LiveChatState.teamAvatars = s.team_avatars;
12403
+ }
12404
+
12405
+ // Colors / theme
12406
+ if (s.primary_color && !this._hasExplicitOption('primaryColor')) {
12407
+ this.liveChatOptions.primaryColor = s.primary_color;
12408
+ stylesChanged = true;
12409
+ }
12410
+ if (s.background_color && !this._hasExplicitOption('backgroundColor')) {
12411
+ this.liveChatOptions.backgroundColor = s.background_color;
12412
+ stylesChanged = true;
12413
+ }
12414
+ if (s.text_color && !this._hasExplicitOption('textColor')) {
12415
+ this.liveChatOptions.textColor = s.text_color;
12416
+ stylesChanged = true;
12417
+ }
12418
+ if (s.theme && !this._hasExplicitOption('theme')) {
12419
+ this.liveChatOptions.theme = s.theme;
12420
+ stylesChanged = true;
12421
+ }
12422
+ if (stylesChanged) {
12423
+ applyliveChatCustomStyles({
12424
+ primaryColor: this.liveChatOptions.primaryColor,
12425
+ textColor: this.liveChatOptions.textColor,
12426
+ backgroundColor: this.liveChatOptions.backgroundColor,
12427
+ theme: this.liveChatOptions.theme,
12428
+ });
12429
+ }
12430
+
12431
+ // Launcher position & padding
12432
+ if (s.launcher_position && !this._hasExplicitOption('position')) {
12433
+ const parts = s.launcher_position.split('-');
12434
+ this.liveChatOptions.position = parts[parts.length - 1] || 'right';
12435
+ }
12436
+ if (
12437
+ typeof s.horizontal_padding === 'number' &&
12438
+ !this._hasExplicitOption('horizontalPadding')
12439
+ ) {
12440
+ this.liveChatOptions.horizontalPadding = s.horizontal_padding;
12441
+ }
12442
+ if (
12443
+ typeof s.vertical_padding === 'number' &&
12444
+ !this._hasExplicitOption('verticalPadding')
12445
+ ) {
12446
+ this.liveChatOptions.verticalPadding = s.vertical_padding;
12447
+ }
12448
+ if (this._widgetContainer) {
12449
+ this._widgetContainer.style.setProperty(
12450
+ '--liveChat-h-padding',
12451
+ `${this.liveChatOptions.horizontalPadding ?? 20}px`
12452
+ );
12453
+ this._widgetContainer.style.setProperty(
12454
+ '--liveChat-v-padding',
12455
+ `${this.liveChatOptions.verticalPadding ?? 20}px`
12456
+ );
12457
+ }
12458
+
12459
+ // Module visibility
12460
+ if (
12461
+ typeof s.home_module_enabled === 'boolean' &&
12462
+ !this._hasExplicitOption('homeModuleEnabled')
12463
+ ) {
12464
+ this.LiveChatState.homeModuleEnabled = s.home_module_enabled;
12465
+ if (
12466
+ !s.home_module_enabled &&
12467
+ this.LiveChatState.currentView === 'home'
12468
+ ) {
12469
+ this.LiveChatState.currentView =
12470
+ this.LiveChatState.messagesModuleEnabled !== false
12471
+ ? 'messages'
12472
+ : 'help';
12473
+ }
12474
+ }
12475
+ if (
12476
+ typeof s.messages_module_enabled === 'boolean' &&
12477
+ !this._hasExplicitOption('messagesModuleEnabled')
12478
+ ) {
12479
+ this.LiveChatState.messagesModuleEnabled = s.messages_module_enabled;
12480
+ if (
12481
+ !s.messages_module_enabled &&
12482
+ this.LiveChatState.currentView === 'messages'
12483
+ ) {
12484
+ this.LiveChatState.currentView =
12485
+ this.LiveChatState.homeModuleEnabled !== false ? 'home' : 'help';
12486
+ }
12487
+ }
12488
+
12489
+ // Feature flags
12490
+ if (
12491
+ typeof s.show_avatars === 'boolean' &&
12492
+ !this._hasExplicitOption('showAvatars')
12493
+ ) {
12494
+ this.LiveChatState.showAvatars = s.show_avatars;
12495
+ }
12496
+ if (s.start_button_text && !this._hasExplicitOption('startButtonText')) {
12497
+ this.LiveChatState.startButtonText = s.start_button_text;
12498
+ }
12499
+ if (
12500
+ typeof s.require_email_before_chat === 'boolean' &&
12501
+ !this._hasExplicitOption('requireEmailBeforeChat')
12502
+ ) {
12503
+ this.LiveChatState.requireEmailBeforeChat = s.require_email_before_chat;
12504
+ }
12505
+ if (
12506
+ typeof s.allow_attachments === 'boolean' &&
12507
+ !this._hasExplicitOption('allowAttachments')
12508
+ ) {
12509
+ this.LiveChatState.allowAttachments = s.allow_attachments;
12510
+ }
12511
+ if (
12512
+ typeof s.allow_emoji === 'boolean' &&
12513
+ !this._hasExplicitOption('allowEmoji')
12514
+ ) {
12515
+ this.LiveChatState.allowEmoji = s.allow_emoji;
12516
+ }
12517
+ if (
12518
+ typeof s.show_reply_time === 'boolean' &&
12519
+ !this._hasExplicitOption('showReplyTime')
12520
+ ) {
12521
+ this.LiveChatState.showReplyTime = s.show_reply_time;
12522
+ }
12523
+
12524
+ // URLs
12525
+ if (s.feedback_url && !this._hasExplicitOption('feedbackUrl')) {
12526
+ this.liveChatOptions.feedbackUrl = s.feedback_url;
12527
+ this.LiveChatState.urls.feedback = s.feedback_url;
12528
+ }
12529
+ if (s.help_url && !this._hasExplicitOption('helpUrl')) {
12530
+ this.liveChatOptions.helpUrl = s.help_url;
12531
+ this.LiveChatState.urls.help = s.help_url;
12532
+ }
12533
+ if (s.changelog_url && !this._hasExplicitOption('changelogUrl')) {
12534
+ this.liveChatOptions.changelogUrl = s.changelog_url;
12535
+ this.LiveChatState.urls.changelog = s.changelog_url;
12536
+ }
12537
+ if (s.roadmap_url && !this._hasExplicitOption('roadmapUrl')) {
12538
+ this.liveChatOptions.roadmapUrl = s.roadmap_url;
12539
+ this.LiveChatState.urls.roadmap = s.roadmap_url;
12540
+ }
12541
+
12542
+ // Business hours availability
12543
+ if (s.availability && typeof s.availability === 'object') {
12544
+ this.LiveChatState.businessHoursState = s.availability.state || null;
12545
+ this.LiveChatState.nextOpenAt = s.availability.next_open_at || null;
12546
+ this.LiveChatState.holidayName = s.availability.holiday_name || null;
12547
+ }
12339
12548
 
12340
- // Notify views to re-render with new values
12341
- this.LiveChatState._notify('availabilityUpdate', {});
12549
+ this.LiveChatState._notify('settingsUpdate', {});
12342
12550
  } catch (e) {
12343
12551
  // non-fatal
12344
12552
  }