hale-commenting-system 2.0.3 → 2.1.0
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 +16 -207
- package/bin/detect.d.ts +10 -0
- package/bin/detect.js +134 -0
- package/bin/generators.d.ts +18 -0
- package/bin/generators.js +193 -0
- package/bin/hale-commenting.js +4 -0
- package/bin/index.d.ts +2 -0
- package/bin/index.js +61 -0
- package/bin/onboarding.d.ts +1 -0
- package/bin/onboarding.js +344 -0
- package/bin/postinstall.d.ts +2 -0
- package/bin/postinstall.js +65 -0
- package/bin/validators.d.ts +2 -0
- package/bin/validators.js +66 -0
- package/dist/cli/detect.d.ts +10 -0
- package/dist/cli/detect.js +134 -0
- package/dist/cli/generators.d.ts +18 -0
- package/dist/cli/generators.js +193 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +61 -0
- package/dist/cli/onboarding.d.ts +1 -0
- package/dist/cli/onboarding.js +344 -0
- package/dist/cli/postinstall.d.ts +2 -0
- package/dist/cli/postinstall.js +65 -0
- package/dist/cli/validators.d.ts +2 -0
- package/dist/cli/validators.js +66 -0
- package/dist/components/CommentOverlay.d.ts +2 -0
- package/dist/components/CommentOverlay.js +101 -0
- package/dist/components/CommentPanel.d.ts +6 -0
- package/dist/components/CommentPanel.js +334 -0
- package/dist/components/CommentPin.d.ts +11 -0
- package/dist/components/CommentPin.js +64 -0
- package/dist/components/DetailsTab.d.ts +2 -0
- package/dist/components/DetailsTab.js +380 -0
- package/dist/components/FloatingWidget.d.ts +8 -0
- package/dist/components/FloatingWidget.js +128 -0
- package/dist/components/JiraTab.d.ts +2 -0
- package/dist/components/JiraTab.js +507 -0
- package/dist/contexts/CommentContext.d.ts +30 -0
- package/dist/contexts/CommentContext.js +891 -0
- package/dist/contexts/GitHubAuthContext.d.ts +13 -0
- package/dist/contexts/GitHubAuthContext.js +96 -0
- package/dist/index.d.ts +10 -97
- package/dist/index.js +26 -786
- package/dist/services/githubAdapter.d.ts +56 -0
- package/dist/services/githubAdapter.js +321 -0
- package/dist/types/index.d.ts +25 -0
- package/dist/types/index.js +2 -0
- package/dist/utils/version.d.ts +1 -0
- package/dist/utils/version.js +23 -0
- package/package.json +39 -38
- package/templates/webpack-middleware.js +226 -0
- package/cli/dist/index.js +0 -370
- package/cli/dist/index.js.map +0 -1
- package/dist/index.d.mts +0 -97
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -759
- package/dist/index.mjs.map +0 -1
package/dist/index.mjs
DELETED
|
@@ -1,759 +0,0 @@
|
|
|
1
|
-
// src/components/CommentOverlay.tsx
|
|
2
|
-
import * as React3 from "react";
|
|
3
|
-
import { useLocation } from "react-router-dom";
|
|
4
|
-
|
|
5
|
-
// src/contexts/CommentContext.tsx
|
|
6
|
-
import * as React from "react";
|
|
7
|
-
import { jsx } from "react/jsx-runtime";
|
|
8
|
-
var CommentContext = React.createContext(void 0);
|
|
9
|
-
var STORAGE_KEY = "hale-threads";
|
|
10
|
-
var SHOW_PINS_KEY = "hale-show-pins";
|
|
11
|
-
var ENABLE_COMMENTING_KEY = "hale-enable-commenting";
|
|
12
|
-
var migrateOldComments = () => {
|
|
13
|
-
try {
|
|
14
|
-
const oldThreadsKey = localStorage.getItem("apollo-threads");
|
|
15
|
-
const oldCommentsKey = localStorage.getItem("apollo-comments");
|
|
16
|
-
if (oldThreadsKey) {
|
|
17
|
-
const parsed = JSON.parse(oldThreadsKey);
|
|
18
|
-
const cleanThreads = parsed.map((t) => ({
|
|
19
|
-
id: t.id,
|
|
20
|
-
x: t.x,
|
|
21
|
-
y: t.y,
|
|
22
|
-
route: t.route,
|
|
23
|
-
comments: t.comments.map((c) => ({
|
|
24
|
-
id: c.id,
|
|
25
|
-
text: c.text || "",
|
|
26
|
-
createdAt: c.createdAt,
|
|
27
|
-
author: c.author
|
|
28
|
-
})),
|
|
29
|
-
version: t.version
|
|
30
|
-
}));
|
|
31
|
-
localStorage.setItem(STORAGE_KEY, JSON.stringify(cleanThreads));
|
|
32
|
-
localStorage.removeItem("apollo-threads");
|
|
33
|
-
return cleanThreads;
|
|
34
|
-
}
|
|
35
|
-
if (oldCommentsKey) {
|
|
36
|
-
const parsed = JSON.parse(oldCommentsKey);
|
|
37
|
-
const threads = parsed.map((oldComment) => ({
|
|
38
|
-
id: oldComment.id,
|
|
39
|
-
x: oldComment.x,
|
|
40
|
-
y: oldComment.y,
|
|
41
|
-
route: oldComment.route,
|
|
42
|
-
comments: [
|
|
43
|
-
{
|
|
44
|
-
id: `${oldComment.id}-comment-0`,
|
|
45
|
-
text: oldComment.text || "",
|
|
46
|
-
createdAt: oldComment.createdAt
|
|
47
|
-
}
|
|
48
|
-
]
|
|
49
|
-
}));
|
|
50
|
-
localStorage.setItem(STORAGE_KEY, JSON.stringify(threads));
|
|
51
|
-
localStorage.removeItem("apollo-comments");
|
|
52
|
-
return threads;
|
|
53
|
-
}
|
|
54
|
-
} catch (error) {
|
|
55
|
-
console.error("Failed to migrate old comments:", error);
|
|
56
|
-
}
|
|
57
|
-
return [];
|
|
58
|
-
};
|
|
59
|
-
var CommentProvider = ({ children }) => {
|
|
60
|
-
const [threads, setThreads] = React.useState(() => {
|
|
61
|
-
try {
|
|
62
|
-
const stored = localStorage.getItem(STORAGE_KEY);
|
|
63
|
-
if (stored) {
|
|
64
|
-
return JSON.parse(stored);
|
|
65
|
-
}
|
|
66
|
-
return migrateOldComments();
|
|
67
|
-
} catch (error) {
|
|
68
|
-
console.error("Failed to load threads from localStorage:", error);
|
|
69
|
-
return [];
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
const [showPins, setShowPins] = React.useState(() => {
|
|
73
|
-
try {
|
|
74
|
-
const stored = localStorage.getItem(SHOW_PINS_KEY);
|
|
75
|
-
if (stored !== null) return stored === "true";
|
|
76
|
-
const oldKey = localStorage.getItem("apollo-show-pins");
|
|
77
|
-
return oldKey === "true";
|
|
78
|
-
} catch (error) {
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
const [enableCommenting, setEnableCommenting] = React.useState(() => {
|
|
83
|
-
try {
|
|
84
|
-
const stored = localStorage.getItem(ENABLE_COMMENTING_KEY);
|
|
85
|
-
if (stored !== null) return stored === "true";
|
|
86
|
-
const oldKey = localStorage.getItem("apollo-enable-commenting");
|
|
87
|
-
return oldKey === "true";
|
|
88
|
-
} catch (error) {
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
React.useEffect(() => {
|
|
93
|
-
try {
|
|
94
|
-
localStorage.setItem(STORAGE_KEY, JSON.stringify(threads));
|
|
95
|
-
} catch (error) {
|
|
96
|
-
console.error("Failed to save threads to localStorage:", error);
|
|
97
|
-
}
|
|
98
|
-
}, [threads]);
|
|
99
|
-
React.useEffect(() => {
|
|
100
|
-
try {
|
|
101
|
-
localStorage.setItem(SHOW_PINS_KEY, String(showPins));
|
|
102
|
-
} catch (error) {
|
|
103
|
-
console.error("Failed to save showPins to localStorage:", error);
|
|
104
|
-
}
|
|
105
|
-
}, [showPins]);
|
|
106
|
-
React.useEffect(() => {
|
|
107
|
-
try {
|
|
108
|
-
localStorage.setItem(ENABLE_COMMENTING_KEY, String(enableCommenting));
|
|
109
|
-
} catch (error) {
|
|
110
|
-
console.error("Failed to save enableCommenting to localStorage:", error);
|
|
111
|
-
}
|
|
112
|
-
}, [enableCommenting]);
|
|
113
|
-
const toggleShowPins = React.useCallback(() => {
|
|
114
|
-
setShowPins((prev) => !prev);
|
|
115
|
-
}, []);
|
|
116
|
-
const toggleEnableCommenting = React.useCallback(() => {
|
|
117
|
-
setEnableCommenting((prev) => !prev);
|
|
118
|
-
}, []);
|
|
119
|
-
const addThread = React.useCallback((x, y, route, version) => {
|
|
120
|
-
const threadId = `thread-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
121
|
-
const newThread = {
|
|
122
|
-
id: threadId,
|
|
123
|
-
x,
|
|
124
|
-
y,
|
|
125
|
-
route,
|
|
126
|
-
comments: [],
|
|
127
|
-
version
|
|
128
|
-
};
|
|
129
|
-
setThreads((prev) => [...prev, newThread]);
|
|
130
|
-
return threadId;
|
|
131
|
-
}, []);
|
|
132
|
-
const addReply = React.useCallback((threadId, text) => {
|
|
133
|
-
const commentId = `${threadId}-comment-${Date.now()}`;
|
|
134
|
-
const newComment = {
|
|
135
|
-
id: commentId,
|
|
136
|
-
text,
|
|
137
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
138
|
-
};
|
|
139
|
-
setThreads(
|
|
140
|
-
(prev) => prev.map((t) => {
|
|
141
|
-
if (t.id === threadId) {
|
|
142
|
-
return {
|
|
143
|
-
...t,
|
|
144
|
-
comments: [...t.comments, newComment]
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
return t;
|
|
148
|
-
})
|
|
149
|
-
);
|
|
150
|
-
}, []);
|
|
151
|
-
const updateComment = React.useCallback((threadId, commentId, text) => {
|
|
152
|
-
setThreads(
|
|
153
|
-
(prev) => prev.map((t) => {
|
|
154
|
-
if (t.id === threadId) {
|
|
155
|
-
return {
|
|
156
|
-
...t,
|
|
157
|
-
comments: t.comments.map(
|
|
158
|
-
(c) => c.id === commentId ? { ...c, text } : c
|
|
159
|
-
)
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
return t;
|
|
163
|
-
})
|
|
164
|
-
);
|
|
165
|
-
}, []);
|
|
166
|
-
const deleteComment = React.useCallback((threadId, commentId) => {
|
|
167
|
-
setThreads(
|
|
168
|
-
(prev) => prev.map((t) => {
|
|
169
|
-
if (t.id === threadId) {
|
|
170
|
-
return {
|
|
171
|
-
...t,
|
|
172
|
-
comments: t.comments.filter((c) => c.id !== commentId)
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
return t;
|
|
176
|
-
})
|
|
177
|
-
);
|
|
178
|
-
}, []);
|
|
179
|
-
const deleteThread = React.useCallback((threadId) => {
|
|
180
|
-
setThreads((prev) => prev.filter((t) => t.id !== threadId));
|
|
181
|
-
}, []);
|
|
182
|
-
const clearAllThreads = React.useCallback(() => {
|
|
183
|
-
setThreads([]);
|
|
184
|
-
}, []);
|
|
185
|
-
const getThreadsForRoute = React.useCallback((route, version) => {
|
|
186
|
-
return threads.filter((thread) => {
|
|
187
|
-
const routeMatch = thread.route === route;
|
|
188
|
-
const threadVersion = thread.version || "3";
|
|
189
|
-
const versionMatch = !version || threadVersion === version;
|
|
190
|
-
return routeMatch && versionMatch;
|
|
191
|
-
});
|
|
192
|
-
}, [threads]);
|
|
193
|
-
const value = React.useMemo(
|
|
194
|
-
() => ({
|
|
195
|
-
threads,
|
|
196
|
-
showPins,
|
|
197
|
-
enableCommenting,
|
|
198
|
-
toggleShowPins,
|
|
199
|
-
toggleEnableCommenting,
|
|
200
|
-
addThread,
|
|
201
|
-
addReply,
|
|
202
|
-
updateComment,
|
|
203
|
-
deleteComment,
|
|
204
|
-
deleteThread,
|
|
205
|
-
clearAllThreads,
|
|
206
|
-
getThreadsForRoute
|
|
207
|
-
}),
|
|
208
|
-
[threads, showPins, enableCommenting, toggleShowPins, toggleEnableCommenting, addThread, addReply, updateComment, deleteComment, deleteThread, clearAllThreads, getThreadsForRoute]
|
|
209
|
-
);
|
|
210
|
-
return /* @__PURE__ */ jsx(CommentContext.Provider, { value, children });
|
|
211
|
-
};
|
|
212
|
-
var useComments = () => {
|
|
213
|
-
const context = React.useContext(CommentContext);
|
|
214
|
-
if (!context) {
|
|
215
|
-
throw new Error("useComments must be used within a CommentProvider");
|
|
216
|
-
}
|
|
217
|
-
return context;
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
// src/contexts/VersionContext.tsx
|
|
221
|
-
import * as React2 from "react";
|
|
222
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
223
|
-
var VersionContext = React2.createContext(void 0);
|
|
224
|
-
var VERSION_STORAGE_KEY = "hale-current-version";
|
|
225
|
-
var VersionProvider = ({ children }) => {
|
|
226
|
-
const [currentVersion, setCurrentVersionState] = React2.useState(() => {
|
|
227
|
-
try {
|
|
228
|
-
const stored = localStorage.getItem(VERSION_STORAGE_KEY);
|
|
229
|
-
return stored || "3";
|
|
230
|
-
} catch (error) {
|
|
231
|
-
console.error("Failed to load version from localStorage:", error);
|
|
232
|
-
return "3";
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
React2.useEffect(() => {
|
|
236
|
-
try {
|
|
237
|
-
localStorage.setItem(VERSION_STORAGE_KEY, currentVersion);
|
|
238
|
-
} catch (error) {
|
|
239
|
-
console.error("Failed to save version to localStorage:", error);
|
|
240
|
-
}
|
|
241
|
-
}, [currentVersion]);
|
|
242
|
-
const setCurrentVersion = React2.useCallback((version) => {
|
|
243
|
-
setCurrentVersionState(version);
|
|
244
|
-
}, []);
|
|
245
|
-
const value = React2.useMemo(
|
|
246
|
-
() => ({
|
|
247
|
-
currentVersion,
|
|
248
|
-
setCurrentVersion
|
|
249
|
-
}),
|
|
250
|
-
[currentVersion, setCurrentVersion]
|
|
251
|
-
);
|
|
252
|
-
return /* @__PURE__ */ jsx2(VersionContext.Provider, { value, children });
|
|
253
|
-
};
|
|
254
|
-
var useVersion = () => {
|
|
255
|
-
const context = React2.useContext(VersionContext);
|
|
256
|
-
if (!context) {
|
|
257
|
-
throw new Error("useVersion must be used within a VersionProvider");
|
|
258
|
-
}
|
|
259
|
-
return context;
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
// src/components/CommentPin.tsx
|
|
263
|
-
import { Button } from "@patternfly/react-core";
|
|
264
|
-
import { CommentIcon } from "@patternfly/react-icons";
|
|
265
|
-
import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
266
|
-
var CommentPin = ({
|
|
267
|
-
thread,
|
|
268
|
-
onPinClick,
|
|
269
|
-
isSelected = false
|
|
270
|
-
}) => {
|
|
271
|
-
const commentCount = thread.comments.length;
|
|
272
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
273
|
-
/* @__PURE__ */ jsx3("style", { children: `
|
|
274
|
-
@keyframes pulse {
|
|
275
|
-
0%, 100% { opacity: 1; }
|
|
276
|
-
50% { opacity: 0.5; }
|
|
277
|
-
}
|
|
278
|
-
` }),
|
|
279
|
-
/* @__PURE__ */ jsx3(
|
|
280
|
-
Button,
|
|
281
|
-
{
|
|
282
|
-
id: `comment-pin-${thread.id}`,
|
|
283
|
-
variant: "plain",
|
|
284
|
-
"aria-label": `Comment thread with ${commentCount} ${commentCount === 1 ? "comment" : "comments"}`,
|
|
285
|
-
onClick: (e) => {
|
|
286
|
-
e.stopPropagation();
|
|
287
|
-
onPinClick();
|
|
288
|
-
},
|
|
289
|
-
style: {
|
|
290
|
-
position: "absolute",
|
|
291
|
-
left: `${thread.x}px`,
|
|
292
|
-
top: `${thread.y}px`,
|
|
293
|
-
transform: "translate(-50%, -50%)",
|
|
294
|
-
width: "32px",
|
|
295
|
-
height: "32px",
|
|
296
|
-
borderRadius: "50%",
|
|
297
|
-
backgroundColor: "#C9190B",
|
|
298
|
-
color: "white",
|
|
299
|
-
border: isSelected ? "3px solid #0066CC" : "2px solid white",
|
|
300
|
-
boxShadow: isSelected ? "0 0 0 2px #0066CC, 0 4px 12px rgba(0, 0, 0, 0.4)" : "0 2px 8px rgba(0, 0, 0, 0.3)",
|
|
301
|
-
padding: 0,
|
|
302
|
-
display: "flex",
|
|
303
|
-
alignItems: "center",
|
|
304
|
-
justifyContent: "center",
|
|
305
|
-
cursor: "pointer",
|
|
306
|
-
zIndex: isSelected ? 1001 : 1e3,
|
|
307
|
-
transition: "all 0.2s ease",
|
|
308
|
-
fontSize: commentCount > 1 ? "0.7rem" : void 0
|
|
309
|
-
},
|
|
310
|
-
children: commentCount === 0 ? /* @__PURE__ */ jsx3("span", { style: { fontWeight: "bold", fontSize: "0.75rem" }, children: "0" }) : commentCount === 1 ? /* @__PURE__ */ jsx3(CommentIcon, {}) : /* @__PURE__ */ jsx3("span", { style: { fontWeight: "bold" }, children: commentCount })
|
|
311
|
-
}
|
|
312
|
-
)
|
|
313
|
-
] });
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
// src/components/CommentOverlay.tsx
|
|
317
|
-
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
318
|
-
var CommentOverlay = ({
|
|
319
|
-
selectedThreadId,
|
|
320
|
-
onThreadSelect
|
|
321
|
-
}) => {
|
|
322
|
-
const location = useLocation();
|
|
323
|
-
const { showPins, enableCommenting, addThread, getThreadsForRoute } = useComments();
|
|
324
|
-
const { currentVersion } = useVersion();
|
|
325
|
-
const overlayRef = React3.useRef(null);
|
|
326
|
-
const currentRouteThreads = React3.useMemo(
|
|
327
|
-
() => getThreadsForRoute(location.pathname, currentVersion),
|
|
328
|
-
[getThreadsForRoute, location.pathname, currentVersion]
|
|
329
|
-
);
|
|
330
|
-
const handleOverlayClick = React3.useCallback(
|
|
331
|
-
(event) => {
|
|
332
|
-
if (!enableCommenting) return;
|
|
333
|
-
if (event.target === overlayRef.current) {
|
|
334
|
-
const rect = overlayRef.current.getBoundingClientRect();
|
|
335
|
-
const x = event.clientX - rect.left;
|
|
336
|
-
const y = event.clientY - rect.top;
|
|
337
|
-
const newThreadId = addThread(x, y, location.pathname, currentVersion);
|
|
338
|
-
onThreadSelect(newThreadId);
|
|
339
|
-
}
|
|
340
|
-
},
|
|
341
|
-
[enableCommenting, addThread, location.pathname, currentVersion, onThreadSelect]
|
|
342
|
-
);
|
|
343
|
-
if (!showPins && !enableCommenting) {
|
|
344
|
-
return null;
|
|
345
|
-
}
|
|
346
|
-
return /* @__PURE__ */ jsx4(
|
|
347
|
-
"div",
|
|
348
|
-
{
|
|
349
|
-
ref: overlayRef,
|
|
350
|
-
id: "comment-overlay",
|
|
351
|
-
onClick: handleOverlayClick,
|
|
352
|
-
style: {
|
|
353
|
-
position: "absolute",
|
|
354
|
-
top: 0,
|
|
355
|
-
left: 0,
|
|
356
|
-
right: 0,
|
|
357
|
-
bottom: 0,
|
|
358
|
-
pointerEvents: enableCommenting ? "auto" : "none",
|
|
359
|
-
cursor: enableCommenting ? "crosshair" : "default",
|
|
360
|
-
zIndex: 999
|
|
361
|
-
},
|
|
362
|
-
children: showPins && currentRouteThreads.map((thread) => /* @__PURE__ */ jsx4(
|
|
363
|
-
"div",
|
|
364
|
-
{
|
|
365
|
-
style: { pointerEvents: "auto" },
|
|
366
|
-
onClick: (e) => e.stopPropagation(),
|
|
367
|
-
children: /* @__PURE__ */ jsx4(
|
|
368
|
-
CommentPin,
|
|
369
|
-
{
|
|
370
|
-
thread,
|
|
371
|
-
onPinClick: () => onThreadSelect(thread.id),
|
|
372
|
-
isSelected: thread.id === selectedThreadId
|
|
373
|
-
}
|
|
374
|
-
)
|
|
375
|
-
},
|
|
376
|
-
thread.id
|
|
377
|
-
))
|
|
378
|
-
}
|
|
379
|
-
);
|
|
380
|
-
};
|
|
381
|
-
|
|
382
|
-
// src/components/CommentDrawer.tsx
|
|
383
|
-
import * as React4 from "react";
|
|
384
|
-
import {
|
|
385
|
-
Drawer,
|
|
386
|
-
DrawerContent,
|
|
387
|
-
DrawerContentBody,
|
|
388
|
-
DrawerPanelContent,
|
|
389
|
-
DrawerHead,
|
|
390
|
-
DrawerActions,
|
|
391
|
-
DrawerCloseButton,
|
|
392
|
-
Title,
|
|
393
|
-
Button as Button2,
|
|
394
|
-
TextArea,
|
|
395
|
-
Card,
|
|
396
|
-
CardBody,
|
|
397
|
-
CardTitle,
|
|
398
|
-
EmptyState,
|
|
399
|
-
EmptyStateBody,
|
|
400
|
-
Divider,
|
|
401
|
-
ExpandableSection,
|
|
402
|
-
Alert
|
|
403
|
-
} from "@patternfly/react-core";
|
|
404
|
-
import { CommentIcon as CommentIcon2, TimesIcon, PlusCircleIcon, MagicIcon } from "@patternfly/react-icons";
|
|
405
|
-
import { useLocation as useLocation2 } from "react-router-dom";
|
|
406
|
-
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
407
|
-
var CommentDrawer = ({
|
|
408
|
-
children,
|
|
409
|
-
selectedThreadId,
|
|
410
|
-
onThreadSelect
|
|
411
|
-
}) => {
|
|
412
|
-
const location = useLocation2();
|
|
413
|
-
const {
|
|
414
|
-
getThreadsForRoute,
|
|
415
|
-
addReply,
|
|
416
|
-
updateComment,
|
|
417
|
-
deleteComment,
|
|
418
|
-
deleteThread,
|
|
419
|
-
enableCommenting
|
|
420
|
-
} = useComments();
|
|
421
|
-
const { currentVersion } = useVersion();
|
|
422
|
-
const [editingCommentId, setEditingCommentId] = React4.useState(null);
|
|
423
|
-
const [editText, setEditText] = React4.useState("");
|
|
424
|
-
const [replyText, setReplyText] = React4.useState("");
|
|
425
|
-
const replyTextAreaRef = React4.useRef(null);
|
|
426
|
-
const [threadSummaries, setThreadSummaries] = React4.useState({});
|
|
427
|
-
const [loadingSummary, setLoadingSummary] = React4.useState(false);
|
|
428
|
-
const [summaryExpanded, setSummaryExpanded] = React4.useState(true);
|
|
429
|
-
const currentRouteThreads = getThreadsForRoute(location.pathname, currentVersion);
|
|
430
|
-
const selectedThread = currentRouteThreads.find((t) => t.id === selectedThreadId);
|
|
431
|
-
const isDrawerOpen = selectedThreadId !== null && selectedThread !== void 0;
|
|
432
|
-
React4.useEffect(() => {
|
|
433
|
-
if (!isDrawerOpen || !enableCommenting) return;
|
|
434
|
-
const timer = setTimeout(() => {
|
|
435
|
-
replyTextAreaRef.current?.focus();
|
|
436
|
-
}, 100);
|
|
437
|
-
return () => clearTimeout(timer);
|
|
438
|
-
}, [isDrawerOpen, enableCommenting, selectedThreadId]);
|
|
439
|
-
const handleEdit = (commentId, text) => {
|
|
440
|
-
setEditingCommentId(commentId);
|
|
441
|
-
setEditText(text);
|
|
442
|
-
};
|
|
443
|
-
const handleSave = async (threadId, commentId) => {
|
|
444
|
-
await updateComment(threadId, commentId, editText);
|
|
445
|
-
setEditingCommentId(null);
|
|
446
|
-
};
|
|
447
|
-
const handleAddReply = async () => {
|
|
448
|
-
if (selectedThreadId && replyText.trim()) {
|
|
449
|
-
await addReply(selectedThreadId, replyText);
|
|
450
|
-
setReplyText("");
|
|
451
|
-
}
|
|
452
|
-
};
|
|
453
|
-
const handleDeleteThread = async () => {
|
|
454
|
-
if (selectedThreadId && window.confirm("Delete this entire thread and all its comments?")) {
|
|
455
|
-
await deleteThread(selectedThreadId);
|
|
456
|
-
onThreadSelect(null);
|
|
457
|
-
}
|
|
458
|
-
};
|
|
459
|
-
const handleSummarizeThread = async () => {
|
|
460
|
-
console.log("AI features not available in local-only mode");
|
|
461
|
-
};
|
|
462
|
-
const handleDeleteComment = async (threadId, commentId) => {
|
|
463
|
-
if (window.confirm("Delete this comment?")) {
|
|
464
|
-
await deleteComment(threadId, commentId);
|
|
465
|
-
}
|
|
466
|
-
};
|
|
467
|
-
const formatDate = (isoDate) => {
|
|
468
|
-
const date = new Date(isoDate);
|
|
469
|
-
return date.toLocaleString(void 0, {
|
|
470
|
-
month: "short",
|
|
471
|
-
day: "numeric",
|
|
472
|
-
hour: "2-digit",
|
|
473
|
-
minute: "2-digit"
|
|
474
|
-
});
|
|
475
|
-
};
|
|
476
|
-
const panelContent = /* @__PURE__ */ jsxs2(DrawerPanelContent, { isResizable: true, defaultSize: "400px", minSize: "300px", children: [
|
|
477
|
-
/* @__PURE__ */ jsxs2(DrawerHead, { children: [
|
|
478
|
-
/* @__PURE__ */ jsx5("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", flex: 1 }, children: /* @__PURE__ */ jsxs2(Title, { headingLevel: "h2", size: "xl", children: [
|
|
479
|
-
/* @__PURE__ */ jsx5(CommentIcon2, { style: { marginRight: "0.5rem", color: "#C9190B" } }),
|
|
480
|
-
"Thread"
|
|
481
|
-
] }) }),
|
|
482
|
-
/* @__PURE__ */ jsx5(DrawerActions, { children: /* @__PURE__ */ jsx5(DrawerCloseButton, { onClick: () => onThreadSelect(null) }) })
|
|
483
|
-
] }),
|
|
484
|
-
/* @__PURE__ */ jsx5(DrawerContentBody, { style: { padding: "1rem" }, children: !selectedThread ? /* @__PURE__ */ jsxs2(EmptyState, { children: [
|
|
485
|
-
/* @__PURE__ */ jsx5(CommentIcon2, { style: { fontSize: "3rem", color: "var(--pf-v6-global--Color--200)", marginBottom: "1rem" } }),
|
|
486
|
-
/* @__PURE__ */ jsx5(Title, { headingLevel: "h3", size: "lg", children: "No thread selected" }),
|
|
487
|
-
/* @__PURE__ */ jsx5(EmptyStateBody, { children: "Click a pin to view its comments." })
|
|
488
|
-
] }) : /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
|
|
489
|
-
/* @__PURE__ */ jsx5(Card, { isCompact: true, children: /* @__PURE__ */ jsxs2(CardBody, { children: [
|
|
490
|
-
/* @__PURE__ */ jsxs2("div", { style: { fontSize: "0.875rem", marginBottom: "0.5rem" }, children: [
|
|
491
|
-
/* @__PURE__ */ jsx5("strong", { children: "Location:" }),
|
|
492
|
-
" (",
|
|
493
|
-
Math.round(selectedThread.x),
|
|
494
|
-
", ",
|
|
495
|
-
Math.round(selectedThread.y),
|
|
496
|
-
")"
|
|
497
|
-
] }),
|
|
498
|
-
selectedThread.version && /* @__PURE__ */ jsxs2("div", { style: { fontSize: "0.875rem", marginBottom: "0.5rem" }, children: [
|
|
499
|
-
/* @__PURE__ */ jsx5("strong", { children: "Version:" }),
|
|
500
|
-
" ",
|
|
501
|
-
selectedThread.version
|
|
502
|
-
] }),
|
|
503
|
-
/* @__PURE__ */ jsxs2("div", { style: { fontSize: "0.875rem", marginBottom: "0.5rem" }, children: [
|
|
504
|
-
/* @__PURE__ */ jsx5("strong", { children: "Comments:" }),
|
|
505
|
-
" ",
|
|
506
|
-
selectedThread.comments.length
|
|
507
|
-
] }),
|
|
508
|
-
selectedThread.comments.length > 0 && /* @__PURE__ */ jsx5(
|
|
509
|
-
Button2,
|
|
510
|
-
{
|
|
511
|
-
id: `ai-summarize-thread-${selectedThread.id}`,
|
|
512
|
-
variant: "secondary",
|
|
513
|
-
size: "sm",
|
|
514
|
-
icon: /* @__PURE__ */ jsx5(MagicIcon, {}),
|
|
515
|
-
onClick: handleSummarizeThread,
|
|
516
|
-
isLoading: loadingSummary,
|
|
517
|
-
isDisabled: loadingSummary,
|
|
518
|
-
style: { marginTop: "0.5rem" },
|
|
519
|
-
children: loadingSummary ? "Generating..." : "AI Summarize Thread"
|
|
520
|
-
}
|
|
521
|
-
),
|
|
522
|
-
enableCommenting && /* @__PURE__ */ jsx5(
|
|
523
|
-
Button2,
|
|
524
|
-
{
|
|
525
|
-
id: `delete-thread-${selectedThread.id}`,
|
|
526
|
-
variant: "danger",
|
|
527
|
-
size: "sm",
|
|
528
|
-
icon: /* @__PURE__ */ jsx5(TimesIcon, {}),
|
|
529
|
-
onClick: handleDeleteThread,
|
|
530
|
-
style: { marginTop: "0.5rem", marginLeft: selectedThread.comments.length > 0 ? "0.5rem" : "0" },
|
|
531
|
-
children: "Delete Thread"
|
|
532
|
-
}
|
|
533
|
-
)
|
|
534
|
-
] }) }),
|
|
535
|
-
threadSummaries[selectedThread.id] && /* @__PURE__ */ jsx5(
|
|
536
|
-
Alert,
|
|
537
|
-
{
|
|
538
|
-
variant: "info",
|
|
539
|
-
isInline: true,
|
|
540
|
-
title: "AI Summary",
|
|
541
|
-
actionClose: /* @__PURE__ */ jsx5(
|
|
542
|
-
Button2,
|
|
543
|
-
{
|
|
544
|
-
variant: "plain",
|
|
545
|
-
onClick: () => {
|
|
546
|
-
const newSummaries = { ...threadSummaries };
|
|
547
|
-
delete newSummaries[selectedThread.id];
|
|
548
|
-
setThreadSummaries(newSummaries);
|
|
549
|
-
},
|
|
550
|
-
"aria-label": "Clear summary",
|
|
551
|
-
children: /* @__PURE__ */ jsx5(TimesIcon, {})
|
|
552
|
-
}
|
|
553
|
-
),
|
|
554
|
-
children: /* @__PURE__ */ jsx5(
|
|
555
|
-
ExpandableSection,
|
|
556
|
-
{
|
|
557
|
-
toggleText: summaryExpanded ? "Hide summary" : "Show summary",
|
|
558
|
-
onToggle: (_event, isExpanded) => setSummaryExpanded(isExpanded),
|
|
559
|
-
isExpanded: summaryExpanded,
|
|
560
|
-
isIndented: true,
|
|
561
|
-
children: /* @__PURE__ */ jsx5("div", { style: { fontSize: "0.875rem", lineHeight: "1.5" }, children: threadSummaries[selectedThread.id] })
|
|
562
|
-
}
|
|
563
|
-
)
|
|
564
|
-
}
|
|
565
|
-
),
|
|
566
|
-
/* @__PURE__ */ jsx5(Divider, {}),
|
|
567
|
-
/* @__PURE__ */ jsx5("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: selectedThread.comments.length === 0 ? /* @__PURE__ */ jsxs2(EmptyState, { children: [
|
|
568
|
-
/* @__PURE__ */ jsx5(Title, { headingLevel: "h4", size: "md", children: "No comments yet" }),
|
|
569
|
-
/* @__PURE__ */ jsx5(EmptyStateBody, { children: enableCommenting ? "Add a reply below to start the conversation." : "Enable commenting to add replies." })
|
|
570
|
-
] }) : selectedThread.comments.map((comment, index) => /* @__PURE__ */ jsxs2(Card, { isCompact: true, children: [
|
|
571
|
-
/* @__PURE__ */ jsxs2(CardTitle, { children: [
|
|
572
|
-
"Comment #",
|
|
573
|
-
index + 1,
|
|
574
|
-
/* @__PURE__ */ jsxs2("div", { style: { fontSize: "0.75rem", color: "var(--pf-v6-global--Color--200)", fontWeight: "normal" }, children: [
|
|
575
|
-
comment.author && /* @__PURE__ */ jsxs2("span", { style: { marginRight: "0.5rem" }, children: [
|
|
576
|
-
"@",
|
|
577
|
-
comment.author
|
|
578
|
-
] }),
|
|
579
|
-
formatDate(comment.createdAt)
|
|
580
|
-
] })
|
|
581
|
-
] }),
|
|
582
|
-
/* @__PURE__ */ jsx5(CardBody, { children: editingCommentId === comment.id ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
583
|
-
/* @__PURE__ */ jsx5(
|
|
584
|
-
TextArea,
|
|
585
|
-
{
|
|
586
|
-
id: `edit-comment-${comment.id}`,
|
|
587
|
-
value: editText,
|
|
588
|
-
onChange: (_event, value) => setEditText(value),
|
|
589
|
-
rows: 3,
|
|
590
|
-
style: { marginBottom: "0.5rem" },
|
|
591
|
-
onKeyDown: (e) => {
|
|
592
|
-
if (e.key === "Enter" && !e.shiftKey) {
|
|
593
|
-
e.preventDefault();
|
|
594
|
-
handleSave(selectedThread.id, comment.id);
|
|
595
|
-
}
|
|
596
|
-
if (e.key === "Escape") {
|
|
597
|
-
setEditingCommentId(null);
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
),
|
|
602
|
-
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "0.5rem" }, children: [
|
|
603
|
-
/* @__PURE__ */ jsx5(
|
|
604
|
-
Button2,
|
|
605
|
-
{
|
|
606
|
-
id: `save-comment-${comment.id}`,
|
|
607
|
-
variant: "primary",
|
|
608
|
-
size: "sm",
|
|
609
|
-
onClick: () => handleSave(selectedThread.id, comment.id),
|
|
610
|
-
children: "Save"
|
|
611
|
-
}
|
|
612
|
-
),
|
|
613
|
-
/* @__PURE__ */ jsx5(
|
|
614
|
-
Button2,
|
|
615
|
-
{
|
|
616
|
-
id: `cancel-edit-${comment.id}`,
|
|
617
|
-
variant: "link",
|
|
618
|
-
size: "sm",
|
|
619
|
-
onClick: () => setEditingCommentId(null),
|
|
620
|
-
children: "Cancel"
|
|
621
|
-
}
|
|
622
|
-
)
|
|
623
|
-
] })
|
|
624
|
-
] }) : /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
625
|
-
/* @__PURE__ */ jsx5("div", { style: { marginBottom: "0.75rem", whiteSpace: "pre-wrap" }, children: comment.text || /* @__PURE__ */ jsx5("em", { style: { color: "var(--pf-v6-global--Color--200)" }, children: "No text" }) }),
|
|
626
|
-
enableCommenting && /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "0.5rem" }, children: [
|
|
627
|
-
/* @__PURE__ */ jsx5(
|
|
628
|
-
Button2,
|
|
629
|
-
{
|
|
630
|
-
id: `edit-comment-btn-${comment.id}`,
|
|
631
|
-
variant: "secondary",
|
|
632
|
-
size: "sm",
|
|
633
|
-
onClick: () => handleEdit(comment.id, comment.text),
|
|
634
|
-
children: "Edit"
|
|
635
|
-
}
|
|
636
|
-
),
|
|
637
|
-
/* @__PURE__ */ jsx5(
|
|
638
|
-
Button2,
|
|
639
|
-
{
|
|
640
|
-
id: `delete-comment-btn-${comment.id}`,
|
|
641
|
-
variant: "danger",
|
|
642
|
-
size: "sm",
|
|
643
|
-
icon: /* @__PURE__ */ jsx5(TimesIcon, {}),
|
|
644
|
-
onClick: () => handleDeleteComment(selectedThread.id, comment.id),
|
|
645
|
-
children: "Delete"
|
|
646
|
-
}
|
|
647
|
-
)
|
|
648
|
-
] })
|
|
649
|
-
] }) })
|
|
650
|
-
] }, comment.id)) }),
|
|
651
|
-
enableCommenting && /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
652
|
-
/* @__PURE__ */ jsx5(Divider, {}),
|
|
653
|
-
/* @__PURE__ */ jsxs2(Card, { isCompact: true, children: [
|
|
654
|
-
/* @__PURE__ */ jsxs2(CardTitle, { children: [
|
|
655
|
-
/* @__PURE__ */ jsx5(PlusCircleIcon, { style: { marginRight: "0.5rem" } }),
|
|
656
|
-
"Add Reply"
|
|
657
|
-
] }),
|
|
658
|
-
/* @__PURE__ */ jsxs2(CardBody, { children: [
|
|
659
|
-
/* @__PURE__ */ jsx5(
|
|
660
|
-
TextArea,
|
|
661
|
-
{
|
|
662
|
-
ref: replyTextAreaRef,
|
|
663
|
-
id: `reply-textarea-${selectedThread.id}`,
|
|
664
|
-
value: replyText,
|
|
665
|
-
onChange: (_event, value) => setReplyText(value),
|
|
666
|
-
placeholder: "Enter your reply...",
|
|
667
|
-
rows: 3,
|
|
668
|
-
style: { marginBottom: "0.5rem" },
|
|
669
|
-
onKeyDown: (e) => {
|
|
670
|
-
if (e.key === "Enter" && !e.shiftKey) {
|
|
671
|
-
e.preventDefault();
|
|
672
|
-
handleAddReply();
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
),
|
|
677
|
-
/* @__PURE__ */ jsx5(
|
|
678
|
-
Button2,
|
|
679
|
-
{
|
|
680
|
-
id: `add-reply-${selectedThread.id}`,
|
|
681
|
-
variant: "primary",
|
|
682
|
-
size: "sm",
|
|
683
|
-
onClick: handleAddReply,
|
|
684
|
-
isDisabled: !replyText.trim(),
|
|
685
|
-
children: "Add Reply"
|
|
686
|
-
}
|
|
687
|
-
)
|
|
688
|
-
] })
|
|
689
|
-
] })
|
|
690
|
-
] })
|
|
691
|
-
] }) })
|
|
692
|
-
] });
|
|
693
|
-
return /* @__PURE__ */ jsx5(Drawer, { isExpanded: isDrawerOpen, isInline: true, position: "right", children: /* @__PURE__ */ jsx5(DrawerContent, { panelContent, children: /* @__PURE__ */ jsx5(DrawerContentBody, { children }) }) });
|
|
694
|
-
};
|
|
695
|
-
|
|
696
|
-
// src/contexts/GitHubAuthContext.tsx
|
|
697
|
-
import * as React5 from "react";
|
|
698
|
-
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
699
|
-
var GitHubAuthContext = React5.createContext(void 0);
|
|
700
|
-
var GitHubAuthProvider = ({ children }) => {
|
|
701
|
-
const value = {
|
|
702
|
-
user: null,
|
|
703
|
-
isAuthenticated: false,
|
|
704
|
-
login: () => {
|
|
705
|
-
console.log("GitHub login not available in local mode");
|
|
706
|
-
},
|
|
707
|
-
logout: () => {
|
|
708
|
-
console.log("GitHub logout not available in local mode");
|
|
709
|
-
}
|
|
710
|
-
};
|
|
711
|
-
return /* @__PURE__ */ jsx6(GitHubAuthContext.Provider, { value, children });
|
|
712
|
-
};
|
|
713
|
-
var useGitHubAuth = () => {
|
|
714
|
-
const context = React5.useContext(GitHubAuthContext);
|
|
715
|
-
if (context === void 0) {
|
|
716
|
-
throw new Error("useGitHubAuth must be used within a GitHubAuthProvider");
|
|
717
|
-
}
|
|
718
|
-
return context;
|
|
719
|
-
};
|
|
720
|
-
|
|
721
|
-
// src/contexts/GitLabAuthContext.tsx
|
|
722
|
-
import * as React6 from "react";
|
|
723
|
-
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
724
|
-
var GitLabAuthContext = React6.createContext(void 0);
|
|
725
|
-
var GitLabAuthProvider = ({ children }) => {
|
|
726
|
-
const value = {
|
|
727
|
-
user: null,
|
|
728
|
-
isAuthenticated: false,
|
|
729
|
-
login: () => {
|
|
730
|
-
console.log("GitLab login not available in local mode");
|
|
731
|
-
},
|
|
732
|
-
logout: () => {
|
|
733
|
-
console.log("GitLab logout not available in local mode");
|
|
734
|
-
},
|
|
735
|
-
getToken: () => null
|
|
736
|
-
};
|
|
737
|
-
return /* @__PURE__ */ jsx7(GitLabAuthContext.Provider, { value, children });
|
|
738
|
-
};
|
|
739
|
-
var useGitLabAuth = () => {
|
|
740
|
-
const ctx = React6.useContext(GitLabAuthContext);
|
|
741
|
-
if (!ctx) {
|
|
742
|
-
throw new Error("useGitLabAuth must be used within a GitLabAuthProvider");
|
|
743
|
-
}
|
|
744
|
-
return ctx;
|
|
745
|
-
};
|
|
746
|
-
export {
|
|
747
|
-
CommentDrawer,
|
|
748
|
-
CommentOverlay,
|
|
749
|
-
CommentPin,
|
|
750
|
-
CommentProvider,
|
|
751
|
-
GitHubAuthProvider,
|
|
752
|
-
GitLabAuthProvider,
|
|
753
|
-
VersionProvider,
|
|
754
|
-
useComments,
|
|
755
|
-
useGitHubAuth,
|
|
756
|
-
useGitLabAuth,
|
|
757
|
-
useVersion
|
|
758
|
-
};
|
|
759
|
-
//# sourceMappingURL=index.mjs.map
|