hale-commenting-system 2.0.1 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -11
- package/cli/dist/index.js +49 -39
- package/cli/dist/index.js.map +1 -1
- package/dist/index.js +94 -97
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +78 -81
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -426,39 +426,11 @@ var CommentOverlay = ({
|
|
|
426
426
|
};
|
|
427
427
|
|
|
428
428
|
// src/components/CommentDrawer.tsx
|
|
429
|
-
var
|
|
429
|
+
var React4 = __toESM(require("react"));
|
|
430
430
|
var import_react_core2 = require("@patternfly/react-core");
|
|
431
431
|
var import_react_icons2 = require("@patternfly/react-icons");
|
|
432
432
|
var import_react_router_dom2 = require("react-router-dom");
|
|
433
|
-
|
|
434
|
-
// src/contexts/GitLabAuthContext.tsx
|
|
435
|
-
var React4 = __toESM(require("react"));
|
|
436
433
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
437
|
-
var GitLabAuthContext = React4.createContext(void 0);
|
|
438
|
-
var GitLabAuthProvider = ({ children }) => {
|
|
439
|
-
const value = {
|
|
440
|
-
user: null,
|
|
441
|
-
isAuthenticated: false,
|
|
442
|
-
login: () => {
|
|
443
|
-
console.log("GitLab login not available in local mode");
|
|
444
|
-
},
|
|
445
|
-
logout: () => {
|
|
446
|
-
console.log("GitLab logout not available in local mode");
|
|
447
|
-
},
|
|
448
|
-
getToken: () => null
|
|
449
|
-
};
|
|
450
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(GitLabAuthContext.Provider, { value, children });
|
|
451
|
-
};
|
|
452
|
-
var useGitLabAuth = () => {
|
|
453
|
-
const ctx = React4.useContext(GitLabAuthContext);
|
|
454
|
-
if (!ctx) {
|
|
455
|
-
throw new Error("useGitLabAuth must be used within a GitLabAuthProvider");
|
|
456
|
-
}
|
|
457
|
-
return ctx;
|
|
458
|
-
};
|
|
459
|
-
|
|
460
|
-
// src/components/CommentDrawer.tsx
|
|
461
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
462
434
|
var CommentDrawer = ({
|
|
463
435
|
children,
|
|
464
436
|
selectedThreadId,
|
|
@@ -474,18 +446,17 @@ var CommentDrawer = ({
|
|
|
474
446
|
enableCommenting
|
|
475
447
|
} = useComments();
|
|
476
448
|
const { currentVersion } = useVersion();
|
|
477
|
-
const
|
|
478
|
-
const [
|
|
479
|
-
const [
|
|
480
|
-
const
|
|
481
|
-
const
|
|
482
|
-
const [
|
|
483
|
-
const [
|
|
484
|
-
const [summaryExpanded, setSummaryExpanded] = React5.useState(true);
|
|
449
|
+
const [editingCommentId, setEditingCommentId] = React4.useState(null);
|
|
450
|
+
const [editText, setEditText] = React4.useState("");
|
|
451
|
+
const [replyText, setReplyText] = React4.useState("");
|
|
452
|
+
const replyTextAreaRef = React4.useRef(null);
|
|
453
|
+
const [threadSummaries, setThreadSummaries] = React4.useState({});
|
|
454
|
+
const [loadingSummary, setLoadingSummary] = React4.useState(false);
|
|
455
|
+
const [summaryExpanded, setSummaryExpanded] = React4.useState(true);
|
|
485
456
|
const currentRouteThreads = getThreadsForRoute(location.pathname, currentVersion);
|
|
486
457
|
const selectedThread = currentRouteThreads.find((t) => t.id === selectedThreadId);
|
|
487
458
|
const isDrawerOpen = selectedThreadId !== null && selectedThread !== void 0;
|
|
488
|
-
|
|
459
|
+
React4.useEffect(() => {
|
|
489
460
|
if (!isDrawerOpen || !enableCommenting) return;
|
|
490
461
|
const timer = setTimeout(() => {
|
|
491
462
|
replyTextAreaRef.current?.focus();
|
|
@@ -529,45 +500,45 @@ var CommentDrawer = ({
|
|
|
529
500
|
minute: "2-digit"
|
|
530
501
|
});
|
|
531
502
|
};
|
|
532
|
-
const panelContent = /* @__PURE__ */ (0,
|
|
533
|
-
/* @__PURE__ */ (0,
|
|
534
|
-
/* @__PURE__ */ (0,
|
|
535
|
-
/* @__PURE__ */ (0,
|
|
503
|
+
const panelContent = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_core2.DrawerPanelContent, { isResizable: true, defaultSize: "400px", minSize: "300px", children: [
|
|
504
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_core2.DrawerHead, { children: [
|
|
505
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_core2.Title, { headingLevel: "h2", size: "xl", children: [
|
|
506
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_icons2.CommentIcon, { style: { marginRight: "0.5rem", color: "#C9190B" } }),
|
|
536
507
|
"Thread"
|
|
537
508
|
] }) }),
|
|
538
|
-
/* @__PURE__ */ (0,
|
|
509
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core2.DrawerActions, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core2.DrawerCloseButton, { onClick: () => onThreadSelect(null) }) })
|
|
539
510
|
] }),
|
|
540
|
-
/* @__PURE__ */ (0,
|
|
541
|
-
/* @__PURE__ */ (0,
|
|
542
|
-
/* @__PURE__ */ (0,
|
|
543
|
-
/* @__PURE__ */ (0,
|
|
544
|
-
] }) : /* @__PURE__ */ (0,
|
|
545
|
-
/* @__PURE__ */ (0,
|
|
546
|
-
/* @__PURE__ */ (0,
|
|
547
|
-
/* @__PURE__ */ (0,
|
|
511
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core2.DrawerContentBody, { style: { padding: "1rem" }, children: !selectedThread ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_core2.EmptyState, { children: [
|
|
512
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_icons2.CommentIcon, { style: { fontSize: "3rem", color: "var(--pf-v6-global--Color--200)", marginBottom: "1rem" } }),
|
|
513
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core2.Title, { headingLevel: "h3", size: "lg", children: "No thread selected" }),
|
|
514
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core2.EmptyStateBody, { children: "Click a pin to view its comments." })
|
|
515
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
|
|
516
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core2.Card, { isCompact: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_core2.CardBody, { children: [
|
|
517
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { fontSize: "0.875rem", marginBottom: "0.5rem" }, children: [
|
|
518
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: "Location:" }),
|
|
548
519
|
" (",
|
|
549
520
|
Math.round(selectedThread.x),
|
|
550
521
|
", ",
|
|
551
522
|
Math.round(selectedThread.y),
|
|
552
523
|
")"
|
|
553
524
|
] }),
|
|
554
|
-
selectedThread.version && /* @__PURE__ */ (0,
|
|
555
|
-
/* @__PURE__ */ (0,
|
|
525
|
+
selectedThread.version && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { fontSize: "0.875rem", marginBottom: "0.5rem" }, children: [
|
|
526
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: "Version:" }),
|
|
556
527
|
" ",
|
|
557
528
|
selectedThread.version
|
|
558
529
|
] }),
|
|
559
|
-
/* @__PURE__ */ (0,
|
|
560
|
-
/* @__PURE__ */ (0,
|
|
530
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { fontSize: "0.875rem", marginBottom: "0.5rem" }, children: [
|
|
531
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: "Comments:" }),
|
|
561
532
|
" ",
|
|
562
533
|
selectedThread.comments.length
|
|
563
534
|
] }),
|
|
564
|
-
selectedThread.comments.length > 0 && /* @__PURE__ */ (0,
|
|
535
|
+
selectedThread.comments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
565
536
|
import_react_core2.Button,
|
|
566
537
|
{
|
|
567
538
|
id: `ai-summarize-thread-${selectedThread.id}`,
|
|
568
539
|
variant: "secondary",
|
|
569
540
|
size: "sm",
|
|
570
|
-
icon: /* @__PURE__ */ (0,
|
|
541
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_icons2.MagicIcon, {}),
|
|
571
542
|
onClick: handleSummarizeThread,
|
|
572
543
|
isLoading: loadingSummary,
|
|
573
544
|
isDisabled: loadingSummary,
|
|
@@ -575,26 +546,26 @@ var CommentDrawer = ({
|
|
|
575
546
|
children: loadingSummary ? "Generating..." : "AI Summarize Thread"
|
|
576
547
|
}
|
|
577
548
|
),
|
|
578
|
-
enableCommenting && /* @__PURE__ */ (0,
|
|
549
|
+
enableCommenting && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
579
550
|
import_react_core2.Button,
|
|
580
551
|
{
|
|
581
552
|
id: `delete-thread-${selectedThread.id}`,
|
|
582
553
|
variant: "danger",
|
|
583
554
|
size: "sm",
|
|
584
|
-
icon: /* @__PURE__ */ (0,
|
|
555
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_icons2.TimesIcon, {}),
|
|
585
556
|
onClick: handleDeleteThread,
|
|
586
557
|
style: { marginTop: "0.5rem", marginLeft: selectedThread.comments.length > 0 ? "0.5rem" : "0" },
|
|
587
558
|
children: "Delete Thread"
|
|
588
559
|
}
|
|
589
560
|
)
|
|
590
561
|
] }) }),
|
|
591
|
-
threadSummaries[selectedThread.id] && /* @__PURE__ */ (0,
|
|
562
|
+
threadSummaries[selectedThread.id] && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
592
563
|
import_react_core2.Alert,
|
|
593
564
|
{
|
|
594
565
|
variant: "info",
|
|
595
566
|
isInline: true,
|
|
596
567
|
title: "AI Summary",
|
|
597
|
-
actionClose: /* @__PURE__ */ (0,
|
|
568
|
+
actionClose: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
598
569
|
import_react_core2.Button,
|
|
599
570
|
{
|
|
600
571
|
variant: "plain",
|
|
@@ -604,39 +575,39 @@ var CommentDrawer = ({
|
|
|
604
575
|
setThreadSummaries(newSummaries);
|
|
605
576
|
},
|
|
606
577
|
"aria-label": "Clear summary",
|
|
607
|
-
children: /* @__PURE__ */ (0,
|
|
578
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_icons2.TimesIcon, {})
|
|
608
579
|
}
|
|
609
580
|
),
|
|
610
|
-
children: /* @__PURE__ */ (0,
|
|
581
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
611
582
|
import_react_core2.ExpandableSection,
|
|
612
583
|
{
|
|
613
584
|
toggleText: summaryExpanded ? "Hide summary" : "Show summary",
|
|
614
585
|
onToggle: (_event, isExpanded) => setSummaryExpanded(isExpanded),
|
|
615
586
|
isExpanded: summaryExpanded,
|
|
616
587
|
isIndented: true,
|
|
617
|
-
children: /* @__PURE__ */ (0,
|
|
588
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { fontSize: "0.875rem", lineHeight: "1.5" }, children: threadSummaries[selectedThread.id] })
|
|
618
589
|
}
|
|
619
590
|
)
|
|
620
591
|
}
|
|
621
592
|
),
|
|
622
|
-
/* @__PURE__ */ (0,
|
|
623
|
-
/* @__PURE__ */ (0,
|
|
624
|
-
/* @__PURE__ */ (0,
|
|
625
|
-
/* @__PURE__ */ (0,
|
|
626
|
-
] }) : selectedThread.comments.map((comment, index) => /* @__PURE__ */ (0,
|
|
627
|
-
/* @__PURE__ */ (0,
|
|
593
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core2.Divider, {}),
|
|
594
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: selectedThread.comments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_core2.EmptyState, { children: [
|
|
595
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core2.Title, { headingLevel: "h4", size: "md", children: "No comments yet" }),
|
|
596
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core2.EmptyStateBody, { children: enableCommenting ? "Add a reply below to start the conversation." : "Enable commenting to add replies." })
|
|
597
|
+
] }) : selectedThread.comments.map((comment, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_core2.Card, { isCompact: true, children: [
|
|
598
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_core2.CardTitle, { children: [
|
|
628
599
|
"Comment #",
|
|
629
600
|
index + 1,
|
|
630
|
-
/* @__PURE__ */ (0,
|
|
631
|
-
comment.author && /* @__PURE__ */ (0,
|
|
601
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { fontSize: "0.75rem", color: "var(--pf-v6-global--Color--200)", fontWeight: "normal" }, children: [
|
|
602
|
+
comment.author && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { style: { marginRight: "0.5rem" }, children: [
|
|
632
603
|
"@",
|
|
633
604
|
comment.author
|
|
634
605
|
] }),
|
|
635
606
|
formatDate(comment.createdAt)
|
|
636
607
|
] })
|
|
637
608
|
] }),
|
|
638
|
-
/* @__PURE__ */ (0,
|
|
639
|
-
/* @__PURE__ */ (0,
|
|
609
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core2.CardBody, { children: editingCommentId === comment.id ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
610
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
640
611
|
import_react_core2.TextArea,
|
|
641
612
|
{
|
|
642
613
|
id: `edit-comment-${comment.id}`,
|
|
@@ -655,8 +626,8 @@ var CommentDrawer = ({
|
|
|
655
626
|
}
|
|
656
627
|
}
|
|
657
628
|
),
|
|
658
|
-
/* @__PURE__ */ (0,
|
|
659
|
-
/* @__PURE__ */ (0,
|
|
629
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", gap: "0.5rem" }, children: [
|
|
630
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
660
631
|
import_react_core2.Button,
|
|
661
632
|
{
|
|
662
633
|
id: `save-comment-${comment.id}`,
|
|
@@ -666,7 +637,7 @@ var CommentDrawer = ({
|
|
|
666
637
|
children: "Save"
|
|
667
638
|
}
|
|
668
639
|
),
|
|
669
|
-
/* @__PURE__ */ (0,
|
|
640
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
670
641
|
import_react_core2.Button,
|
|
671
642
|
{
|
|
672
643
|
id: `cancel-edit-${comment.id}`,
|
|
@@ -677,10 +648,10 @@ var CommentDrawer = ({
|
|
|
677
648
|
}
|
|
678
649
|
)
|
|
679
650
|
] })
|
|
680
|
-
] }) : /* @__PURE__ */ (0,
|
|
681
|
-
/* @__PURE__ */ (0,
|
|
682
|
-
enableCommenting && /* @__PURE__ */ (0,
|
|
683
|
-
/* @__PURE__ */ (0,
|
|
651
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
652
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { marginBottom: "0.75rem", whiteSpace: "pre-wrap" }, children: comment.text || /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("em", { style: { color: "var(--pf-v6-global--Color--200)" }, children: "No text" }) }),
|
|
653
|
+
enableCommenting && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", gap: "0.5rem" }, children: [
|
|
654
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
684
655
|
import_react_core2.Button,
|
|
685
656
|
{
|
|
686
657
|
id: `edit-comment-btn-${comment.id}`,
|
|
@@ -690,13 +661,13 @@ var CommentDrawer = ({
|
|
|
690
661
|
children: "Edit"
|
|
691
662
|
}
|
|
692
663
|
),
|
|
693
|
-
/* @__PURE__ */ (0,
|
|
664
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
694
665
|
import_react_core2.Button,
|
|
695
666
|
{
|
|
696
667
|
id: `delete-comment-btn-${comment.id}`,
|
|
697
668
|
variant: "danger",
|
|
698
669
|
size: "sm",
|
|
699
|
-
icon: /* @__PURE__ */ (0,
|
|
670
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_icons2.TimesIcon, {}),
|
|
700
671
|
onClick: () => handleDeleteComment(selectedThread.id, comment.id),
|
|
701
672
|
children: "Delete"
|
|
702
673
|
}
|
|
@@ -704,15 +675,15 @@ var CommentDrawer = ({
|
|
|
704
675
|
] })
|
|
705
676
|
] }) })
|
|
706
677
|
] }, comment.id)) }),
|
|
707
|
-
enableCommenting && /* @__PURE__ */ (0,
|
|
708
|
-
/* @__PURE__ */ (0,
|
|
709
|
-
/* @__PURE__ */ (0,
|
|
710
|
-
/* @__PURE__ */ (0,
|
|
711
|
-
/* @__PURE__ */ (0,
|
|
678
|
+
enableCommenting && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
679
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core2.Divider, {}),
|
|
680
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_core2.Card, { isCompact: true, children: [
|
|
681
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_core2.CardTitle, { children: [
|
|
682
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_icons2.PlusCircleIcon, { style: { marginRight: "0.5rem" } }),
|
|
712
683
|
"Add Reply"
|
|
713
684
|
] }),
|
|
714
|
-
/* @__PURE__ */ (0,
|
|
715
|
-
/* @__PURE__ */ (0,
|
|
685
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_core2.CardBody, { children: [
|
|
686
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
716
687
|
import_react_core2.TextArea,
|
|
717
688
|
{
|
|
718
689
|
ref: replyTextAreaRef,
|
|
@@ -730,7 +701,7 @@ var CommentDrawer = ({
|
|
|
730
701
|
}
|
|
731
702
|
}
|
|
732
703
|
),
|
|
733
|
-
/* @__PURE__ */ (0,
|
|
704
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
734
705
|
import_react_core2.Button,
|
|
735
706
|
{
|
|
736
707
|
id: `add-reply-${selectedThread.id}`,
|
|
@@ -746,13 +717,13 @@ var CommentDrawer = ({
|
|
|
746
717
|
] })
|
|
747
718
|
] }) })
|
|
748
719
|
] });
|
|
749
|
-
return /* @__PURE__ */ (0,
|
|
720
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core2.Drawer, { isExpanded: isDrawerOpen, isInline: true, position: "right", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core2.DrawerContent, { panelContent, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core2.DrawerContentBody, { children }) }) });
|
|
750
721
|
};
|
|
751
722
|
|
|
752
723
|
// src/contexts/GitHubAuthContext.tsx
|
|
753
|
-
var
|
|
754
|
-
var
|
|
755
|
-
var GitHubAuthContext =
|
|
724
|
+
var React5 = __toESM(require("react"));
|
|
725
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
726
|
+
var GitHubAuthContext = React5.createContext(void 0);
|
|
756
727
|
var GitHubAuthProvider = ({ children }) => {
|
|
757
728
|
const value = {
|
|
758
729
|
user: null,
|
|
@@ -764,15 +735,41 @@ var GitHubAuthProvider = ({ children }) => {
|
|
|
764
735
|
console.log("GitHub logout not available in local mode");
|
|
765
736
|
}
|
|
766
737
|
};
|
|
767
|
-
return /* @__PURE__ */ (0,
|
|
738
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(GitHubAuthContext.Provider, { value, children });
|
|
768
739
|
};
|
|
769
740
|
var useGitHubAuth = () => {
|
|
770
|
-
const context =
|
|
741
|
+
const context = React5.useContext(GitHubAuthContext);
|
|
771
742
|
if (context === void 0) {
|
|
772
743
|
throw new Error("useGitHubAuth must be used within a GitHubAuthProvider");
|
|
773
744
|
}
|
|
774
745
|
return context;
|
|
775
746
|
};
|
|
747
|
+
|
|
748
|
+
// src/contexts/GitLabAuthContext.tsx
|
|
749
|
+
var React6 = __toESM(require("react"));
|
|
750
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
751
|
+
var GitLabAuthContext = React6.createContext(void 0);
|
|
752
|
+
var GitLabAuthProvider = ({ children }) => {
|
|
753
|
+
const value = {
|
|
754
|
+
user: null,
|
|
755
|
+
isAuthenticated: false,
|
|
756
|
+
login: () => {
|
|
757
|
+
console.log("GitLab login not available in local mode");
|
|
758
|
+
},
|
|
759
|
+
logout: () => {
|
|
760
|
+
console.log("GitLab logout not available in local mode");
|
|
761
|
+
},
|
|
762
|
+
getToken: () => null
|
|
763
|
+
};
|
|
764
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(GitLabAuthContext.Provider, { value, children });
|
|
765
|
+
};
|
|
766
|
+
var useGitLabAuth = () => {
|
|
767
|
+
const ctx = React6.useContext(GitLabAuthContext);
|
|
768
|
+
if (!ctx) {
|
|
769
|
+
throw new Error("useGitLabAuth must be used within a GitLabAuthProvider");
|
|
770
|
+
}
|
|
771
|
+
return ctx;
|
|
772
|
+
};
|
|
776
773
|
// Annotate the CommonJS export names for ESM import in node:
|
|
777
774
|
0 && (module.exports = {
|
|
778
775
|
CommentDrawer,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/components/CommentOverlay.tsx","../src/contexts/CommentContext.tsx","../src/contexts/VersionContext.tsx","../src/components/CommentPin.tsx","../src/components/CommentDrawer.tsx","../src/contexts/GitLabAuthContext.tsx","../src/contexts/GitHubAuthContext.tsx"],"sourcesContent":["// Components\nexport { CommentOverlay } from './components/CommentOverlay';\nexport { CommentDrawer } from './components/CommentDrawer';\nexport { CommentPin } from './components/CommentPin';\n\n// Contexts / Providers\nexport { CommentProvider, useComments } from './contexts/CommentContext';\nexport { VersionProvider, useVersion } from './contexts/VersionContext';\nexport { GitHubAuthProvider, useGitHubAuth } from './contexts/GitHubAuthContext';\nexport { GitLabAuthProvider, useGitLabAuth } from './contexts/GitLabAuthContext';\n\n// Types\nexport type { \n Comment, \n Thread\n} from './contexts/CommentContext';\n","import * as React from 'react';\nimport { useLocation } from 'react-router-dom';\nimport { useComments } from '../contexts/CommentContext';\nimport { useVersion } from '../contexts/VersionContext';\nimport { CommentPin } from './CommentPin';\n\ninterface CommentOverlayProps {\n selectedThreadId: string | null;\n onThreadSelect: (id: string) => void;\n}\n\nexport const CommentOverlay: React.FunctionComponent<CommentOverlayProps> = ({\n selectedThreadId,\n onThreadSelect\n}) => {\n const location = useLocation();\n const { showPins, enableCommenting, addThread, getThreadsForRoute } = useComments();\n const { currentVersion } = useVersion();\n const overlayRef = React.useRef<HTMLDivElement>(null);\n\n const currentRouteThreads = React.useMemo(\n () => getThreadsForRoute(location.pathname, currentVersion),\n [getThreadsForRoute, location.pathname, currentVersion]\n );\n\n const handleOverlayClick = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n if (!enableCommenting) return;\n\n // Only add thread if clicking the overlay itself, not a pin\n if (event.target === overlayRef.current) {\n const rect = overlayRef.current.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n const newThreadId = addThread(x, y, location.pathname, currentVersion);\n \n // Auto-open the drawer for the newly created thread\n onThreadSelect(newThreadId);\n }\n },\n [enableCommenting, addThread, location.pathname, currentVersion, onThreadSelect]\n );\n\n // Don't render anything if neither showPins nor enableCommenting are true\n if (!showPins && !enableCommenting) {\n return null;\n }\n\n return (\n <div\n ref={overlayRef}\n id=\"comment-overlay\"\n onClick={handleOverlayClick}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n pointerEvents: enableCommenting ? 'auto' : 'none',\n cursor: enableCommenting ? 'crosshair' : 'default',\n zIndex: 999\n }}\n >\n {showPins && currentRouteThreads.map((thread) => (\n <div\n key={thread.id}\n style={{ pointerEvents: 'auto' }}\n onClick={(e) => e.stopPropagation()}\n >\n <CommentPin\n thread={thread}\n onPinClick={() => onThreadSelect(thread.id)}\n isSelected={thread.id === selectedThreadId}\n />\n </div>\n ))}\n </div>\n );\n};\n\n","import * as React from 'react';\n\nexport interface Comment {\n id: string;\n author?: string;\n text: string;\n createdAt: string;\n}\n\nexport interface Thread {\n id: string;\n x: number;\n y: number;\n route: string;\n comments: Comment[];\n version?: string;\n}\n\ninterface CommentContextType {\n threads: Thread[];\n showPins: boolean;\n enableCommenting: boolean;\n toggleShowPins: () => void;\n toggleEnableCommenting: () => void;\n addThread: (x: number, y: number, route: string, version?: string) => string;\n addReply: (threadId: string, text: string) => void;\n updateComment: (threadId: string, commentId: string, text: string) => void;\n deleteComment: (threadId: string, commentId: string) => void;\n deleteThread: (threadId: string) => void;\n clearAllThreads: () => void;\n getThreadsForRoute: (route: string, version?: string) => Thread[];\n}\n\nconst CommentContext = React.createContext<CommentContextType | undefined>(undefined);\n\nconst STORAGE_KEY = 'hale-threads';\nconst SHOW_PINS_KEY = 'hale-show-pins';\nconst ENABLE_COMMENTING_KEY = 'hale-enable-commenting';\n\n// Migration function to convert old Apollo comments to Hale threads\nconst migrateOldComments = (): Thread[] => {\n try {\n const oldThreadsKey = localStorage.getItem('apollo-threads');\n const oldCommentsKey = localStorage.getItem('apollo-comments');\n \n // Try apollo-threads first (newer format)\n if (oldThreadsKey) {\n const parsed = JSON.parse(oldThreadsKey);\n // Clean up sync-related fields\n const cleanThreads: Thread[] = parsed.map((t: any) => ({\n id: t.id,\n x: t.x,\n y: t.y,\n route: t.route,\n comments: t.comments.map((c: any) => ({\n id: c.id,\n text: c.text || '',\n createdAt: c.createdAt,\n author: c.author\n })),\n version: t.version\n }));\n localStorage.setItem(STORAGE_KEY, JSON.stringify(cleanThreads));\n localStorage.removeItem('apollo-threads');\n return cleanThreads;\n }\n \n // Fallback to old apollo-comments format (oldest)\n if (oldCommentsKey) {\n const parsed = JSON.parse(oldCommentsKey);\n const threads: Thread[] = parsed.map((oldComment: any) => ({\n id: oldComment.id,\n x: oldComment.x,\n y: oldComment.y,\n route: oldComment.route,\n comments: [\n {\n id: `${oldComment.id}-comment-0`,\n text: oldComment.text || '',\n createdAt: oldComment.createdAt\n }\n ]\n }));\n localStorage.setItem(STORAGE_KEY, JSON.stringify(threads));\n localStorage.removeItem('apollo-comments');\n return threads;\n }\n } catch (error) {\n console.error('Failed to migrate old comments:', error);\n }\n return [];\n};\n\nexport const CommentProvider: React.FunctionComponent<{ children: React.ReactNode }> = ({ children }) => {\n // Load initial state from localStorage with migration\n const [threads, setThreads] = React.useState<Thread[]>(() => {\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored) {\n return JSON.parse(stored);\n }\n // Try to migrate old comments\n return migrateOldComments();\n } catch (error) {\n console.error('Failed to load threads from localStorage:', error);\n return [];\n }\n });\n\n const [showPins, setShowPins] = React.useState<boolean>(() => {\n try {\n const stored = localStorage.getItem(SHOW_PINS_KEY);\n if (stored !== null) return stored === 'true';\n // Check old key for migration\n const oldKey = localStorage.getItem('apollo-show-pins');\n return oldKey === 'true';\n } catch (error) {\n return false;\n }\n });\n\n const [enableCommenting, setEnableCommenting] = React.useState<boolean>(() => {\n try {\n const stored = localStorage.getItem(ENABLE_COMMENTING_KEY);\n if (stored !== null) return stored === 'true';\n // Check old key for migration\n const oldKey = localStorage.getItem('apollo-enable-commenting');\n return oldKey === 'true';\n } catch (error) {\n return false;\n }\n });\n\n // Persist threads to localStorage whenever they change\n React.useEffect(() => {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(threads));\n } catch (error) {\n console.error('Failed to save threads to localStorage:', error);\n }\n }, [threads]);\n\n // Persist showPins to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(SHOW_PINS_KEY, String(showPins));\n } catch (error) {\n console.error('Failed to save showPins to localStorage:', error);\n }\n }, [showPins]);\n\n // Persist enableCommenting to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(ENABLE_COMMENTING_KEY, String(enableCommenting));\n } catch (error) {\n console.error('Failed to save enableCommenting to localStorage:', error);\n }\n }, [enableCommenting]);\n\n const toggleShowPins = React.useCallback(() => {\n setShowPins(prev => !prev);\n }, []);\n\n const toggleEnableCommenting = React.useCallback(() => {\n setEnableCommenting(prev => !prev);\n }, []);\n\n const addThread = React.useCallback((x: number, y: number, route: string, version?: string): string => {\n const threadId = `thread-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const newThread: Thread = {\n id: threadId,\n x,\n y,\n route,\n comments: [],\n version\n };\n setThreads(prev => [...prev, newThread]);\n return threadId;\n }, []);\n\n const addReply = React.useCallback((threadId: string, text: string) => {\n const commentId = `${threadId}-comment-${Date.now()}`;\n const newComment: Comment = {\n id: commentId,\n text,\n createdAt: new Date().toISOString()\n };\n\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: [...t.comments, newComment]\n };\n }\n return t;\n })\n );\n }, []);\n\n const updateComment = React.useCallback((threadId: string, commentId: string, text: string) => {\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: t.comments.map(c =>\n c.id === commentId ? { ...c, text } : c\n )\n };\n }\n return t;\n })\n );\n }, []);\n\n const deleteComment = React.useCallback((threadId: string, commentId: string) => {\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: t.comments.filter(c => c.id !== commentId)\n };\n }\n return t;\n })\n );\n }, []);\n\n const deleteThread = React.useCallback((threadId: string) => {\n setThreads(prev => prev.filter(t => t.id !== threadId));\n }, []);\n\n const clearAllThreads = React.useCallback(() => {\n setThreads([]);\n }, []);\n\n const getThreadsForRoute = React.useCallback((route: string, version?: string): Thread[] => {\n return threads.filter(thread => {\n const routeMatch = thread.route === route;\n // Treat legacy comments (without version) as Version 3 (current)\n const threadVersion = thread.version || '3';\n const versionMatch = !version || threadVersion === version;\n return routeMatch && versionMatch;\n });\n }, [threads]);\n\n const value = React.useMemo(\n () => ({\n threads,\n showPins,\n enableCommenting,\n toggleShowPins,\n toggleEnableCommenting,\n addThread,\n addReply,\n updateComment,\n deleteComment,\n deleteThread,\n clearAllThreads,\n getThreadsForRoute\n }),\n [threads, showPins, enableCommenting, toggleShowPins, toggleEnableCommenting, addThread, addReply, updateComment, deleteComment, deleteThread, clearAllThreads, getThreadsForRoute]\n );\n\n return <CommentContext.Provider value={value}>{children}</CommentContext.Provider>;\n};\n\nexport const useComments = (): CommentContextType => {\n const context = React.useContext(CommentContext);\n if (!context) {\n throw new Error('useComments must be used within a CommentProvider');\n }\n return context;\n};\n","import * as React from 'react';\n\ninterface VersionContextType {\n currentVersion: string;\n setCurrentVersion: (version: string) => void;\n}\n\nconst VersionContext = React.createContext<VersionContextType | undefined>(undefined);\n\nconst VERSION_STORAGE_KEY = 'hale-current-version';\n\nexport const VersionProvider: React.FunctionComponent<{ children: React.ReactNode }> = ({ children }) => {\n const [currentVersion, setCurrentVersionState] = React.useState<string>(() => {\n try {\n const stored = localStorage.getItem(VERSION_STORAGE_KEY);\n return stored || '3'; // Default to version 3 (current)\n } catch (error) {\n console.error('Failed to load version from localStorage:', error);\n return '3';\n }\n });\n\n // Persist version to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(VERSION_STORAGE_KEY, currentVersion);\n } catch (error) {\n console.error('Failed to save version to localStorage:', error);\n }\n }, [currentVersion]);\n\n const setCurrentVersion = React.useCallback((version: string) => {\n setCurrentVersionState(version);\n }, []);\n\n const value = React.useMemo(\n () => ({\n currentVersion,\n setCurrentVersion,\n }),\n [currentVersion, setCurrentVersion]\n );\n\n return <VersionContext.Provider value={value}>{children}</VersionContext.Provider>;\n};\n\nexport const useVersion = (): VersionContextType => {\n const context = React.useContext(VersionContext);\n if (!context) {\n throw new Error('useVersion must be used within a VersionProvider');\n }\n return context;\n};\n\n","import * as React from 'react';\nimport { Button } from '@patternfly/react-core';\nimport { CommentIcon, ExclamationTriangleIcon } from '@patternfly/react-icons';\nimport { Thread } from '../contexts/CommentContext';\n\ninterface CommentPinProps {\n thread: Thread;\n onPinClick: () => void;\n isSelected?: boolean;\n}\n\nexport const CommentPin: React.FunctionComponent<CommentPinProps> = ({ \n thread, \n onPinClick,\n isSelected = false\n}) => {\n const commentCount = thread.comments.length;\n // Sync status removed in local-only version\n\n return (\n <>\n <style>\n {`\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n `}\n </style>\n <Button\n id={`comment-pin-${thread.id}`}\n variant=\"plain\"\n aria-label={`Comment thread with ${commentCount} ${commentCount === 1 ? 'comment' : 'comments'}`}\n onClick={(e) => {\n e.stopPropagation();\n onPinClick();\n }}\n style={{\n position: 'absolute',\n left: `${thread.x}px`,\n top: `${thread.y}px`,\n transform: 'translate(-50%, -50%)',\n width: '32px',\n height: '32px',\n borderRadius: '50%',\n backgroundColor: '#C9190B',\n color: 'white',\n border: isSelected ? '3px solid #0066CC' : '2px solid white',\n boxShadow: isSelected \n ? '0 0 0 2px #0066CC, 0 4px 12px rgba(0, 0, 0, 0.4)'\n : '0 2px 8px rgba(0, 0, 0, 0.3)',\n padding: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n zIndex: isSelected ? 1001 : 1000,\n transition: 'all 0.2s ease',\n fontSize: commentCount > 1 ? '0.7rem' : undefined\n }}\n >\n {commentCount === 0 ? (\n <span style={{ fontWeight: 'bold', fontSize: '0.75rem' }}>0</span>\n ) : commentCount === 1 ? (\n <CommentIcon />\n ) : (\n <span style={{ fontWeight: 'bold' }}>{commentCount}</span>\n )}\n </Button>\n </>\n );\n};\n\n","import * as React from 'react';\nimport {\n Drawer,\n DrawerContent,\n DrawerContentBody,\n DrawerPanelContent,\n DrawerHead,\n DrawerActions,\n DrawerCloseButton,\n Title,\n Button,\n TextArea,\n Card,\n CardBody,\n CardTitle,\n EmptyState,\n EmptyStateBody,\n Divider,\n Label,\n Spinner,\n ExpandableSection,\n Alert\n} from '@patternfly/react-core';\nimport { CommentIcon, TimesIcon, PlusCircleIcon, SyncAltIcon, GithubIcon, ExternalLinkAltIcon, RedoIcon, MagicIcon, InfoCircleIcon } from '@patternfly/react-icons';\nimport { useComments } from '../contexts/CommentContext';\nimport { useVersion } from '../contexts/VersionContext';\nimport { useLocation } from 'react-router-dom';\nimport { useGitLabAuth } from '../contexts/GitLabAuthContext';\n\ninterface CommentDrawerProps {\n children: React.ReactNode;\n selectedThreadId: string | null;\n onThreadSelect: (id: string | null) => void;\n}\n\nexport const CommentDrawer: React.FunctionComponent<CommentDrawerProps> = ({\n children,\n selectedThreadId,\n onThreadSelect\n}) => {\n const location = useLocation();\n const { \n getThreadsForRoute, \n addReply, \n updateComment, \n deleteComment,\n deleteThread,\n enableCommenting\n } = useComments();\n const { currentVersion } = useVersion();\n const { isAuthenticated: isGitLabAuthenticated } = useGitLabAuth();\n \n const [editingCommentId, setEditingCommentId] = React.useState<string | null>(null);\n const [editText, setEditText] = React.useState('');\n const [replyText, setReplyText] = React.useState('');\n const replyTextAreaRef = React.useRef<HTMLTextAreaElement>(null);\n \n // AI Summary state\n const [threadSummaries, setThreadSummaries] = React.useState<Record<string, string>>({});\n const [loadingSummary, setLoadingSummary] = React.useState(false);\n const [summaryExpanded, setSummaryExpanded] = React.useState(true);\n\n const currentRouteThreads = getThreadsForRoute(location.pathname, currentVersion);\n const selectedThread = currentRouteThreads.find(t => t.id === selectedThreadId);\n const isDrawerOpen = selectedThreadId !== null && selectedThread !== undefined;\n\n // Auto-focus reply textarea when drawer opens and commenting is enabled\n React.useEffect(() => {\n if (!isDrawerOpen || !enableCommenting) return;\n \n // Small delay to ensure drawer animation completes\n const timer = setTimeout(() => {\n replyTextAreaRef.current?.focus();\n }, 100);\n \n return () => clearTimeout(timer);\n }, [isDrawerOpen, enableCommenting, selectedThreadId]);\n\n // Note: Sync functionality removed in local-only version\n\n const handleEdit = (commentId: string, text: string) => {\n setEditingCommentId(commentId);\n setEditText(text);\n };\n\n const handleSave = async (threadId: string, commentId: string) => {\n await updateComment(threadId, commentId, editText);\n setEditingCommentId(null);\n };\n\n const handleAddReply = async () => {\n if (selectedThreadId && replyText.trim()) {\n await addReply(selectedThreadId, replyText);\n setReplyText('');\n }\n };\n\n const handleDeleteThread = async () => {\n if (selectedThreadId && window.confirm('Delete this entire thread and all its comments?')) {\n await deleteThread(selectedThreadId);\n onThreadSelect(null);\n }\n };\n\n const handleSummarizeThread = async () => {\n // AI summarization removed in local-only version\n console.log('AI features not available in local-only mode');\n };\n\n const handleDeleteComment = async (threadId: string, commentId: string) => {\n if (window.confirm('Delete this comment?')) {\n await deleteComment(threadId, commentId);\n }\n };\n\n // Sync handlers removed in local-only version\n\n const formatDate = (isoDate: string): string => {\n const date = new Date(isoDate);\n return date.toLocaleString(undefined, {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n };\n\n const panelContent = (\n <DrawerPanelContent isResizable defaultSize=\"400px\" minSize=\"300px\">\n <DrawerHead>\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', flex: 1 }}>\n <Title headingLevel=\"h2\" size=\"xl\">\n <CommentIcon style={{ marginRight: '0.5rem', color: '#C9190B' }} />\n Thread\n </Title>\n {/* Sync buttons removed in local-only version */}\n </div>\n <DrawerActions>\n <DrawerCloseButton onClick={() => onThreadSelect(null)} />\n </DrawerActions>\n </DrawerHead>\n <DrawerContentBody style={{ padding: '1rem' }}>\n {!selectedThread ? (\n <EmptyState>\n <CommentIcon style={{ fontSize: '3rem', color: 'var(--pf-v6-global--Color--200)', marginBottom: '1rem' }} />\n <Title headingLevel=\"h3\" size=\"lg\">\n No thread selected\n </Title>\n <EmptyStateBody>\n Click a pin to view its comments.\n </EmptyStateBody>\n </EmptyState>\n ) : (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n {/* Thread Info */}\n <Card isCompact>\n <CardBody>\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Location:</strong> ({Math.round(selectedThread.x)}, {Math.round(selectedThread.y)})\n </div>\n {selectedThread.version && (\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Version:</strong> {selectedThread.version}\n </div>\n )}\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Comments:</strong> {selectedThread.comments.length}\n </div>\n {/* Status and issue link removed in local-only version */}\n {/* AI Summarize Thread Button */}\n {selectedThread.comments.length > 0 && (\n <Button\n id={`ai-summarize-thread-${selectedThread.id}`}\n variant=\"secondary\"\n size=\"sm\"\n icon={<MagicIcon />}\n onClick={handleSummarizeThread}\n isLoading={loadingSummary}\n isDisabled={loadingSummary}\n style={{ marginTop: '0.5rem' }}\n >\n {loadingSummary ? 'Generating...' : 'AI Summarize Thread'}\n </Button>\n )}\n {enableCommenting && (\n <Button\n id={`delete-thread-${selectedThread.id}`}\n variant=\"danger\"\n size=\"sm\"\n icon={<TimesIcon />}\n onClick={handleDeleteThread}\n style={{ marginTop: '0.5rem', marginLeft: selectedThread.comments.length > 0 ? '0.5rem' : '0' }}\n >\n Delete Thread\n </Button>\n )}\n </CardBody>\n </Card>\n\n {/* AI Summary Display */}\n {threadSummaries[selectedThread.id] && (\n <Alert\n variant=\"info\"\n isInline\n title=\"AI Summary\"\n actionClose={\n <Button\n variant=\"plain\"\n onClick={() => {\n const newSummaries = { ...threadSummaries };\n delete newSummaries[selectedThread.id];\n setThreadSummaries(newSummaries);\n }}\n aria-label=\"Clear summary\"\n >\n <TimesIcon />\n </Button>\n }\n >\n <ExpandableSection\n toggleText={summaryExpanded ? 'Hide summary' : 'Show summary'}\n onToggle={(_event, isExpanded) => setSummaryExpanded(isExpanded)}\n isExpanded={summaryExpanded}\n isIndented\n >\n <div style={{ fontSize: '0.875rem', lineHeight: '1.5' }}>\n {threadSummaries[selectedThread.id]}\n </div>\n </ExpandableSection>\n </Alert>\n )}\n\n <Divider />\n\n {/* Comments List */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n {selectedThread.comments.length === 0 ? (\n <EmptyState>\n <Title headingLevel=\"h4\" size=\"md\">\n No comments yet\n </Title>\n <EmptyStateBody>\n {enableCommenting \n ? 'Add a reply below to start the conversation.'\n : 'Enable commenting to add replies.'}\n </EmptyStateBody>\n </EmptyState>\n ) : (\n selectedThread.comments.map((comment, index) => (\n <Card key={comment.id} isCompact>\n <CardTitle>\n Comment #{index + 1}\n <div style={{ fontSize: '0.75rem', color: 'var(--pf-v6-global--Color--200)', fontWeight: 'normal' }}>\n {comment.author && <span style={{ marginRight: '0.5rem' }}>@{comment.author}</span>}\n {formatDate(comment.createdAt)}\n </div>\n </CardTitle>\n <CardBody>\n {editingCommentId === comment.id ? (\n <>\n <TextArea\n id={`edit-comment-${comment.id}`}\n value={editText}\n onChange={(_event, value) => setEditText(value)}\n rows={3}\n style={{ marginBottom: '0.5rem' }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSave(selectedThread.id, comment.id);\n }\n if (e.key === 'Escape') {\n setEditingCommentId(null);\n }\n }}\n />\n <div style={{ display: 'flex', gap: '0.5rem' }}>\n <Button\n id={`save-comment-${comment.id}`}\n variant=\"primary\"\n size=\"sm\"\n onClick={() => handleSave(selectedThread.id, comment.id)}\n >\n Save\n </Button>\n <Button\n id={`cancel-edit-${comment.id}`}\n variant=\"link\"\n size=\"sm\"\n onClick={() => setEditingCommentId(null)}\n >\n Cancel\n </Button>\n </div>\n </>\n ) : (\n <>\n <div style={{ marginBottom: '0.75rem', whiteSpace: 'pre-wrap' }}>\n {comment.text || <em style={{ color: 'var(--pf-v6-global--Color--200)' }}>No text</em>}\n </div>\n {enableCommenting && (\n <div style={{ display: 'flex', gap: '0.5rem' }}>\n <Button\n id={`edit-comment-btn-${comment.id}`}\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => handleEdit(comment.id, comment.text)}\n >\n Edit\n </Button>\n <Button\n id={`delete-comment-btn-${comment.id}`}\n variant=\"danger\"\n size=\"sm\"\n icon={<TimesIcon />}\n onClick={() => handleDeleteComment(selectedThread.id, comment.id)}\n >\n Delete\n </Button>\n </div>\n )}\n </>\n )}\n </CardBody>\n </Card>\n ))\n )}\n </div>\n\n {/* Add Reply */}\n {enableCommenting && (\n <>\n <Divider />\n <Card isCompact>\n <CardTitle>\n <PlusCircleIcon style={{ marginRight: '0.5rem' }} />\n Add Reply\n </CardTitle>\n <CardBody>\n <TextArea\n ref={replyTextAreaRef}\n id={`reply-textarea-${selectedThread.id}`}\n value={replyText}\n onChange={(_event, value) => setReplyText(value)}\n placeholder=\"Enter your reply...\"\n rows={3}\n style={{ marginBottom: '0.5rem' }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleAddReply();\n }\n }}\n />\n <Button\n id={`add-reply-${selectedThread.id}`}\n variant=\"primary\"\n size=\"sm\"\n onClick={handleAddReply}\n isDisabled={!replyText.trim()}\n >\n Add Reply\n </Button>\n </CardBody>\n </Card>\n </>\n )}\n </div>\n )}\n </DrawerContentBody>\n </DrawerPanelContent>\n );\n\n return (\n <Drawer isExpanded={isDrawerOpen} isInline position=\"right\">\n <DrawerContent panelContent={panelContent}>\n <DrawerContentBody>{children}</DrawerContentBody>\n </DrawerContent>\n </Drawer>\n );\n};\n","import * as React from 'react';\n\ninterface GitLabUser {\n username?: string;\n avatar?: string;\n}\n\ninterface GitLabAuthContextType {\n user: GitLabUser | null;\n isAuthenticated: boolean;\n login: () => void;\n logout: () => void;\n getToken: () => string | null;\n}\n\nconst GitLabAuthContext = React.createContext<GitLabAuthContextType | undefined>(undefined);\n\n// Mock provider for local-only mode (no actual OAuth)\nexport const GitLabAuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const value = {\n user: null,\n isAuthenticated: false,\n login: () => {\n console.log('GitLab login not available in local mode');\n },\n logout: () => {\n console.log('GitLab logout not available in local mode');\n },\n getToken: () => null,\n };\n\n return (\n <GitLabAuthContext.Provider value={value}>\n {children}\n </GitLabAuthContext.Provider>\n );\n};\n\nexport const useGitLabAuth = () => {\n const ctx = React.useContext(GitLabAuthContext);\n if (!ctx) {\n throw new Error('useGitLabAuth must be used within a GitLabAuthProvider');\n }\n return ctx;\n};\n","import * as React from 'react';\n\ninterface GitHubUser {\n login: string;\n avatar: string;\n}\n\ninterface GitHubAuthContextType {\n user: GitHubUser | null;\n isAuthenticated: boolean;\n login: () => void;\n logout: () => void;\n}\n\nconst GitHubAuthContext = React.createContext<GitHubAuthContextType | undefined>(undefined);\n\n// Mock provider for local-only mode (no actual OAuth)\nexport const GitHubAuthProvider: React.FC<{ children: React.ReactNode; config?: any }> = ({ children }) => {\n const value = {\n user: null,\n isAuthenticated: false,\n login: () => {\n console.log('GitHub login not available in local mode');\n },\n logout: () => {\n console.log('GitHub logout not available in local mode');\n },\n };\n\n return (\n <GitHubAuthContext.Provider value={value}>\n {children}\n </GitHubAuthContext.Provider>\n );\n};\n\nexport const useGitHubAuth = () => {\n const context = React.useContext(GitHubAuthContext);\n if (context === undefined) {\n throw new Error('useGitHubAuth must be used within a GitHubAuthProvider');\n }\n return context;\n};\n"],"mappings":"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","names":["React","React","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_react_core","import_react_icons","import_react_router_dom","React","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/components/CommentOverlay.tsx","../src/contexts/CommentContext.tsx","../src/contexts/VersionContext.tsx","../src/components/CommentPin.tsx","../src/components/CommentDrawer.tsx","../src/contexts/GitHubAuthContext.tsx","../src/contexts/GitLabAuthContext.tsx"],"sourcesContent":["// Components\nexport { CommentOverlay } from './components/CommentOverlay';\nexport { CommentDrawer } from './components/CommentDrawer';\nexport { CommentPin } from './components/CommentPin';\n\n// Contexts / Providers\nexport { CommentProvider, useComments } from './contexts/CommentContext';\nexport { VersionProvider, useVersion } from './contexts/VersionContext';\nexport { GitHubAuthProvider, useGitHubAuth } from './contexts/GitHubAuthContext';\nexport { GitLabAuthProvider, useGitLabAuth } from './contexts/GitLabAuthContext';\n\n// Types\nexport type { \n Comment, \n Thread\n} from './contexts/CommentContext';\n","import * as React from 'react';\nimport { useLocation } from 'react-router-dom';\nimport { useComments } from '../contexts/CommentContext';\nimport { useVersion } from '../contexts/VersionContext';\nimport { CommentPin } from './CommentPin';\n\ninterface CommentOverlayProps {\n selectedThreadId: string | null;\n onThreadSelect: (id: string) => void;\n}\n\nexport const CommentOverlay: React.FunctionComponent<CommentOverlayProps> = ({\n selectedThreadId,\n onThreadSelect\n}) => {\n const location = useLocation();\n const { showPins, enableCommenting, addThread, getThreadsForRoute } = useComments();\n const { currentVersion } = useVersion();\n const overlayRef = React.useRef<HTMLDivElement>(null);\n\n const currentRouteThreads = React.useMemo(\n () => getThreadsForRoute(location.pathname, currentVersion),\n [getThreadsForRoute, location.pathname, currentVersion]\n );\n\n const handleOverlayClick = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n if (!enableCommenting) return;\n\n // Only add thread if clicking the overlay itself, not a pin\n if (event.target === overlayRef.current) {\n const rect = overlayRef.current.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n const newThreadId = addThread(x, y, location.pathname, currentVersion);\n \n // Auto-open the drawer for the newly created thread\n onThreadSelect(newThreadId);\n }\n },\n [enableCommenting, addThread, location.pathname, currentVersion, onThreadSelect]\n );\n\n // Don't render anything if neither showPins nor enableCommenting are true\n if (!showPins && !enableCommenting) {\n return null;\n }\n\n return (\n <div\n ref={overlayRef}\n id=\"comment-overlay\"\n onClick={handleOverlayClick}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n pointerEvents: enableCommenting ? 'auto' : 'none',\n cursor: enableCommenting ? 'crosshair' : 'default',\n zIndex: 999\n }}\n >\n {showPins && currentRouteThreads.map((thread) => (\n <div\n key={thread.id}\n style={{ pointerEvents: 'auto' }}\n onClick={(e) => e.stopPropagation()}\n >\n <CommentPin\n thread={thread}\n onPinClick={() => onThreadSelect(thread.id)}\n isSelected={thread.id === selectedThreadId}\n />\n </div>\n ))}\n </div>\n );\n};\n\n","import * as React from 'react';\n\nexport interface Comment {\n id: string;\n author?: string;\n text: string;\n createdAt: string;\n}\n\nexport interface Thread {\n id: string;\n x: number;\n y: number;\n route: string;\n comments: Comment[];\n version?: string;\n}\n\ninterface CommentContextType {\n threads: Thread[];\n showPins: boolean;\n enableCommenting: boolean;\n toggleShowPins: () => void;\n toggleEnableCommenting: () => void;\n addThread: (x: number, y: number, route: string, version?: string) => string;\n addReply: (threadId: string, text: string) => void;\n updateComment: (threadId: string, commentId: string, text: string) => void;\n deleteComment: (threadId: string, commentId: string) => void;\n deleteThread: (threadId: string) => void;\n clearAllThreads: () => void;\n getThreadsForRoute: (route: string, version?: string) => Thread[];\n}\n\nconst CommentContext = React.createContext<CommentContextType | undefined>(undefined);\n\nconst STORAGE_KEY = 'hale-threads';\nconst SHOW_PINS_KEY = 'hale-show-pins';\nconst ENABLE_COMMENTING_KEY = 'hale-enable-commenting';\n\n// Migration function to convert old Apollo comments to Hale threads\nconst migrateOldComments = (): Thread[] => {\n try {\n const oldThreadsKey = localStorage.getItem('apollo-threads');\n const oldCommentsKey = localStorage.getItem('apollo-comments');\n \n // Try apollo-threads first (newer format)\n if (oldThreadsKey) {\n const parsed = JSON.parse(oldThreadsKey);\n // Clean up sync-related fields\n const cleanThreads: Thread[] = parsed.map((t: any) => ({\n id: t.id,\n x: t.x,\n y: t.y,\n route: t.route,\n comments: t.comments.map((c: any) => ({\n id: c.id,\n text: c.text || '',\n createdAt: c.createdAt,\n author: c.author\n })),\n version: t.version\n }));\n localStorage.setItem(STORAGE_KEY, JSON.stringify(cleanThreads));\n localStorage.removeItem('apollo-threads');\n return cleanThreads;\n }\n \n // Fallback to old apollo-comments format (oldest)\n if (oldCommentsKey) {\n const parsed = JSON.parse(oldCommentsKey);\n const threads: Thread[] = parsed.map((oldComment: any) => ({\n id: oldComment.id,\n x: oldComment.x,\n y: oldComment.y,\n route: oldComment.route,\n comments: [\n {\n id: `${oldComment.id}-comment-0`,\n text: oldComment.text || '',\n createdAt: oldComment.createdAt\n }\n ]\n }));\n localStorage.setItem(STORAGE_KEY, JSON.stringify(threads));\n localStorage.removeItem('apollo-comments');\n return threads;\n }\n } catch (error) {\n console.error('Failed to migrate old comments:', error);\n }\n return [];\n};\n\nexport const CommentProvider: React.FunctionComponent<{ children: React.ReactNode }> = ({ children }) => {\n // Load initial state from localStorage with migration\n const [threads, setThreads] = React.useState<Thread[]>(() => {\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored) {\n return JSON.parse(stored);\n }\n // Try to migrate old comments\n return migrateOldComments();\n } catch (error) {\n console.error('Failed to load threads from localStorage:', error);\n return [];\n }\n });\n\n const [showPins, setShowPins] = React.useState<boolean>(() => {\n try {\n const stored = localStorage.getItem(SHOW_PINS_KEY);\n if (stored !== null) return stored === 'true';\n // Check old key for migration\n const oldKey = localStorage.getItem('apollo-show-pins');\n return oldKey === 'true';\n } catch (error) {\n return false;\n }\n });\n\n const [enableCommenting, setEnableCommenting] = React.useState<boolean>(() => {\n try {\n const stored = localStorage.getItem(ENABLE_COMMENTING_KEY);\n if (stored !== null) return stored === 'true';\n // Check old key for migration\n const oldKey = localStorage.getItem('apollo-enable-commenting');\n return oldKey === 'true';\n } catch (error) {\n return false;\n }\n });\n\n // Persist threads to localStorage whenever they change\n React.useEffect(() => {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(threads));\n } catch (error) {\n console.error('Failed to save threads to localStorage:', error);\n }\n }, [threads]);\n\n // Persist showPins to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(SHOW_PINS_KEY, String(showPins));\n } catch (error) {\n console.error('Failed to save showPins to localStorage:', error);\n }\n }, [showPins]);\n\n // Persist enableCommenting to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(ENABLE_COMMENTING_KEY, String(enableCommenting));\n } catch (error) {\n console.error('Failed to save enableCommenting to localStorage:', error);\n }\n }, [enableCommenting]);\n\n const toggleShowPins = React.useCallback(() => {\n setShowPins(prev => !prev);\n }, []);\n\n const toggleEnableCommenting = React.useCallback(() => {\n setEnableCommenting(prev => !prev);\n }, []);\n\n const addThread = React.useCallback((x: number, y: number, route: string, version?: string): string => {\n const threadId = `thread-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const newThread: Thread = {\n id: threadId,\n x,\n y,\n route,\n comments: [],\n version\n };\n setThreads(prev => [...prev, newThread]);\n return threadId;\n }, []);\n\n const addReply = React.useCallback((threadId: string, text: string) => {\n const commentId = `${threadId}-comment-${Date.now()}`;\n const newComment: Comment = {\n id: commentId,\n text,\n createdAt: new Date().toISOString()\n };\n\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: [...t.comments, newComment]\n };\n }\n return t;\n })\n );\n }, []);\n\n const updateComment = React.useCallback((threadId: string, commentId: string, text: string) => {\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: t.comments.map(c =>\n c.id === commentId ? { ...c, text } : c\n )\n };\n }\n return t;\n })\n );\n }, []);\n\n const deleteComment = React.useCallback((threadId: string, commentId: string) => {\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: t.comments.filter(c => c.id !== commentId)\n };\n }\n return t;\n })\n );\n }, []);\n\n const deleteThread = React.useCallback((threadId: string) => {\n setThreads(prev => prev.filter(t => t.id !== threadId));\n }, []);\n\n const clearAllThreads = React.useCallback(() => {\n setThreads([]);\n }, []);\n\n const getThreadsForRoute = React.useCallback((route: string, version?: string): Thread[] => {\n return threads.filter(thread => {\n const routeMatch = thread.route === route;\n // Treat legacy comments (without version) as Version 3 (current)\n const threadVersion = thread.version || '3';\n const versionMatch = !version || threadVersion === version;\n return routeMatch && versionMatch;\n });\n }, [threads]);\n\n const value = React.useMemo(\n () => ({\n threads,\n showPins,\n enableCommenting,\n toggleShowPins,\n toggleEnableCommenting,\n addThread,\n addReply,\n updateComment,\n deleteComment,\n deleteThread,\n clearAllThreads,\n getThreadsForRoute\n }),\n [threads, showPins, enableCommenting, toggleShowPins, toggleEnableCommenting, addThread, addReply, updateComment, deleteComment, deleteThread, clearAllThreads, getThreadsForRoute]\n );\n\n return <CommentContext.Provider value={value}>{children}</CommentContext.Provider>;\n};\n\nexport const useComments = (): CommentContextType => {\n const context = React.useContext(CommentContext);\n if (!context) {\n throw new Error('useComments must be used within a CommentProvider');\n }\n return context;\n};\n","import * as React from 'react';\n\ninterface VersionContextType {\n currentVersion: string;\n setCurrentVersion: (version: string) => void;\n}\n\nconst VersionContext = React.createContext<VersionContextType | undefined>(undefined);\n\nconst VERSION_STORAGE_KEY = 'hale-current-version';\n\nexport const VersionProvider: React.FunctionComponent<{ children: React.ReactNode }> = ({ children }) => {\n const [currentVersion, setCurrentVersionState] = React.useState<string>(() => {\n try {\n const stored = localStorage.getItem(VERSION_STORAGE_KEY);\n return stored || '3'; // Default to version 3 (current)\n } catch (error) {\n console.error('Failed to load version from localStorage:', error);\n return '3';\n }\n });\n\n // Persist version to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(VERSION_STORAGE_KEY, currentVersion);\n } catch (error) {\n console.error('Failed to save version to localStorage:', error);\n }\n }, [currentVersion]);\n\n const setCurrentVersion = React.useCallback((version: string) => {\n setCurrentVersionState(version);\n }, []);\n\n const value = React.useMemo(\n () => ({\n currentVersion,\n setCurrentVersion,\n }),\n [currentVersion, setCurrentVersion]\n );\n\n return <VersionContext.Provider value={value}>{children}</VersionContext.Provider>;\n};\n\nexport const useVersion = (): VersionContextType => {\n const context = React.useContext(VersionContext);\n if (!context) {\n throw new Error('useVersion must be used within a VersionProvider');\n }\n return context;\n};\n\n","import * as React from 'react';\nimport { Button } from '@patternfly/react-core';\nimport { CommentIcon, ExclamationTriangleIcon } from '@patternfly/react-icons';\nimport { Thread } from '../contexts/CommentContext';\n\ninterface CommentPinProps {\n thread: Thread;\n onPinClick: () => void;\n isSelected?: boolean;\n}\n\nexport const CommentPin: React.FunctionComponent<CommentPinProps> = ({ \n thread, \n onPinClick,\n isSelected = false\n}) => {\n const commentCount = thread.comments.length;\n // Sync status removed in local-only version\n\n return (\n <>\n <style>\n {`\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n `}\n </style>\n <Button\n id={`comment-pin-${thread.id}`}\n variant=\"plain\"\n aria-label={`Comment thread with ${commentCount} ${commentCount === 1 ? 'comment' : 'comments'}`}\n onClick={(e) => {\n e.stopPropagation();\n onPinClick();\n }}\n style={{\n position: 'absolute',\n left: `${thread.x}px`,\n top: `${thread.y}px`,\n transform: 'translate(-50%, -50%)',\n width: '32px',\n height: '32px',\n borderRadius: '50%',\n backgroundColor: '#C9190B',\n color: 'white',\n border: isSelected ? '3px solid #0066CC' : '2px solid white',\n boxShadow: isSelected \n ? '0 0 0 2px #0066CC, 0 4px 12px rgba(0, 0, 0, 0.4)'\n : '0 2px 8px rgba(0, 0, 0, 0.3)',\n padding: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n zIndex: isSelected ? 1001 : 1000,\n transition: 'all 0.2s ease',\n fontSize: commentCount > 1 ? '0.7rem' : undefined\n }}\n >\n {commentCount === 0 ? (\n <span style={{ fontWeight: 'bold', fontSize: '0.75rem' }}>0</span>\n ) : commentCount === 1 ? (\n <CommentIcon />\n ) : (\n <span style={{ fontWeight: 'bold' }}>{commentCount}</span>\n )}\n </Button>\n </>\n );\n};\n\n","import * as React from 'react';\nimport {\n Drawer,\n DrawerContent,\n DrawerContentBody,\n DrawerPanelContent,\n DrawerHead,\n DrawerActions,\n DrawerCloseButton,\n Title,\n Button,\n TextArea,\n Card,\n CardBody,\n CardTitle,\n EmptyState,\n EmptyStateBody,\n Divider,\n Label,\n Spinner,\n ExpandableSection,\n Alert\n} from '@patternfly/react-core';\nimport { CommentIcon, TimesIcon, PlusCircleIcon, SyncAltIcon, GithubIcon, ExternalLinkAltIcon, RedoIcon, MagicIcon, InfoCircleIcon } from '@patternfly/react-icons';\nimport { useComments } from '../contexts/CommentContext';\nimport { useVersion } from '../contexts/VersionContext';\nimport { useLocation } from 'react-router-dom';\n\ninterface CommentDrawerProps {\n children: React.ReactNode;\n selectedThreadId: string | null;\n onThreadSelect: (id: string | null) => void;\n}\n\nexport const CommentDrawer: React.FunctionComponent<CommentDrawerProps> = ({\n children,\n selectedThreadId,\n onThreadSelect\n}) => {\n const location = useLocation();\n const { \n getThreadsForRoute, \n addReply, \n updateComment, \n deleteComment,\n deleteThread,\n enableCommenting\n } = useComments();\n const { currentVersion } = useVersion();\n \n const [editingCommentId, setEditingCommentId] = React.useState<string | null>(null);\n const [editText, setEditText] = React.useState('');\n const [replyText, setReplyText] = React.useState('');\n const replyTextAreaRef = React.useRef<HTMLTextAreaElement>(null);\n \n // AI Summary state\n const [threadSummaries, setThreadSummaries] = React.useState<Record<string, string>>({});\n const [loadingSummary, setLoadingSummary] = React.useState(false);\n const [summaryExpanded, setSummaryExpanded] = React.useState(true);\n\n const currentRouteThreads = getThreadsForRoute(location.pathname, currentVersion);\n const selectedThread = currentRouteThreads.find(t => t.id === selectedThreadId);\n const isDrawerOpen = selectedThreadId !== null && selectedThread !== undefined;\n\n // Auto-focus reply textarea when drawer opens and commenting is enabled\n React.useEffect(() => {\n if (!isDrawerOpen || !enableCommenting) return;\n \n // Small delay to ensure drawer animation completes\n const timer = setTimeout(() => {\n replyTextAreaRef.current?.focus();\n }, 100);\n \n return () => clearTimeout(timer);\n }, [isDrawerOpen, enableCommenting, selectedThreadId]);\n\n // Note: Sync functionality removed in local-only version\n\n const handleEdit = (commentId: string, text: string) => {\n setEditingCommentId(commentId);\n setEditText(text);\n };\n\n const handleSave = async (threadId: string, commentId: string) => {\n await updateComment(threadId, commentId, editText);\n setEditingCommentId(null);\n };\n\n const handleAddReply = async () => {\n if (selectedThreadId && replyText.trim()) {\n await addReply(selectedThreadId, replyText);\n setReplyText('');\n }\n };\n\n const handleDeleteThread = async () => {\n if (selectedThreadId && window.confirm('Delete this entire thread and all its comments?')) {\n await deleteThread(selectedThreadId);\n onThreadSelect(null);\n }\n };\n\n const handleSummarizeThread = async () => {\n // AI summarization removed in local-only version\n console.log('AI features not available in local-only mode');\n };\n\n const handleDeleteComment = async (threadId: string, commentId: string) => {\n if (window.confirm('Delete this comment?')) {\n await deleteComment(threadId, commentId);\n }\n };\n\n // Sync handlers removed in local-only version\n\n const formatDate = (isoDate: string): string => {\n const date = new Date(isoDate);\n return date.toLocaleString(undefined, {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n };\n\n const panelContent = (\n <DrawerPanelContent isResizable defaultSize=\"400px\" minSize=\"300px\">\n <DrawerHead>\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', flex: 1 }}>\n <Title headingLevel=\"h2\" size=\"xl\">\n <CommentIcon style={{ marginRight: '0.5rem', color: '#C9190B' }} />\n Thread\n </Title>\n {/* Sync buttons removed in local-only version */}\n </div>\n <DrawerActions>\n <DrawerCloseButton onClick={() => onThreadSelect(null)} />\n </DrawerActions>\n </DrawerHead>\n <DrawerContentBody style={{ padding: '1rem' }}>\n {!selectedThread ? (\n <EmptyState>\n <CommentIcon style={{ fontSize: '3rem', color: 'var(--pf-v6-global--Color--200)', marginBottom: '1rem' }} />\n <Title headingLevel=\"h3\" size=\"lg\">\n No thread selected\n </Title>\n <EmptyStateBody>\n Click a pin to view its comments.\n </EmptyStateBody>\n </EmptyState>\n ) : (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n {/* Thread Info */}\n <Card isCompact>\n <CardBody>\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Location:</strong> ({Math.round(selectedThread.x)}, {Math.round(selectedThread.y)})\n </div>\n {selectedThread.version && (\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Version:</strong> {selectedThread.version}\n </div>\n )}\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Comments:</strong> {selectedThread.comments.length}\n </div>\n {/* Status and issue link removed in local-only version */}\n {/* AI Summarize Thread Button */}\n {selectedThread.comments.length > 0 && (\n <Button\n id={`ai-summarize-thread-${selectedThread.id}`}\n variant=\"secondary\"\n size=\"sm\"\n icon={<MagicIcon />}\n onClick={handleSummarizeThread}\n isLoading={loadingSummary}\n isDisabled={loadingSummary}\n style={{ marginTop: '0.5rem' }}\n >\n {loadingSummary ? 'Generating...' : 'AI Summarize Thread'}\n </Button>\n )}\n {enableCommenting && (\n <Button\n id={`delete-thread-${selectedThread.id}`}\n variant=\"danger\"\n size=\"sm\"\n icon={<TimesIcon />}\n onClick={handleDeleteThread}\n style={{ marginTop: '0.5rem', marginLeft: selectedThread.comments.length > 0 ? '0.5rem' : '0' }}\n >\n Delete Thread\n </Button>\n )}\n </CardBody>\n </Card>\n\n {/* AI Summary Display */}\n {threadSummaries[selectedThread.id] && (\n <Alert\n variant=\"info\"\n isInline\n title=\"AI Summary\"\n actionClose={\n <Button\n variant=\"plain\"\n onClick={() => {\n const newSummaries = { ...threadSummaries };\n delete newSummaries[selectedThread.id];\n setThreadSummaries(newSummaries);\n }}\n aria-label=\"Clear summary\"\n >\n <TimesIcon />\n </Button>\n }\n >\n <ExpandableSection\n toggleText={summaryExpanded ? 'Hide summary' : 'Show summary'}\n onToggle={(_event, isExpanded) => setSummaryExpanded(isExpanded)}\n isExpanded={summaryExpanded}\n isIndented\n >\n <div style={{ fontSize: '0.875rem', lineHeight: '1.5' }}>\n {threadSummaries[selectedThread.id]}\n </div>\n </ExpandableSection>\n </Alert>\n )}\n\n <Divider />\n\n {/* Comments List */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n {selectedThread.comments.length === 0 ? (\n <EmptyState>\n <Title headingLevel=\"h4\" size=\"md\">\n No comments yet\n </Title>\n <EmptyStateBody>\n {enableCommenting \n ? 'Add a reply below to start the conversation.'\n : 'Enable commenting to add replies.'}\n </EmptyStateBody>\n </EmptyState>\n ) : (\n selectedThread.comments.map((comment, index) => (\n <Card key={comment.id} isCompact>\n <CardTitle>\n Comment #{index + 1}\n <div style={{ fontSize: '0.75rem', color: 'var(--pf-v6-global--Color--200)', fontWeight: 'normal' }}>\n {comment.author && <span style={{ marginRight: '0.5rem' }}>@{comment.author}</span>}\n {formatDate(comment.createdAt)}\n </div>\n </CardTitle>\n <CardBody>\n {editingCommentId === comment.id ? (\n <>\n <TextArea\n id={`edit-comment-${comment.id}`}\n value={editText}\n onChange={(_event, value) => setEditText(value)}\n rows={3}\n style={{ marginBottom: '0.5rem' }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSave(selectedThread.id, comment.id);\n }\n if (e.key === 'Escape') {\n setEditingCommentId(null);\n }\n }}\n />\n <div style={{ display: 'flex', gap: '0.5rem' }}>\n <Button\n id={`save-comment-${comment.id}`}\n variant=\"primary\"\n size=\"sm\"\n onClick={() => handleSave(selectedThread.id, comment.id)}\n >\n Save\n </Button>\n <Button\n id={`cancel-edit-${comment.id}`}\n variant=\"link\"\n size=\"sm\"\n onClick={() => setEditingCommentId(null)}\n >\n Cancel\n </Button>\n </div>\n </>\n ) : (\n <>\n <div style={{ marginBottom: '0.75rem', whiteSpace: 'pre-wrap' }}>\n {comment.text || <em style={{ color: 'var(--pf-v6-global--Color--200)' }}>No text</em>}\n </div>\n {enableCommenting && (\n <div style={{ display: 'flex', gap: '0.5rem' }}>\n <Button\n id={`edit-comment-btn-${comment.id}`}\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => handleEdit(comment.id, comment.text)}\n >\n Edit\n </Button>\n <Button\n id={`delete-comment-btn-${comment.id}`}\n variant=\"danger\"\n size=\"sm\"\n icon={<TimesIcon />}\n onClick={() => handleDeleteComment(selectedThread.id, comment.id)}\n >\n Delete\n </Button>\n </div>\n )}\n </>\n )}\n </CardBody>\n </Card>\n ))\n )}\n </div>\n\n {/* Add Reply */}\n {enableCommenting && (\n <>\n <Divider />\n <Card isCompact>\n <CardTitle>\n <PlusCircleIcon style={{ marginRight: '0.5rem' }} />\n Add Reply\n </CardTitle>\n <CardBody>\n <TextArea\n ref={replyTextAreaRef}\n id={`reply-textarea-${selectedThread.id}`}\n value={replyText}\n onChange={(_event, value) => setReplyText(value)}\n placeholder=\"Enter your reply...\"\n rows={3}\n style={{ marginBottom: '0.5rem' }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleAddReply();\n }\n }}\n />\n <Button\n id={`add-reply-${selectedThread.id}`}\n variant=\"primary\"\n size=\"sm\"\n onClick={handleAddReply}\n isDisabled={!replyText.trim()}\n >\n Add Reply\n </Button>\n </CardBody>\n </Card>\n </>\n )}\n </div>\n )}\n </DrawerContentBody>\n </DrawerPanelContent>\n );\n\n return (\n <Drawer isExpanded={isDrawerOpen} isInline position=\"right\">\n <DrawerContent panelContent={panelContent}>\n <DrawerContentBody>{children}</DrawerContentBody>\n </DrawerContent>\n </Drawer>\n );\n};\n","import * as React from 'react';\n\ninterface GitHubUser {\n login: string;\n avatar: string;\n}\n\ninterface GitHubAuthContextType {\n user: GitHubUser | null;\n isAuthenticated: boolean;\n login: () => void;\n logout: () => void;\n}\n\nconst GitHubAuthContext = React.createContext<GitHubAuthContextType | undefined>(undefined);\n\n// Mock provider for local-only mode (no actual OAuth)\nexport const GitHubAuthProvider: React.FC<{ children: React.ReactNode; config?: any }> = ({ children }) => {\n const value = {\n user: null,\n isAuthenticated: false,\n login: () => {\n console.log('GitHub login not available in local mode');\n },\n logout: () => {\n console.log('GitHub logout not available in local mode');\n },\n };\n\n return (\n <GitHubAuthContext.Provider value={value}>\n {children}\n </GitHubAuthContext.Provider>\n );\n};\n\nexport const useGitHubAuth = () => {\n const context = React.useContext(GitHubAuthContext);\n if (context === undefined) {\n throw new Error('useGitHubAuth must be used within a GitHubAuthProvider');\n }\n return context;\n};\n","import * as React from 'react';\n\ninterface GitLabUser {\n username?: string;\n avatar?: string;\n}\n\ninterface GitLabAuthContextType {\n user: GitLabUser | null;\n isAuthenticated: boolean;\n login: () => void;\n logout: () => void;\n getToken: () => string | null;\n}\n\nconst GitLabAuthContext = React.createContext<GitLabAuthContextType | undefined>(undefined);\n\n// Mock provider for local-only mode (no actual OAuth)\nexport const GitLabAuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const value = {\n user: null,\n isAuthenticated: false,\n login: () => {\n console.log('GitLab login not available in local mode');\n },\n logout: () => {\n console.log('GitLab logout not available in local mode');\n },\n getToken: () => null,\n };\n\n return (\n <GitLabAuthContext.Provider value={value}>\n {children}\n </GitLabAuthContext.Provider>\n );\n};\n\nexport const useGitLabAuth = () => {\n const ctx = React.useContext(GitLabAuthContext);\n if (!ctx) {\n throw new Error('useGitLabAuth must be used within a GitLabAuthProvider');\n }\n return ctx;\n};\n"],"mappings":"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","names":["React","React","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_react_core","import_react_icons","import_react_router_dom","import_jsx_runtime","React","import_jsx_runtime","React","import_jsx_runtime"]}
|