@product7/feedback-sdk 1.6.0 → 1.6.1
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 +5 -5
- package/dist/README.md +5 -5
- package/dist/feedback-sdk.js +347 -134
- 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/index.js +12 -4
- package/src/styles/messenger-views.js +156 -15
- package/src/styles/survey.js +0 -10
- package/src/widgets/MessengerWidget.js +7 -1
- package/src/widgets/SurveyWidget.js +14 -10
- package/src/widgets/messenger/components/NavigationTabs.js +13 -36
- package/src/widgets/messenger/views/ChangelogView.js +21 -30
- package/src/widgets/messenger/views/HelpView.js +124 -28
|
@@ -4,6 +4,9 @@ export class HelpView {
|
|
|
4
4
|
this.options = options;
|
|
5
5
|
this.element = null;
|
|
6
6
|
this._unsubscribe = null;
|
|
7
|
+
|
|
8
|
+
// Configurable header colour — defaults to Product7 blue
|
|
9
|
+
this._headerBg = `linear-gradient(180deg, #f0f4ff 0%, #ffffff 100%)`;
|
|
7
10
|
}
|
|
8
11
|
|
|
9
12
|
render() {
|
|
@@ -28,18 +31,23 @@ export class HelpView {
|
|
|
28
31
|
<div class="messenger-help-header">
|
|
29
32
|
<div class="messenger-help-header-top">
|
|
30
33
|
<h2>Help</h2>
|
|
31
|
-
<button class="sdk-close-btn" aria-label="Close">
|
|
34
|
+
<button class="sdk-close-btn messenger-help-close-btn" aria-label="Close">
|
|
32
35
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256">
|
|
33
36
|
<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
37
|
</svg>
|
|
35
38
|
</button>
|
|
36
39
|
</div>
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
<div class="messenger-help-search-wrap">
|
|
41
|
+
<span class="messenger-help-search-icon">
|
|
42
|
+
<iconify-icon icon="ph:magnifying-glass-duotone" width="16" height="16"></iconify-icon>
|
|
43
|
+
</span>
|
|
44
|
+
<input
|
|
45
|
+
type="text"
|
|
46
|
+
class="messenger-help-search-input"
|
|
47
|
+
placeholder="Search for help..."
|
|
48
|
+
value="${searchQuery}"
|
|
49
|
+
/>
|
|
50
|
+
</div>
|
|
43
51
|
</div>
|
|
44
52
|
|
|
45
53
|
<div class="messenger-help-body">
|
|
@@ -66,13 +74,6 @@ export class HelpView {
|
|
|
66
74
|
)
|
|
67
75
|
: collections;
|
|
68
76
|
|
|
69
|
-
const headerEl = this.element.querySelector(
|
|
70
|
-
'.messenger-help-collections-header'
|
|
71
|
-
);
|
|
72
|
-
if (headerEl) {
|
|
73
|
-
headerEl.textContent = `${filteredCollections.length} collections`;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
77
|
if (filteredCollections.length === 0) {
|
|
77
78
|
collectionsContainer.innerHTML = this._renderEmptyState();
|
|
78
79
|
return;
|
|
@@ -85,32 +86,125 @@ export class HelpView {
|
|
|
85
86
|
this._attachCollectionEvents();
|
|
86
87
|
}
|
|
87
88
|
|
|
89
|
+
// ─── Avatar helpers ──────────────────────────────────────────────────────────
|
|
90
|
+
|
|
91
|
+
_avatarColors = [
|
|
92
|
+
{ bg: '#EF4444', text: '#FFFFFF' },
|
|
93
|
+
{ bg: '#F97316', text: '#FFFFFF' },
|
|
94
|
+
{ bg: '#F59E0B', text: '#FFFFFF' },
|
|
95
|
+
{ bg: '#10B981', text: '#FFFFFF' },
|
|
96
|
+
{ bg: '#06B6D4', text: '#FFFFFF' },
|
|
97
|
+
{ bg: '#3B82F6', text: '#FFFFFF' },
|
|
98
|
+
{ bg: '#8B5CF6', text: '#FFFFFF' },
|
|
99
|
+
{ bg: '#EC4899', text: '#FFFFFF' },
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
_getAvatarColor(id) {
|
|
103
|
+
const hash = id
|
|
104
|
+
.split('')
|
|
105
|
+
.reduce((acc, char) => acc + char.charCodeAt(0), 0);
|
|
106
|
+
return this._avatarColors[hash % this._avatarColors.length];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
_getInitials(name) {
|
|
110
|
+
if (!name) return 'A';
|
|
111
|
+
return name
|
|
112
|
+
.split(' ')
|
|
113
|
+
.map((n) => n[0])
|
|
114
|
+
.join('')
|
|
115
|
+
.toUpperCase()
|
|
116
|
+
.slice(0, 2);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
_renderAuthorAvatar(collection) {
|
|
120
|
+
if (collection.author?.picture) {
|
|
121
|
+
return `
|
|
122
|
+
<img
|
|
123
|
+
src="${collection.author.picture}"
|
|
124
|
+
alt="${collection.author.name || ''}"
|
|
125
|
+
class="messenger-help-collection-avatar"
|
|
126
|
+
title="${collection.author.name || ''}"
|
|
127
|
+
/>
|
|
128
|
+
`;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const { bg, text } = this._getAvatarColor(collection.id);
|
|
132
|
+
const initials = collection.author?.name
|
|
133
|
+
? this._getInitials(collection.author.name)
|
|
134
|
+
: 'A';
|
|
135
|
+
|
|
136
|
+
return `
|
|
137
|
+
<span
|
|
138
|
+
class="messenger-help-collection-avatar messenger-help-collection-avatar--initials"
|
|
139
|
+
style="background-color: ${bg}; color: ${text};"
|
|
140
|
+
title="${collection.author?.name || 'Author'}"
|
|
141
|
+
>${initials}</span>
|
|
142
|
+
`;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// ─── Icon resolution ─────────────────────────────────────────────────────────
|
|
146
|
+
|
|
147
|
+
_resolveCollectionIcon(icon) {
|
|
148
|
+
if (!icon) return this._defaultCollectionIcon();
|
|
149
|
+
|
|
150
|
+
if (icon.trimStart().startsWith('<')) {
|
|
151
|
+
return `<span class="messenger-help-collection-icon">${icon}</span>`;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (icon.startsWith('ph:')) {
|
|
155
|
+
return `
|
|
156
|
+
<span class="messenger-help-collection-icon">
|
|
157
|
+
<iconify-icon icon="${icon}" width="20" height="20"></iconify-icon>
|
|
158
|
+
</span>
|
|
159
|
+
`;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return this._defaultCollectionIcon();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
_defaultCollectionIcon() {
|
|
166
|
+
return `
|
|
167
|
+
<span class="messenger-help-collection-icon">
|
|
168
|
+
<iconify-icon icon="ph:book-open-duotone" width="20" height="20"></iconify-icon>
|
|
169
|
+
</span>
|
|
170
|
+
`;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ─── Rendering ───────────────────────────────────────────────────────────────
|
|
174
|
+
|
|
88
175
|
_renderCollectionItem(collection) {
|
|
89
176
|
const articleCount = collection.articleCount || 0;
|
|
177
|
+
const iconHtml = this._resolveCollectionIcon(collection.icon);
|
|
178
|
+
const avatarHtml = this._renderAuthorAvatar(collection);
|
|
179
|
+
|
|
90
180
|
return `
|
|
91
181
|
<div class="messenger-help-collection" data-collection-id="${collection.id}">
|
|
182
|
+
${iconHtml}
|
|
92
183
|
<div class="messenger-help-collection-content">
|
|
93
184
|
<h3 class="messenger-help-collection-title">${collection.title}</h3>
|
|
94
|
-
|
|
95
|
-
<
|
|
185
|
+
${collection.description ? `<p class="messenger-help-collection-desc">${collection.description}</p>` : ''}
|
|
186
|
+
<div class="messenger-help-collection-meta">
|
|
187
|
+
${avatarHtml}
|
|
188
|
+
<span class="messenger-help-collection-count">
|
|
189
|
+
${articleCount} ${articleCount === 1 ? 'article' : 'articles'}
|
|
190
|
+
</span>
|
|
191
|
+
</div>
|
|
96
192
|
</div>
|
|
97
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="
|
|
193
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256" class="messenger-help-collection-arrow">
|
|
98
194
|
<path d="M181.66,133.66l-80,80a8,8,0,0,1-11.32-11.32L164.69,128,90.34,53.66a8,8,0,0,1,11.32-11.32l80,80A8,8,0,0,1,181.66,133.66Z"></path>
|
|
99
195
|
</svg>
|
|
100
196
|
</div>
|
|
101
197
|
`;
|
|
102
198
|
}
|
|
103
199
|
|
|
104
|
-
|
|
105
|
-
const isSearching = this.state.helpSearchQuery;
|
|
200
|
+
// ─── Empty states ────────────────────────────────────────────────────────────
|
|
106
201
|
|
|
107
|
-
|
|
202
|
+
_renderEmptyState() {
|
|
203
|
+
if (this.state.helpSearchQuery) {
|
|
108
204
|
return `
|
|
109
205
|
<div class="messenger-empty-state">
|
|
110
206
|
<div class="messenger-empty-state-icon">
|
|
111
|
-
<
|
|
112
|
-
<path d="M229.66,218.34l-50.07-50.06a88.11,88.11,0,1,0-11.31,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM40,112a72,72,0,1,1,72,72A72.08,72.08,0,0,1,40,112Z"></path>
|
|
113
|
-
</svg>
|
|
207
|
+
<iconify-icon icon="ph:magnifying-glass-duotone" width="48" height="48"></iconify-icon>
|
|
114
208
|
</div>
|
|
115
209
|
<h3>No results found</h3>
|
|
116
210
|
<p>Try a different search term</p>
|
|
@@ -121,9 +215,7 @@ export class HelpView {
|
|
|
121
215
|
return `
|
|
122
216
|
<div class="messenger-empty-state">
|
|
123
217
|
<div class="messenger-empty-state-icon">
|
|
124
|
-
<
|
|
125
|
-
<path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z"></path>
|
|
126
|
-
</svg>
|
|
218
|
+
<iconify-icon icon="ph:books-duotone" width="48" height="48"></iconify-icon>
|
|
127
219
|
</div>
|
|
128
220
|
<h3>Help collections</h3>
|
|
129
221
|
<p>No collections available yet</p>
|
|
@@ -131,9 +223,11 @@ export class HelpView {
|
|
|
131
223
|
`;
|
|
132
224
|
}
|
|
133
225
|
|
|
226
|
+
// ─── Events ──────────────────────────────────────────────────────────────────
|
|
227
|
+
|
|
134
228
|
_attachEvents() {
|
|
135
229
|
this.element
|
|
136
|
-
.querySelector('.
|
|
230
|
+
.querySelector('.messenger-help-close-btn')
|
|
137
231
|
.addEventListener('click', () => {
|
|
138
232
|
this.state.setOpen(false);
|
|
139
233
|
});
|
|
@@ -161,7 +255,7 @@ export class HelpView {
|
|
|
161
255
|
const collection = this.state.helpArticles.find(
|
|
162
256
|
(c) => c.id === collectionId
|
|
163
257
|
);
|
|
164
|
-
if (collection
|
|
258
|
+
if (collection?.url) {
|
|
165
259
|
window.open(collection.url, '_blank');
|
|
166
260
|
} else if (this.options.onArticleClick) {
|
|
167
261
|
this.options.onArticleClick(collection);
|
|
@@ -170,6 +264,8 @@ export class HelpView {
|
|
|
170
264
|
});
|
|
171
265
|
}
|
|
172
266
|
|
|
267
|
+
// ─── Lifecycle ───────────────────────────────────────────────────────────────
|
|
268
|
+
|
|
173
269
|
destroy() {
|
|
174
270
|
if (this._unsubscribe) {
|
|
175
271
|
this._unsubscribe();
|