@salesforcedevs/docs-components 1.17.0-hack-alpha5 → 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
CHANGED
|
@@ -1,71 +1,178 @@
|
|
|
1
|
-
# Comment Popup Component
|
|
1
|
+
# Comment Popup Component
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A Lightning Web Component that allows users to leave comments on documentation sections. The component supports both local storage (for development) and a new API format for production use.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- ✅ **
|
|
8
|
-
- ✅ **
|
|
9
|
-
- ✅ **
|
|
10
|
-
- ✅ **
|
|
11
|
-
- ✅ **
|
|
7
|
+
- ✅ **New API Format**: Supports branch-based comment fetching
|
|
8
|
+
- ✅ **Pre-loaded Comments**: Comments are fetched when component is rendered, not when popup opens
|
|
9
|
+
- ✅ **Local Storage**: Comments persist across page refreshes during development
|
|
10
|
+
- ✅ **Form Validation**: Email format and required field validation
|
|
11
|
+
- ✅ **Real-time Display**: Comments appear immediately after posting
|
|
12
|
+
- ✅ **Timestamp Formatting**: Shows relative time (e.g., "2 hours ago")
|
|
13
|
+
- ✅ **Email Masking**: Protects user privacy in comment display
|
|
14
|
+
- ✅ **Comment Count Badge**: Shows total number of comments
|
|
15
|
+
- ✅ **Responsive Design**: Works on mobile and desktop
|
|
16
|
+
- ✅ **Keyboard Accessibility**: ESC key to close popup
|
|
17
|
+
- ✅ **Dark Mode Support**: Adapts to system preferences
|
|
18
|
+
- ✅ **Development Tools**: Helper utilities for testing
|
|
12
19
|
|
|
13
|
-
##
|
|
20
|
+
## API Format
|
|
14
21
|
|
|
15
|
-
|
|
22
|
+
The component now supports a new API format where comments are fetched by branch and then filtered by file path and heading title.
|
|
16
23
|
|
|
17
|
-
|
|
24
|
+
### API Endpoints
|
|
25
|
+
|
|
26
|
+
- **GET** `/get-comments?branch={branch}` - Fetch all comments for a branch
|
|
27
|
+
- **POST** `/post-comment` - Add a new comment
|
|
28
|
+
|
|
29
|
+
### API Response Format
|
|
18
30
|
|
|
19
31
|
```json
|
|
20
32
|
{
|
|
21
|
-
"
|
|
33
|
+
"request_branch": "feature/documentation-updates",
|
|
34
|
+
"paths": [
|
|
22
35
|
{
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
|
|
36
|
+
"path": "docs/installation.md",
|
|
37
|
+
"titles": [
|
|
38
|
+
{
|
|
39
|
+
"title": "Installation Guide",
|
|
40
|
+
"comments": [
|
|
41
|
+
{
|
|
42
|
+
"email": "john.doe@example.com",
|
|
43
|
+
"comment_text": "This installation guide is very helpful for new users.",
|
|
44
|
+
"timestamp": "2024-01-15T10:30:00Z"
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
]
|
|
26
49
|
}
|
|
27
50
|
]
|
|
28
51
|
}
|
|
29
52
|
```
|
|
30
53
|
|
|
31
|
-
### API
|
|
32
|
-
|
|
33
|
-
When posting comments, the component uses this exact format (ready for backend):
|
|
54
|
+
### API Request Format
|
|
34
55
|
|
|
35
56
|
```json
|
|
36
57
|
{
|
|
37
58
|
"branch": "feature/documentation-updates",
|
|
38
59
|
"file_path": "docs/installation.md",
|
|
39
60
|
"heading_title": "Installation Guide",
|
|
61
|
+
"start_line": "1",
|
|
62
|
+
"end_line": "50",
|
|
40
63
|
"comment": {
|
|
41
|
-
"comment_text": "This
|
|
42
|
-
"email": "
|
|
64
|
+
"comment_text": "This is a helpful comment.",
|
|
65
|
+
"email": "user@example.com",
|
|
43
66
|
"timestamp": "2024-01-15T10:30:00Z"
|
|
44
67
|
}
|
|
45
68
|
}
|
|
46
69
|
```
|
|
47
70
|
|
|
71
|
+
## Usage
|
|
72
|
+
|
|
73
|
+
### Basic Usage
|
|
74
|
+
|
|
75
|
+
```html
|
|
76
|
+
<sb-doc-comment-popup
|
|
77
|
+
heading-title="Installation Guide"
|
|
78
|
+
file-path="docs/installation.md"
|
|
79
|
+
current-branch="feature/documentation-updates"
|
|
80
|
+
start-line="1"
|
|
81
|
+
end-line="50"
|
|
82
|
+
open="false"
|
|
83
|
+
icon-symbol="chat"
|
|
84
|
+
icon-size="medium"
|
|
85
|
+
>
|
|
86
|
+
</sb-doc-comment-popup>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Comment Loading Behavior
|
|
90
|
+
|
|
91
|
+
The component now fetches comments when it is rendered (connected to the DOM) rather than when the popup is opened. This ensures:
|
|
92
|
+
|
|
93
|
+
- **Faster Popup Opening**: Comments are already loaded when the user clicks the icon
|
|
94
|
+
- **Immediate Comment Count**: The comment count badge shows the correct number immediately
|
|
95
|
+
- **Better User Experience**: No loading delay when opening the popup
|
|
96
|
+
|
|
97
|
+
Comments are automatically refetched when any of these properties change:
|
|
98
|
+
|
|
99
|
+
- `heading-title`
|
|
100
|
+
- `file-path`
|
|
101
|
+
- `current-branch`
|
|
102
|
+
|
|
103
|
+
### Required Properties
|
|
104
|
+
|
|
105
|
+
- `heading-title`: The title of the section being commented on
|
|
106
|
+
- `file-path`: The file path where the comment is located
|
|
107
|
+
- `current-branch`: The current git branch
|
|
108
|
+
|
|
109
|
+
### Optional Properties
|
|
110
|
+
|
|
111
|
+
- `start-line`: Starting line number (for future line-specific comments)
|
|
112
|
+
- `end-line`: Ending line number (for future line-specific comments)
|
|
113
|
+
- `open`: Controls the popup visibility (default: false)
|
|
114
|
+
- `icon-symbol`: Icon symbol for the comment button (default: "chat")
|
|
115
|
+
- `icon-size`: Size of the comment icon (default: "medium")
|
|
116
|
+
|
|
117
|
+
### Available Icon Symbols
|
|
118
|
+
|
|
119
|
+
- `chat` - Chat bubble icon
|
|
120
|
+
- `comment` - Comment icon
|
|
121
|
+
- `message` - Message icon
|
|
122
|
+
- `feedback` - Feedback icon
|
|
123
|
+
|
|
124
|
+
### Available Icon Sizes
|
|
125
|
+
|
|
126
|
+
- `small` - Small icon
|
|
127
|
+
- `medium` - Medium icon (default)
|
|
128
|
+
- `large` - Large icon
|
|
129
|
+
|
|
130
|
+
## Local Storage Implementation
|
|
131
|
+
|
|
132
|
+
During development, the component uses localStorage to persist comments. Comments are stored with a unique key format:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
{branch}_{file_path}_{heading_title}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Local Storage Structure
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"main_docs/installation.md_Installation Guide": [
|
|
143
|
+
{
|
|
144
|
+
"email": "user@example.com",
|
|
145
|
+
"comment_text": "This is a comment",
|
|
146
|
+
"timestamp": "2024-01-15T10:30:00Z"
|
|
147
|
+
}
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
48
152
|
## Development Tools
|
|
49
153
|
|
|
50
|
-
|
|
154
|
+
The component includes development tools for testing and managing comments during development.
|
|
51
155
|
|
|
52
|
-
|
|
156
|
+
### Console Commands
|
|
53
157
|
|
|
54
158
|
```javascript
|
|
55
159
|
// Export all comments to a JSON file
|
|
56
160
|
CommentDevHelper.exportCommentsToFile();
|
|
57
161
|
|
|
58
|
-
//
|
|
59
|
-
CommentDevHelper.
|
|
162
|
+
// Add sample comments matching the new API format
|
|
163
|
+
CommentDevHelper.addSampleCommentsForNewApi();
|
|
60
164
|
|
|
61
165
|
// Get statistics about stored comments
|
|
62
166
|
CommentDevHelper.getCommentsStats();
|
|
63
167
|
|
|
64
|
-
//
|
|
65
|
-
CommentDevHelper.
|
|
168
|
+
// Clear all comments from localStorage
|
|
169
|
+
CommentDevHelper.clearAllComments();
|
|
170
|
+
|
|
171
|
+
// Test the API response format
|
|
172
|
+
CommentDevHelper.testApiResponseFormat();
|
|
66
173
|
|
|
67
|
-
//
|
|
68
|
-
CommentDevHelper.
|
|
174
|
+
// Simulate API call for a specific branch
|
|
175
|
+
CommentDevHelper.simulateApiCall("main");
|
|
69
176
|
|
|
70
177
|
// Show all comments in console
|
|
71
178
|
CommentDevHelper.showAllComments();
|
|
@@ -73,140 +180,115 @@ CommentDevHelper.showAllComments();
|
|
|
73
180
|
|
|
74
181
|
### Development UI
|
|
75
182
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
- Export comments
|
|
79
|
-
- Clear all comments
|
|
80
|
-
- View statistics
|
|
81
|
-
- Show API format
|
|
82
|
-
|
|
83
|
-
## Migration to Backend
|
|
183
|
+
The component automatically creates a development UI when running on localhost. This UI provides buttons for:
|
|
84
184
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
// Export all comments to JSON file
|
|
91
|
-
CommentDevHelper.exportCommentsToFile();
|
|
92
|
-
```
|
|
185
|
+
- Adding sample comments
|
|
186
|
+
- Testing API response format
|
|
187
|
+
- Exporting comments
|
|
188
|
+
- Clearing all comments
|
|
189
|
+
- Viewing statistics
|
|
93
190
|
|
|
94
|
-
|
|
191
|
+
## Migration to Backend API
|
|
95
192
|
|
|
96
|
-
|
|
97
|
-
// Get comments in API format
|
|
98
|
-
const apiFormat = CommentDevHelper.convertToApiFormat();
|
|
99
|
-
console.log(apiFormat);
|
|
100
|
-
```
|
|
193
|
+
When the backend API is ready, follow these steps to migrate from localStorage:
|
|
101
194
|
|
|
102
|
-
|
|
195
|
+
1. **Uncomment API calls**: In `commentPopup.ts`, uncomment the API implementation sections
|
|
196
|
+
2. **Comment localStorage calls**: Comment out the localStorage implementation sections
|
|
197
|
+
3. **Update API endpoints**: Ensure the API endpoints match your backend
|
|
198
|
+
4. **Test API integration**: Use the development tools to test API calls
|
|
103
199
|
|
|
104
|
-
|
|
200
|
+
### Example Migration
|
|
105
201
|
|
|
106
202
|
```typescript
|
|
107
|
-
//
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
203
|
+
// Before (localStorage)
|
|
204
|
+
await this.saveCommentToLocalStorage(payload);
|
|
205
|
+
|
|
206
|
+
// After (API)
|
|
207
|
+
const response = await fetch("/post-comment", {
|
|
208
|
+
method: "POST",
|
|
111
209
|
headers: {
|
|
112
|
-
|
|
210
|
+
"Content-Type": "application/json"
|
|
113
211
|
},
|
|
114
212
|
body: JSON.stringify(payload)
|
|
115
213
|
});
|
|
116
|
-
*/
|
|
117
214
|
```
|
|
118
215
|
|
|
119
|
-
|
|
216
|
+
## Testing
|
|
120
217
|
|
|
121
|
-
|
|
218
|
+
### Storybook Stories
|
|
122
219
|
|
|
123
|
-
|
|
124
|
-
- GET: `/api/comments` (for fetching comments)
|
|
220
|
+
The component includes comprehensive Storybook stories for testing:
|
|
125
221
|
|
|
126
|
-
|
|
222
|
+
1. **Base**: Basic component functionality
|
|
223
|
+
2. **WithNewApiFormatComments**: Testing with new API format
|
|
224
|
+
3. **MultipleBranchesAndFiles**: Testing multiple branches and files
|
|
225
|
+
4. **FormValidation**: Testing form validation features
|
|
127
226
|
|
|
128
|
-
|
|
129
|
-
commentPopup/
|
|
130
|
-
├── commentPopup.ts # Main component
|
|
131
|
-
├── commentPopup.html # Template
|
|
132
|
-
├── commentPopup.css # Styles
|
|
133
|
-
├── commentUtils.ts # Utility functions
|
|
134
|
-
├── commentDevHelper.ts # Development tools
|
|
135
|
-
└── README.md # This file
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
## Usage
|
|
227
|
+
### Jest Tests
|
|
139
228
|
|
|
140
|
-
|
|
229
|
+
Run the test suite:
|
|
141
230
|
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
heading-title="Installation Guide"
|
|
145
|
-
file-path="docs/installation.md"
|
|
146
|
-
current-branch="main"
|
|
147
|
-
>
|
|
148
|
-
</c-comment-popup>
|
|
231
|
+
```bash
|
|
232
|
+
npm test commentPopup.test.ts
|
|
149
233
|
```
|
|
150
234
|
|
|
151
|
-
|
|
235
|
+
The test suite covers:
|
|
152
236
|
|
|
153
|
-
-
|
|
154
|
-
-
|
|
155
|
-
-
|
|
237
|
+
- Component initialization
|
|
238
|
+
- Form validation
|
|
239
|
+
- Local storage operations
|
|
240
|
+
- API response format handling
|
|
241
|
+
- Comment operations
|
|
242
|
+
- UI interactions
|
|
243
|
+
- Error handling
|
|
244
|
+
- Lifecycle methods
|
|
156
245
|
|
|
157
|
-
|
|
246
|
+
## Troubleshooting
|
|
158
247
|
|
|
159
|
-
|
|
160
|
-
- `end-line`: Ending line number (for future line-specific comments)
|
|
161
|
-
- `open`: Boolean to control popup visibility
|
|
248
|
+
### Common Issues
|
|
162
249
|
|
|
163
|
-
|
|
250
|
+
1. **Comments not appearing**: Check that `heading-title`, `file-path`, and `current-branch` are set correctly
|
|
251
|
+
2. **Form validation errors**: Ensure email format is valid and all required fields are filled
|
|
252
|
+
3. **localStorage errors**: Check browser console for localStorage quota exceeded errors
|
|
253
|
+
4. **API integration issues**: Verify API endpoints and response format match expected structure
|
|
164
254
|
|
|
165
|
-
|
|
255
|
+
### Debug Commands
|
|
166
256
|
|
|
167
257
|
```javascript
|
|
168
|
-
//
|
|
169
|
-
|
|
170
|
-
console.log("New comment:", event.detail);
|
|
171
|
-
});
|
|
172
|
-
```
|
|
258
|
+
// Check current comments
|
|
259
|
+
console.log(CommentDevHelper.getAllComments());
|
|
173
260
|
|
|
174
|
-
|
|
261
|
+
// Check component state
|
|
262
|
+
console.log(element.comments);
|
|
263
|
+
console.log(element.email);
|
|
264
|
+
console.log(element.comment);
|
|
175
265
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
## Storage Limits
|
|
180
|
-
|
|
181
|
-
- localStorage typically has a 5-10MB limit
|
|
182
|
-
- Comments are stored as JSON strings
|
|
183
|
-
- Monitor storage usage with `CommentDevHelper.getCommentsStats()`
|
|
184
|
-
|
|
185
|
-
## Troubleshooting
|
|
266
|
+
// Test API response parsing
|
|
267
|
+
CommentDevHelper.testApiResponseFormat();
|
|
268
|
+
```
|
|
186
269
|
|
|
187
|
-
|
|
270
|
+
## Browser Support
|
|
188
271
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
272
|
+
- Chrome 60+
|
|
273
|
+
- Firefox 55+
|
|
274
|
+
- Safari 12+
|
|
275
|
+
- Edge 79+
|
|
192
276
|
|
|
193
|
-
|
|
277
|
+
## Dependencies
|
|
194
278
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
279
|
+
- Lightning Web Components (LWC)
|
|
280
|
+
- TypeScript
|
|
281
|
+
- Jest (for testing)
|
|
198
282
|
|
|
199
|
-
|
|
283
|
+
## Contributing
|
|
200
284
|
|
|
201
|
-
1.
|
|
202
|
-
2.
|
|
203
|
-
3.
|
|
285
|
+
1. Fork the repository
|
|
286
|
+
2. Create a feature branch
|
|
287
|
+
3. Make your changes
|
|
288
|
+
4. Add tests for new functionality
|
|
289
|
+
5. Update documentation
|
|
290
|
+
6. Submit a pull request
|
|
204
291
|
|
|
205
|
-
##
|
|
292
|
+
## License
|
|
206
293
|
|
|
207
|
-
|
|
208
|
-
- [ ] Comment threading/replies
|
|
209
|
-
- [ ] Comment moderation
|
|
210
|
-
- [ ] User authentication integration
|
|
211
|
-
- [ ] Real-time comment updates
|
|
212
|
-
- [ ] Comment search and filtering
|
|
294
|
+
This component is part of the Salesforce Developer Documentation Components package.
|
|
@@ -9,7 +9,10 @@ import {
|
|
|
9
9
|
clearAllComments,
|
|
10
10
|
getCommentsStats,
|
|
11
11
|
convertToApiFormat,
|
|
12
|
-
addComment
|
|
12
|
+
addComment,
|
|
13
|
+
getCommentsForBranch,
|
|
14
|
+
fetchCommentsForBranch,
|
|
15
|
+
extractCommentsFromApiResponse
|
|
13
16
|
} from "./commentUtils";
|
|
14
17
|
|
|
15
18
|
// Make functions available globally for console access
|
|
@@ -21,7 +24,10 @@ if (typeof window !== "undefined") {
|
|
|
21
24
|
clearAllComments,
|
|
22
25
|
getCommentsStats,
|
|
23
26
|
convertToApiFormat,
|
|
24
|
-
addComment
|
|
27
|
+
addComment,
|
|
28
|
+
getCommentsForBranch,
|
|
29
|
+
fetchCommentsForBranch,
|
|
30
|
+
extractCommentsFromApiResponse
|
|
25
31
|
};
|
|
26
32
|
}
|
|
27
33
|
|
|
@@ -44,7 +50,7 @@ export function createDevUI(): void {
|
|
|
44
50
|
position: fixed;
|
|
45
51
|
top: 20px;
|
|
46
52
|
right: 20px;
|
|
47
|
-
width:
|
|
53
|
+
width: 350px;
|
|
48
54
|
background: white;
|
|
49
55
|
border: 2px solid #007bff;
|
|
50
56
|
border-radius: 8px;
|
|
@@ -53,6 +59,8 @@ export function createDevUI(): void {
|
|
|
53
59
|
font-size: 14px;
|
|
54
60
|
z-index: 10000;
|
|
55
61
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
62
|
+
max-height: 80vh;
|
|
63
|
+
overflow-y: auto;
|
|
56
64
|
`;
|
|
57
65
|
|
|
58
66
|
const stats = getCommentsStats();
|
|
@@ -65,6 +73,7 @@ export function createDevUI(): void {
|
|
|
65
73
|
|
|
66
74
|
<div style="margin-bottom: 12px;">
|
|
67
75
|
<strong>Stats:</strong><br>
|
|
76
|
+
Branches: ${stats.branches.length}<br>
|
|
68
77
|
Locations: ${stats.totalLocations}<br>
|
|
69
78
|
Total Comments: ${stats.totalComments}
|
|
70
79
|
</div>
|
|
@@ -85,6 +94,14 @@ export function createDevUI(): void {
|
|
|
85
94
|
<button onclick="console.log(CommentDevHelper.convertToApiFormat())" style="padding: 8px; background: #6f42c1; color: white; border: none; border-radius: 4px; cursor: pointer;">
|
|
86
95
|
Show API Format in Console
|
|
87
96
|
</button>
|
|
97
|
+
|
|
98
|
+
<button onclick="CommentDevHelper.addSampleCommentsForNewApi()" style="padding: 8px; background: #fd7e14; color: white; border: none; border-radius: 4px; cursor: pointer;">
|
|
99
|
+
Add Sample Comments (New API Format)
|
|
100
|
+
</button>
|
|
101
|
+
|
|
102
|
+
<button onclick="CommentDevHelper.testApiResponseFormat()" style="padding: 8px; background: #20c997; color: white; border: none; border-radius: 4px; cursor: pointer;">
|
|
103
|
+
Test API Response Format
|
|
104
|
+
</button>
|
|
88
105
|
</div>
|
|
89
106
|
|
|
90
107
|
<div style="margin-top: 12px; font-size: 12px; color: #666;">
|
|
@@ -92,7 +109,9 @@ export function createDevUI(): void {
|
|
|
92
109
|
CommentDevHelper.exportCommentsToFile()<br>
|
|
93
110
|
CommentDevHelper.clearAllComments()<br>
|
|
94
111
|
CommentDevHelper.getCommentsStats()<br>
|
|
95
|
-
CommentDevHelper.convertToApiFormat()
|
|
112
|
+
CommentDevHelper.convertToApiFormat()<br>
|
|
113
|
+
CommentDevHelper.getCommentsForBranch('main')<br>
|
|
114
|
+
CommentDevHelper.testApiResponseFormat()
|
|
96
115
|
</div>
|
|
97
116
|
`;
|
|
98
117
|
|
|
@@ -110,24 +129,134 @@ export function removeDevUI(): void {
|
|
|
110
129
|
}
|
|
111
130
|
|
|
112
131
|
/**
|
|
113
|
-
* Add
|
|
132
|
+
* Add sample comments that match the new API format
|
|
114
133
|
*/
|
|
115
|
-
export function
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
134
|
+
export function addSampleCommentsForNewApi(): void {
|
|
135
|
+
const sampleComments = [
|
|
136
|
+
{
|
|
137
|
+
branch: "feature/documentation-updates",
|
|
138
|
+
file_path: "docs/installation.md",
|
|
139
|
+
heading_title: "Installation Guide",
|
|
140
|
+
start_line: "1",
|
|
141
|
+
end_line: "50",
|
|
142
|
+
comment: {
|
|
143
|
+
comment_text:
|
|
144
|
+
"This installation guide is very helpful for new users.",
|
|
145
|
+
email: "john.doe@example.com",
|
|
146
|
+
timestamp: new Date(Date.now() - 3600000).toISOString() // 1 hour ago
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
branch: "feature/documentation-updates",
|
|
151
|
+
file_path: "docs/installation.md",
|
|
152
|
+
heading_title: "Installation Guide",
|
|
153
|
+
start_line: "1",
|
|
154
|
+
end_line: "50",
|
|
155
|
+
comment: {
|
|
156
|
+
comment_text:
|
|
157
|
+
"Consider adding troubleshooting section for common issues.",
|
|
158
|
+
email: "jane.smith@example.com",
|
|
159
|
+
timestamp: new Date(Date.now() - 1800000).toISOString() // 30 minutes ago
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
branch: "feature/documentation-updates",
|
|
164
|
+
file_path: "docs/installation.md",
|
|
165
|
+
heading_title: "Prerequisites",
|
|
166
|
+
start_line: "10",
|
|
167
|
+
end_line: "25",
|
|
168
|
+
comment: {
|
|
169
|
+
comment_text:
|
|
170
|
+
"The prerequisites section is clear and well-organized.",
|
|
171
|
+
email: "mike.wilson@example.com",
|
|
172
|
+
timestamp: new Date(Date.now() - 900000).toISOString() // 15 minutes ago
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
branch: "feature/documentation-updates",
|
|
177
|
+
file_path: "docs/api.md",
|
|
178
|
+
heading_title: "API Reference",
|
|
179
|
+
start_line: "1",
|
|
180
|
+
end_line: "100",
|
|
181
|
+
comment: {
|
|
182
|
+
comment_text:
|
|
183
|
+
"The API documentation needs more examples for authentication.",
|
|
184
|
+
email: "sarah.jones@example.com",
|
|
185
|
+
timestamp: new Date(Date.now() - 600000).toISOString() // 10 minutes ago
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
branch: "feature/documentation-updates",
|
|
190
|
+
file_path: "docs/api.md",
|
|
191
|
+
heading_title: "API Reference",
|
|
192
|
+
start_line: "1",
|
|
193
|
+
end_line: "100",
|
|
194
|
+
comment: {
|
|
195
|
+
comment_text: "Great work on the endpoint descriptions!",
|
|
196
|
+
email: "david.brown@example.com",
|
|
197
|
+
timestamp: new Date().toISOString() // now
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
branch: "main",
|
|
202
|
+
file_path: "docs/getting-started.md",
|
|
203
|
+
heading_title: "Quick Start",
|
|
204
|
+
start_line: "1",
|
|
205
|
+
end_line: "30",
|
|
206
|
+
comment: {
|
|
207
|
+
comment_text:
|
|
208
|
+
"This quick start guide is perfect for beginners.",
|
|
209
|
+
email: "alice.johnson@example.com",
|
|
210
|
+
timestamp: new Date(Date.now() - 7200000).toISOString() // 2 hours ago
|
|
211
|
+
}
|
|
126
212
|
}
|
|
127
|
-
|
|
213
|
+
];
|
|
214
|
+
|
|
215
|
+
sampleComments.forEach((comment) => {
|
|
216
|
+
addComment(comment);
|
|
217
|
+
});
|
|
128
218
|
|
|
129
|
-
|
|
130
|
-
console.log("Sample
|
|
219
|
+
console.log("Added sample comments for new API format");
|
|
220
|
+
console.log("Sample data includes multiple branches, files, and titles");
|
|
221
|
+
|
|
222
|
+
// Refresh the page to show the new comments
|
|
223
|
+
setTimeout(() => {
|
|
224
|
+
window.location.reload();
|
|
225
|
+
}, 1000);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Test the API response format
|
|
230
|
+
*/
|
|
231
|
+
export function testApiResponseFormat(): void {
|
|
232
|
+
console.log("=== Testing API Response Format ===");
|
|
233
|
+
|
|
234
|
+
// Test with feature/documentation-updates branch
|
|
235
|
+
const featureBranchResponse = getCommentsForBranch(
|
|
236
|
+
"feature/documentation-updates"
|
|
237
|
+
);
|
|
238
|
+
console.log("Feature branch response:", featureBranchResponse);
|
|
239
|
+
|
|
240
|
+
// Test with main branch
|
|
241
|
+
const mainBranchResponse = getCommentsForBranch("main");
|
|
242
|
+
console.log("Main branch response:", mainBranchResponse);
|
|
243
|
+
|
|
244
|
+
// Test extracting specific comments
|
|
245
|
+
const installationComments = extractCommentsFromApiResponse(
|
|
246
|
+
featureBranchResponse,
|
|
247
|
+
"docs/installation.md",
|
|
248
|
+
"Installation Guide"
|
|
249
|
+
);
|
|
250
|
+
console.log("Installation Guide comments:", installationComments);
|
|
251
|
+
|
|
252
|
+
const apiComments = extractCommentsFromApiResponse(
|
|
253
|
+
featureBranchResponse,
|
|
254
|
+
"docs/api.md",
|
|
255
|
+
"API Reference"
|
|
256
|
+
);
|
|
257
|
+
console.log("API Reference comments:", apiComments);
|
|
258
|
+
|
|
259
|
+
console.log("=== API Response Format Test Complete ===");
|
|
131
260
|
}
|
|
132
261
|
|
|
133
262
|
/**
|
|
@@ -141,6 +270,46 @@ export function showAllComments(): void {
|
|
|
141
270
|
const stats = getCommentsStats();
|
|
142
271
|
console.log("=== STATISTICS ===");
|
|
143
272
|
console.table(stats.locations);
|
|
273
|
+
|
|
274
|
+
console.log("=== BRANCHES ===");
|
|
275
|
+
console.log("Available branches:", stats.branches);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Simulate API call and show response
|
|
280
|
+
*/
|
|
281
|
+
export async function simulateApiCall(
|
|
282
|
+
branch: string = "feature/documentation-updates"
|
|
283
|
+
): Promise<void> {
|
|
284
|
+
console.log(`=== Simulating API Call for branch: ${branch} ===`);
|
|
285
|
+
|
|
286
|
+
try {
|
|
287
|
+
const response = await fetchCommentsForBranch(branch);
|
|
288
|
+
console.log("API Response:", response);
|
|
289
|
+
|
|
290
|
+
// Show all paths and titles
|
|
291
|
+
response.paths.forEach((path) => {
|
|
292
|
+
console.log(`File: ${path.path}`);
|
|
293
|
+
path.titles.forEach((title) => {
|
|
294
|
+
console.log(
|
|
295
|
+
` Title: ${title.title} (${title.comments.length} comments)`
|
|
296
|
+
);
|
|
297
|
+
});
|
|
298
|
+
});
|
|
299
|
+
} catch (error) {
|
|
300
|
+
console.error("API call simulation failed:", error);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Add the helper functions to the global CommentDevHelper
|
|
305
|
+
if (typeof window !== "undefined") {
|
|
306
|
+
(window as any).CommentDevHelper = {
|
|
307
|
+
...(window as any).CommentDevHelper,
|
|
308
|
+
addSampleCommentsForNewApi,
|
|
309
|
+
testApiResponseFormat,
|
|
310
|
+
showAllComments,
|
|
311
|
+
simulateApiCall
|
|
312
|
+
};
|
|
144
313
|
}
|
|
145
314
|
|
|
146
315
|
// Auto-create UI when this module is imported (in development)
|
|
@@ -20,6 +20,17 @@ interface ApiCommentPayload {
|
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
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
|
+
|
|
23
34
|
// Local storage key for comments
|
|
24
35
|
const COMMENTS_STORAGE_KEY = "dsc_comments";
|
|
25
36
|
|
|
@@ -31,11 +42,49 @@ export default class CommentPopup extends LightningElement {
|
|
|
31
42
|
emailPlaceholder = "Enter your email";
|
|
32
43
|
commentPlaceholder = "Enter your comment";
|
|
33
44
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
+
}
|
|
39
88
|
|
|
40
89
|
private _open = false;
|
|
41
90
|
@api get open() {
|
|
@@ -85,7 +134,12 @@ export default class CommentPopup extends LightningElement {
|
|
|
85
134
|
|
|
86
135
|
handleIconClick() {
|
|
87
136
|
this._open = !this._open;
|
|
88
|
-
|
|
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) {
|
|
89
143
|
this.fetchComments();
|
|
90
144
|
}
|
|
91
145
|
}
|
|
@@ -156,18 +210,18 @@ export default class CommentPopup extends LightningElement {
|
|
|
156
210
|
|
|
157
211
|
private async addComment() {
|
|
158
212
|
// Validate required fields before creating payload
|
|
159
|
-
if (!this.
|
|
213
|
+
if (!this._currentBranch || !this._filePath || !this._headingTitle) {
|
|
160
214
|
throw new Error(
|
|
161
215
|
"Missing required fields: branch, file_path, or heading_title"
|
|
162
216
|
);
|
|
163
217
|
}
|
|
164
218
|
|
|
165
219
|
const payload: ApiCommentPayload = {
|
|
166
|
-
branch: this.
|
|
167
|
-
file_path: this.
|
|
168
|
-
heading_title: this.
|
|
169
|
-
start_line: this.
|
|
170
|
-
end_line: this.
|
|
220
|
+
branch: this._currentBranch,
|
|
221
|
+
file_path: this._filePath,
|
|
222
|
+
heading_title: this._headingTitle,
|
|
223
|
+
start_line: this._startLine || "",
|
|
224
|
+
end_line: this._endLine || "",
|
|
171
225
|
comment: {
|
|
172
226
|
comment_text: this.comment.trim(),
|
|
173
227
|
email: this.email.trim(),
|
|
@@ -308,10 +362,12 @@ export default class CommentPopup extends LightningElement {
|
|
|
308
362
|
|
|
309
363
|
connectedCallback() {
|
|
310
364
|
document.addEventListener("keydown", this.handleKeyDown.bind(this));
|
|
365
|
+
// Fetch comments when component is connected
|
|
366
|
+
this.fetchComments();
|
|
311
367
|
}
|
|
312
368
|
|
|
313
369
|
private async fetchComments() {
|
|
314
|
-
if (!this.
|
|
370
|
+
if (!this._currentBranch || !this._filePath || !this._headingTitle) {
|
|
315
371
|
console.warn("Cannot fetch comments: missing required parameters");
|
|
316
372
|
return;
|
|
317
373
|
}
|
|
@@ -328,30 +384,23 @@ export default class CommentPopup extends LightningElement {
|
|
|
328
384
|
// API IMPLEMENTATION (Commented until backend is ready)
|
|
329
385
|
/*
|
|
330
386
|
const params = new URLSearchParams({
|
|
331
|
-
branch: this.
|
|
332
|
-
file_path: this.filePath,
|
|
333
|
-
heading_title: this.headingTitle
|
|
387
|
+
branch: this._currentBranch
|
|
334
388
|
});
|
|
335
389
|
|
|
336
390
|
console.log('Fetching comments with params:', params.toString());
|
|
337
391
|
|
|
338
|
-
const response = await fetch(`/
|
|
392
|
+
const response = await fetch(`/get-comments?${params.toString()}`);
|
|
339
393
|
|
|
340
394
|
if (!response.ok) {
|
|
341
395
|
throw new Error(`Failed to fetch comments: ${response.status} ${response.statusText}`);
|
|
342
396
|
}
|
|
343
397
|
|
|
344
|
-
const data = await response.json();
|
|
345
|
-
console.log('Fetched comments:', data);
|
|
398
|
+
const data: ApiCommentResponse = await response.json();
|
|
399
|
+
console.log('Fetched comments from API:', data);
|
|
346
400
|
|
|
347
|
-
//
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
} else if (data && Array.isArray(data.comments)) {
|
|
351
|
-
this.comments = data.comments;
|
|
352
|
-
} else {
|
|
353
|
-
this.comments = [];
|
|
354
|
-
}
|
|
401
|
+
// Find comments for this specific file path and heading title
|
|
402
|
+
const comments = this.extractCommentsFromApiResponse(data);
|
|
403
|
+
this.comments = comments;
|
|
355
404
|
*/
|
|
356
405
|
} catch (error) {
|
|
357
406
|
console.error("Error fetching comments:", error);
|
|
@@ -362,6 +411,47 @@ export default class CommentPopup extends LightningElement {
|
|
|
362
411
|
}
|
|
363
412
|
}
|
|
364
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
|
+
|
|
365
455
|
private async getCommentsFromLocalStorage(): Promise<Comment[]> {
|
|
366
456
|
try {
|
|
367
457
|
const existingData = localStorage.getItem(COMMENTS_STORAGE_KEY);
|
|
@@ -370,7 +460,7 @@ export default class CommentPopup extends LightningElement {
|
|
|
370
460
|
}
|
|
371
461
|
|
|
372
462
|
const allComments = JSON.parse(existingData);
|
|
373
|
-
const commentKey = `${this.
|
|
463
|
+
const commentKey = `${this._currentBranch}_${this._filePath}_${this._headingTitle}`;
|
|
374
464
|
|
|
375
465
|
return allComments[commentKey] || [];
|
|
376
466
|
} catch (error) {
|
|
@@ -20,6 +20,17 @@ export interface ApiCommentPayload {
|
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
export 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
|
+
|
|
23
34
|
const COMMENTS_STORAGE_KEY = "dsc_comments";
|
|
24
35
|
|
|
25
36
|
/**
|
|
@@ -117,6 +128,68 @@ export function getCommentsForLocation(
|
|
|
117
128
|
}
|
|
118
129
|
}
|
|
119
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Get all comments for a specific branch (simulating API response format)
|
|
133
|
+
*/
|
|
134
|
+
export function getCommentsForBranch(branch: string): ApiCommentResponse {
|
|
135
|
+
try {
|
|
136
|
+
const allComments = getAllComments();
|
|
137
|
+
const branchComments: ApiCommentResponse = {
|
|
138
|
+
request_branch: branch,
|
|
139
|
+
paths: []
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// Group comments by file path and title
|
|
143
|
+
const pathMap = new Map<string, Map<string, Comment[]>>();
|
|
144
|
+
|
|
145
|
+
Object.keys(allComments).forEach((key) => {
|
|
146
|
+
const [commentBranch, filePath, headingTitle] = key.split("_", 3);
|
|
147
|
+
|
|
148
|
+
if (commentBranch === branch) {
|
|
149
|
+
if (!pathMap.has(filePath)) {
|
|
150
|
+
pathMap.set(filePath, new Map());
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const titleMap = pathMap.get(filePath)!;
|
|
154
|
+
if (!titleMap.has(headingTitle)) {
|
|
155
|
+
titleMap.set(headingTitle, []);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
titleMap.get(headingTitle)!.push(...allComments[key]);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Convert to API response format
|
|
163
|
+
pathMap.forEach((titleMap, filePath) => {
|
|
164
|
+
const titles: Array<{ title: string; comments: Comment[] }> = [];
|
|
165
|
+
|
|
166
|
+
titleMap.forEach((comments, title) => {
|
|
167
|
+
titles.push({
|
|
168
|
+
title,
|
|
169
|
+
comments: comments.sort(
|
|
170
|
+
(a, b) =>
|
|
171
|
+
new Date(b.timestamp).getTime() -
|
|
172
|
+
new Date(a.timestamp).getTime()
|
|
173
|
+
)
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
branchComments.paths.push({
|
|
178
|
+
path: filePath,
|
|
179
|
+
titles
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
return branchComments;
|
|
184
|
+
} catch (error) {
|
|
185
|
+
console.error("Error getting comments for branch:", error);
|
|
186
|
+
return {
|
|
187
|
+
request_branch: branch,
|
|
188
|
+
paths: []
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
120
193
|
/**
|
|
121
194
|
* Clear all comments from localStorage
|
|
122
195
|
*/
|
|
@@ -135,8 +208,12 @@ export function clearAllComments(): void {
|
|
|
135
208
|
export function getCommentsStats(): {
|
|
136
209
|
totalLocations: number;
|
|
137
210
|
totalComments: number;
|
|
211
|
+
branches: string[];
|
|
138
212
|
locations: Array<{
|
|
139
213
|
key: string;
|
|
214
|
+
branch: string;
|
|
215
|
+
filePath: string;
|
|
216
|
+
headingTitle: string;
|
|
140
217
|
commentCount: number;
|
|
141
218
|
lastComment?: string;
|
|
142
219
|
}>;
|
|
@@ -145,13 +222,19 @@ export function getCommentsStats(): {
|
|
|
145
222
|
const allComments = getAllComments();
|
|
146
223
|
const locations = Object.keys(allComments);
|
|
147
224
|
let totalComments = 0;
|
|
225
|
+
const branches = new Set<string>();
|
|
148
226
|
|
|
149
227
|
const locationStats = locations.map((key) => {
|
|
228
|
+
const [branch, filePath, headingTitle] = key.split("_", 3);
|
|
150
229
|
const comments = allComments[key];
|
|
151
230
|
totalComments += comments.length;
|
|
231
|
+
branches.add(branch);
|
|
152
232
|
|
|
153
233
|
return {
|
|
154
234
|
key,
|
|
235
|
+
branch,
|
|
236
|
+
filePath,
|
|
237
|
+
headingTitle,
|
|
155
238
|
commentCount: comments.length,
|
|
156
239
|
lastComment:
|
|
157
240
|
comments.length > 0
|
|
@@ -163,6 +246,7 @@ export function getCommentsStats(): {
|
|
|
163
246
|
return {
|
|
164
247
|
totalLocations: locations.length,
|
|
165
248
|
totalComments,
|
|
249
|
+
branches: Array.from(branches),
|
|
166
250
|
locations: locationStats
|
|
167
251
|
};
|
|
168
252
|
} catch (error) {
|
|
@@ -170,6 +254,7 @@ export function getCommentsStats(): {
|
|
|
170
254
|
return {
|
|
171
255
|
totalLocations: 0,
|
|
172
256
|
totalComments: 0,
|
|
257
|
+
branches: [],
|
|
173
258
|
locations: []
|
|
174
259
|
};
|
|
175
260
|
}
|
|
@@ -198,21 +283,14 @@ export function convertToApiFormat(): Array<{
|
|
|
198
283
|
}> = [];
|
|
199
284
|
|
|
200
285
|
Object.keys(allComments).forEach((key) => {
|
|
201
|
-
const [branch, file_path, heading_title
|
|
202
|
-
|
|
203
|
-
if (
|
|
204
|
-
branch &&
|
|
205
|
-
file_path &&
|
|
206
|
-
heading_title &&
|
|
207
|
-
start_line &&
|
|
208
|
-
end_line
|
|
209
|
-
) {
|
|
286
|
+
const [branch, file_path, heading_title] = key.split("_", 3);
|
|
287
|
+
if (branch && file_path && heading_title) {
|
|
210
288
|
apiFormat.push({
|
|
211
289
|
branch,
|
|
212
290
|
file_path,
|
|
213
291
|
heading_title,
|
|
214
|
-
start_line,
|
|
215
|
-
end_line,
|
|
292
|
+
start_line: "",
|
|
293
|
+
end_line: "",
|
|
216
294
|
comments: allComments[key]
|
|
217
295
|
});
|
|
218
296
|
}
|
|
@@ -248,3 +326,57 @@ export function addComment(payload: ApiCommentPayload): void {
|
|
|
248
326
|
throw error;
|
|
249
327
|
}
|
|
250
328
|
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Simulate API call to get comments for a branch
|
|
332
|
+
*/
|
|
333
|
+
export async function fetchCommentsForBranch(
|
|
334
|
+
branch: string
|
|
335
|
+
): Promise<ApiCommentResponse> {
|
|
336
|
+
try {
|
|
337
|
+
// Simulate API delay
|
|
338
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
339
|
+
|
|
340
|
+
return getCommentsForBranch(branch);
|
|
341
|
+
} catch (error) {
|
|
342
|
+
console.error("Error fetching comments for branch:", error);
|
|
343
|
+
throw error;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Extract comments for specific file path and heading title from API response
|
|
349
|
+
*/
|
|
350
|
+
export function extractCommentsFromApiResponse(
|
|
351
|
+
data: ApiCommentResponse,
|
|
352
|
+
filePath: string,
|
|
353
|
+
headingTitle: string
|
|
354
|
+
): Comment[] {
|
|
355
|
+
try {
|
|
356
|
+
// Find the path that matches our file path
|
|
357
|
+
const matchingPath = data.paths.find((path) => path.path === filePath);
|
|
358
|
+
|
|
359
|
+
if (!matchingPath) {
|
|
360
|
+
console.log(`No comments found for file path: ${filePath}`);
|
|
361
|
+
return [];
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Find the title that matches our heading title
|
|
365
|
+
const matchingTitle = matchingPath.titles.find(
|
|
366
|
+
(title) => title.title === headingTitle
|
|
367
|
+
);
|
|
368
|
+
|
|
369
|
+
if (!matchingTitle) {
|
|
370
|
+
console.log(`No comments found for heading title: ${headingTitle}`);
|
|
371
|
+
return [];
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
console.log(
|
|
375
|
+
`Found ${matchingTitle.comments.length} comments for ${filePath} - ${headingTitle}`
|
|
376
|
+
);
|
|
377
|
+
return matchingTitle.comments;
|
|
378
|
+
} catch (error) {
|
|
379
|
+
console.error("Error extracting comments from API response:", error);
|
|
380
|
+
return [];
|
|
381
|
+
}
|
|
382
|
+
}
|