@parhelia/core 0.1.12468 → 0.1.12470
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/config/config.js +2 -21
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +0 -2
- package/dist/config/types.js.map +1 -1
- package/dist/editor/ConfirmationDialog.js +4 -20
- package/dist/editor/ConfirmationDialog.js.map +1 -1
- package/dist/editor/ContentTree.js +7 -19
- package/dist/editor/ContentTree.js.map +1 -1
- package/dist/editor/Editor.js.map +1 -1
- package/dist/editor/PictureCropper.js +41 -45
- package/dist/editor/PictureCropper.js.map +1 -1
- package/dist/editor/ai/AgentTerminal.js +8 -97
- package/dist/editor/ai/AgentTerminal.js.map +1 -1
- package/dist/editor/ai/AgentTerminalStatusBar.js +0 -65
- package/dist/editor/ai/AgentTerminalStatusBar.js.map +1 -1
- package/dist/editor/ai/Agents.js +0 -19
- package/dist/editor/ai/Agents.js.map +1 -1
- package/dist/editor/ai/AiResponseMessage.js +0 -5
- package/dist/editor/ai/AiResponseMessage.js.map +1 -1
- package/dist/editor/ai/ContentInspectorPopover.d.ts +0 -1
- package/dist/editor/ai/ContentInspectorPopover.js +8 -22
- package/dist/editor/ai/ContentInspectorPopover.js.map +1 -1
- package/dist/editor/ai/ToolCallDisplay.d.ts +0 -2
- package/dist/editor/ai/ToolCallDisplay.js +11 -54
- package/dist/editor/ai/ToolCallDisplay.js.map +1 -1
- package/dist/editor/ai/dialogs/AgentDialogHandler.js +3 -32
- package/dist/editor/ai/dialogs/AgentDialogHandler.js.map +1 -1
- package/dist/editor/ai/dialogs/QuestionnaireInline.js +20 -55
- package/dist/editor/ai/dialogs/QuestionnaireInline.js.map +1 -1
- package/dist/editor/ai/dialogs/agentDialogTypes.d.ts +4 -7
- package/dist/editor/ai/dialogs/agentDialogTypes.js.map +1 -1
- package/dist/editor/ai/types.d.ts +0 -2
- package/dist/editor/services/agentService.d.ts +0 -27
- package/dist/editor/services/agentService.js +2 -11
- package/dist/editor/services/agentService.js.map +1 -1
- package/dist/editor/services/aiService.js +3 -54
- package/dist/editor/services/aiService.js.map +1 -1
- package/dist/editor/services/serviceHelper.js +2 -5
- package/dist/editor/services/serviceHelper.js.map +1 -1
- package/dist/editor/settings/About.js +4 -40
- package/dist/editor/settings/About.js.map +1 -1
- package/dist/editor/settings/panels/ProjectTemplateAgentPanel.d.ts +1 -7
- package/dist/editor/settings/panels/ProjectTemplateAgentPanel.js +3 -3
- package/dist/editor/settings/panels/ProjectTemplateAgentPanel.js.map +1 -1
- package/dist/editor/settings/panels/ProjectTemplatesPanel.js +84 -165
- package/dist/editor/settings/panels/ProjectTemplatesPanel.js.map +1 -1
- package/dist/editor/settings/panels/index.d.ts +0 -1
- package/dist/editor/settings/panels/index.js +0 -1
- package/dist/editor/settings/panels/index.js.map +1 -1
- package/dist/editor/sidebar/NavigationPanelItem.js +1 -1
- package/dist/editor/sidebar/NavigationPanelItem.js.map +1 -1
- package/dist/editor/sidebar/WorkspaceButton.js +1 -1
- package/dist/editor/sidebar/WorkspaceButton.js.map +1 -1
- package/dist/editor/tree-indicators/GutterColumns.js +4 -24
- package/dist/editor/tree-indicators/GutterColumns.js.map +1 -1
- package/dist/editor/tree-indicators/types.d.ts +0 -10
- package/dist/editor/ui/Splitter.d.ts +0 -1
- package/dist/editor/ui/Splitter.js +1 -7
- package/dist/editor/ui/Splitter.js.map +1 -1
- package/dist/licensing/LicenseContext.js +4 -40
- package/dist/licensing/LicenseContext.js.map +1 -1
- package/dist/licensing/LicenseOverlay.js +1 -1
- package/dist/licensing/LicenseOverlay.js.map +1 -1
- package/dist/licensing/types.d.ts +1 -3
- package/dist/licensing/types.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/task-board/TaskBoardWorkspace.js +354 -165
- package/dist/task-board/TaskBoardWorkspace.js.map +1 -1
- package/dist/task-board/assigneeDisplay.js +3 -1
- package/dist/task-board/assigneeDisplay.js.map +1 -1
- package/dist/task-board/components/CreateProjectDialog.js +1 -2
- package/dist/task-board/components/CreateProjectDialog.js.map +1 -1
- package/dist/task-board/components/ProjectDashboard.js +1 -2
- package/dist/task-board/components/ProjectDashboard.js.map +1 -1
- package/dist/task-board/components/ProjectSettingsDialog.d.ts +0 -1
- package/dist/task-board/components/ProjectSettingsDialog.js +12 -146
- package/dist/task-board/components/ProjectSettingsDialog.js.map +1 -1
- package/dist/task-board/components/TaskAgentPanel.d.ts +0 -1
- package/dist/task-board/components/TaskAgentPanel.js +2 -2
- package/dist/task-board/components/TaskAgentPanel.js.map +1 -1
- package/dist/task-board/components/TaskAssigneePicker.js +2 -2
- package/dist/task-board/components/TaskAssigneePicker.js.map +1 -1
- package/dist/task-board/components/TaskBoardMyTasksSidebar.js +1 -1
- package/dist/task-board/components/TaskBoardMyTasksSidebar.js.map +1 -1
- package/dist/task-board/components/TaskDetailDialog.d.ts +0 -1
- package/dist/task-board/components/TaskDetailDialog.js +2 -2
- package/dist/task-board/components/TaskDetailDialog.js.map +1 -1
- package/dist/task-board/components/TaskDetailPanel.d.ts +0 -1
- package/dist/task-board/components/TaskDetailPanel.js +8 -23
- package/dist/task-board/components/TaskDetailPanel.js.map +1 -1
- package/dist/task-board/components/TaskRow.js +2 -3
- package/dist/task-board/components/TaskRow.js.map +1 -1
- package/dist/task-board/components/WizardTaskDetailsPanel.js +1 -2
- package/dist/task-board/components/WizardTaskDetailsPanel.js.map +1 -1
- package/dist/task-board/services/taskService.d.ts +1 -17
- package/dist/task-board/services/taskService.js +0 -56
- package/dist/task-board/services/taskService.js.map +1 -1
- package/dist/task-board/taskExecutionRecords.js +0 -2
- package/dist/task-board/taskExecutionRecords.js.map +1 -1
- package/dist/task-board/types.d.ts +1 -78
- package/dist/task-board/utils/taskDependencyOrdering.d.ts +0 -6
- package/dist/task-board/utils/taskDependencyOrdering.js +1 -138
- package/dist/task-board/utils/taskDependencyOrdering.js.map +1 -1
- package/dist/task-board/views/DependencyGraphView.d.ts +2 -5
- package/dist/task-board/views/DependencyGraphView.js +69 -261
- package/dist/task-board/views/DependencyGraphView.js.map +1 -1
- package/dist/task-board/views/KanbanView.js +1 -8
- package/dist/task-board/views/KanbanView.js.map +1 -1
- package/dist/task-board/views/ListView.js +1 -1
- package/dist/task-board/views/ListView.js.map +1 -1
- package/dist/task-board/views/WizardView.js +24 -30
- package/dist/task-board/views/WizardView.js.map +1 -1
- package/dist/tour/Tour.js +32 -0
- package/dist/tour/Tour.js.map +1 -1
- package/package.json +1 -1
- package/dist/editor/settings/panels/PersistentLogsPanel.d.ts +0 -2
- package/dist/editor/settings/panels/PersistentLogsPanel.js +0 -244
- package/dist/editor/settings/panels/PersistentLogsPanel.js.map +0 -1
- package/dist/task-board/components/ProjectExecutionUserPicker.d.ts +0 -14
- package/dist/task-board/components/ProjectExecutionUserPicker.js +0 -65
- package/dist/task-board/components/ProjectExecutionUserPicker.js.map +0 -1
- package/dist/task-board/components/TaskboardPersistentLogPanel.d.ts +0 -11
- package/dist/task-board/components/TaskboardPersistentLogPanel.js +0 -141
- package/dist/task-board/components/TaskboardPersistentLogPanel.js.map +0 -1
- package/dist/task-board/persistentLogCopy.d.ts +0 -7
- package/dist/task-board/persistentLogCopy.js +0 -80
- package/dist/task-board/persistentLogCopy.js.map +0 -1
- package/dist/task-board/persistentLogLabels.d.ts +0 -38
- package/dist/task-board/persistentLogLabels.js +0 -189
- package/dist/task-board/persistentLogLabels.js.map +0 -1
- package/dist/task-board/useTaskBoardAgentPanelState.d.ts +0 -34
- package/dist/task-board/useTaskBoardAgentPanelState.js +0 -283
- package/dist/task-board/useTaskBoardAgentPanelState.js.map +0 -1
|
@@ -4,6 +4,7 @@ import { toast } from "sonner";
|
|
|
4
4
|
import { cn } from "../lib/utils";
|
|
5
5
|
import { Splitter } from "../editor/ui/Splitter";
|
|
6
6
|
import { deleteProject, getExecutionState, getGraphLayout, getProjects, getTasks, getDependencies, runOrchestrator, triggerPlanning, updateProject, updateTask, } from "./services/taskService";
|
|
7
|
+
import { getAgent, } from "../editor/services/agentService";
|
|
7
8
|
import { loadAiProfiles } from "../editor/services/aiService";
|
|
8
9
|
import { useEditContext } from "../editor/client/editContext";
|
|
9
10
|
import { KanbanView } from "./views/KanbanView";
|
|
@@ -12,7 +13,7 @@ import { DependencyGraphView } from "./views/DependencyGraphView";
|
|
|
12
13
|
import { WizardView } from "./views/WizardView";
|
|
13
14
|
import { SimpleTabs } from "../editor/ui/SimpleTabs";
|
|
14
15
|
import { TaskDetailPanel } from "./components/TaskDetailPanel";
|
|
15
|
-
import { TaskAgentPanel } from "./components/TaskAgentPanel";
|
|
16
|
+
import { TaskAgentPanel, } from "./components/TaskAgentPanel";
|
|
16
17
|
import { ProjectDashboard, } from "./components/ProjectDashboard";
|
|
17
18
|
import { CreateTaskDialog } from "./components/CreateTaskDialog";
|
|
18
19
|
import { AssignAgentDialog } from "./components/AssignAgentDialog";
|
|
@@ -35,7 +36,6 @@ import { WizardCommunicationCenter } from "./components/WizardCommunicationCente
|
|
|
35
36
|
import { Button } from "../components/ui/button";
|
|
36
37
|
import { Loader2, Plus } from "lucide-react";
|
|
37
38
|
import { MainContentTree } from "../editor/sidebar/MainContentTree";
|
|
38
|
-
import { useTaskBoardAgentPanelState } from "./useTaskBoardAgentPanelState";
|
|
39
39
|
function TaskboardPreviewEditor({ itemDescriptor, }) {
|
|
40
40
|
const slotContext = useEditorSlotContext({
|
|
41
41
|
slotId: "taskboard-preview-slot",
|
|
@@ -50,7 +50,6 @@ const TASKBOARD_PROJECT_QUERY_KEY = "tbProjectId";
|
|
|
50
50
|
const TASKBOARD_TASK_QUERY_KEY = "tbTaskId";
|
|
51
51
|
const TASKBOARD_VIEW_QUERY_KEY = "tbView";
|
|
52
52
|
const TASKBOARD_WIZARD_QUERY_KEY = "tbWizard";
|
|
53
|
-
const WS_REFRESH_DELAY_MS = 500;
|
|
54
53
|
function getInitialQueryValue(queryKey) {
|
|
55
54
|
if (typeof window === "undefined")
|
|
56
55
|
return null;
|
|
@@ -162,6 +161,11 @@ export function TaskBoardWorkspace() {
|
|
|
162
161
|
const [subprojectTasksByProjectId, setSubprojectTasksByProjectId] = useState({});
|
|
163
162
|
const [subprojectExecutionRecordsByProjectId, setSubprojectExecutionRecordsByProjectId,] = useState({});
|
|
164
163
|
const [subprojectCountsLoading, setSubprojectCountsLoading] = useState(false);
|
|
164
|
+
const [previewItemName, setPreviewItemName] = useState("");
|
|
165
|
+
const [previewItemPath, setPreviewItemPath] = useState("");
|
|
166
|
+
const [agentContextItems, setAgentContextItems] = useState([]);
|
|
167
|
+
const [contextItemNamesByKey, setContextItemNamesByKey] = useState({});
|
|
168
|
+
const [contextItemPathsByKey, setContextItemPathsByKey] = useState({});
|
|
165
169
|
const [wizardPinnedTaskId, setWizardPinnedTaskId] = useState(null);
|
|
166
170
|
const [, setWizardPinnedTaskSource] = useState(null);
|
|
167
171
|
const [wizardForceOverview, setWizardForceOverview] = useState(false);
|
|
@@ -179,15 +183,6 @@ export function TaskBoardWorkspace() {
|
|
|
179
183
|
}, [setWizardPinnedTask]);
|
|
180
184
|
const wsRefreshTimeoutRef = useRef(null);
|
|
181
185
|
const wsSubprojectRefreshTimeoutRef = useRef(null);
|
|
182
|
-
const wsRefreshQueuedRef = useRef(false);
|
|
183
|
-
const wsRefreshRunningRef = useRef(false);
|
|
184
|
-
const wsRefreshNeedsTasksRef = useRef(false);
|
|
185
|
-
const wsRefreshNeedsExecutionStateRef = useRef(false);
|
|
186
|
-
const wsRefreshNeedsDependenciesRef = useRef(false);
|
|
187
|
-
const wsRefreshNeedsProjectsRef = useRef(false);
|
|
188
|
-
const wsSubprojectRefreshQueuedRef = useRef(false);
|
|
189
|
-
const wsSubprojectRefreshRunningRef = useRef(false);
|
|
190
|
-
const wsSubprojectRefreshNeedsProjectsRef = useRef(false);
|
|
191
186
|
const wizardCloseTransitionTimeoutRef = useRef(null);
|
|
192
187
|
const projectsRequestCountRef = useRef(0);
|
|
193
188
|
const tasksRequestCountRef = useRef(0);
|
|
@@ -416,16 +411,110 @@ export function TaskBoardWorkspace() {
|
|
|
416
411
|
return selectedProject;
|
|
417
412
|
return (projects.find((project) => project.project.projectId === selectedTask.projectId) ?? selectedProject);
|
|
418
413
|
}, [projects, selectedProject, selectedTask]);
|
|
419
|
-
const
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
414
|
+
const selectedTaskIsPlan = useMemo(() => {
|
|
415
|
+
const taskType = String(selectedTask?.taskType ?? "").toLowerCase();
|
|
416
|
+
return taskType === "plan" || selectedTask?.title === "Project Plan";
|
|
417
|
+
}, [selectedTask]);
|
|
418
|
+
const selectedTaskIsBlocked = useMemo(() => {
|
|
419
|
+
if (!selectedTask)
|
|
420
|
+
return false;
|
|
421
|
+
if (selectedTask.projectId !== selectedProjectId)
|
|
422
|
+
return false;
|
|
423
|
+
const blockerIds = dependencies
|
|
424
|
+
.filter((dependency) => dependency.taskId === selectedTask.taskId &&
|
|
425
|
+
dependency.dependencyType === "BlockedBy")
|
|
426
|
+
.map((dependency) => dependency.dependsOnTaskId);
|
|
427
|
+
if (blockerIds.length === 0)
|
|
428
|
+
return false;
|
|
429
|
+
const taskById = new Map(tasksWithDisplayAssignees.map((task) => [task.taskId, task]));
|
|
430
|
+
return blockerIds.some((blockerId) => {
|
|
431
|
+
const blockerTask = taskById.get(blockerId);
|
|
432
|
+
return (!blockerTask ||
|
|
433
|
+
normalizeTaskStatus(blockerTask.status, blockerTask.executionState) !==
|
|
434
|
+
"Done");
|
|
435
|
+
});
|
|
436
|
+
}, [
|
|
424
437
|
selectedTask,
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
438
|
+
selectedProjectId,
|
|
439
|
+
dependencies,
|
|
440
|
+
tasksWithDisplayAssignees,
|
|
441
|
+
]);
|
|
442
|
+
const selectedTaskHasAssignedAgentProfile = useMemo(() => {
|
|
443
|
+
if (!selectedTask)
|
|
444
|
+
return false;
|
|
445
|
+
return selectedTask.assigneeType === "Agent" && !!selectedTask.assigneeId;
|
|
446
|
+
}, [selectedTask]);
|
|
447
|
+
const canRunAssignedAgent = useMemo(() => {
|
|
448
|
+
return !selectedTaskIsBlocked;
|
|
449
|
+
}, [selectedTaskIsBlocked]);
|
|
450
|
+
const runAssignedAgentDisabledReason = useMemo(() => {
|
|
451
|
+
if (selectedTaskIsBlocked) {
|
|
452
|
+
return "This task is blocked by unfinished dependencies.";
|
|
453
|
+
}
|
|
454
|
+
return undefined;
|
|
455
|
+
}, [selectedTaskIsBlocked]);
|
|
456
|
+
// ── current agent ID and panel mode for the right panel ──
|
|
457
|
+
const currentAgentId = useMemo(() => {
|
|
458
|
+
return getLinkedAgentId(selectedTask);
|
|
459
|
+
}, [selectedTask]);
|
|
460
|
+
const selectedTaskStatus = useMemo(() => {
|
|
461
|
+
if (!selectedTask)
|
|
462
|
+
return null;
|
|
463
|
+
return normalizeTaskStatus(selectedTask.status, selectedTask.executionState);
|
|
464
|
+
}, [selectedTask]);
|
|
465
|
+
const selectedTaskHasResultData = useMemo(() => {
|
|
466
|
+
return !!selectedTask?.resultData?.trim();
|
|
467
|
+
}, [selectedTask?.resultData]);
|
|
468
|
+
const shouldHideAgentPanelForSelectedTask = useMemo(() => {
|
|
469
|
+
return (!!selectedTask &&
|
|
470
|
+
selectedTaskIsPlan &&
|
|
471
|
+
selectedTaskStatus === "Done" &&
|
|
472
|
+
selectedTaskHasResultData);
|
|
473
|
+
}, [
|
|
474
|
+
selectedTask,
|
|
475
|
+
selectedTaskIsPlan,
|
|
476
|
+
selectedTaskStatus,
|
|
477
|
+
selectedTaskHasResultData,
|
|
478
|
+
]);
|
|
479
|
+
const displayAgentId = useMemo(() => {
|
|
480
|
+
return currentAgentId;
|
|
481
|
+
}, [currentAgentId]);
|
|
482
|
+
useEffect(() => {
|
|
483
|
+
if (isMobile && selectedTaskId) {
|
|
484
|
+
setMobileActiveTab(1); // Task tab
|
|
485
|
+
}
|
|
486
|
+
}, [selectedTaskId, isMobile]);
|
|
487
|
+
useEffect(() => {
|
|
488
|
+
if (isMobile && displayAgentId && !shouldHideAgentPanelForSelectedTask) {
|
|
489
|
+
setMobileActiveTab(2); // Agent tab
|
|
490
|
+
}
|
|
491
|
+
}, [displayAgentId, isMobile, shouldHideAgentPanelForSelectedTask]);
|
|
492
|
+
useEffect(() => {
|
|
493
|
+
if (!isMobile)
|
|
494
|
+
return;
|
|
495
|
+
if (!shouldHideAgentPanelForSelectedTask)
|
|
496
|
+
return;
|
|
497
|
+
if (mobileActiveTab !== 2)
|
|
498
|
+
return;
|
|
499
|
+
setMobileActiveTab(1);
|
|
500
|
+
}, [isMobile, mobileActiveTab, shouldHideAgentPanelForSelectedTask]);
|
|
501
|
+
useEffect(() => {
|
|
502
|
+
if (!showEditorPanel && mobileActiveTab === 3) {
|
|
503
|
+
setMobileActiveTab(0);
|
|
504
|
+
}
|
|
505
|
+
}, [showEditorPanel, mobileActiveTab]);
|
|
506
|
+
const currentItemKey = useMemo(() => {
|
|
507
|
+
if (!currentItemDescriptor)
|
|
508
|
+
return "";
|
|
509
|
+
return `${currentItemDescriptor.id}|${currentItemDescriptor.language}|${currentItemDescriptor.version}`;
|
|
510
|
+
}, [currentItemDescriptor]);
|
|
511
|
+
const agentPanelMode = useMemo(() => {
|
|
512
|
+
if (!selectedTask)
|
|
513
|
+
return "no-task-selected";
|
|
514
|
+
if (displayAgentId)
|
|
515
|
+
return "agent";
|
|
516
|
+
return "no-agent";
|
|
517
|
+
}, [selectedTask, displayAgentId]);
|
|
429
518
|
const wizardAttentionState = useMemo(() => {
|
|
430
519
|
const openTasks = orderedWizardTasks.filter((task) => normalizeTaskStatus(task.status, task.executionState) !== "Done");
|
|
431
520
|
let runningCount = 0;
|
|
@@ -523,6 +612,19 @@ export function TaskBoardWorkspace() {
|
|
|
523
612
|
wizardForceOverview,
|
|
524
613
|
wizardPinnedTaskId,
|
|
525
614
|
]);
|
|
615
|
+
useEffect(() => {
|
|
616
|
+
if (!wizardDisplayedTask ||
|
|
617
|
+
(wizardDisplayedExecutionDisplay?.label !== "Questions" &&
|
|
618
|
+
wizardDisplayedTask.executionState !== "WaitingForInput" &&
|
|
619
|
+
wizardDisplayedTask.executionState !== "WaitingForUser")) {
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
}, [
|
|
623
|
+
wizardDisplayedTask,
|
|
624
|
+
wizardDisplayedAgentId,
|
|
625
|
+
wizardDisplayedExecutionDisplay?.label,
|
|
626
|
+
selectedProjectId,
|
|
627
|
+
]);
|
|
526
628
|
const clearWizardCloseTransitionTimeout = useCallback(() => {
|
|
527
629
|
if (wizardCloseTransitionTimeoutRef.current !== null) {
|
|
528
630
|
window.clearTimeout(wizardCloseTransitionTimeoutRef.current);
|
|
@@ -646,8 +748,7 @@ export function TaskBoardWorkspace() {
|
|
|
646
748
|
toast.error(result.summary || "Failed to load tasks");
|
|
647
749
|
return;
|
|
648
750
|
}
|
|
649
|
-
|
|
650
|
-
setTasks(nextTasks);
|
|
751
|
+
setTasks(result.data || []);
|
|
651
752
|
}
|
|
652
753
|
finally {
|
|
653
754
|
tasksRequestCountRef.current = Math.max(0, tasksRequestCountRef.current - 1);
|
|
@@ -932,114 +1033,6 @@ export function TaskBoardWorkspace() {
|
|
|
932
1033
|
directSubprojects,
|
|
933
1034
|
taskSelectionUniverse,
|
|
934
1035
|
]);
|
|
935
|
-
const queueSelectedProjectRefresh = useCallback((options) => {
|
|
936
|
-
if (options?.refreshTasks) {
|
|
937
|
-
wsRefreshNeedsTasksRef.current = true;
|
|
938
|
-
}
|
|
939
|
-
if (options?.refreshExecutionState) {
|
|
940
|
-
wsRefreshNeedsExecutionStateRef.current = true;
|
|
941
|
-
}
|
|
942
|
-
if (options?.refreshDependencies) {
|
|
943
|
-
wsRefreshNeedsDependenciesRef.current = true;
|
|
944
|
-
}
|
|
945
|
-
if (options?.refreshProjects) {
|
|
946
|
-
wsRefreshNeedsProjectsRef.current = true;
|
|
947
|
-
}
|
|
948
|
-
wsRefreshQueuedRef.current = true;
|
|
949
|
-
if (wsRefreshTimeoutRef.current !== null || wsRefreshRunningRef.current) {
|
|
950
|
-
return;
|
|
951
|
-
}
|
|
952
|
-
wsRefreshTimeoutRef.current = window.setTimeout(() => {
|
|
953
|
-
wsRefreshTimeoutRef.current = null;
|
|
954
|
-
const projectId = selectedProjectIdRef.current;
|
|
955
|
-
const shouldRefreshTasks = wsRefreshNeedsTasksRef.current;
|
|
956
|
-
const shouldRefreshExecutionState = wsRefreshNeedsExecutionStateRef.current;
|
|
957
|
-
const shouldRefreshDependencies = wsRefreshNeedsDependenciesRef.current;
|
|
958
|
-
const shouldRefreshProjects = wsRefreshNeedsProjectsRef.current;
|
|
959
|
-
wsRefreshQueuedRef.current = false;
|
|
960
|
-
wsRefreshNeedsTasksRef.current = false;
|
|
961
|
-
wsRefreshNeedsExecutionStateRef.current = false;
|
|
962
|
-
wsRefreshNeedsDependenciesRef.current = false;
|
|
963
|
-
wsRefreshNeedsProjectsRef.current = false;
|
|
964
|
-
const work = [];
|
|
965
|
-
if (shouldRefreshProjects) {
|
|
966
|
-
const refreshProjectsFn = refreshProjectsRef.current;
|
|
967
|
-
if (refreshProjectsFn) {
|
|
968
|
-
work.push(refreshProjectsFn());
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
if (projectId) {
|
|
972
|
-
if (shouldRefreshTasks) {
|
|
973
|
-
const refreshTasksFn = refreshTasksRef.current;
|
|
974
|
-
if (refreshTasksFn) {
|
|
975
|
-
work.push(refreshTasksFn(projectId));
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
if (shouldRefreshExecutionState) {
|
|
979
|
-
const refreshExecutionStateFn = refreshExecutionStateRef.current;
|
|
980
|
-
if (refreshExecutionStateFn) {
|
|
981
|
-
work.push(refreshExecutionStateFn(projectId));
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
if (shouldRefreshDependencies) {
|
|
985
|
-
const refreshDependenciesFn = refreshDependenciesRef.current;
|
|
986
|
-
if (refreshDependenciesFn) {
|
|
987
|
-
work.push(refreshDependenciesFn(projectId));
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
}
|
|
991
|
-
if (work.length === 0) {
|
|
992
|
-
return;
|
|
993
|
-
}
|
|
994
|
-
wsRefreshRunningRef.current = true;
|
|
995
|
-
void Promise.all(work).finally(() => {
|
|
996
|
-
wsRefreshRunningRef.current = false;
|
|
997
|
-
if (wsRefreshQueuedRef.current ||
|
|
998
|
-
wsRefreshNeedsTasksRef.current ||
|
|
999
|
-
wsRefreshNeedsExecutionStateRef.current ||
|
|
1000
|
-
wsRefreshNeedsDependenciesRef.current ||
|
|
1001
|
-
wsRefreshNeedsProjectsRef.current) {
|
|
1002
|
-
queueSelectedProjectRefresh();
|
|
1003
|
-
}
|
|
1004
|
-
});
|
|
1005
|
-
}, WS_REFRESH_DELAY_MS);
|
|
1006
|
-
}, []);
|
|
1007
|
-
const queueSubprojectRefresh = useCallback((options) => {
|
|
1008
|
-
if (options?.refreshProjects) {
|
|
1009
|
-
wsSubprojectRefreshNeedsProjectsRef.current = true;
|
|
1010
|
-
}
|
|
1011
|
-
wsSubprojectRefreshQueuedRef.current = true;
|
|
1012
|
-
if (wsSubprojectRefreshTimeoutRef.current !== null ||
|
|
1013
|
-
wsSubprojectRefreshRunningRef.current) {
|
|
1014
|
-
return;
|
|
1015
|
-
}
|
|
1016
|
-
wsSubprojectRefreshTimeoutRef.current = window.setTimeout(() => {
|
|
1017
|
-
wsSubprojectRefreshTimeoutRef.current = null;
|
|
1018
|
-
const shouldRefreshProjects = wsSubprojectRefreshNeedsProjectsRef.current;
|
|
1019
|
-
wsSubprojectRefreshQueuedRef.current = false;
|
|
1020
|
-
wsSubprojectRefreshNeedsProjectsRef.current = false;
|
|
1021
|
-
const refreshSubprojectsFn = refreshSubprojectTaskCountsRef.current;
|
|
1022
|
-
const refreshProjectsFn = refreshProjectsRef.current;
|
|
1023
|
-
const work = [];
|
|
1024
|
-
if (refreshSubprojectsFn) {
|
|
1025
|
-
work.push(refreshSubprojectsFn());
|
|
1026
|
-
}
|
|
1027
|
-
if (shouldRefreshProjects && refreshProjectsFn) {
|
|
1028
|
-
work.push(refreshProjectsFn());
|
|
1029
|
-
}
|
|
1030
|
-
if (work.length === 0) {
|
|
1031
|
-
return;
|
|
1032
|
-
}
|
|
1033
|
-
wsSubprojectRefreshRunningRef.current = true;
|
|
1034
|
-
void Promise.all(work).finally(() => {
|
|
1035
|
-
wsSubprojectRefreshRunningRef.current = false;
|
|
1036
|
-
if (wsSubprojectRefreshQueuedRef.current ||
|
|
1037
|
-
wsSubprojectRefreshNeedsProjectsRef.current) {
|
|
1038
|
-
queueSubprojectRefresh();
|
|
1039
|
-
}
|
|
1040
|
-
});
|
|
1041
|
-
}, WS_REFRESH_DELAY_MS);
|
|
1042
|
-
}, []);
|
|
1043
1036
|
const handleRunOrchestrator = useCallback(async (options) => {
|
|
1044
1037
|
if (!selectedProjectId)
|
|
1045
1038
|
return;
|
|
@@ -1446,16 +1439,34 @@ export function TaskBoardWorkspace() {
|
|
|
1446
1439
|
const payload = message?.payload;
|
|
1447
1440
|
const projectId = payload?.projectId ?? payload?.ProjectId;
|
|
1448
1441
|
const currentProjectId = selectedProjectIdRef.current;
|
|
1442
|
+
const refreshProjectsFn = refreshProjectsRef.current;
|
|
1449
1443
|
if (!projectId ||
|
|
1450
1444
|
!currentProjectId ||
|
|
1445
|
+
!refreshProjectsFn ||
|
|
1451
1446
|
!isProjectWithinSelectedTree(projectId, currentProjectId)) {
|
|
1452
1447
|
return;
|
|
1453
1448
|
}
|
|
1454
|
-
if (
|
|
1455
|
-
|
|
1456
|
-
|
|
1449
|
+
if (wsRefreshTimeoutRef.current !== null) {
|
|
1450
|
+
window.clearTimeout(wsRefreshTimeoutRef.current);
|
|
1451
|
+
wsRefreshTimeoutRef.current = null;
|
|
1457
1452
|
}
|
|
1458
|
-
|
|
1453
|
+
wsRefreshTimeoutRef.current = window.setTimeout(() => {
|
|
1454
|
+
wsRefreshTimeoutRef.current = null;
|
|
1455
|
+
const selectedId = selectedProjectIdRef.current;
|
|
1456
|
+
const refreshProjectsFn = refreshProjectsRef.current;
|
|
1457
|
+
if (!selectedId || !refreshProjectsFn)
|
|
1458
|
+
return;
|
|
1459
|
+
void refreshProjectsFn();
|
|
1460
|
+
if (projectId === selectedId) {
|
|
1461
|
+
const refreshExecutionStateFn = refreshExecutionStateRef.current;
|
|
1462
|
+
if (refreshExecutionStateFn)
|
|
1463
|
+
void refreshExecutionStateFn(selectedId);
|
|
1464
|
+
return;
|
|
1465
|
+
}
|
|
1466
|
+
const refreshSubprojectsFn = refreshSubprojectTaskCountsRef.current;
|
|
1467
|
+
if (refreshSubprojectsFn)
|
|
1468
|
+
void refreshSubprojectsFn();
|
|
1469
|
+
}, 250);
|
|
1459
1470
|
return;
|
|
1460
1471
|
}
|
|
1461
1472
|
if (messageType === "task:state-changed") {
|
|
@@ -1505,7 +1516,16 @@ export function TaskBoardWorkspace() {
|
|
|
1505
1516
|
},
|
|
1506
1517
|
};
|
|
1507
1518
|
});
|
|
1508
|
-
|
|
1519
|
+
if (wsSubprojectRefreshTimeoutRef.current !== null) {
|
|
1520
|
+
window.clearTimeout(wsSubprojectRefreshTimeoutRef.current);
|
|
1521
|
+
wsSubprojectRefreshTimeoutRef.current = null;
|
|
1522
|
+
}
|
|
1523
|
+
wsSubprojectRefreshTimeoutRef.current = window.setTimeout(() => {
|
|
1524
|
+
wsSubprojectRefreshTimeoutRef.current = null;
|
|
1525
|
+
const refreshSubprojectsFn = refreshSubprojectTaskCountsRef.current;
|
|
1526
|
+
if (refreshSubprojectsFn)
|
|
1527
|
+
void refreshSubprojectsFn();
|
|
1528
|
+
}, 250);
|
|
1509
1529
|
}
|
|
1510
1530
|
return;
|
|
1511
1531
|
}
|
|
@@ -1517,23 +1537,49 @@ export function TaskBoardWorkspace() {
|
|
|
1517
1537
|
const payload = message?.payload;
|
|
1518
1538
|
const projectId = payload?.projectId ?? payload?.ProjectId;
|
|
1519
1539
|
const currentProjectId = selectedProjectIdRef.current;
|
|
1520
|
-
const isDirectSubproject = !!projectId && directSubprojectIdsRef.current.has(projectId);
|
|
1521
1540
|
if (!projectId || !currentProjectId)
|
|
1522
1541
|
return;
|
|
1523
1542
|
if (projectId !== currentProjectId) {
|
|
1524
|
-
if (!
|
|
1543
|
+
if (!directSubprojectIdsRef.current.has(projectId))
|
|
1525
1544
|
return;
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1545
|
+
if (wsSubprojectRefreshTimeoutRef.current !== null) {
|
|
1546
|
+
window.clearTimeout(wsSubprojectRefreshTimeoutRef.current);
|
|
1547
|
+
wsSubprojectRefreshTimeoutRef.current = null;
|
|
1548
|
+
}
|
|
1549
|
+
wsSubprojectRefreshTimeoutRef.current = window.setTimeout(() => {
|
|
1550
|
+
wsSubprojectRefreshTimeoutRef.current = null;
|
|
1551
|
+
const refreshSubprojectsFn = refreshSubprojectTaskCountsRef.current;
|
|
1552
|
+
const refreshProjectsFn = refreshProjectsRef.current;
|
|
1553
|
+
if (!refreshSubprojectsFn)
|
|
1554
|
+
return;
|
|
1555
|
+
void refreshSubprojectsFn();
|
|
1556
|
+
if (refreshProjectsFn)
|
|
1557
|
+
void refreshProjectsFn();
|
|
1558
|
+
}, 250);
|
|
1529
1559
|
return;
|
|
1530
1560
|
}
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1561
|
+
if (wsRefreshTimeoutRef.current !== null) {
|
|
1562
|
+
window.clearTimeout(wsRefreshTimeoutRef.current);
|
|
1563
|
+
wsRefreshTimeoutRef.current = null;
|
|
1564
|
+
}
|
|
1565
|
+
wsRefreshTimeoutRef.current = window.setTimeout(() => {
|
|
1566
|
+
wsRefreshTimeoutRef.current = null;
|
|
1567
|
+
const pid = selectedProjectIdRef.current;
|
|
1568
|
+
const refreshProjectsFn = refreshProjectsRef.current;
|
|
1569
|
+
const refreshTasksFn = refreshTasksRef.current;
|
|
1570
|
+
const refreshExecutionStateFn = refreshExecutionStateRef.current;
|
|
1571
|
+
const refreshDepsFn = refreshDependenciesRef.current;
|
|
1572
|
+
if (!pid ||
|
|
1573
|
+
!refreshTasksFn ||
|
|
1574
|
+
!refreshDepsFn ||
|
|
1575
|
+
!refreshExecutionStateFn)
|
|
1576
|
+
return;
|
|
1577
|
+
void refreshTasksFn(pid);
|
|
1578
|
+
void refreshExecutionStateFn(pid);
|
|
1579
|
+
void refreshDepsFn(pid);
|
|
1580
|
+
if (refreshProjectsFn)
|
|
1581
|
+
void refreshProjectsFn();
|
|
1582
|
+
}, 250);
|
|
1537
1583
|
});
|
|
1538
1584
|
return () => {
|
|
1539
1585
|
unsubscribe();
|
|
@@ -1542,7 +1588,7 @@ export function TaskBoardWorkspace() {
|
|
|
1542
1588
|
// Clearing it here was the bug: editContext changes caused cleanup to
|
|
1543
1589
|
// cancel the pending debounced refresh before it could fire.
|
|
1544
1590
|
};
|
|
1545
|
-
}, [editContext
|
|
1591
|
+
}, [editContext]);
|
|
1546
1592
|
// Keep project dropdown in sync when projects are created elsewhere (e.g. by agents).
|
|
1547
1593
|
useEffect(() => {
|
|
1548
1594
|
const addListener = editContext?.addSocketMessageListener;
|
|
@@ -1566,15 +1612,6 @@ export function TaskBoardWorkspace() {
|
|
|
1566
1612
|
window.clearTimeout(wsSubprojectRefreshTimeoutRef.current);
|
|
1567
1613
|
wsSubprojectRefreshTimeoutRef.current = null;
|
|
1568
1614
|
}
|
|
1569
|
-
wsRefreshQueuedRef.current = false;
|
|
1570
|
-
wsRefreshRunningRef.current = false;
|
|
1571
|
-
wsRefreshNeedsTasksRef.current = false;
|
|
1572
|
-
wsRefreshNeedsExecutionStateRef.current = false;
|
|
1573
|
-
wsRefreshNeedsDependenciesRef.current = false;
|
|
1574
|
-
wsRefreshNeedsProjectsRef.current = false;
|
|
1575
|
-
wsSubprojectRefreshQueuedRef.current = false;
|
|
1576
|
-
wsSubprojectRefreshRunningRef.current = false;
|
|
1577
|
-
wsSubprojectRefreshNeedsProjectsRef.current = false;
|
|
1578
1615
|
if (wizardCloseTransitionTimeoutRef.current !== null) {
|
|
1579
1616
|
window.clearTimeout(wizardCloseTransitionTimeoutRef.current);
|
|
1580
1617
|
wizardCloseTransitionTimeoutRef.current = null;
|
|
@@ -1670,7 +1707,7 @@ export function TaskBoardWorkspace() {
|
|
|
1670
1707
|
return (_jsx("div", { className: "flex h-full min-h-[240px] items-center justify-center rounded-lg border border-dashed border-slate-200 bg-slate-50/70", "data-testid": "taskboard-project-loading-state", children: _jsxs("div", { className: "text-muted-foreground flex flex-col items-center gap-3 text-sm", children: [_jsx(Loader2, { className: "h-6 w-6 animate-spin" }), _jsx("div", { children: "Loading project..." })] }) }));
|
|
1671
1708
|
}
|
|
1672
1709
|
if (!selectedProjectId || (!selectedProject && !isProjectsLoading)) {
|
|
1673
|
-
return (_jsx("div", { className: "flex min-h-full w-full flex-col p-4 md:p-8", children: _jsx("div", { className: "mx-auto flex h-full
|
|
1710
|
+
return (_jsx("div", { className: "flex min-h-full w-full flex-col p-4 md:p-8", children: _jsx("div", { className: "mx-auto flex h-full w-full max-w-7xl flex-1 min-h-0", children: _jsx(ProjectOverviewContent, { nav: nav }) }) }));
|
|
1674
1711
|
}
|
|
1675
1712
|
if (isWizardMode) {
|
|
1676
1713
|
return (_jsx(WizardView, { projectId: selectedProjectId, tasks: tasksWithDisplayAssignees, projectTasksLoading: isTasksLoading, dependencies: dependencies, subprojectTaskLists: wizardSubprojectTaskLists, subprojectTasksLoading: subprojectCountsLoading, selectedTaskId: wizardDisplayedTask?.taskId ?? null, onSelectTask: (id) => {
|
|
@@ -1684,7 +1721,7 @@ export function TaskBoardWorkspace() {
|
|
|
1684
1721
|
}, projectId: selectedProjectId, permission: selectedProject?.permission })] }));
|
|
1685
1722
|
}
|
|
1686
1723
|
if (isGraphView) {
|
|
1687
|
-
return (_jsxs("div", { className: "flex h-full min-h-0 min-w-0 flex-col gap-3", children: [_jsx(ProjectDashboard, { projectId: selectedProjectId, selectedProjectTitle: selectedProject?.project.title ?? "No project selected", selectedProjectDescription: selectedProject?.project.description, selectedProjectStatus: selectedProject?.project.status, selectedProjectCostUsed: selectedProjectCumulativeCostUsed, selectedProjectCostLimit: selectedProject?.project.costLimit ?? null, canEditProjectStatus: selectedProject?.permission === "Owner", savingProjectStatus: savingProjectStatus, onStatusChange: handleProjectStatusChange, selectedProjectTaskCounts: selectedProjectTaskCounts, subprojects: directSubprojects, taskCountsByProjectId: subprojectTaskCounts, loading: subprojectCountsLoading, parentProjectId: parentProject?.project.projectId ?? null, parentProjectTitle: parentProject?.project.title ?? null, onSelectProject: handleSelectProject, canEditProperties: selectedProject?.permission === "Owner" }), sharedViewSwitcher, _jsx("div", { className: "min-h-0 flex-1", children: _jsx(DependencyGraphView, { projectId: selectedProjectId, tasks: tasksWithDisplayAssignees, dependencies: dependencies, orientation: "horizontal",
|
|
1724
|
+
return (_jsxs("div", { className: "flex h-full min-h-0 min-w-0 flex-col gap-3", children: [_jsx(ProjectDashboard, { projectId: selectedProjectId, selectedProjectTitle: selectedProject?.project.title ?? "No project selected", selectedProjectDescription: selectedProject?.project.description, selectedProjectStatus: selectedProject?.project.status, selectedProjectCostUsed: selectedProjectCumulativeCostUsed, selectedProjectCostLimit: selectedProject?.project.costLimit ?? null, canEditProjectStatus: selectedProject?.permission === "Owner", savingProjectStatus: savingProjectStatus, onStatusChange: handleProjectStatusChange, selectedProjectTaskCounts: selectedProjectTaskCounts, subprojects: directSubprojects, taskCountsByProjectId: subprojectTaskCounts, loading: subprojectCountsLoading, parentProjectId: parentProject?.project.projectId ?? null, parentProjectTitle: parentProject?.project.title ?? null, onSelectProject: handleSelectProject, canEditProperties: selectedProject?.permission === "Owner" }), sharedViewSwitcher, _jsx("div", { className: "min-h-0 flex-1", children: _jsx(DependencyGraphView, { projectId: selectedProjectId, tasks: tasksWithDisplayAssignees, dependencies: dependencies, orientation: "horizontal", savedLayout: graphLayout, selectedTaskId: selectedTaskId, onSelectTask: (id) => setTaskSelection(id, { source: "user" }), permission: selectedProject?.permission, onLayoutSaved: (layout) => setGraphLayout(layout && selectedProjectId
|
|
1688
1725
|
? {
|
|
1689
1726
|
projectId: selectedProjectId,
|
|
1690
1727
|
...layout,
|
|
@@ -1726,7 +1763,7 @@ export function TaskBoardWorkspace() {
|
|
|
1726
1763
|
setTaskSelection,
|
|
1727
1764
|
refreshVisibleTaskData,
|
|
1728
1765
|
]);
|
|
1729
|
-
const taskDetailPanel = useMemo(() => (_jsx(TaskDetailPanel, { project: selectedTaskProject,
|
|
1766
|
+
const taskDetailPanel = useMemo(() => (_jsx(TaskDetailPanel, { project: selectedTaskProject, task: selectedTask, allTasks: taskSelectionUniverse, dependencies: dependencies, onTaskChanged: () => {
|
|
1730
1767
|
void refreshVisibleTaskData();
|
|
1731
1768
|
}, onSelectTask: (taskId) => setTaskSelection(taskId, { source: "user" }), onClose: () => setTaskSelection(null), variant: "panel" })), [
|
|
1732
1769
|
selectedTaskProject,
|
|
@@ -1768,6 +1805,161 @@ export function TaskBoardWorkspace() {
|
|
|
1768
1805
|
selectedTask,
|
|
1769
1806
|
handleReopenSelectedTask,
|
|
1770
1807
|
]);
|
|
1808
|
+
const previewItemVersion = useMemo(() => {
|
|
1809
|
+
if (!currentItemDescriptor)
|
|
1810
|
+
return null;
|
|
1811
|
+
return currentItemDescriptor.version === 0
|
|
1812
|
+
? (editContext?.item?.version ?? null)
|
|
1813
|
+
: currentItemDescriptor.version;
|
|
1814
|
+
}, [currentItemDescriptor, editContext?.item?.version]);
|
|
1815
|
+
const contextItemOptions = useMemo(() => {
|
|
1816
|
+
return agentContextItems.map((contextItem) => {
|
|
1817
|
+
const key = `${contextItem.id}|${contextItem.language}|${contextItem.version}`;
|
|
1818
|
+
const name = contextItemNamesByKey[key] || contextItem.name || contextItem.id;
|
|
1819
|
+
const path = contextItemPathsByKey[key] || contextItem.path || "";
|
|
1820
|
+
return {
|
|
1821
|
+
value: key,
|
|
1822
|
+
label: name,
|
|
1823
|
+
description: `${path || contextItem.id} (${contextItem.language}/v${contextItem.version})`,
|
|
1824
|
+
};
|
|
1825
|
+
});
|
|
1826
|
+
}, [agentContextItems, contextItemNamesByKey, contextItemPathsByKey]);
|
|
1827
|
+
const selectedContextItemValue = useMemo(() => {
|
|
1828
|
+
if (currentItemKey)
|
|
1829
|
+
return currentItemKey;
|
|
1830
|
+
const first = agentContextItems[0];
|
|
1831
|
+
if (!first)
|
|
1832
|
+
return "";
|
|
1833
|
+
return `${first.id}|${first.language}|${first.version}`;
|
|
1834
|
+
}, [currentItemKey, agentContextItems]);
|
|
1835
|
+
const hasMultipleContextItems = contextItemOptions.length > 1;
|
|
1836
|
+
useEffect(() => {
|
|
1837
|
+
if (!currentAgentId) {
|
|
1838
|
+
setAgentContextItems([]);
|
|
1839
|
+
return;
|
|
1840
|
+
}
|
|
1841
|
+
let cancelled = false;
|
|
1842
|
+
getAgent(currentAgentId)
|
|
1843
|
+
.then((agent) => {
|
|
1844
|
+
if (cancelled)
|
|
1845
|
+
return;
|
|
1846
|
+
const rawContext = agent?.agentContext;
|
|
1847
|
+
if (!rawContext) {
|
|
1848
|
+
setAgentContextItems([]);
|
|
1849
|
+
return;
|
|
1850
|
+
}
|
|
1851
|
+
let parsed = null;
|
|
1852
|
+
try {
|
|
1853
|
+
parsed = JSON.parse(rawContext);
|
|
1854
|
+
}
|
|
1855
|
+
catch {
|
|
1856
|
+
parsed = null;
|
|
1857
|
+
}
|
|
1858
|
+
const items = (parsed?.items || []).filter((x) => !!x?.id && !!x?.language && typeof x?.version === "number");
|
|
1859
|
+
setAgentContextItems(items);
|
|
1860
|
+
})
|
|
1861
|
+
.catch(() => {
|
|
1862
|
+
if (cancelled)
|
|
1863
|
+
return;
|
|
1864
|
+
setAgentContextItems([]);
|
|
1865
|
+
});
|
|
1866
|
+
return () => {
|
|
1867
|
+
cancelled = true;
|
|
1868
|
+
};
|
|
1869
|
+
}, [currentAgentId]);
|
|
1870
|
+
useEffect(() => {
|
|
1871
|
+
if (!editContext || agentContextItems.length === 0) {
|
|
1872
|
+
setContextItemNamesByKey({});
|
|
1873
|
+
setContextItemPathsByKey({});
|
|
1874
|
+
return;
|
|
1875
|
+
}
|
|
1876
|
+
let cancelled = false;
|
|
1877
|
+
Promise.all(agentContextItems.map(async (contextItem) => {
|
|
1878
|
+
const key = `${contextItem.id}|${contextItem.language}|${contextItem.version}`;
|
|
1879
|
+
const descriptor = {
|
|
1880
|
+
id: contextItem.id,
|
|
1881
|
+
language: contextItem.language,
|
|
1882
|
+
version: contextItem.version,
|
|
1883
|
+
};
|
|
1884
|
+
const item = await editContext.itemsRepository.getItem(descriptor);
|
|
1885
|
+
return {
|
|
1886
|
+
key,
|
|
1887
|
+
name: item?.name || contextItem.name || "",
|
|
1888
|
+
path: item?.path || contextItem.path || "",
|
|
1889
|
+
};
|
|
1890
|
+
}))
|
|
1891
|
+
.then((results) => {
|
|
1892
|
+
if (cancelled)
|
|
1893
|
+
return;
|
|
1894
|
+
const nextNames = {};
|
|
1895
|
+
const nextPaths = {};
|
|
1896
|
+
for (const result of results) {
|
|
1897
|
+
nextNames[result.key] = result.name;
|
|
1898
|
+
nextPaths[result.key] = result.path;
|
|
1899
|
+
}
|
|
1900
|
+
setContextItemNamesByKey(nextNames);
|
|
1901
|
+
setContextItemPathsByKey(nextPaths);
|
|
1902
|
+
})
|
|
1903
|
+
.catch(() => {
|
|
1904
|
+
if (cancelled)
|
|
1905
|
+
return;
|
|
1906
|
+
setContextItemNamesByKey({});
|
|
1907
|
+
setContextItemPathsByKey({});
|
|
1908
|
+
});
|
|
1909
|
+
return () => {
|
|
1910
|
+
cancelled = true;
|
|
1911
|
+
};
|
|
1912
|
+
}, [editContext, agentContextItems]);
|
|
1913
|
+
const handleSelectContextItem = useCallback((value) => {
|
|
1914
|
+
const [id, language, versionText] = value.split("|");
|
|
1915
|
+
const version = Number(versionText);
|
|
1916
|
+
if (!id || !language || Number.isNaN(version) || !editContext?.loadItem)
|
|
1917
|
+
return;
|
|
1918
|
+
void editContext.loadItem({ id, language, version });
|
|
1919
|
+
}, [editContext]);
|
|
1920
|
+
useEffect(() => {
|
|
1921
|
+
if (!editContext || !currentItemDescriptor) {
|
|
1922
|
+
setPreviewItemName("");
|
|
1923
|
+
setPreviewItemPath("");
|
|
1924
|
+
return;
|
|
1925
|
+
}
|
|
1926
|
+
const activeItem = editContext.item;
|
|
1927
|
+
const itemMatchesDescriptor = activeItem?.id === currentItemDescriptor.id &&
|
|
1928
|
+
activeItem?.language === currentItemDescriptor.language;
|
|
1929
|
+
if (itemMatchesDescriptor) {
|
|
1930
|
+
setPreviewItemName(activeItem?.name || "");
|
|
1931
|
+
setPreviewItemPath(activeItem?.path || "");
|
|
1932
|
+
return;
|
|
1933
|
+
}
|
|
1934
|
+
let cancelled = false;
|
|
1935
|
+
editContext.itemsRepository
|
|
1936
|
+
.getItem(currentItemDescriptor)
|
|
1937
|
+
.then((item) => {
|
|
1938
|
+
if (cancelled)
|
|
1939
|
+
return;
|
|
1940
|
+
setPreviewItemName(item?.name || "");
|
|
1941
|
+
setPreviewItemPath(item?.path || "");
|
|
1942
|
+
})
|
|
1943
|
+
.catch(() => {
|
|
1944
|
+
if (cancelled)
|
|
1945
|
+
return;
|
|
1946
|
+
setPreviewItemName("");
|
|
1947
|
+
setPreviewItemPath("");
|
|
1948
|
+
});
|
|
1949
|
+
return () => {
|
|
1950
|
+
cancelled = true;
|
|
1951
|
+
};
|
|
1952
|
+
}, [
|
|
1953
|
+
editContext,
|
|
1954
|
+
currentItemDescriptor,
|
|
1955
|
+
currentItemDescriptor?.id,
|
|
1956
|
+
currentItemDescriptor?.language,
|
|
1957
|
+
currentItemDescriptor?.version,
|
|
1958
|
+
editContext?.item?.id,
|
|
1959
|
+
editContext?.item?.language,
|
|
1960
|
+
editContext?.item?.name,
|
|
1961
|
+
editContext?.item?.path,
|
|
1962
|
+
]);
|
|
1771
1963
|
const itemPreviewPanel = useMemo(() => {
|
|
1772
1964
|
const hasCurrentItem = !!currentItemDescriptor;
|
|
1773
1965
|
const previewSidebar = (_jsx("div", { className: "relative z-10 flex h-full min-h-0 flex-col bg-white", children: _jsx("div", { className: "min-h-0 flex-1", children: _jsx(MainContentTree, { mode: "normal" }) }) }));
|
|
@@ -1940,7 +2132,7 @@ export function TaskBoardWorkspace() {
|
|
|
1940
2132
|
id: "agent",
|
|
1941
2133
|
label: "Agent",
|
|
1942
2134
|
content: null,
|
|
1943
|
-
disabled: !
|
|
2135
|
+
disabled: !currentAgentId || shouldHideAgentPanelForSelectedTask,
|
|
1944
2136
|
},
|
|
1945
2137
|
...(showEditorPanel
|
|
1946
2138
|
? [{ id: "editor", label: "Editor", content: null }]
|
|
@@ -1966,10 +2158,7 @@ export function TaskBoardWorkspace() {
|
|
|
1966
2158
|
} }), _jsx(ProjectSettingsDialog, { open: !!settingsProjectId, onOpenChange: (open) => {
|
|
1967
2159
|
if (!open)
|
|
1968
2160
|
setSettingsProjectId(null);
|
|
1969
|
-
}, projectId: settingsProjectId, selectedProject: settingsProject,
|
|
1970
|
-
await refreshProjects();
|
|
1971
|
-
await refreshVisibleTaskData();
|
|
1972
|
-
} }), _jsx(AssignAgentDialog, { open: assignAgentDialogOpen, task: selectedTask, onOpenChange: setAssignAgentDialogOpen, onAssigned: async () => {
|
|
2161
|
+
}, projectId: settingsProjectId, selectedProject: settingsProject, onChanged: refreshProjects }), _jsx(AssignAgentDialog, { open: assignAgentDialogOpen, task: selectedTask, onOpenChange: setAssignAgentDialogOpen, onAssigned: async () => {
|
|
1973
2162
|
if (!selectedProjectId)
|
|
1974
2163
|
return;
|
|
1975
2164
|
await refreshTasks(selectedProjectId);
|