@tutti-os/workspace-issue-manager 0.0.12 → 0.0.14
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/dist/{chunk-YGTTLXTS.js → chunk-5A25XEF2.js} +36 -7
- package/dist/chunk-5A25XEF2.js.map +1 -0
- package/dist/{chunk-ENJ7OUQF.js → chunk-ABQR5VIJ.js} +22 -6
- package/dist/chunk-ABQR5VIJ.js.map +1 -0
- package/dist/{chunk-XC4FNAHC.js → chunk-JOEMRSA4.js} +591 -103
- package/dist/chunk-JOEMRSA4.js.map +1 -0
- package/dist/{chunk-4A2ECWB6.js → chunk-MLBXKQLG.js} +33 -2
- package/dist/chunk-MLBXKQLG.js.map +1 -0
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +2 -2
- package/dist/{feature-D1XjdnWx.d.ts → feature-D8dqrbk5.d.ts} +9 -0
- package/dist/i18n/index.js +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/{issueManagerControllerService.interface-DsqD_RrN.d.ts → issueManagerControllerService.interface-LRf_GbaU.d.ts} +9 -2
- package/dist/services/index.d.ts +4 -3
- package/dist/services/index.js +3 -3
- package/dist/ui/index.d.ts +7 -6
- package/dist/ui/index.js +4 -4
- package/dist/workbench/index.d.ts +8 -7
- package/dist/workbench/index.js +8 -6
- package/dist/workbench/index.js.map +1 -1
- package/package.json +9 -9
- package/dist/chunk-4A2ECWB6.js.map +0 -1
- package/dist/chunk-ENJ7OUQF.js.map +0 -1
- package/dist/chunk-XC4FNAHC.js.map +0 -1
- package/dist/chunk-YGTTLXTS.js.map +0 -1
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
defaultTaskPriority,
|
|
17
17
|
formatIssueManagerDate,
|
|
18
18
|
formatIssueManagerTimestamp,
|
|
19
|
+
logIssueManagerDiagnostic,
|
|
19
20
|
persistIssueManagerIssueDraftContent,
|
|
20
21
|
persistIssueManagerTaskDraftContent,
|
|
21
22
|
resolveIssueManagerErrorMessage,
|
|
@@ -23,7 +24,7 @@ import {
|
|
|
23
24
|
resolveIssueManagerTopicDeleteErrorMessage,
|
|
24
25
|
toContextRefInput,
|
|
25
26
|
toIssueManagerWorkspaceFileLinkInput
|
|
26
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-MLBXKQLG.js";
|
|
27
28
|
import {
|
|
28
29
|
appendIssueManagerWorkspaceFileLinksToContent,
|
|
29
30
|
clampIssueManagerSidebarWidth,
|
|
@@ -34,7 +35,7 @@ import {
|
|
|
34
35
|
issueManagerSidebarMinWidth,
|
|
35
36
|
normalizeIssueManagerContent,
|
|
36
37
|
shouldAutoCollapseIssueManagerSidebar
|
|
37
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-5A25XEF2.js";
|
|
38
39
|
|
|
39
40
|
// src/ui/react/internal/shell/IssueManagerNodeState.ts
|
|
40
41
|
import { useEffect, useEffectEvent, useState } from "react";
|
|
@@ -1434,6 +1435,7 @@ function createIssueManagerControllerActionsBridge(input) {
|
|
|
1434
1435
|
const {
|
|
1435
1436
|
controllerSession,
|
|
1436
1437
|
copy,
|
|
1438
|
+
diagnostics,
|
|
1437
1439
|
feature,
|
|
1438
1440
|
issueDetail,
|
|
1439
1441
|
issueDraft,
|
|
@@ -1460,10 +1462,37 @@ function createIssueManagerControllerActionsBridge(input) {
|
|
|
1460
1462
|
),
|
|
1461
1463
|
setIsRunningTask: (update) => controllerSession.setIsRunningTask(update),
|
|
1462
1464
|
setIssueDraftInternal: (update) => controllerSession.setIssueDraftInternal(update),
|
|
1463
|
-
setIssueEditorModeState: (update) =>
|
|
1465
|
+
setIssueEditorModeState: (update) => {
|
|
1466
|
+
const nextMode = typeof update === "function" ? update(issueEditorMode) : update;
|
|
1467
|
+
logIssueManagerDiagnostic(
|
|
1468
|
+
diagnostics,
|
|
1469
|
+
"issue_editor_mode.action_requested",
|
|
1470
|
+
{
|
|
1471
|
+
nextIssueEditorMode: nextMode,
|
|
1472
|
+
previousIssueEditorMode: issueEditorMode,
|
|
1473
|
+
selectedIssueId: nodeState.selectedIssueId,
|
|
1474
|
+
selectedTaskId: nodeState.selectedTaskId
|
|
1475
|
+
},
|
|
1476
|
+
{ includeStack: true }
|
|
1477
|
+
);
|
|
1478
|
+
controllerSession.setIssueEditorModeState(nextMode);
|
|
1479
|
+
},
|
|
1464
1480
|
setReferenceTarget: (update) => controllerSession.setReferenceTarget(update),
|
|
1465
1481
|
setTaskDraftInternal: (update) => controllerSession.setTaskDraftInternal(update),
|
|
1466
|
-
setTaskEditorModeState: (update) =>
|
|
1482
|
+
setTaskEditorModeState: (update) => {
|
|
1483
|
+
const nextMode = typeof update === "function" ? update(taskEditorMode) : update;
|
|
1484
|
+
logIssueManagerDiagnostic(
|
|
1485
|
+
diagnostics,
|
|
1486
|
+
"task_editor_mode.action_requested",
|
|
1487
|
+
{
|
|
1488
|
+
nextTaskEditorMode: nextMode,
|
|
1489
|
+
previousSelectedTaskId: nodeState.selectedTaskId,
|
|
1490
|
+
previousTaskEditorMode: taskEditorMode
|
|
1491
|
+
},
|
|
1492
|
+
{ includeStack: true }
|
|
1493
|
+
);
|
|
1494
|
+
controllerSession.setTaskEditorModeState(nextMode);
|
|
1495
|
+
},
|
|
1467
1496
|
taskDetail,
|
|
1468
1497
|
taskDraft,
|
|
1469
1498
|
taskEditorMode,
|
|
@@ -1481,7 +1510,13 @@ function createIssueManagerControllerNotificationState(current, input) {
|
|
|
1481
1510
|
|
|
1482
1511
|
// src/ui/react/internal/issue/createIssueManagerIssueBindings.ts
|
|
1483
1512
|
function createIssueManagerIssueBindings(input) {
|
|
1484
|
-
const {
|
|
1513
|
+
const {
|
|
1514
|
+
controllerSession,
|
|
1515
|
+
diagnostics,
|
|
1516
|
+
feature,
|
|
1517
|
+
issueEditorMode,
|
|
1518
|
+
nodeState
|
|
1519
|
+
} = input;
|
|
1485
1520
|
return {
|
|
1486
1521
|
setIssueContent(content) {
|
|
1487
1522
|
controllerSession.setIssueDraftInternal((current) => {
|
|
@@ -1507,6 +1542,17 @@ function createIssueManagerIssueBindings(input) {
|
|
|
1507
1542
|
}));
|
|
1508
1543
|
},
|
|
1509
1544
|
setIssueEditorMode(mode) {
|
|
1545
|
+
logIssueManagerDiagnostic(
|
|
1546
|
+
diagnostics,
|
|
1547
|
+
"issue_editor_mode.requested",
|
|
1548
|
+
{
|
|
1549
|
+
nextIssueEditorMode: mode,
|
|
1550
|
+
previousIssueEditorMode: issueEditorMode,
|
|
1551
|
+
selectedIssueId: nodeState.selectedIssueId,
|
|
1552
|
+
selectedTaskId: nodeState.selectedTaskId
|
|
1553
|
+
},
|
|
1554
|
+
{ includeStack: true }
|
|
1555
|
+
);
|
|
1510
1556
|
controllerSession.setIssueEditorModeState(mode);
|
|
1511
1557
|
if (mode === "create") {
|
|
1512
1558
|
controllerSession.setIssueDraftInternal(
|
|
@@ -1540,12 +1586,24 @@ function createIssueManagerIssueBindings(input) {
|
|
|
1540
1586
|
|
|
1541
1587
|
// src/ui/react/internal/task/createIssueManagerTaskBindings.ts
|
|
1542
1588
|
function createIssueManagerTaskBindings(input) {
|
|
1543
|
-
const { controllerSession, feature, nodeState, taskEditorMode } = input;
|
|
1589
|
+
const { controllerSession, diagnostics, feature, nodeState, taskEditorMode } = input;
|
|
1544
1590
|
return {
|
|
1545
1591
|
selectTask(taskId) {
|
|
1546
|
-
controllerSession.updateNodeState(
|
|
1547
|
-
(
|
|
1548
|
-
|
|
1592
|
+
controllerSession.updateNodeState((current) => {
|
|
1593
|
+
logIssueManagerDiagnostic(
|
|
1594
|
+
diagnostics,
|
|
1595
|
+
"task_selection.requested",
|
|
1596
|
+
{
|
|
1597
|
+
activeTopicId: current.activeTopicId ?? null,
|
|
1598
|
+
nextSelectedTaskId: taskId,
|
|
1599
|
+
previousSelectedIssueId: current.selectedIssueId,
|
|
1600
|
+
previousSelectedTaskId: current.selectedTaskId,
|
|
1601
|
+
taskEditorMode
|
|
1602
|
+
},
|
|
1603
|
+
{ includeStack: true }
|
|
1604
|
+
);
|
|
1605
|
+
return applyIssueManagerTaskSelection(current, taskId);
|
|
1606
|
+
});
|
|
1549
1607
|
controllerSession.setTaskEditorModeState("read");
|
|
1550
1608
|
},
|
|
1551
1609
|
setTaskContent(content) {
|
|
@@ -1572,6 +1630,16 @@ function createIssueManagerTaskBindings(input) {
|
|
|
1572
1630
|
}));
|
|
1573
1631
|
},
|
|
1574
1632
|
setTaskEditorMode(mode) {
|
|
1633
|
+
logIssueManagerDiagnostic(
|
|
1634
|
+
diagnostics,
|
|
1635
|
+
"task_editor_mode.requested",
|
|
1636
|
+
{
|
|
1637
|
+
nextTaskEditorMode: mode,
|
|
1638
|
+
previousSelectedTaskId: nodeState.selectedTaskId,
|
|
1639
|
+
previousTaskEditorMode: taskEditorMode
|
|
1640
|
+
},
|
|
1641
|
+
{ includeStack: true }
|
|
1642
|
+
);
|
|
1575
1643
|
controllerSession.setTaskEditorModeState(mode);
|
|
1576
1644
|
if (mode === "create") {
|
|
1577
1645
|
controllerSession.setTaskDraftInternal(
|
|
@@ -1607,21 +1675,24 @@ function createIssueManagerTaskBindings(input) {
|
|
|
1607
1675
|
function createIssueManagerControllerBindings(input) {
|
|
1608
1676
|
const {
|
|
1609
1677
|
controllerSession,
|
|
1678
|
+
diagnostics,
|
|
1610
1679
|
feature,
|
|
1611
1680
|
issueEditorMode,
|
|
1612
1681
|
nodeState,
|
|
1613
|
-
|
|
1682
|
+
onResolveRichTextTriggerProviders,
|
|
1614
1683
|
taskEditorMode,
|
|
1615
1684
|
workspaceId
|
|
1616
1685
|
} = input;
|
|
1617
1686
|
const issueBindings = createIssueManagerIssueBindings({
|
|
1618
1687
|
controllerSession,
|
|
1688
|
+
diagnostics,
|
|
1619
1689
|
feature,
|
|
1620
1690
|
issueEditorMode,
|
|
1621
1691
|
nodeState
|
|
1622
1692
|
});
|
|
1623
1693
|
const taskBindings = createIssueManagerTaskBindings({
|
|
1624
1694
|
controllerSession,
|
|
1695
|
+
diagnostics,
|
|
1625
1696
|
feature,
|
|
1626
1697
|
nodeState,
|
|
1627
1698
|
taskEditorMode
|
|
@@ -1638,16 +1709,26 @@ function createIssueManagerControllerBindings(input) {
|
|
|
1638
1709
|
reportIssueSearchUsage(query) {
|
|
1639
1710
|
controllerSession.reportIssueSearchUsage(query);
|
|
1640
1711
|
},
|
|
1641
|
-
|
|
1642
|
-
return
|
|
1712
|
+
resolveRichTextTriggerProviders(surface) {
|
|
1713
|
+
return onResolveRichTextTriggerProviders?.({
|
|
1643
1714
|
surface,
|
|
1644
1715
|
workspaceId
|
|
1645
1716
|
}) ?? [];
|
|
1646
1717
|
},
|
|
1647
1718
|
selectIssue(issueId) {
|
|
1648
|
-
controllerSession.updateNodeState(
|
|
1649
|
-
(
|
|
1650
|
-
|
|
1719
|
+
controllerSession.updateNodeState((current) => {
|
|
1720
|
+
logIssueManagerDiagnostic(
|
|
1721
|
+
diagnostics,
|
|
1722
|
+
"issue_selection.requested",
|
|
1723
|
+
{
|
|
1724
|
+
nextSelectedIssueId: issueId,
|
|
1725
|
+
previousSelectedIssueId: current.selectedIssueId,
|
|
1726
|
+
previousSelectedTaskId: current.selectedTaskId
|
|
1727
|
+
},
|
|
1728
|
+
{ includeStack: true }
|
|
1729
|
+
);
|
|
1730
|
+
return applyIssueManagerIssueSelection(current, issueId);
|
|
1731
|
+
});
|
|
1651
1732
|
controllerSession.setIssueEditorModeState("read");
|
|
1652
1733
|
controllerSession.setTaskEditorModeState("read");
|
|
1653
1734
|
},
|
|
@@ -1684,19 +1765,28 @@ function resolveIssueManagerFloatingNoticeViewState(input) {
|
|
|
1684
1765
|
|
|
1685
1766
|
// src/ui/react/internal/controller/useIssueManagerControllerRuntime.ts
|
|
1686
1767
|
function useIssueManagerControllerRuntime(input) {
|
|
1687
|
-
const {
|
|
1768
|
+
const {
|
|
1769
|
+
diagnostics,
|
|
1770
|
+
feature,
|
|
1771
|
+
openSource,
|
|
1772
|
+
onStateChange,
|
|
1773
|
+
service,
|
|
1774
|
+
state,
|
|
1775
|
+
workspaceId
|
|
1776
|
+
} = input;
|
|
1688
1777
|
const controllerService = useMemo(
|
|
1689
1778
|
() => service ?? createIssueManagerControllerService(),
|
|
1690
1779
|
[service]
|
|
1691
1780
|
);
|
|
1692
1781
|
const controllerSession = useMemo(
|
|
1693
1782
|
() => controllerService.createSession({
|
|
1783
|
+
diagnostics,
|
|
1694
1784
|
feature,
|
|
1695
1785
|
openSource,
|
|
1696
1786
|
state,
|
|
1697
1787
|
workspaceId
|
|
1698
1788
|
}),
|
|
1699
|
-
[controllerService, feature, openSource, workspaceId]
|
|
1789
|
+
[controllerService, diagnostics, feature, openSource, workspaceId]
|
|
1700
1790
|
);
|
|
1701
1791
|
const snapshot = useSnapshot(
|
|
1702
1792
|
controllerSession.store
|
|
@@ -1735,16 +1825,18 @@ function useIssueManagerControllerRuntime(input) {
|
|
|
1735
1825
|
|
|
1736
1826
|
// src/ui/react/internal/controller/useIssueManagerController.ts
|
|
1737
1827
|
function useIssueManagerController({
|
|
1828
|
+
diagnostics,
|
|
1738
1829
|
feature,
|
|
1739
1830
|
openSource,
|
|
1740
1831
|
onStateChange,
|
|
1741
|
-
|
|
1832
|
+
resolveRichTextTriggerProviders,
|
|
1742
1833
|
service,
|
|
1743
1834
|
state,
|
|
1744
1835
|
workspaceId
|
|
1745
1836
|
}) {
|
|
1746
1837
|
const copy = feature.i18n;
|
|
1747
1838
|
const { controllerSession, floatingNotice, snapshot } = useIssueManagerControllerRuntime({
|
|
1839
|
+
diagnostics,
|
|
1748
1840
|
feature,
|
|
1749
1841
|
openSource,
|
|
1750
1842
|
onStateChange,
|
|
@@ -1788,6 +1880,7 @@ function useIssueManagerController({
|
|
|
1788
1880
|
const actions = createIssueManagerControllerActionsBridge({
|
|
1789
1881
|
controllerSession,
|
|
1790
1882
|
copy,
|
|
1883
|
+
diagnostics,
|
|
1791
1884
|
feature,
|
|
1792
1885
|
issueDetail,
|
|
1793
1886
|
issueDraft,
|
|
@@ -1801,10 +1894,11 @@ function useIssueManagerController({
|
|
|
1801
1894
|
});
|
|
1802
1895
|
const bindings = createIssueManagerControllerBindings({
|
|
1803
1896
|
controllerSession,
|
|
1897
|
+
diagnostics,
|
|
1804
1898
|
feature,
|
|
1805
1899
|
issueEditorMode,
|
|
1806
1900
|
nodeState,
|
|
1807
|
-
|
|
1901
|
+
onResolveRichTextTriggerProviders: resolveRichTextTriggerProviders,
|
|
1808
1902
|
taskEditorMode,
|
|
1809
1903
|
workspaceId
|
|
1810
1904
|
});
|
|
@@ -1825,6 +1919,7 @@ function useIssueManagerController({
|
|
|
1825
1919
|
canSelectExecutionDirectory,
|
|
1826
1920
|
canUploadWorkspaceFiles,
|
|
1827
1921
|
copy,
|
|
1922
|
+
diagnostics: diagnostics ?? null,
|
|
1828
1923
|
async createTopic(topicInput) {
|
|
1829
1924
|
try {
|
|
1830
1925
|
const topic = await feature.backend.createTopic({
|
|
@@ -1873,6 +1968,12 @@ function useIssueManagerController({
|
|
|
1873
1968
|
isRunningTask,
|
|
1874
1969
|
nodeState,
|
|
1875
1970
|
notification,
|
|
1971
|
+
async openMention(mention) {
|
|
1972
|
+
await feature.mentionActionHandler?.openMention({
|
|
1973
|
+
mention,
|
|
1974
|
+
workspaceId
|
|
1975
|
+
});
|
|
1976
|
+
},
|
|
1876
1977
|
providerOptions,
|
|
1877
1978
|
executionDirectoryProjectService: feature.executionDirectoryPicker?.service ?? null,
|
|
1878
1979
|
workspaceUserProjectI18n: feature.workspaceUserProjectI18n,
|
|
@@ -1916,20 +2017,22 @@ function useIssueManagerController({
|
|
|
1916
2017
|
|
|
1917
2018
|
// src/ui/react/internal/shell/useIssueManagerNodeView.ts
|
|
1918
2019
|
function useIssueManagerNodeView({
|
|
2020
|
+
diagnostics,
|
|
1919
2021
|
feature,
|
|
1920
2022
|
nodeId,
|
|
1921
2023
|
openSource,
|
|
1922
2024
|
onStateChange,
|
|
1923
|
-
|
|
2025
|
+
resolveRichTextTriggerProviders,
|
|
1924
2026
|
service,
|
|
1925
2027
|
state,
|
|
1926
2028
|
workspaceId
|
|
1927
2029
|
}) {
|
|
1928
2030
|
const controller = useIssueManagerController({
|
|
2031
|
+
diagnostics,
|
|
1929
2032
|
feature,
|
|
1930
2033
|
openSource,
|
|
1931
2034
|
onStateChange,
|
|
1932
|
-
|
|
2035
|
+
resolveRichTextTriggerProviders,
|
|
1933
2036
|
service,
|
|
1934
2037
|
state,
|
|
1935
2038
|
workspaceId
|
|
@@ -1966,6 +2069,14 @@ function useIssueManagerNodeView({
|
|
|
1966
2069
|
selectedTask,
|
|
1967
2070
|
shell: {
|
|
1968
2071
|
onCloseTaskDrawer: () => {
|
|
2072
|
+
logIssueManagerDiagnostic(
|
|
2073
|
+
controller.diagnostics,
|
|
2074
|
+
"task_drawer.close_requested",
|
|
2075
|
+
{
|
|
2076
|
+
selectedIssueId: controller.nodeState.selectedIssueId,
|
|
2077
|
+
selectedTaskId: controller.nodeState.selectedTaskId
|
|
2078
|
+
}
|
|
2079
|
+
);
|
|
1969
2080
|
controller.selectTask(null);
|
|
1970
2081
|
},
|
|
1971
2082
|
onDismissIssueCreate: () => {
|
|
@@ -1983,13 +2094,17 @@ import {
|
|
|
1983
2094
|
// src/ui/IssueManagerNode.tsx
|
|
1984
2095
|
import {
|
|
1985
2096
|
useEffect as useEffect9,
|
|
1986
|
-
useRef as
|
|
2097
|
+
useRef as useRef7
|
|
1987
2098
|
} from "react";
|
|
1988
2099
|
import { Button as Button13, PanelIcon, cn as cn11 } from "@tutti-os/ui-system";
|
|
1989
2100
|
import { WorkspaceFileReferencePicker } from "@tutti-os/workspace-file-reference/ui";
|
|
1990
2101
|
|
|
1991
2102
|
// src/ui/internal/shell/IssueManagerShell.tsx
|
|
1992
|
-
import {
|
|
2103
|
+
import {
|
|
2104
|
+
useEffect as useEffect7,
|
|
2105
|
+
useRef as useRef6,
|
|
2106
|
+
useState as useState8
|
|
2107
|
+
} from "react";
|
|
1993
2108
|
import { Button as Button11, FileCreateIcon as FileCreateIcon4, cn as cn9 } from "@tutti-os/ui-system";
|
|
1994
2109
|
|
|
1995
2110
|
// src/ui/internal/shell/IssueManagerPanels.tsx
|
|
@@ -2295,6 +2410,7 @@ function IssueManagerOutputSection({
|
|
|
2295
2410
|
}
|
|
2296
2411
|
function IssueManagerSubtaskSection({
|
|
2297
2412
|
copy,
|
|
2413
|
+
diagnostics,
|
|
2298
2414
|
onCreate,
|
|
2299
2415
|
onSelectTask,
|
|
2300
2416
|
selectedTaskId,
|
|
@@ -2316,7 +2432,17 @@ function IssueManagerSubtaskSection({
|
|
|
2316
2432
|
selectedTaskId === task.taskId ? "bg-transparency-actived" : "bg-transparent hover:bg-transparency-hover"
|
|
2317
2433
|
),
|
|
2318
2434
|
type: "button",
|
|
2319
|
-
onClick: () =>
|
|
2435
|
+
onClick: (event) => {
|
|
2436
|
+
logIssueManagerDiagnostic(diagnostics, "task_row.click", {
|
|
2437
|
+
clientX: event.clientX,
|
|
2438
|
+
clientY: event.clientY,
|
|
2439
|
+
selectedTaskId,
|
|
2440
|
+
surface: "detail_subtasks",
|
|
2441
|
+
taskId: task.taskId,
|
|
2442
|
+
taskTitle: task.title
|
|
2443
|
+
});
|
|
2444
|
+
onSelectTask(task.taskId);
|
|
2445
|
+
},
|
|
2320
2446
|
children: [
|
|
2321
2447
|
/* @__PURE__ */ jsxs3("div", { className: "min-w-0 flex-1", children: [
|
|
2322
2448
|
/* @__PURE__ */ jsxs3("div", { className: "flex min-w-0 items-center gap-2.5", children: [
|
|
@@ -2340,10 +2466,20 @@ function IssueManagerSubtaskSection({
|
|
|
2340
2466
|
|
|
2341
2467
|
// src/ui/internal/issue/IssueManagerIssueAcceptanceState.ts
|
|
2342
2468
|
function resolveIssueManagerIssueAcceptanceTaskId(input) {
|
|
2343
|
-
if (input.selectedIssue?.status !== "pending_acceptance" || input.
|
|
2469
|
+
if (input.selectedIssue?.status !== "pending_acceptance" || input.latestRun?.status !== "completed" || input.selectedTaskId) {
|
|
2344
2470
|
return null;
|
|
2345
2471
|
}
|
|
2346
|
-
|
|
2472
|
+
return resolveIssueManagerIssueRunTaskId({
|
|
2473
|
+
latestRun: input.latestRun,
|
|
2474
|
+
selectedIssue: input.selectedIssue,
|
|
2475
|
+
tasks: input.tasks
|
|
2476
|
+
});
|
|
2477
|
+
}
|
|
2478
|
+
function resolveIssueManagerIssueRunTaskId(input) {
|
|
2479
|
+
if (!input.selectedIssue) {
|
|
2480
|
+
return null;
|
|
2481
|
+
}
|
|
2482
|
+
const taskId = input.latestRun?.taskId?.trim() ?? "";
|
|
2347
2483
|
if (!taskId) {
|
|
2348
2484
|
return null;
|
|
2349
2485
|
}
|
|
@@ -2356,7 +2492,7 @@ function resolveIssueManagerIssueAcceptanceTaskId(input) {
|
|
|
2356
2492
|
return taskId;
|
|
2357
2493
|
}
|
|
2358
2494
|
function resolveIssueManagerVisibleSubtasks(input) {
|
|
2359
|
-
const hiddenTaskId = input.
|
|
2495
|
+
const hiddenTaskId = input.hiddenIssueRunTaskId?.trim() ?? "";
|
|
2360
2496
|
if (!hiddenTaskId) {
|
|
2361
2497
|
return [...input.tasks];
|
|
2362
2498
|
}
|
|
@@ -2375,6 +2511,7 @@ function IssueManagerDescriptionSection({
|
|
|
2375
2511
|
emptyLabel,
|
|
2376
2512
|
label,
|
|
2377
2513
|
minHeightClass = "min-h-[14rem]",
|
|
2514
|
+
onMentionAction,
|
|
2378
2515
|
onOpen,
|
|
2379
2516
|
variant = "card"
|
|
2380
2517
|
}) {
|
|
@@ -2419,6 +2556,7 @@ function IssueManagerDescriptionSection({
|
|
|
2419
2556
|
IssueManagerDescriptionContent,
|
|
2420
2557
|
{
|
|
2421
2558
|
content: displayContent,
|
|
2559
|
+
onMentionAction,
|
|
2422
2560
|
onOpen
|
|
2423
2561
|
}
|
|
2424
2562
|
) }) : /* @__PURE__ */ jsx4("p", { className: "text-[13px] font-normal leading-5 text-[var(--text-secondary)]", children: emptyLabel })
|
|
@@ -2446,6 +2584,7 @@ function IssueManagerDescriptionSection({
|
|
|
2446
2584
|
IssueManagerDescriptionContent,
|
|
2447
2585
|
{
|
|
2448
2586
|
content: displayContent,
|
|
2587
|
+
onMentionAction,
|
|
2449
2588
|
onOpen
|
|
2450
2589
|
}
|
|
2451
2590
|
) : /* @__PURE__ */ jsx4("p", { className: "font-normal text-[var(--text-secondary)]", children: emptyLabel })
|
|
@@ -2467,6 +2606,7 @@ function IssueManagerDescriptionSection({
|
|
|
2467
2606
|
}
|
|
2468
2607
|
function IssueManagerDescriptionContent({
|
|
2469
2608
|
content,
|
|
2609
|
+
onMentionAction,
|
|
2470
2610
|
onOpen
|
|
2471
2611
|
}) {
|
|
2472
2612
|
return /* @__PURE__ */ jsx4(
|
|
@@ -2475,6 +2615,7 @@ function IssueManagerDescriptionContent({
|
|
|
2475
2615
|
className: "min-w-0 max-w-full [overflow-wrap:anywhere]",
|
|
2476
2616
|
paragraphClassName: "break-words [overflow-wrap:anywhere]",
|
|
2477
2617
|
value: content,
|
|
2618
|
+
onMentionAction,
|
|
2478
2619
|
onOpenWorkspaceReference: onOpen ? (reference) => onOpen({
|
|
2479
2620
|
displayName: reference.label,
|
|
2480
2621
|
kind: reference.kind,
|
|
@@ -2486,7 +2627,7 @@ function IssueManagerDescriptionContent({
|
|
|
2486
2627
|
|
|
2487
2628
|
// src/ui/internal/content/IssueManagerRichTextTextarea.tsx
|
|
2488
2629
|
import { useEffect as useEffect5, useMemo as useMemo3, useRef as useRef2, useState as useState4 } from "react";
|
|
2489
|
-
import {
|
|
2630
|
+
import { RichTextTriggerEditor } from "@tutti-os/ui-rich-text/editor";
|
|
2490
2631
|
import { Button as Button3, LinkIcon, cn as cn3 } from "@tutti-os/ui-system";
|
|
2491
2632
|
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2492
2633
|
var issueManagerRichTextTextareaBaseClassName = "min-h-20 w-full rounded-[8px] border border-transparent bg-[var(--transparency-block)] p-3 text-[13px] font-normal leading-[1.3] text-[var(--text-primary)] transition-[background-color,border-color,color] outline-none shadow-none placeholder:text-[var(--text-placeholder)] hover:bg-[var(--transparency-hover)] focus:bg-[var(--transparency-hover)] focus-visible:border-transparent focus-visible:bg-[var(--transparency-hover)] focus-visible:ring-0 disabled:cursor-not-allowed disabled:bg-[var(--transparency-block)] disabled:text-[var(--text-disabled)] disabled:opacity-100 aria-invalid:border-[var(--state-danger)] aria-invalid:bg-[var(--transparency-block)] aria-invalid:hover:bg-[var(--transparency-hover)] aria-invalid:focus:bg-[var(--transparency-hover)] aria-invalid:focus-visible:bg-[var(--transparency-hover)] aria-invalid:ring-0 aria-invalid:shadow-none";
|
|
@@ -2500,7 +2641,7 @@ function IssueManagerRichTextTextarea({
|
|
|
2500
2641
|
value
|
|
2501
2642
|
}) {
|
|
2502
2643
|
const providers = useMemo3(
|
|
2503
|
-
() => controller.
|
|
2644
|
+
() => controller.resolveRichTextTriggerProviders(surface),
|
|
2504
2645
|
[controller, surface]
|
|
2505
2646
|
);
|
|
2506
2647
|
const showReferenceAction = controller.canReferenceWorkspaceFiles;
|
|
@@ -2516,12 +2657,12 @@ function IssueManagerRichTextTextarea({
|
|
|
2516
2657
|
previousValueRef.current = value;
|
|
2517
2658
|
}, [controller.referenceTarget, surface, value]);
|
|
2518
2659
|
return /* @__PURE__ */ jsx5(
|
|
2519
|
-
|
|
2660
|
+
RichTextTriggerEditor,
|
|
2520
2661
|
{
|
|
2521
2662
|
focusSignal,
|
|
2522
2663
|
maxResults: 8,
|
|
2523
2664
|
minQueryLength: 1,
|
|
2524
|
-
providers,
|
|
2665
|
+
triggerProviders: providers,
|
|
2525
2666
|
textOverrides: {
|
|
2526
2667
|
loadingLabel: controller.copy.t("richTextAt.loading"),
|
|
2527
2668
|
noMatchesLabel: controller.copy.t("richTextAt.noMatches"),
|
|
@@ -2689,7 +2830,8 @@ function IssueManagerIssuePane({
|
|
|
2689
2830
|
const tasks = controller.issueDetail.value?.tasks ?? [];
|
|
2690
2831
|
const selectedTaskId = controller.nodeState.selectedTaskId;
|
|
2691
2832
|
const selectedTask = selectedTaskId ? (controller.taskDetail.value?.task?.taskId === selectedTaskId ? controller.taskDetail.value.task : tasks.find((task) => task.taskId === selectedTaskId)) ?? null : null;
|
|
2692
|
-
const
|
|
2833
|
+
const issueLatestRun = controller.issueDetail.value?.latestRun ?? controller.issueDetail.value?.recentRuns[0] ?? null;
|
|
2834
|
+
const latestRun = selectedTask ? controller.taskDetail.value?.latestRun ?? controller.taskDetail.value?.recentRuns[0] ?? null : issueLatestRun;
|
|
2693
2835
|
const latestOutputs = selectedTask ? controller.taskDetail.value?.latestOutputs ?? [] : controller.issueDetail.value?.latestOutputs ?? [];
|
|
2694
2836
|
const issueAcceptanceTaskId = resolveIssueManagerIssueAcceptanceTaskId({
|
|
2695
2837
|
latestRun,
|
|
@@ -2697,8 +2839,13 @@ function IssueManagerIssuePane({
|
|
|
2697
2839
|
selectedTaskId,
|
|
2698
2840
|
tasks
|
|
2699
2841
|
});
|
|
2842
|
+
const issueRunTaskId = resolveIssueManagerIssueRunTaskId({
|
|
2843
|
+
latestRun: issueLatestRun,
|
|
2844
|
+
selectedIssue,
|
|
2845
|
+
tasks
|
|
2846
|
+
});
|
|
2700
2847
|
const visibleTasks = resolveIssueManagerVisibleSubtasks({
|
|
2701
|
-
|
|
2848
|
+
hiddenIssueRunTaskId: issueRunTaskId,
|
|
2702
2849
|
tasks
|
|
2703
2850
|
});
|
|
2704
2851
|
const [deleteDialogOpen, setDeleteDialogOpen] = useState5(false);
|
|
@@ -2893,6 +3040,7 @@ function IssueManagerIssuePane({
|
|
|
2893
3040
|
content: issueContent,
|
|
2894
3041
|
emptyLabel: copy.t("messages.issueContentEmpty"),
|
|
2895
3042
|
label: copy.t("labels.description"),
|
|
3043
|
+
onMentionAction: controller.openMention,
|
|
2896
3044
|
onOpen: controller.openReference,
|
|
2897
3045
|
variant: "plain"
|
|
2898
3046
|
}
|
|
@@ -2919,6 +3067,7 @@ function IssueManagerIssuePane({
|
|
|
2919
3067
|
IssueManagerSubtaskSection,
|
|
2920
3068
|
{
|
|
2921
3069
|
copy,
|
|
3070
|
+
diagnostics: controller.diagnostics,
|
|
2922
3071
|
onCreate: controller.createTaskDraft,
|
|
2923
3072
|
onSelectTask: controller.selectTask,
|
|
2924
3073
|
selectedTaskId: selectedTask?.taskId ?? null,
|
|
@@ -3872,6 +4021,7 @@ function IssueManagerTaskComposerPane({
|
|
|
3872
4021
|
}
|
|
3873
4022
|
|
|
3874
4023
|
// src/ui/internal/shell/IssueManagerTaskDrawer.tsx
|
|
4024
|
+
import { useRef as useRef4 } from "react";
|
|
3875
4025
|
import { ScrollArea as ScrollArea4, cn as cn8 } from "@tutti-os/ui-system";
|
|
3876
4026
|
|
|
3877
4027
|
// src/ui/internal/shell/IssueManagerTaskDrawerSections.tsx
|
|
@@ -4097,6 +4247,7 @@ function IssueManagerTaskDrawerReadBody({
|
|
|
4097
4247
|
content: taskContent,
|
|
4098
4248
|
emptyLabel: copy.t("messages.taskContentEmpty"),
|
|
4099
4249
|
label: copy.t("labels.description"),
|
|
4250
|
+
onMentionAction: controller.openMention,
|
|
4100
4251
|
onOpen: controller.openReference,
|
|
4101
4252
|
variant: "plain"
|
|
4102
4253
|
}
|
|
@@ -4208,13 +4359,63 @@ function IssueManagerTaskDrawer({
|
|
|
4208
4359
|
renderLatestRunStatus,
|
|
4209
4360
|
selectedIssue,
|
|
4210
4361
|
selectedTask,
|
|
4211
|
-
onClose
|
|
4362
|
+
onClose,
|
|
4363
|
+
shouldIgnoreBackdropClick
|
|
4212
4364
|
}) {
|
|
4213
4365
|
const view = resolveIssueManagerTaskDrawerViewState({
|
|
4214
4366
|
controller,
|
|
4215
4367
|
selectedTask
|
|
4216
4368
|
});
|
|
4217
4369
|
const taskContent = selectedTask?.content ?? "";
|
|
4370
|
+
const hasRequestedBackdropCloseRef = useRef4(false);
|
|
4371
|
+
const requestBackdropClose = (event, phase) => {
|
|
4372
|
+
const target = event.target;
|
|
4373
|
+
logIssueManagerDiagnostic(
|
|
4374
|
+
controller.diagnostics,
|
|
4375
|
+
"task_drawer.backdrop_close_event",
|
|
4376
|
+
{
|
|
4377
|
+
clientX: event.clientX,
|
|
4378
|
+
clientY: event.clientY,
|
|
4379
|
+
currentTargetTag: event.currentTarget.tagName,
|
|
4380
|
+
hasRequestedBackdropClose: hasRequestedBackdropCloseRef.current,
|
|
4381
|
+
isClosing,
|
|
4382
|
+
isDirectBackdropClick: event.target === event.currentTarget,
|
|
4383
|
+
phase,
|
|
4384
|
+
selectedIssueId: selectedIssue?.issueId ?? null,
|
|
4385
|
+
selectedTaskId: selectedTask?.taskId ?? null,
|
|
4386
|
+
selectedTaskTitle: selectedTask?.title ?? null,
|
|
4387
|
+
targetClassName: target instanceof HTMLElement ? target.className : null,
|
|
4388
|
+
targetTag: target instanceof HTMLElement ? target.tagName : null
|
|
4389
|
+
}
|
|
4390
|
+
);
|
|
4391
|
+
if (event.target !== event.currentTarget) {
|
|
4392
|
+
return;
|
|
4393
|
+
}
|
|
4394
|
+
event.preventDefault();
|
|
4395
|
+
event.stopPropagation();
|
|
4396
|
+
if (hasRequestedBackdropCloseRef.current) {
|
|
4397
|
+
return;
|
|
4398
|
+
}
|
|
4399
|
+
if (shouldIgnoreBackdropClick?.(event)) {
|
|
4400
|
+
return;
|
|
4401
|
+
}
|
|
4402
|
+
hasRequestedBackdropCloseRef.current = true;
|
|
4403
|
+
onClose("backdrop");
|
|
4404
|
+
};
|
|
4405
|
+
const handleBackdropPointerDown = (event) => {
|
|
4406
|
+
if (event.pointerType === "mouse" && event.button !== 0) {
|
|
4407
|
+
return;
|
|
4408
|
+
}
|
|
4409
|
+
requestBackdropClose(event, "pointer_down");
|
|
4410
|
+
};
|
|
4411
|
+
const handleBackdropClick = (event) => {
|
|
4412
|
+
if (hasRequestedBackdropCloseRef.current) {
|
|
4413
|
+
event.preventDefault();
|
|
4414
|
+
event.stopPropagation();
|
|
4415
|
+
return;
|
|
4416
|
+
}
|
|
4417
|
+
requestBackdropClose(event, "click");
|
|
4418
|
+
};
|
|
4218
4419
|
return /* @__PURE__ */ jsx16(
|
|
4219
4420
|
"div",
|
|
4220
4421
|
{
|
|
@@ -4222,7 +4423,8 @@ function IssueManagerTaskDrawer({
|
|
|
4222
4423
|
"absolute inset-0 z-20 flex justify-end overscroll-contain bg-[var(--backdrop)] backdrop-blur-[1px] motion-reduce:animate-none",
|
|
4223
4424
|
isClosing ? "motion-safe:animate-out motion-safe:fade-out-0 motion-safe:duration-[180ms] motion-safe:ease-[cubic-bezier(0.4,0,0.2,1)]" : "motion-safe:animate-in motion-safe:fade-in-0 motion-safe:duration-[180ms] motion-safe:ease-[cubic-bezier(0.4,0,0.2,1)]"
|
|
4224
4425
|
),
|
|
4225
|
-
onClick:
|
|
4426
|
+
onClick: handleBackdropClick,
|
|
4427
|
+
onPointerDown: handleBackdropPointerDown,
|
|
4226
4428
|
onTouchMove: (event) => {
|
|
4227
4429
|
event.preventDefault();
|
|
4228
4430
|
},
|
|
@@ -4244,7 +4446,7 @@ function IssueManagerTaskDrawer({
|
|
|
4244
4446
|
IssueManagerTaskDrawerHeader,
|
|
4245
4447
|
{
|
|
4246
4448
|
controller,
|
|
4247
|
-
onClose,
|
|
4449
|
+
onClose: () => onClose("header_back"),
|
|
4248
4450
|
selectedTask,
|
|
4249
4451
|
view
|
|
4250
4452
|
}
|
|
@@ -4294,7 +4496,7 @@ function IssueManagerTaskDrawer({
|
|
|
4294
4496
|
import {
|
|
4295
4497
|
useEffect as useEffect6,
|
|
4296
4498
|
useEffectEvent as useEffectEvent2,
|
|
4297
|
-
useRef as
|
|
4499
|
+
useRef as useRef5,
|
|
4298
4500
|
useState as useState7
|
|
4299
4501
|
} from "react";
|
|
4300
4502
|
function useIssueManagerShellView({
|
|
@@ -4302,8 +4504,8 @@ function useIssueManagerShellView({
|
|
|
4302
4504
|
selectedIssue,
|
|
4303
4505
|
selectedTask
|
|
4304
4506
|
}) {
|
|
4305
|
-
const layoutRef =
|
|
4306
|
-
const resizeRef =
|
|
4507
|
+
const layoutRef = useRef5(null);
|
|
4508
|
+
const resizeRef = useRef5(null);
|
|
4307
4509
|
const [sidebarWidth, setSidebarWidth] = useState7(
|
|
4308
4510
|
issueManagerSidebarDefaultWidth
|
|
4309
4511
|
);
|
|
@@ -4312,6 +4514,7 @@ function useIssueManagerShellView({
|
|
|
4312
4514
|
controller.dismissNotification();
|
|
4313
4515
|
});
|
|
4314
4516
|
const floatingNotice = controller.floatingNotice;
|
|
4517
|
+
const lastContentDiagnosticRef = useRef5(null);
|
|
4315
4518
|
useEffect6(() => {
|
|
4316
4519
|
const publishLayout = () => {
|
|
4317
4520
|
const width = layoutRef.current?.getBoundingClientRect().width ?? 0;
|
|
@@ -4352,6 +4555,48 @@ function useIssueManagerShellView({
|
|
|
4352
4555
|
selectedTaskPresent: selectedTask !== null,
|
|
4353
4556
|
taskEditorMode: controller.taskEditorMode
|
|
4354
4557
|
});
|
|
4558
|
+
useEffect6(() => {
|
|
4559
|
+
const nextDiagnostic = {
|
|
4560
|
+
isIssueEditing: content.isIssueEditing,
|
|
4561
|
+
isTaskCreating: content.isTaskCreating,
|
|
4562
|
+
isTaskDrawerOpen: content.isTaskDrawerOpen,
|
|
4563
|
+
issueEditorMode: controller.issueEditorMode,
|
|
4564
|
+
selectedIssueId: controller.nodeState.selectedIssueId,
|
|
4565
|
+
selectedTaskId: controller.nodeState.selectedTaskId,
|
|
4566
|
+
selectedTaskPresent: selectedTask !== null,
|
|
4567
|
+
taskEditorMode: controller.taskEditorMode
|
|
4568
|
+
};
|
|
4569
|
+
const previousDiagnostic = lastContentDiagnosticRef.current;
|
|
4570
|
+
if (previousDiagnostic && previousDiagnostic.isIssueEditing === nextDiagnostic.isIssueEditing && previousDiagnostic.isTaskCreating === nextDiagnostic.isTaskCreating && previousDiagnostic.isTaskDrawerOpen === nextDiagnostic.isTaskDrawerOpen && previousDiagnostic.issueEditorMode === nextDiagnostic.issueEditorMode && previousDiagnostic.selectedIssueId === nextDiagnostic.selectedIssueId && previousDiagnostic.selectedTaskId === nextDiagnostic.selectedTaskId && previousDiagnostic.selectedTaskPresent === nextDiagnostic.selectedTaskPresent && previousDiagnostic.taskEditorMode === nextDiagnostic.taskEditorMode) {
|
|
4571
|
+
return;
|
|
4572
|
+
}
|
|
4573
|
+
lastContentDiagnosticRef.current = nextDiagnostic;
|
|
4574
|
+
logIssueManagerDiagnostic(controller.diagnostics, "shell_content.derived", {
|
|
4575
|
+
isIssueEditing: content.isIssueEditing,
|
|
4576
|
+
isTaskCreating: content.isTaskCreating,
|
|
4577
|
+
isTaskDrawerOpen: content.isTaskDrawerOpen,
|
|
4578
|
+
issueEditorMode: controller.issueEditorMode,
|
|
4579
|
+
previousIsTaskDrawerOpen: previousDiagnostic?.isTaskDrawerOpen ?? null,
|
|
4580
|
+
previousSelectedTaskId: previousDiagnostic?.selectedTaskId ?? null,
|
|
4581
|
+
previousTaskEditorMode: previousDiagnostic?.taskEditorMode ?? null,
|
|
4582
|
+
selectedIssueId: controller.nodeState.selectedIssueId,
|
|
4583
|
+
selectedTaskId: controller.nodeState.selectedTaskId,
|
|
4584
|
+
selectedTaskPresent: selectedTask !== null,
|
|
4585
|
+
showBottomBar: content.showBottomBar,
|
|
4586
|
+
taskEditorMode: controller.taskEditorMode
|
|
4587
|
+
});
|
|
4588
|
+
}, [
|
|
4589
|
+
content.isIssueEditing,
|
|
4590
|
+
content.isTaskCreating,
|
|
4591
|
+
content.isTaskDrawerOpen,
|
|
4592
|
+
content.showBottomBar,
|
|
4593
|
+
controller.diagnostics,
|
|
4594
|
+
controller.issueEditorMode,
|
|
4595
|
+
controller.nodeState.selectedIssueId,
|
|
4596
|
+
controller.nodeState.selectedTaskId,
|
|
4597
|
+
controller.taskEditorMode,
|
|
4598
|
+
selectedTask
|
|
4599
|
+
]);
|
|
4355
4600
|
const sidebarViewState = resolveIssueManagerSidebarViewState({
|
|
4356
4601
|
copy: controller.copy,
|
|
4357
4602
|
issues: controller.issues
|
|
@@ -4444,9 +4689,34 @@ function useIssueManagerShellView({
|
|
|
4444
4689
|
};
|
|
4445
4690
|
}
|
|
4446
4691
|
|
|
4692
|
+
// src/ui/internal/shell/IssueManagerTaskDrawerEcho.ts
|
|
4693
|
+
var issueManagerTaskDrawerBackdropEchoMs = 900;
|
|
4694
|
+
var issueManagerTaskDrawerBackdropEchoDistancePx = 72;
|
|
4695
|
+
function shouldIgnoreIssueManagerTaskDrawerBackdropEcho(input) {
|
|
4696
|
+
if (!input.openPointer) {
|
|
4697
|
+
return {
|
|
4698
|
+
distancePx: null,
|
|
4699
|
+
elapsedMs: null,
|
|
4700
|
+
ignore: false
|
|
4701
|
+
};
|
|
4702
|
+
}
|
|
4703
|
+
const elapsedMs = input.nowMs - input.openPointer.timeMs;
|
|
4704
|
+
const distancePx = Math.hypot(
|
|
4705
|
+
input.clickClientX - input.openPointer.clientX,
|
|
4706
|
+
input.clickClientY - input.openPointer.clientY
|
|
4707
|
+
);
|
|
4708
|
+
return {
|
|
4709
|
+
distancePx,
|
|
4710
|
+
elapsedMs,
|
|
4711
|
+
ignore: elapsedMs <= (input.maxElapsedMs ?? issueManagerTaskDrawerBackdropEchoMs) && distancePx <= (input.maxDistancePx ?? issueManagerTaskDrawerBackdropEchoDistancePx)
|
|
4712
|
+
};
|
|
4713
|
+
}
|
|
4714
|
+
|
|
4447
4715
|
// src/ui/internal/shell/IssueManagerShell.tsx
|
|
4448
4716
|
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4449
4717
|
var issueManagerTaskDrawerExitDurationMs = 180;
|
|
4718
|
+
var issueManagerTaskDrawerCloseBlockerMs = 500;
|
|
4719
|
+
var issueManagerTaskDrawerCloseBlockerUntilMs = 0;
|
|
4450
4720
|
function IssueManagerShell({
|
|
4451
4721
|
controller,
|
|
4452
4722
|
emptyIllustration,
|
|
@@ -4462,30 +4732,193 @@ function IssueManagerShell({
|
|
|
4462
4732
|
selectedTask
|
|
4463
4733
|
});
|
|
4464
4734
|
const [renderedTaskDrawerTask, setRenderedTaskDrawerTask] = useState8(selectedTask);
|
|
4465
|
-
const [
|
|
4735
|
+
const [taskDrawerCloseBlockerUntilMs, setTaskDrawerCloseBlockerUntilMs] = useState8(issueManagerTaskDrawerCloseBlockerUntilMs);
|
|
4736
|
+
const lastContentPointerDownRef = useRef6(
|
|
4737
|
+
null
|
|
4738
|
+
);
|
|
4739
|
+
const taskDrawerOpenPointerRef = useRef6(
|
|
4740
|
+
null
|
|
4741
|
+
);
|
|
4742
|
+
const pendingTaskDrawerCloseRef = useRef6(false);
|
|
4743
|
+
const taskDrawerCloseBlockerTimeoutRef = useRef6(null);
|
|
4744
|
+
const previousTaskDrawerOpenRef = useRef6({
|
|
4745
|
+
isOpen: shellView.content.isTaskDrawerOpen,
|
|
4746
|
+
taskId: selectedTask?.taskId ?? null
|
|
4747
|
+
});
|
|
4748
|
+
const clearTaskDrawerCloseBlocker = () => {
|
|
4749
|
+
if (taskDrawerCloseBlockerTimeoutRef.current !== null) {
|
|
4750
|
+
window.clearTimeout(taskDrawerCloseBlockerTimeoutRef.current);
|
|
4751
|
+
taskDrawerCloseBlockerTimeoutRef.current = null;
|
|
4752
|
+
}
|
|
4753
|
+
issueManagerTaskDrawerCloseBlockerUntilMs = 0;
|
|
4754
|
+
setTaskDrawerCloseBlockerUntilMs(0);
|
|
4755
|
+
};
|
|
4756
|
+
const startTaskDrawerCloseBlocker = () => {
|
|
4757
|
+
issueManagerTaskDrawerCloseBlockerUntilMs = performance.now() + issueManagerTaskDrawerCloseBlockerMs;
|
|
4758
|
+
setTaskDrawerCloseBlockerUntilMs(issueManagerTaskDrawerCloseBlockerUntilMs);
|
|
4759
|
+
};
|
|
4760
|
+
useEffect7(() => {
|
|
4761
|
+
if (taskDrawerCloseBlockerTimeoutRef.current !== null) {
|
|
4762
|
+
window.clearTimeout(taskDrawerCloseBlockerTimeoutRef.current);
|
|
4763
|
+
taskDrawerCloseBlockerTimeoutRef.current = null;
|
|
4764
|
+
}
|
|
4765
|
+
if (taskDrawerCloseBlockerUntilMs <= performance.now()) {
|
|
4766
|
+
return void 0;
|
|
4767
|
+
}
|
|
4768
|
+
taskDrawerCloseBlockerTimeoutRef.current = window.setTimeout(() => {
|
|
4769
|
+
if (issueManagerTaskDrawerCloseBlockerUntilMs <= performance.now()) {
|
|
4770
|
+
issueManagerTaskDrawerCloseBlockerUntilMs = 0;
|
|
4771
|
+
}
|
|
4772
|
+
taskDrawerCloseBlockerTimeoutRef.current = null;
|
|
4773
|
+
setTaskDrawerCloseBlockerUntilMs(
|
|
4774
|
+
issueManagerTaskDrawerCloseBlockerUntilMs
|
|
4775
|
+
);
|
|
4776
|
+
}, taskDrawerCloseBlockerUntilMs - performance.now());
|
|
4777
|
+
return () => {
|
|
4778
|
+
if (taskDrawerCloseBlockerTimeoutRef.current !== null) {
|
|
4779
|
+
window.clearTimeout(taskDrawerCloseBlockerTimeoutRef.current);
|
|
4780
|
+
taskDrawerCloseBlockerTimeoutRef.current = null;
|
|
4781
|
+
}
|
|
4782
|
+
};
|
|
4783
|
+
}, [taskDrawerCloseBlockerUntilMs]);
|
|
4784
|
+
const handleCloseTaskDrawer = (source) => {
|
|
4785
|
+
logIssueManagerDiagnostic(
|
|
4786
|
+
controller.diagnostics,
|
|
4787
|
+
"task_drawer.close_source_requested",
|
|
4788
|
+
{
|
|
4789
|
+
isTaskDrawerOpen: shellView.content.isTaskDrawerOpen,
|
|
4790
|
+
renderedTaskId: renderedTaskDrawerTask?.taskId ?? null,
|
|
4791
|
+
selectedIssueId: selectedIssue?.issueId ?? null,
|
|
4792
|
+
selectedTaskId: selectedTask?.taskId ?? null,
|
|
4793
|
+
source
|
|
4794
|
+
}
|
|
4795
|
+
);
|
|
4796
|
+
pendingTaskDrawerCloseRef.current = true;
|
|
4797
|
+
setRenderedTaskDrawerTask(null);
|
|
4798
|
+
if (source === "backdrop") {
|
|
4799
|
+
startTaskDrawerCloseBlocker();
|
|
4800
|
+
} else {
|
|
4801
|
+
clearTaskDrawerCloseBlocker();
|
|
4802
|
+
}
|
|
4803
|
+
onCloseTaskDrawer();
|
|
4804
|
+
};
|
|
4805
|
+
const handleContentPointerDownCapture = (event) => {
|
|
4806
|
+
if (shellView.content.isTaskDrawerOpen || event.button !== 0) {
|
|
4807
|
+
return;
|
|
4808
|
+
}
|
|
4809
|
+
lastContentPointerDownRef.current = {
|
|
4810
|
+
clientX: event.clientX,
|
|
4811
|
+
clientY: event.clientY,
|
|
4812
|
+
timeMs: performance.now()
|
|
4813
|
+
};
|
|
4814
|
+
};
|
|
4815
|
+
const shouldIgnoreTaskDrawerBackdropClick = (event) => {
|
|
4816
|
+
const openPointer = taskDrawerOpenPointerRef.current;
|
|
4817
|
+
if (!openPointer) {
|
|
4818
|
+
return false;
|
|
4819
|
+
}
|
|
4820
|
+
const echo = shouldIgnoreIssueManagerTaskDrawerBackdropEcho({
|
|
4821
|
+
clickClientX: event.clientX,
|
|
4822
|
+
clickClientY: event.clientY,
|
|
4823
|
+
nowMs: performance.now(),
|
|
4824
|
+
openPointer
|
|
4825
|
+
});
|
|
4826
|
+
if (echo.ignore) {
|
|
4827
|
+
logIssueManagerDiagnostic(
|
|
4828
|
+
controller.diagnostics,
|
|
4829
|
+
"task_drawer.backdrop_click_ignored_as_open_echo",
|
|
4830
|
+
{
|
|
4831
|
+
clickClientX: event.clientX,
|
|
4832
|
+
clickClientY: event.clientY,
|
|
4833
|
+
distancePx: echo.distancePx,
|
|
4834
|
+
elapsedMs: echo.elapsedMs,
|
|
4835
|
+
openClientX: openPointer.clientX,
|
|
4836
|
+
openClientY: openPointer.clientY,
|
|
4837
|
+
selectedIssueId: selectedIssue?.issueId ?? null,
|
|
4838
|
+
selectedTaskId: selectedTask?.taskId ?? null
|
|
4839
|
+
}
|
|
4840
|
+
);
|
|
4841
|
+
}
|
|
4842
|
+
return echo.ignore;
|
|
4843
|
+
};
|
|
4466
4844
|
useEffect7(() => {
|
|
4845
|
+
const selectedTaskId = selectedTask?.taskId ?? null;
|
|
4846
|
+
const previousOpen = previousTaskDrawerOpenRef.current;
|
|
4467
4847
|
if (shellView.content.isTaskDrawerOpen) {
|
|
4468
|
-
|
|
4469
|
-
|
|
4848
|
+
if (pendingTaskDrawerCloseRef.current) {
|
|
4849
|
+
return void 0;
|
|
4850
|
+
}
|
|
4851
|
+
if (!previousOpen.isOpen || previousOpen.taskId !== selectedTaskId) {
|
|
4852
|
+
taskDrawerOpenPointerRef.current = lastContentPointerDownRef.current;
|
|
4853
|
+
logIssueManagerDiagnostic(
|
|
4854
|
+
controller.diagnostics,
|
|
4855
|
+
"task_drawer.open_state",
|
|
4856
|
+
{
|
|
4857
|
+
isOpen: true,
|
|
4858
|
+
openClientX: taskDrawerOpenPointerRef.current?.clientX ?? null,
|
|
4859
|
+
openClientY: taskDrawerOpenPointerRef.current?.clientY ?? null,
|
|
4860
|
+
selectedIssueId: selectedIssue?.issueId ?? null,
|
|
4861
|
+
selectedTaskId,
|
|
4862
|
+
selectedTaskTitle: selectedTask?.title ?? null
|
|
4863
|
+
}
|
|
4864
|
+
);
|
|
4865
|
+
}
|
|
4866
|
+
previousTaskDrawerOpenRef.current = {
|
|
4867
|
+
isOpen: true,
|
|
4868
|
+
taskId: selectedTaskId
|
|
4869
|
+
};
|
|
4870
|
+
if (renderedTaskDrawerTask?.taskId !== selectedTaskId) {
|
|
4871
|
+
setRenderedTaskDrawerTask(selectedTask);
|
|
4872
|
+
}
|
|
4470
4873
|
return void 0;
|
|
4471
4874
|
}
|
|
4875
|
+
previousTaskDrawerOpenRef.current = {
|
|
4876
|
+
isOpen: false,
|
|
4877
|
+
taskId: null
|
|
4878
|
+
};
|
|
4879
|
+
taskDrawerOpenPointerRef.current = null;
|
|
4880
|
+
pendingTaskDrawerCloseRef.current = false;
|
|
4472
4881
|
if (!renderedTaskDrawerTask) {
|
|
4473
4882
|
return void 0;
|
|
4474
4883
|
}
|
|
4475
|
-
|
|
4884
|
+
logIssueManagerDiagnostic(
|
|
4885
|
+
controller.diagnostics,
|
|
4886
|
+
"task_drawer.exit_started",
|
|
4887
|
+
{
|
|
4888
|
+
renderedTaskId: renderedTaskDrawerTask.taskId,
|
|
4889
|
+
renderedTaskTitle: renderedTaskDrawerTask.title,
|
|
4890
|
+
selectedIssueId: selectedIssue?.issueId ?? null,
|
|
4891
|
+
selectedTaskId: selectedTask?.taskId ?? null
|
|
4892
|
+
}
|
|
4893
|
+
);
|
|
4476
4894
|
const timeout = window.setTimeout(() => {
|
|
4895
|
+
logIssueManagerDiagnostic(
|
|
4896
|
+
controller.diagnostics,
|
|
4897
|
+
"task_drawer.exit_finished",
|
|
4898
|
+
{
|
|
4899
|
+
renderedTaskId: renderedTaskDrawerTask.taskId,
|
|
4900
|
+
renderedTaskTitle: renderedTaskDrawerTask.title
|
|
4901
|
+
}
|
|
4902
|
+
);
|
|
4477
4903
|
setRenderedTaskDrawerTask(null);
|
|
4478
|
-
setIsTaskDrawerClosing(false);
|
|
4479
4904
|
}, issueManagerTaskDrawerExitDurationMs);
|
|
4480
4905
|
return () => {
|
|
4481
4906
|
window.clearTimeout(timeout);
|
|
4482
4907
|
};
|
|
4483
4908
|
}, [
|
|
4909
|
+
controller.diagnostics,
|
|
4484
4910
|
renderedTaskDrawerTask,
|
|
4911
|
+
renderedTaskDrawerTask?.taskId,
|
|
4912
|
+
selectedIssue?.issueId,
|
|
4485
4913
|
selectedTask,
|
|
4914
|
+
selectedTask?.taskId,
|
|
4915
|
+
selectedTask?.title,
|
|
4486
4916
|
shellView.content.isTaskDrawerOpen
|
|
4487
4917
|
]);
|
|
4488
|
-
const
|
|
4918
|
+
const isTaskDrawerOpenForRender = shellView.content.isTaskDrawerOpen && !pendingTaskDrawerCloseRef.current;
|
|
4919
|
+
const taskDrawerTask = isTaskDrawerOpenForRender ? selectedTask : renderedTaskDrawerTask;
|
|
4920
|
+
const isTaskDrawerClosing = !isTaskDrawerOpenForRender && renderedTaskDrawerTask !== null;
|
|
4921
|
+
const isTaskDrawerCloseBlockerVisible = !taskDrawerTask && taskDrawerCloseBlockerUntilMs > performance.now();
|
|
4489
4922
|
return /* @__PURE__ */ jsxs15(
|
|
4490
4923
|
"div",
|
|
4491
4924
|
{
|
|
@@ -4529,60 +4962,91 @@ function IssueManagerShell({
|
|
|
4529
4962
|
children: /* @__PURE__ */ jsx17("span", { className: "absolute top-0 bottom-0 left-1/2 w-px -translate-x-1/2 bg-transparent transition-[background-color,width] duration-150 group-hover:w-0.5 group-hover:bg-[color-mix(in_srgb,var(--border-focus)_40%,transparent)] group-focus-visible:w-0.5 group-focus-visible:bg-[color-mix(in_srgb,var(--border-focus)_40%,transparent)]" })
|
|
4530
4963
|
}
|
|
4531
4964
|
),
|
|
4532
|
-
/* @__PURE__ */ jsxs15(
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
selectedIssue
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4965
|
+
/* @__PURE__ */ jsxs15(
|
|
4966
|
+
"div",
|
|
4967
|
+
{
|
|
4968
|
+
className: "relative h-full min-h-0 overflow-hidden bg-transparent @container/issue-manager-content",
|
|
4969
|
+
onPointerDownCapture: handleContentPointerDownCapture,
|
|
4970
|
+
children: [
|
|
4971
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex h-full min-h-0 flex-col", children: [
|
|
4972
|
+
/* @__PURE__ */ jsx17("div", { className: "min-h-0 flex-1 overflow-hidden", children: shellView.content.isIssueEditing ? /* @__PURE__ */ jsx17(
|
|
4973
|
+
IssueManagerIssuePane,
|
|
4974
|
+
{
|
|
4975
|
+
controller,
|
|
4976
|
+
renderLatestRunStatus,
|
|
4977
|
+
selectedIssue,
|
|
4978
|
+
onDismissCreate: onDismissIssueCreate
|
|
4979
|
+
}
|
|
4980
|
+
) : shellView.content.isTaskCreating ? /* @__PURE__ */ jsx17(
|
|
4981
|
+
IssueManagerTaskComposerPane,
|
|
4982
|
+
{
|
|
4983
|
+
controller,
|
|
4984
|
+
selectedIssue,
|
|
4985
|
+
onCancel: () => controller.setTaskEditorMode("read")
|
|
4986
|
+
}
|
|
4987
|
+
) : selectedIssue ? /* @__PURE__ */ jsx17(
|
|
4988
|
+
IssueManagerIssuePane,
|
|
4989
|
+
{
|
|
4990
|
+
controller,
|
|
4991
|
+
renderLatestRunStatus,
|
|
4992
|
+
selectedIssue,
|
|
4993
|
+
onDismissCreate: onDismissIssueCreate
|
|
4994
|
+
}
|
|
4995
|
+
) : /* @__PURE__ */ jsx17(
|
|
4996
|
+
IssueManagerShellEmptyState,
|
|
4997
|
+
{
|
|
4998
|
+
controller,
|
|
4999
|
+
emptyIllustration
|
|
5000
|
+
}
|
|
5001
|
+
) }),
|
|
5002
|
+
/* @__PURE__ */ jsx17(
|
|
5003
|
+
IssueManagerBottomBar,
|
|
5004
|
+
{
|
|
5005
|
+
controller,
|
|
5006
|
+
isNarrowLayout: shellView.isNarrowLayout,
|
|
5007
|
+
selectedIssue,
|
|
5008
|
+
visible: shellView.content.showBottomBar
|
|
5009
|
+
}
|
|
5010
|
+
)
|
|
5011
|
+
] }),
|
|
5012
|
+
taskDrawerTask ? /* @__PURE__ */ jsx17(
|
|
5013
|
+
IssueManagerTaskDrawer,
|
|
5014
|
+
{
|
|
5015
|
+
controller,
|
|
5016
|
+
isClosing: isTaskDrawerClosing,
|
|
5017
|
+
renderLatestRunStatus,
|
|
5018
|
+
selectedIssue,
|
|
5019
|
+
selectedTask: taskDrawerTask,
|
|
5020
|
+
onClose: handleCloseTaskDrawer,
|
|
5021
|
+
shouldIgnoreBackdropClick: shouldIgnoreTaskDrawerBackdropClick
|
|
5022
|
+
}
|
|
5023
|
+
) : null,
|
|
5024
|
+
isTaskDrawerCloseBlockerVisible ? /* @__PURE__ */ jsx17(
|
|
5025
|
+
"div",
|
|
5026
|
+
{
|
|
5027
|
+
"aria-hidden": "true",
|
|
5028
|
+
className: "absolute inset-0 z-20 bg-transparent",
|
|
5029
|
+
onClick: (event) => {
|
|
5030
|
+
event.preventDefault();
|
|
5031
|
+
event.stopPropagation();
|
|
5032
|
+
},
|
|
5033
|
+
onDoubleClick: (event) => {
|
|
5034
|
+
event.preventDefault();
|
|
5035
|
+
event.stopPropagation();
|
|
5036
|
+
},
|
|
5037
|
+
onPointerDown: (event) => {
|
|
5038
|
+
event.preventDefault();
|
|
5039
|
+
event.stopPropagation();
|
|
5040
|
+
},
|
|
5041
|
+
onPointerUp: (event) => {
|
|
5042
|
+
event.preventDefault();
|
|
5043
|
+
event.stopPropagation();
|
|
5044
|
+
}
|
|
5045
|
+
}
|
|
5046
|
+
) : null
|
|
5047
|
+
]
|
|
5048
|
+
}
|
|
5049
|
+
)
|
|
4586
5050
|
]
|
|
4587
5051
|
}
|
|
4588
5052
|
);
|
|
@@ -4944,6 +5408,7 @@ function IssueManagerTopicDialog({
|
|
|
4944
5408
|
// src/ui/IssueManagerNode.tsx
|
|
4945
5409
|
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4946
5410
|
function IssueManagerNode({
|
|
5411
|
+
diagnostics,
|
|
4947
5412
|
emptyIllustration,
|
|
4948
5413
|
feature,
|
|
4949
5414
|
nodeId,
|
|
@@ -4951,30 +5416,53 @@ function IssueManagerNode({
|
|
|
4951
5416
|
openRequest,
|
|
4952
5417
|
onStateChange,
|
|
4953
5418
|
renderLatestRunStatus,
|
|
4954
|
-
|
|
5419
|
+
resolveRichTextTriggerProviders,
|
|
4955
5420
|
service,
|
|
4956
5421
|
state,
|
|
4957
5422
|
workspaceId
|
|
4958
5423
|
}) {
|
|
4959
5424
|
const { controller, referencePicker, selectedIssue, selectedTask, shell } = useIssueManagerNodeView({
|
|
5425
|
+
diagnostics,
|
|
4960
5426
|
feature,
|
|
4961
5427
|
nodeId,
|
|
4962
5428
|
openSource,
|
|
4963
5429
|
onStateChange,
|
|
4964
|
-
|
|
5430
|
+
resolveRichTextTriggerProviders,
|
|
4965
5431
|
service,
|
|
4966
5432
|
state,
|
|
4967
5433
|
workspaceId
|
|
4968
5434
|
});
|
|
4969
|
-
const lastHandledOpenRequestIdRef =
|
|
5435
|
+
const lastHandledOpenRequestIdRef = useRef7(null);
|
|
4970
5436
|
useEffect9(() => {
|
|
4971
5437
|
if (!openRequest?.requestId) {
|
|
4972
5438
|
return;
|
|
4973
5439
|
}
|
|
4974
5440
|
if (lastHandledOpenRequestIdRef.current === openRequest.requestId) {
|
|
5441
|
+
logIssueManagerDiagnostic(
|
|
5442
|
+
controller.diagnostics,
|
|
5443
|
+
"open_request.skipped_duplicate",
|
|
5444
|
+
{
|
|
5445
|
+
issueId: openRequest.issueId,
|
|
5446
|
+
requestId: openRequest.requestId,
|
|
5447
|
+
taskId: openRequest.taskId?.trim() || null,
|
|
5448
|
+
topicId: openRequest.topicId?.trim() || null
|
|
5449
|
+
}
|
|
5450
|
+
);
|
|
4975
5451
|
return;
|
|
4976
5452
|
}
|
|
4977
5453
|
lastHandledOpenRequestIdRef.current = openRequest.requestId;
|
|
5454
|
+
logIssueManagerDiagnostic(
|
|
5455
|
+
controller.diagnostics,
|
|
5456
|
+
"open_request.consumed",
|
|
5457
|
+
{
|
|
5458
|
+
issueId: openRequest.issueId,
|
|
5459
|
+
mode: openRequest.mode ?? null,
|
|
5460
|
+
requestId: openRequest.requestId,
|
|
5461
|
+
taskId: openRequest.taskId?.trim() || null,
|
|
5462
|
+
topicId: openRequest.topicId?.trim() || null
|
|
5463
|
+
},
|
|
5464
|
+
{ includeStack: true }
|
|
5465
|
+
);
|
|
4978
5466
|
if (openRequest.topicId?.trim()) {
|
|
4979
5467
|
controller.selectTopic(openRequest.topicId);
|
|
4980
5468
|
}
|
|
@@ -5165,4 +5653,4 @@ export {
|
|
|
5165
5653
|
IssueManagerNode,
|
|
5166
5654
|
IssueManagerNodeHeader
|
|
5167
5655
|
};
|
|
5168
|
-
//# sourceMappingURL=chunk-
|
|
5656
|
+
//# sourceMappingURL=chunk-JOEMRSA4.js.map
|