@salesforcedevs/docs-components 1.17.0-hack-alpha4 → 1.17.0-hack-alpha6
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 +1 -1
- package/src/modules/doc/commentPopup/README.md +294 -0
- package/src/modules/doc/commentPopup/commentDevHelper.ts +321 -0
- package/src/modules/doc/commentPopup/commentPopup.css +91 -0
- package/src/modules/doc/commentPopup/commentPopup.html +20 -1
- package/src/modules/doc/commentPopup/commentPopup.ts +325 -34
- package/src/modules/doc/commentPopup/commentUtils.ts +382 -0
- package/src/modules/doc/heading/heading.css +12 -382
- package/src/modules/doc/heading/heading.html +28 -150
- package/src/modules/doc/heading/heading.ts +4 -204
|
@@ -133,6 +133,72 @@
|
|
|
133
133
|
padding: 0 24px 24px;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
+
/* Success Message */
|
|
137
|
+
.success-message {
|
|
138
|
+
display: flex;
|
|
139
|
+
align-items: center;
|
|
140
|
+
gap: 8px;
|
|
141
|
+
background: #e8f5e8;
|
|
142
|
+
color: #2e7d32;
|
|
143
|
+
padding: 12px 16px;
|
|
144
|
+
border-radius: 8px;
|
|
145
|
+
margin-bottom: 16px;
|
|
146
|
+
border-left: 4px solid #4caf50;
|
|
147
|
+
font-size: 14px;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.success-message dx-icon {
|
|
151
|
+
--sds-c-icon-color-foreground: #4caf50;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* API Error Message */
|
|
155
|
+
.api-error {
|
|
156
|
+
display: flex;
|
|
157
|
+
align-items: center;
|
|
158
|
+
gap: 8px;
|
|
159
|
+
background: #ffebee;
|
|
160
|
+
color: #c62828;
|
|
161
|
+
padding: 12px 16px;
|
|
162
|
+
border-radius: 8px;
|
|
163
|
+
margin-bottom: 16px;
|
|
164
|
+
border-left: 4px solid #f44336;
|
|
165
|
+
font-size: 14px;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.api-error dx-icon {
|
|
169
|
+
--sds-c-icon-color-foreground: #f44336;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/* Loading Message */
|
|
173
|
+
.loading-message {
|
|
174
|
+
display: flex;
|
|
175
|
+
align-items: center;
|
|
176
|
+
gap: 8px;
|
|
177
|
+
background: #e3f2fd;
|
|
178
|
+
color: #1565c0;
|
|
179
|
+
padding: 12px 16px;
|
|
180
|
+
border-radius: 8px;
|
|
181
|
+
margin-bottom: 16px;
|
|
182
|
+
border-left: 4px solid #2196f3;
|
|
183
|
+
font-size: 14px;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.loading-message dx-icon {
|
|
187
|
+
--sds-c-icon-color-foreground: #2196f3;
|
|
188
|
+
|
|
189
|
+
animation: spin 1s linear infinite;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@keyframes spin {
|
|
193
|
+
from {
|
|
194
|
+
transform: rotate(0deg);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
to {
|
|
198
|
+
transform: rotate(360deg);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
136
202
|
/* Comment Form */
|
|
137
203
|
.comment-form {
|
|
138
204
|
margin-bottom: 24px;
|
|
@@ -277,6 +343,13 @@
|
|
|
277
343
|
padding: 0 16px 16px;
|
|
278
344
|
}
|
|
279
345
|
|
|
346
|
+
.success-message,
|
|
347
|
+
.api-error,
|
|
348
|
+
.loading-message {
|
|
349
|
+
padding: 10px 12px;
|
|
350
|
+
font-size: 13px;
|
|
351
|
+
}
|
|
352
|
+
|
|
280
353
|
.comments-section {
|
|
281
354
|
padding-top: 16px;
|
|
282
355
|
}
|
|
@@ -297,6 +370,24 @@
|
|
|
297
370
|
border-bottom-color: #424242;
|
|
298
371
|
}
|
|
299
372
|
|
|
373
|
+
.success-message {
|
|
374
|
+
background: #1b5e20;
|
|
375
|
+
color: #a5d6a7;
|
|
376
|
+
border-left-color: #4caf50;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
.api-error {
|
|
380
|
+
background: #b71c1c;
|
|
381
|
+
color: #ef9a9a;
|
|
382
|
+
border-left-color: #f44336;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.loading-message {
|
|
386
|
+
background: #0d47a1;
|
|
387
|
+
color: #90caf9;
|
|
388
|
+
border-left-color: #2196f3;
|
|
389
|
+
}
|
|
390
|
+
|
|
300
391
|
.form-label {
|
|
301
392
|
color: #e0e0e0;
|
|
302
393
|
}
|
|
@@ -35,8 +35,27 @@
|
|
|
35
35
|
></dx-button>
|
|
36
36
|
</div>
|
|
37
37
|
|
|
38
|
-
<!--
|
|
38
|
+
<!-- Popup Content -->
|
|
39
39
|
<div class="popup-content">
|
|
40
|
+
<!-- Success Message -->
|
|
41
|
+
<div if:true={submitSuccess} class="success-message">
|
|
42
|
+
<dx-icon icon-symbol="success" icon-size="small"></dx-icon>
|
|
43
|
+
<span>Comment posted successfully!</span>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<!-- API Error Message -->
|
|
47
|
+
<div if:true={apiError} class="error-message api-error">
|
|
48
|
+
<dx-icon icon-symbol="error" icon-size="small"></dx-icon>
|
|
49
|
+
<span>{apiError}</span>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<!-- Loading State -->
|
|
53
|
+
<div if:true={isLoading} class="loading-message">
|
|
54
|
+
<dx-icon icon-symbol="spinner" icon-size="small"></dx-icon>
|
|
55
|
+
<span>Loading comments...</span>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<!-- Comment Form -->
|
|
40
59
|
<form class="comment-form" onsubmit={handleSubmit}>
|
|
41
60
|
<div class="form-group">
|
|
42
61
|
<label for="email-input" class="form-label">
|
|
@@ -3,25 +3,88 @@ import { normalizeBoolean } from "dxUtils/normalizers";
|
|
|
3
3
|
|
|
4
4
|
interface Comment {
|
|
5
5
|
email: string;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
timestamp: Date;
|
|
6
|
+
comment_text: string;
|
|
7
|
+
timestamp: string;
|
|
9
8
|
}
|
|
10
9
|
|
|
10
|
+
interface ApiCommentPayload {
|
|
11
|
+
branch: string;
|
|
12
|
+
file_path: string;
|
|
13
|
+
heading_title: string;
|
|
14
|
+
start_line: string;
|
|
15
|
+
end_line: string;
|
|
16
|
+
comment: {
|
|
17
|
+
comment_text: string;
|
|
18
|
+
email: string;
|
|
19
|
+
timestamp: string;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface ApiCommentResponse {
|
|
24
|
+
request_branch: string;
|
|
25
|
+
paths: Array<{
|
|
26
|
+
path: string;
|
|
27
|
+
titles: Array<{
|
|
28
|
+
title: string;
|
|
29
|
+
comments: Comment[];
|
|
30
|
+
}>;
|
|
31
|
+
}>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Local storage key for comments
|
|
35
|
+
const COMMENTS_STORAGE_KEY = "dsc_comments";
|
|
36
|
+
|
|
11
37
|
export default class CommentPopup extends LightningElement {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
38
|
+
iconSymbol = "chat";
|
|
39
|
+
iconSize = "medium";
|
|
40
|
+
popupTitle = "Leave a Comment";
|
|
41
|
+
submitButtonLabel = "Post Comment";
|
|
42
|
+
emailPlaceholder = "Enter your email";
|
|
43
|
+
commentPlaceholder = "Enter your comment";
|
|
44
|
+
|
|
45
|
+
private _headingTitle?: string;
|
|
46
|
+
private _filePath?: string;
|
|
47
|
+
private _startLine?: string;
|
|
48
|
+
private _endLine?: string;
|
|
49
|
+
private _currentBranch?: string;
|
|
50
|
+
|
|
51
|
+
@api get headingTitle() {
|
|
52
|
+
return this._headingTitle;
|
|
53
|
+
}
|
|
54
|
+
set headingTitle(value) {
|
|
55
|
+
this._headingTitle = value;
|
|
56
|
+
this.handlePropertyChange();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@api get filePath() {
|
|
60
|
+
return this._filePath;
|
|
61
|
+
}
|
|
62
|
+
set filePath(value) {
|
|
63
|
+
this._filePath = value;
|
|
64
|
+
this.handlePropertyChange();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@api get startLine() {
|
|
68
|
+
return this._startLine;
|
|
69
|
+
}
|
|
70
|
+
set startLine(value) {
|
|
71
|
+
this._startLine = value;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@api get endLine() {
|
|
75
|
+
return this._endLine;
|
|
76
|
+
}
|
|
77
|
+
set endLine(value) {
|
|
78
|
+
this._endLine = value;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@api get currentBranch() {
|
|
82
|
+
return this._currentBranch;
|
|
83
|
+
}
|
|
84
|
+
set currentBranch(value) {
|
|
85
|
+
this._currentBranch = value;
|
|
86
|
+
this.handlePropertyChange();
|
|
87
|
+
}
|
|
25
88
|
|
|
26
89
|
private _open = false;
|
|
27
90
|
@api get open() {
|
|
@@ -37,10 +100,11 @@ export default class CommentPopup extends LightningElement {
|
|
|
37
100
|
@track private emailError = "";
|
|
38
101
|
@track private commentError = "";
|
|
39
102
|
@track private isSubmitting = false;
|
|
103
|
+
@track private isLoading = false;
|
|
104
|
+
@track private apiError = "";
|
|
105
|
+
@track private submitSuccess = false;
|
|
40
106
|
|
|
41
107
|
get showComments() {
|
|
42
|
-
const unwrapped = JSON.parse(JSON.stringify(this.comments));
|
|
43
|
-
console.log("Comments (JSON unwrapped):", unwrapped);
|
|
44
108
|
return this.comments.length > 0;
|
|
45
109
|
}
|
|
46
110
|
|
|
@@ -54,7 +118,9 @@ export default class CommentPopup extends LightningElement {
|
|
|
54
118
|
|
|
55
119
|
get sortedComments() {
|
|
56
120
|
return [...this.comments].sort(
|
|
57
|
-
(a, b) =>
|
|
121
|
+
(a, b) =>
|
|
122
|
+
new Date(b.timestamp).getTime() -
|
|
123
|
+
new Date(a.timestamp).getTime()
|
|
58
124
|
);
|
|
59
125
|
}
|
|
60
126
|
|
|
@@ -68,31 +134,54 @@ export default class CommentPopup extends LightningElement {
|
|
|
68
134
|
|
|
69
135
|
handleIconClick() {
|
|
70
136
|
this._open = !this._open;
|
|
137
|
+
// Comments are already loaded when component is connected, no need to fetch again
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private handlePropertyChange() {
|
|
141
|
+
// Only fetch comments if component has required properties
|
|
142
|
+
if (this._currentBranch && this._filePath && this._headingTitle) {
|
|
143
|
+
this.fetchComments();
|
|
144
|
+
}
|
|
71
145
|
}
|
|
72
146
|
|
|
73
147
|
handleEmailChange(event: Event) {
|
|
74
148
|
this.email = (event.target as HTMLInputElement).value;
|
|
75
149
|
this.emailError = "";
|
|
150
|
+
this.apiError = "";
|
|
151
|
+
this.submitSuccess = false;
|
|
76
152
|
}
|
|
77
153
|
|
|
78
154
|
handleCommentChange(event: Event) {
|
|
79
155
|
this.comment = (event.target as HTMLTextAreaElement).value;
|
|
80
156
|
this.commentError = "";
|
|
157
|
+
this.apiError = "";
|
|
158
|
+
this.submitSuccess = false;
|
|
81
159
|
}
|
|
82
160
|
|
|
83
|
-
handleSubmit() {
|
|
161
|
+
async handleSubmit() {
|
|
84
162
|
if (!this.validateForm()) {
|
|
85
163
|
return;
|
|
86
164
|
}
|
|
87
165
|
|
|
88
166
|
this.isSubmitting = true;
|
|
167
|
+
this.apiError = "";
|
|
168
|
+
this.submitSuccess = false;
|
|
89
169
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
this.addComment();
|
|
170
|
+
try {
|
|
171
|
+
await this.addComment();
|
|
93
172
|
this.resetForm();
|
|
173
|
+
this.submitSuccess = true;
|
|
174
|
+
|
|
175
|
+
// Auto-hide success message after 3 seconds
|
|
176
|
+
setTimeout(() => {
|
|
177
|
+
this.submitSuccess = false;
|
|
178
|
+
}, 3000);
|
|
179
|
+
} catch (error) {
|
|
180
|
+
console.error("Error submitting comment:", error);
|
|
181
|
+
this.apiError = "Failed to post comment. Please try again.";
|
|
182
|
+
} finally {
|
|
94
183
|
this.isSubmitting = false;
|
|
95
|
-
}
|
|
184
|
+
}
|
|
96
185
|
}
|
|
97
186
|
|
|
98
187
|
private validateForm(): boolean {
|
|
@@ -119,22 +208,115 @@ export default class CommentPopup extends LightningElement {
|
|
|
119
208
|
return emailRegex.test(email);
|
|
120
209
|
}
|
|
121
210
|
|
|
122
|
-
private addComment() {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
211
|
+
private async addComment() {
|
|
212
|
+
// Validate required fields before creating payload
|
|
213
|
+
if (!this._currentBranch || !this._filePath || !this._headingTitle) {
|
|
214
|
+
throw new Error(
|
|
215
|
+
"Missing required fields: branch, file_path, or heading_title"
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const payload: ApiCommentPayload = {
|
|
220
|
+
branch: this._currentBranch,
|
|
221
|
+
file_path: this._filePath,
|
|
222
|
+
heading_title: this._headingTitle,
|
|
223
|
+
start_line: this._startLine || "",
|
|
224
|
+
end_line: this._endLine || "",
|
|
225
|
+
comment: {
|
|
226
|
+
comment_text: this.comment.trim(),
|
|
227
|
+
email: this.email.trim(),
|
|
228
|
+
timestamp: new Date().toISOString()
|
|
229
|
+
}
|
|
128
230
|
};
|
|
129
231
|
|
|
130
|
-
|
|
232
|
+
console.log(
|
|
233
|
+
"Posting comment with payload:",
|
|
234
|
+
JSON.stringify(payload, null, 2)
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
// LOCAL STORAGE IMPLEMENTATION (Temporary until backend is ready)
|
|
238
|
+
try {
|
|
239
|
+
await this.saveCommentToLocalStorage(payload);
|
|
240
|
+
console.log("Comment saved to local storage successfully");
|
|
241
|
+
|
|
242
|
+
// Refresh comments after successful save
|
|
243
|
+
await this.fetchComments();
|
|
244
|
+
|
|
245
|
+
// Dispatch custom event
|
|
246
|
+
this.dispatchEvent(
|
|
247
|
+
new CustomEvent("commentadded", {
|
|
248
|
+
detail: {
|
|
249
|
+
...payload.comment,
|
|
250
|
+
id: Date.now().toString() // Generate temporary ID
|
|
251
|
+
}
|
|
252
|
+
})
|
|
253
|
+
);
|
|
254
|
+
} catch (error) {
|
|
255
|
+
console.error("Error saving comment to local storage:", error);
|
|
256
|
+
throw error;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// API IMPLEMENTATION (Commented until backend is ready)
|
|
260
|
+
/*
|
|
261
|
+
const response = await fetch('/post-comment', {
|
|
262
|
+
method: 'POST',
|
|
263
|
+
headers: {
|
|
264
|
+
'Content-Type': 'application/json'
|
|
265
|
+
},
|
|
266
|
+
body: JSON.stringify(payload)
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
if (!response.ok) {
|
|
270
|
+
const errorText = await response.text();
|
|
271
|
+
throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const responseData = await response.json();
|
|
275
|
+
console.log('Comment posted successfully:', responseData);
|
|
276
|
+
|
|
277
|
+
// Refresh comments after successful post
|
|
278
|
+
await this.fetchComments();
|
|
131
279
|
|
|
132
280
|
// Dispatch custom event
|
|
133
281
|
this.dispatchEvent(
|
|
134
282
|
new CustomEvent("commentadded", {
|
|
135
|
-
detail:
|
|
283
|
+
detail: {
|
|
284
|
+
...payload.comment,
|
|
285
|
+
id: responseData.id // Include any ID returned by the API
|
|
286
|
+
}
|
|
136
287
|
})
|
|
137
288
|
);
|
|
289
|
+
*/
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
private async saveCommentToLocalStorage(payload: ApiCommentPayload) {
|
|
293
|
+
try {
|
|
294
|
+
// Get existing comments from localStorage
|
|
295
|
+
const existingData = localStorage.getItem(COMMENTS_STORAGE_KEY);
|
|
296
|
+
const allComments = existingData ? JSON.parse(existingData) : {};
|
|
297
|
+
|
|
298
|
+
// Create a unique key for this specific comment location
|
|
299
|
+
const commentKey = `${payload.branch}_${payload.file_path}_${payload.heading_title}`;
|
|
300
|
+
|
|
301
|
+
// Initialize array for this location if it doesn't exist
|
|
302
|
+
if (!allComments[commentKey]) {
|
|
303
|
+
allComments[commentKey] = [];
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Add the new comment
|
|
307
|
+
allComments[commentKey].push(payload.comment);
|
|
308
|
+
|
|
309
|
+
// Save back to localStorage
|
|
310
|
+
localStorage.setItem(
|
|
311
|
+
COMMENTS_STORAGE_KEY,
|
|
312
|
+
JSON.stringify(allComments)
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
console.log("Comments saved to localStorage:", allComments);
|
|
316
|
+
} catch (error) {
|
|
317
|
+
console.error("Error saving to localStorage:", error);
|
|
318
|
+
throw new Error("Failed to save comment to local storage");
|
|
319
|
+
}
|
|
138
320
|
}
|
|
139
321
|
|
|
140
322
|
private resetForm() {
|
|
@@ -162,6 +344,8 @@ export default class CommentPopup extends LightningElement {
|
|
|
162
344
|
handleClose() {
|
|
163
345
|
this._open = false;
|
|
164
346
|
this.resetForm();
|
|
347
|
+
this.apiError = "";
|
|
348
|
+
this.submitSuccess = false;
|
|
165
349
|
}
|
|
166
350
|
|
|
167
351
|
handleOverlayClick(event: Event) {
|
|
@@ -178,15 +362,121 @@ export default class CommentPopup extends LightningElement {
|
|
|
178
362
|
|
|
179
363
|
connectedCallback() {
|
|
180
364
|
document.addEventListener("keydown", this.handleKeyDown.bind(this));
|
|
365
|
+
// Fetch comments when component is connected
|
|
366
|
+
this.fetchComments();
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
private async fetchComments() {
|
|
370
|
+
if (!this._currentBranch || !this._filePath || !this._headingTitle) {
|
|
371
|
+
console.warn("Cannot fetch comments: missing required parameters");
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
this.isLoading = true;
|
|
376
|
+
this.apiError = "";
|
|
377
|
+
|
|
378
|
+
try {
|
|
379
|
+
// LOCAL STORAGE IMPLEMENTATION (Temporary until backend is ready)
|
|
380
|
+
const comments = await this.getCommentsFromLocalStorage();
|
|
381
|
+
console.log("Fetched comments from localStorage:", comments);
|
|
382
|
+
this.comments = comments;
|
|
383
|
+
|
|
384
|
+
// API IMPLEMENTATION (Commented until backend is ready)
|
|
385
|
+
/*
|
|
386
|
+
const params = new URLSearchParams({
|
|
387
|
+
branch: this._currentBranch
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
console.log('Fetching comments with params:', params.toString());
|
|
391
|
+
|
|
392
|
+
const response = await fetch(`/get-comments?${params.toString()}`);
|
|
393
|
+
|
|
394
|
+
if (!response.ok) {
|
|
395
|
+
throw new Error(`Failed to fetch comments: ${response.status} ${response.statusText}`);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const data: ApiCommentResponse = await response.json();
|
|
399
|
+
console.log('Fetched comments from API:', data);
|
|
400
|
+
|
|
401
|
+
// Find comments for this specific file path and heading title
|
|
402
|
+
const comments = this.extractCommentsFromApiResponse(data);
|
|
403
|
+
this.comments = comments;
|
|
404
|
+
*/
|
|
405
|
+
} catch (error) {
|
|
406
|
+
console.error("Error fetching comments:", error);
|
|
407
|
+
this.apiError = "Failed to load comments. Please try again later.";
|
|
408
|
+
this.comments = [];
|
|
409
|
+
} finally {
|
|
410
|
+
this.isLoading = false;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
private extractCommentsFromApiResponse(
|
|
415
|
+
data: ApiCommentResponse
|
|
416
|
+
): Comment[] {
|
|
417
|
+
try {
|
|
418
|
+
// Find the path that matches our file path
|
|
419
|
+
const matchingPath = data.paths.find(
|
|
420
|
+
(path) => path.path === this._filePath
|
|
421
|
+
);
|
|
422
|
+
|
|
423
|
+
if (!matchingPath) {
|
|
424
|
+
console.log(
|
|
425
|
+
`No comments found for file path: ${this._filePath}`
|
|
426
|
+
);
|
|
427
|
+
return [];
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// Find the title that matches our heading title
|
|
431
|
+
const matchingTitle = matchingPath.titles.find(
|
|
432
|
+
(title) => title.title === this._headingTitle
|
|
433
|
+
);
|
|
434
|
+
|
|
435
|
+
if (!matchingTitle) {
|
|
436
|
+
console.log(
|
|
437
|
+
`No comments found for heading title: ${this._headingTitle}`
|
|
438
|
+
);
|
|
439
|
+
return [];
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
console.log(
|
|
443
|
+
`Found ${matchingTitle.comments.length} comments for ${this._filePath} - ${this._headingTitle}`
|
|
444
|
+
);
|
|
445
|
+
return matchingTitle.comments;
|
|
446
|
+
} catch (error) {
|
|
447
|
+
console.error(
|
|
448
|
+
"Error extracting comments from API response:",
|
|
449
|
+
error
|
|
450
|
+
);
|
|
451
|
+
return [];
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
private async getCommentsFromLocalStorage(): Promise<Comment[]> {
|
|
456
|
+
try {
|
|
457
|
+
const existingData = localStorage.getItem(COMMENTS_STORAGE_KEY);
|
|
458
|
+
if (!existingData) {
|
|
459
|
+
return [];
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
const allComments = JSON.parse(existingData);
|
|
463
|
+
const commentKey = `${this._currentBranch}_${this._filePath}_${this._headingTitle}`;
|
|
464
|
+
|
|
465
|
+
return allComments[commentKey] || [];
|
|
466
|
+
} catch (error) {
|
|
467
|
+
console.error("Error reading from localStorage:", error);
|
|
468
|
+
return [];
|
|
469
|
+
}
|
|
181
470
|
}
|
|
182
471
|
|
|
183
472
|
disconnectedCallback() {
|
|
184
473
|
document.removeEventListener("keydown", this.handleKeyDown.bind(this));
|
|
185
474
|
}
|
|
186
475
|
|
|
187
|
-
private formatTimestamp(timestamp:
|
|
476
|
+
private formatTimestamp(timestamp: string): string {
|
|
188
477
|
const now = new Date();
|
|
189
|
-
const
|
|
478
|
+
const commentDate = new Date(timestamp);
|
|
479
|
+
const diff = now.getTime() - commentDate.getTime();
|
|
190
480
|
const minutes = Math.floor(diff / 60000);
|
|
191
481
|
const hours = Math.floor(diff / 3600000);
|
|
192
482
|
const days = Math.floor(diff / 86400000);
|
|
@@ -204,6 +494,7 @@ export default class CommentPopup extends LightningElement {
|
|
|
204
494
|
get formattedComments() {
|
|
205
495
|
return this.sortedComments.map((comment) => ({
|
|
206
496
|
...comment,
|
|
497
|
+
comment: comment.comment_text, // Map API field to template expectation
|
|
207
498
|
formattedTimestamp: this.formatTimestamp(comment.timestamp),
|
|
208
499
|
maskedEmail: this.maskEmail(comment.email)
|
|
209
500
|
}));
|