@product7/product7-js 0.6.0 → 0.6.3

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
 
@@ -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,38 @@
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
+ offlineText = diffHours < 24
11129
+ ? `Opens in ${diffHours}h`
11130
+ : `Opens ${opens.toLocaleDateString('en-US', { weekday: 'short', hour: 'numeric', hour12: true })}`;
11131
+ }
11132
+ return `
11133
+ <div class="liveChat-home-availability">
11134
+ <span class="liveChat-availability-dot liveChat-availability-away"></span>
11135
+ <span class="liveChat-availability-text">${offlineText}</span>
11136
+ </div>
11137
+ `;
11138
+ }
11139
+
11140
+ if (businessState === 'away') {
11141
+ return `
11142
+ <div class="liveChat-home-availability">
11143
+ <span class="liveChat-availability-dot liveChat-availability-away"></span>
11144
+ <span class="liveChat-availability-text">${this.state.responseTime}</span>
11145
+ </div>
11146
+ `;
11147
+ }
11099
11148
 
11100
- if (isOnline) {
11149
+ if (this.state.agentsOnline) {
11101
11150
  return `
11102
11151
  <div class="liveChat-home-availability">
11103
11152
  <span class="liveChat-availability-dot liveChat-availability-online"></span>
@@ -11133,7 +11182,7 @@
11133
11182
  ${recentCardHtml}
11134
11183
  <button class="liveChat-home-message-btn">
11135
11184
  <div class="liveChat-home-continue-info">
11136
- <span class="liveChat-home-continue-label">Send us a message</span>
11185
+ <span class="liveChat-home-continue-label">${this.state.startButtonText}</span>
11137
11186
  <span class="liveChat-home-message-subtext">${responseTime}</span>
11138
11187
  </div>
11139
11188
  ${sendIcon}
@@ -11619,6 +11668,15 @@
11619
11668
  const container = document.createElement('div');
11620
11669
  container.className = `liveChat-widget theme-${this.liveChatOptions.theme}`;
11621
11670
  container.style.zIndex = '999999';
11671
+ container.style.setProperty(
11672
+ '--liveChat-h-padding',
11673
+ `${this.liveChatOptions.horizontalPadding ?? 20}px`
11674
+ );
11675
+ container.style.setProperty(
11676
+ '--liveChat-v-padding',
11677
+ `${this.liveChatOptions.verticalPadding ?? 20}px`
11678
+ );
11679
+ this._widgetContainer = container;
11622
11680
 
11623
11681
  applyliveChatCustomStyles({
11624
11682
  primaryColor: this.liveChatOptions.primaryColor,
@@ -11715,7 +11773,10 @@
11715
11773
 
11716
11774
  async _handleStartConversation(messageContent, pendingAttachments) {
11717
11775
  try {
11718
- if (!this.LiveChatState.isIdentified) {
11776
+ if (
11777
+ this.LiveChatState.requireEmailBeforeChat &&
11778
+ !this.LiveChatState.isIdentified
11779
+ ) {
11719
11780
  this.LiveChatState.pendingMessage = {
11720
11781
  content: messageContent,
11721
11782
  attachments: pendingAttachments,
@@ -12321,8 +12382,9 @@
12321
12382
  if (!response?.status || !response?.data) return;
12322
12383
 
12323
12384
  const s = response.data;
12385
+ let stylesChanged = false;
12324
12386
 
12325
- // Only apply values that were NOT explicitly passed in options
12387
+ // Team info
12326
12388
  if (s.team_name && !this._hasExplicitOption('teamName')) {
12327
12389
  this.liveChatOptions.teamName = s.team_name;
12328
12390
  this.LiveChatState.teamName = s.team_name;
@@ -12333,12 +12395,165 @@
12333
12395
  if (s.greeting_message && !this._hasExplicitOption('greetingMessage')) {
12334
12396
  this.LiveChatState.greetingMessage = s.greeting_message;
12335
12397
  }
12398
+ if (s.welcome_message && !this._hasExplicitOption('welcomeMessage')) {
12399
+ this.LiveChatState.welcomeMessage = s.welcome_message;
12400
+ }
12336
12401
  if (s.response_time && !this._hasExplicitOption('responseTime')) {
12337
12402
  this.LiveChatState.responseTime = s.response_time;
12338
12403
  }
12404
+ if (
12405
+ Array.isArray(s.team_avatars) &&
12406
+ s.team_avatars.length > 0 &&
12407
+ !this._hasExplicitOption('teamAvatars')
12408
+ ) {
12409
+ this.LiveChatState.teamAvatars = s.team_avatars;
12410
+ }
12411
+
12412
+ // Colors / theme
12413
+ if (s.primary_color && !this._hasExplicitOption('primaryColor')) {
12414
+ this.liveChatOptions.primaryColor = s.primary_color;
12415
+ stylesChanged = true;
12416
+ }
12417
+ if (s.background_color && !this._hasExplicitOption('backgroundColor')) {
12418
+ this.liveChatOptions.backgroundColor = s.background_color;
12419
+ stylesChanged = true;
12420
+ }
12421
+ if (s.text_color && !this._hasExplicitOption('textColor')) {
12422
+ this.liveChatOptions.textColor = s.text_color;
12423
+ stylesChanged = true;
12424
+ }
12425
+ if (s.theme && !this._hasExplicitOption('theme')) {
12426
+ this.liveChatOptions.theme = s.theme;
12427
+ stylesChanged = true;
12428
+ }
12429
+ if (stylesChanged) {
12430
+ applyliveChatCustomStyles({
12431
+ primaryColor: this.liveChatOptions.primaryColor,
12432
+ textColor: this.liveChatOptions.textColor,
12433
+ backgroundColor: this.liveChatOptions.backgroundColor,
12434
+ theme: this.liveChatOptions.theme,
12435
+ });
12436
+ }
12437
+
12438
+ // Launcher position & padding
12439
+ if (s.launcher_position && !this._hasExplicitOption('position')) {
12440
+ const parts = s.launcher_position.split('-');
12441
+ this.liveChatOptions.position = parts[parts.length - 1] || 'right';
12442
+ }
12443
+ if (
12444
+ typeof s.horizontal_padding === 'number' &&
12445
+ !this._hasExplicitOption('horizontalPadding')
12446
+ ) {
12447
+ this.liveChatOptions.horizontalPadding = s.horizontal_padding;
12448
+ }
12449
+ if (
12450
+ typeof s.vertical_padding === 'number' &&
12451
+ !this._hasExplicitOption('verticalPadding')
12452
+ ) {
12453
+ this.liveChatOptions.verticalPadding = s.vertical_padding;
12454
+ }
12455
+ if (this._widgetContainer) {
12456
+ this._widgetContainer.style.setProperty(
12457
+ '--liveChat-h-padding',
12458
+ `${this.liveChatOptions.horizontalPadding ?? 20}px`
12459
+ );
12460
+ this._widgetContainer.style.setProperty(
12461
+ '--liveChat-v-padding',
12462
+ `${this.liveChatOptions.verticalPadding ?? 20}px`
12463
+ );
12464
+ }
12465
+
12466
+ // Module visibility
12467
+ if (
12468
+ typeof s.home_module_enabled === 'boolean' &&
12469
+ !this._hasExplicitOption('homeModuleEnabled')
12470
+ ) {
12471
+ this.LiveChatState.homeModuleEnabled = s.home_module_enabled;
12472
+ if (
12473
+ !s.home_module_enabled &&
12474
+ this.LiveChatState.currentView === 'home'
12475
+ ) {
12476
+ this.LiveChatState.currentView =
12477
+ this.LiveChatState.messagesModuleEnabled !== false
12478
+ ? 'messages'
12479
+ : 'help';
12480
+ }
12481
+ }
12482
+ if (
12483
+ typeof s.messages_module_enabled === 'boolean' &&
12484
+ !this._hasExplicitOption('messagesModuleEnabled')
12485
+ ) {
12486
+ this.LiveChatState.messagesModuleEnabled = s.messages_module_enabled;
12487
+ if (
12488
+ !s.messages_module_enabled &&
12489
+ this.LiveChatState.currentView === 'messages'
12490
+ ) {
12491
+ this.LiveChatState.currentView =
12492
+ this.LiveChatState.homeModuleEnabled !== false ? 'home' : 'help';
12493
+ }
12494
+ }
12495
+
12496
+ // Feature flags
12497
+ if (
12498
+ typeof s.show_avatars === 'boolean' &&
12499
+ !this._hasExplicitOption('showAvatars')
12500
+ ) {
12501
+ this.LiveChatState.showAvatars = s.show_avatars;
12502
+ }
12503
+ if (s.start_button_text && !this._hasExplicitOption('startButtonText')) {
12504
+ this.LiveChatState.startButtonText = s.start_button_text;
12505
+ }
12506
+ if (
12507
+ typeof s.require_email_before_chat === 'boolean' &&
12508
+ !this._hasExplicitOption('requireEmailBeforeChat')
12509
+ ) {
12510
+ this.LiveChatState.requireEmailBeforeChat = s.require_email_before_chat;
12511
+ }
12512
+ if (
12513
+ typeof s.allow_attachments === 'boolean' &&
12514
+ !this._hasExplicitOption('allowAttachments')
12515
+ ) {
12516
+ this.LiveChatState.allowAttachments = s.allow_attachments;
12517
+ }
12518
+ if (
12519
+ typeof s.allow_emoji === 'boolean' &&
12520
+ !this._hasExplicitOption('allowEmoji')
12521
+ ) {
12522
+ this.LiveChatState.allowEmoji = s.allow_emoji;
12523
+ }
12524
+ if (
12525
+ typeof s.show_reply_time === 'boolean' &&
12526
+ !this._hasExplicitOption('showReplyTime')
12527
+ ) {
12528
+ this.LiveChatState.showReplyTime = s.show_reply_time;
12529
+ }
12530
+
12531
+ // URLs
12532
+ if (s.feedback_url && !this._hasExplicitOption('feedbackUrl')) {
12533
+ this.liveChatOptions.feedbackUrl = s.feedback_url;
12534
+ this.LiveChatState.urls.feedback = s.feedback_url;
12535
+ }
12536
+ if (s.help_url && !this._hasExplicitOption('helpUrl')) {
12537
+ this.liveChatOptions.helpUrl = s.help_url;
12538
+ this.LiveChatState.urls.help = s.help_url;
12539
+ }
12540
+ if (s.changelog_url && !this._hasExplicitOption('changelogUrl')) {
12541
+ this.liveChatOptions.changelogUrl = s.changelog_url;
12542
+ this.LiveChatState.urls.changelog = s.changelog_url;
12543
+ }
12544
+ if (s.roadmap_url && !this._hasExplicitOption('roadmapUrl')) {
12545
+ this.liveChatOptions.roadmapUrl = s.roadmap_url;
12546
+ this.LiveChatState.urls.roadmap = s.roadmap_url;
12547
+ }
12548
+
12549
+ // Business hours availability
12550
+ if (s.availability && typeof s.availability === 'object') {
12551
+ this.LiveChatState.businessHoursState = s.availability.state || null;
12552
+ this.LiveChatState.nextOpenAt = s.availability.next_open_at || null;
12553
+ this.LiveChatState.holidayName = s.availability.holiday_name || null;
12554
+ }
12339
12555
 
12340
- // Notify views to re-render with new values
12341
- this.LiveChatState._notify('availabilityUpdate', {});
12556
+ this.LiveChatState._notify('settingsUpdate', {});
12342
12557
  } catch (e) {
12343
12558
  // non-fatal
12344
12559
  }
@@ -12360,7 +12575,7 @@
12360
12575
  this.LiveChatState.onlineCount = response.data.online_count || 0;
12361
12576
  this.LiveChatState.responseTime = response.data.response_time || '';
12362
12577
 
12363
- if (response.data.available_agents) {
12578
+ if (response.data.available_agents && this.LiveChatState.showAvatars !== false) {
12364
12579
  this.LiveChatState.setTeamAvatarsFromAgents(
12365
12580
  response.data.available_agents
12366
12581
  );