@parhelia/core 0.1.12470 → 0.1.12479
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 +22 -3
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +2 -0
- package/dist/config/types.js.map +1 -1
- package/dist/editor/ConfirmationDialog.js +20 -4
- package/dist/editor/ConfirmationDialog.js.map +1 -1
- package/dist/editor/ContentTree.js +19 -7
- package/dist/editor/ContentTree.js.map +1 -1
- package/dist/editor/Editor.js.map +1 -1
- package/dist/editor/PictureCropper.js +45 -41
- package/dist/editor/PictureCropper.js.map +1 -1
- package/dist/editor/ai/AgentTerminal.js +97 -8
- package/dist/editor/ai/AgentTerminal.js.map +1 -1
- package/dist/editor/ai/AgentTerminalStatusBar.js +65 -0
- package/dist/editor/ai/AgentTerminalStatusBar.js.map +1 -1
- package/dist/editor/ai/Agents.js +19 -0
- package/dist/editor/ai/Agents.js.map +1 -1
- package/dist/editor/ai/AiResponseMessage.js +5 -0
- package/dist/editor/ai/AiResponseMessage.js.map +1 -1
- package/dist/editor/ai/ContentInspectorPopover.d.ts +1 -0
- package/dist/editor/ai/ContentInspectorPopover.js +22 -8
- package/dist/editor/ai/ContentInspectorPopover.js.map +1 -1
- package/dist/editor/ai/ToolCallDisplay.d.ts +2 -0
- package/dist/editor/ai/ToolCallDisplay.js +54 -11
- package/dist/editor/ai/ToolCallDisplay.js.map +1 -1
- package/dist/editor/ai/dialogs/AgentDialogHandler.js +32 -3
- package/dist/editor/ai/dialogs/AgentDialogHandler.js.map +1 -1
- package/dist/editor/ai/dialogs/QuestionnaireInline.js +55 -20
- package/dist/editor/ai/dialogs/QuestionnaireInline.js.map +1 -1
- package/dist/editor/ai/dialogs/agentDialogTypes.d.ts +7 -4
- package/dist/editor/ai/dialogs/agentDialogTypes.js.map +1 -1
- package/dist/editor/ai/types.d.ts +2 -0
- package/dist/editor/client/EditorShell.js +55 -10
- package/dist/editor/client/EditorShell.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +2 -0
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/client/ui/EditorChrome.d.ts +0 -2
- package/dist/editor/client/ui/EditorChrome.js +2 -13
- package/dist/editor/client/ui/EditorChrome.js.map +1 -1
- package/dist/editor/page-viewer/EditorForm.js +8 -1
- package/dist/editor/page-viewer/EditorForm.js.map +1 -1
- package/dist/editor/page-viewer/PageViewer.d.ts +3 -1
- package/dist/editor/page-viewer/PageViewer.js +23 -4
- package/dist/editor/page-viewer/PageViewer.js.map +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.d.ts +2 -1
- package/dist/editor/page-viewer/PageViewerFrame.js +3 -4
- package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
- package/dist/editor/services/agentService.d.ts +27 -0
- package/dist/editor/services/agentService.js +11 -2
- package/dist/editor/services/agentService.js.map +1 -1
- package/dist/editor/services/aiService.js +54 -3
- package/dist/editor/services/aiService.js.map +1 -1
- package/dist/editor/services/serviceHelper.js +5 -2
- package/dist/editor/services/serviceHelper.js.map +1 -1
- package/dist/editor/settings/About.js +40 -4
- package/dist/editor/settings/About.js.map +1 -1
- package/dist/editor/settings/panels/PersistentLogsPanel.d.ts +2 -0
- package/dist/editor/settings/panels/PersistentLogsPanel.js +244 -0
- package/dist/editor/settings/panels/PersistentLogsPanel.js.map +1 -0
- package/dist/editor/settings/panels/ProjectTemplateAgentPanel.d.ts +7 -1
- 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 +165 -84
- package/dist/editor/settings/panels/ProjectTemplatesPanel.js.map +1 -1
- package/dist/editor/settings/panels/index.d.ts +1 -0
- package/dist/editor/settings/panels/index.js +1 -0
- package/dist/editor/settings/panels/index.js.map +1 -1
- package/dist/editor/sidebar/ComponentTree.d.ts +8 -1
- package/dist/editor/sidebar/ComponentTree.js +23 -15
- package/dist/editor/sidebar/ComponentTree.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 +24 -4
- package/dist/editor/tree-indicators/GutterColumns.js.map +1 -1
- package/dist/editor/tree-indicators/types.d.ts +10 -0
- package/dist/editor/ui/Splitter.d.ts +1 -0
- package/dist/editor/ui/Splitter.js +7 -1
- package/dist/editor/ui/Splitter.js.map +1 -1
- package/dist/editor/utils.js +16 -4
- package/dist/editor/utils.js.map +1 -1
- package/dist/editor/views/CompareView.d.ts +3 -1
- package/dist/editor/views/CompareView.js +3 -3
- package/dist/editor/views/CompareView.js.map +1 -1
- package/dist/editor/views/EditorSlot.js +7 -6
- package/dist/editor/views/EditorSlot.js.map +1 -1
- package/dist/editor/views/SingleEditView.d.ts +2 -1
- package/dist/editor/views/SingleEditView.js +8 -8
- package/dist/editor/views/SingleEditView.js.map +1 -1
- package/dist/licensing/LicenseContext.js +40 -4
- 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 +3 -1
- 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 +165 -354
- package/dist/task-board/TaskBoardWorkspace.js.map +1 -1
- package/dist/task-board/assigneeDisplay.js +1 -3
- package/dist/task-board/assigneeDisplay.js.map +1 -1
- package/dist/task-board/components/CreateProjectDialog.js +2 -1
- package/dist/task-board/components/CreateProjectDialog.js.map +1 -1
- package/dist/task-board/components/ProjectDashboard.js +2 -1
- package/dist/task-board/components/ProjectDashboard.js.map +1 -1
- package/dist/task-board/components/ProjectExecutionUserPicker.d.ts +14 -0
- package/dist/task-board/components/ProjectExecutionUserPicker.js +65 -0
- package/dist/task-board/components/ProjectExecutionUserPicker.js.map +1 -0
- package/dist/task-board/components/ProjectSettingsDialog.d.ts +1 -0
- package/dist/task-board/components/ProjectSettingsDialog.js +146 -12
- package/dist/task-board/components/ProjectSettingsDialog.js.map +1 -1
- package/dist/task-board/components/TaskAgentPanel.d.ts +1 -0
- 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 +1 -0
- 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 +1 -0
- package/dist/task-board/components/TaskDetailPanel.js +23 -8
- package/dist/task-board/components/TaskDetailPanel.js.map +1 -1
- package/dist/task-board/components/TaskRow.js +3 -2
- package/dist/task-board/components/TaskRow.js.map +1 -1
- package/dist/task-board/components/TaskboardPersistentLogPanel.d.ts +11 -0
- package/dist/task-board/components/TaskboardPersistentLogPanel.js +141 -0
- package/dist/task-board/components/TaskboardPersistentLogPanel.js.map +1 -0
- package/dist/task-board/components/WizardTaskDetailsPanel.js +2 -1
- package/dist/task-board/components/WizardTaskDetailsPanel.js.map +1 -1
- package/dist/task-board/persistentLogCopy.d.ts +7 -0
- package/dist/task-board/persistentLogCopy.js +80 -0
- package/dist/task-board/persistentLogCopy.js.map +1 -0
- package/dist/task-board/persistentLogLabels.d.ts +38 -0
- package/dist/task-board/persistentLogLabels.js +189 -0
- package/dist/task-board/persistentLogLabels.js.map +1 -0
- package/dist/task-board/services/taskService.d.ts +17 -1
- package/dist/task-board/services/taskService.js +56 -0
- package/dist/task-board/services/taskService.js.map +1 -1
- package/dist/task-board/taskExecutionRecords.js +2 -0
- package/dist/task-board/taskExecutionRecords.js.map +1 -1
- package/dist/task-board/types.d.ts +78 -1
- package/dist/task-board/useTaskBoardAgentPanelState.d.ts +34 -0
- package/dist/task-board/useTaskBoardAgentPanelState.js +283 -0
- package/dist/task-board/useTaskBoardAgentPanelState.js.map +1 -0
- package/dist/task-board/utils/taskDependencyOrdering.d.ts +6 -0
- package/dist/task-board/utils/taskDependencyOrdering.js +138 -1
- package/dist/task-board/utils/taskDependencyOrdering.js.map +1 -1
- package/dist/task-board/views/DependencyGraphView.d.ts +5 -2
- package/dist/task-board/views/DependencyGraphView.js +261 -69
- package/dist/task-board/views/DependencyGraphView.js.map +1 -1
- package/dist/task-board/views/KanbanView.js +8 -1
- 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 +30 -24
- package/dist/task-board/views/WizardView.js.map +1 -1
- package/dist/tour/Tour.js +0 -32
- package/dist/tour/Tour.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,7 +4,6 @@ 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";
|
|
8
7
|
import { loadAiProfiles } from "../editor/services/aiService";
|
|
9
8
|
import { useEditContext } from "../editor/client/editContext";
|
|
10
9
|
import { KanbanView } from "./views/KanbanView";
|
|
@@ -13,7 +12,7 @@ import { DependencyGraphView } from "./views/DependencyGraphView";
|
|
|
13
12
|
import { WizardView } from "./views/WizardView";
|
|
14
13
|
import { SimpleTabs } from "../editor/ui/SimpleTabs";
|
|
15
14
|
import { TaskDetailPanel } from "./components/TaskDetailPanel";
|
|
16
|
-
import { TaskAgentPanel
|
|
15
|
+
import { TaskAgentPanel } from "./components/TaskAgentPanel";
|
|
17
16
|
import { ProjectDashboard, } from "./components/ProjectDashboard";
|
|
18
17
|
import { CreateTaskDialog } from "./components/CreateTaskDialog";
|
|
19
18
|
import { AssignAgentDialog } from "./components/AssignAgentDialog";
|
|
@@ -36,6 +35,7 @@ import { WizardCommunicationCenter } from "./components/WizardCommunicationCente
|
|
|
36
35
|
import { Button } from "../components/ui/button";
|
|
37
36
|
import { Loader2, Plus } from "lucide-react";
|
|
38
37
|
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,6 +50,7 @@ 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;
|
|
53
54
|
function getInitialQueryValue(queryKey) {
|
|
54
55
|
if (typeof window === "undefined")
|
|
55
56
|
return null;
|
|
@@ -161,11 +162,6 @@ export function TaskBoardWorkspace() {
|
|
|
161
162
|
const [subprojectTasksByProjectId, setSubprojectTasksByProjectId] = useState({});
|
|
162
163
|
const [subprojectExecutionRecordsByProjectId, setSubprojectExecutionRecordsByProjectId,] = useState({});
|
|
163
164
|
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({});
|
|
169
165
|
const [wizardPinnedTaskId, setWizardPinnedTaskId] = useState(null);
|
|
170
166
|
const [, setWizardPinnedTaskSource] = useState(null);
|
|
171
167
|
const [wizardForceOverview, setWizardForceOverview] = useState(false);
|
|
@@ -183,6 +179,15 @@ export function TaskBoardWorkspace() {
|
|
|
183
179
|
}, [setWizardPinnedTask]);
|
|
184
180
|
const wsRefreshTimeoutRef = useRef(null);
|
|
185
181
|
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);
|
|
186
191
|
const wizardCloseTransitionTimeoutRef = useRef(null);
|
|
187
192
|
const projectsRequestCountRef = useRef(0);
|
|
188
193
|
const tasksRequestCountRef = useRef(0);
|
|
@@ -411,110 +416,16 @@ export function TaskBoardWorkspace() {
|
|
|
411
416
|
return selectedProject;
|
|
412
417
|
return (projects.find((project) => project.project.projectId === selectedTask.projectId) ?? selectedProject);
|
|
413
418
|
}, [projects, selectedProject, selectedTask]);
|
|
414
|
-
const selectedTaskIsPlan =
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
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
|
-
}, [
|
|
437
|
-
selectedTask,
|
|
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
|
-
}, [
|
|
419
|
+
const { agentPanelMode, canRunAssignedAgent, contextItemOptions, displayAgentId, handleSelectContextItem, hasMultipleContextItems, previewItemName, previewItemPath, previewItemVersion, runAssignedAgentDisabledReason, selectedContextItemValue, selectedTaskHasAssignedAgentProfile, selectedTaskIsBlocked, selectedTaskIsPlan, shouldHideAgentPanelForSelectedTask, } = useTaskBoardAgentPanelState({
|
|
420
|
+
currentItemDescriptor,
|
|
421
|
+
editContext,
|
|
422
|
+
isMobile,
|
|
423
|
+
mobileActiveTab,
|
|
474
424
|
selectedTask,
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
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]);
|
|
425
|
+
selectedTaskId,
|
|
426
|
+
setMobileActiveTab,
|
|
427
|
+
showEditorPanel,
|
|
428
|
+
});
|
|
518
429
|
const wizardAttentionState = useMemo(() => {
|
|
519
430
|
const openTasks = orderedWizardTasks.filter((task) => normalizeTaskStatus(task.status, task.executionState) !== "Done");
|
|
520
431
|
let runningCount = 0;
|
|
@@ -612,19 +523,6 @@ export function TaskBoardWorkspace() {
|
|
|
612
523
|
wizardForceOverview,
|
|
613
524
|
wizardPinnedTaskId,
|
|
614
525
|
]);
|
|
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
|
-
]);
|
|
628
526
|
const clearWizardCloseTransitionTimeout = useCallback(() => {
|
|
629
527
|
if (wizardCloseTransitionTimeoutRef.current !== null) {
|
|
630
528
|
window.clearTimeout(wizardCloseTransitionTimeoutRef.current);
|
|
@@ -748,7 +646,8 @@ export function TaskBoardWorkspace() {
|
|
|
748
646
|
toast.error(result.summary || "Failed to load tasks");
|
|
749
647
|
return;
|
|
750
648
|
}
|
|
751
|
-
|
|
649
|
+
const nextTasks = result.data || [];
|
|
650
|
+
setTasks(nextTasks);
|
|
752
651
|
}
|
|
753
652
|
finally {
|
|
754
653
|
tasksRequestCountRef.current = Math.max(0, tasksRequestCountRef.current - 1);
|
|
@@ -1033,6 +932,114 @@ export function TaskBoardWorkspace() {
|
|
|
1033
932
|
directSubprojects,
|
|
1034
933
|
taskSelectionUniverse,
|
|
1035
934
|
]);
|
|
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
|
+
}, []);
|
|
1036
1043
|
const handleRunOrchestrator = useCallback(async (options) => {
|
|
1037
1044
|
if (!selectedProjectId)
|
|
1038
1045
|
return;
|
|
@@ -1439,34 +1446,16 @@ export function TaskBoardWorkspace() {
|
|
|
1439
1446
|
const payload = message?.payload;
|
|
1440
1447
|
const projectId = payload?.projectId ?? payload?.ProjectId;
|
|
1441
1448
|
const currentProjectId = selectedProjectIdRef.current;
|
|
1442
|
-
const refreshProjectsFn = refreshProjectsRef.current;
|
|
1443
1449
|
if (!projectId ||
|
|
1444
1450
|
!currentProjectId ||
|
|
1445
|
-
!refreshProjectsFn ||
|
|
1446
1451
|
!isProjectWithinSelectedTree(projectId, currentProjectId)) {
|
|
1447
1452
|
return;
|
|
1448
1453
|
}
|
|
1449
|
-
if (
|
|
1450
|
-
|
|
1451
|
-
|
|
1454
|
+
if (projectId === currentProjectId) {
|
|
1455
|
+
queueSelectedProjectRefresh({ refreshProjects: true });
|
|
1456
|
+
return;
|
|
1452
1457
|
}
|
|
1453
|
-
|
|
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);
|
|
1458
|
+
queueSubprojectRefresh({ refreshProjects: true });
|
|
1470
1459
|
return;
|
|
1471
1460
|
}
|
|
1472
1461
|
if (messageType === "task:state-changed") {
|
|
@@ -1516,16 +1505,7 @@ export function TaskBoardWorkspace() {
|
|
|
1516
1505
|
},
|
|
1517
1506
|
};
|
|
1518
1507
|
});
|
|
1519
|
-
|
|
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);
|
|
1508
|
+
queueSubprojectRefresh();
|
|
1529
1509
|
}
|
|
1530
1510
|
return;
|
|
1531
1511
|
}
|
|
@@ -1537,49 +1517,23 @@ export function TaskBoardWorkspace() {
|
|
|
1537
1517
|
const payload = message?.payload;
|
|
1538
1518
|
const projectId = payload?.projectId ?? payload?.ProjectId;
|
|
1539
1519
|
const currentProjectId = selectedProjectIdRef.current;
|
|
1520
|
+
const isDirectSubproject = !!projectId && directSubprojectIdsRef.current.has(projectId);
|
|
1540
1521
|
if (!projectId || !currentProjectId)
|
|
1541
1522
|
return;
|
|
1542
1523
|
if (projectId !== currentProjectId) {
|
|
1543
|
-
if (!
|
|
1524
|
+
if (!isDirectSubproject)
|
|
1544
1525
|
return;
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
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);
|
|
1526
|
+
queueSubprojectRefresh({
|
|
1527
|
+
refreshProjects: messageType !== "task:updated",
|
|
1528
|
+
});
|
|
1559
1529
|
return;
|
|
1560
1530
|
}
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
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);
|
|
1531
|
+
queueSelectedProjectRefresh({
|
|
1532
|
+
refreshTasks: true,
|
|
1533
|
+
refreshExecutionState: messageType !== "task:updated",
|
|
1534
|
+
refreshDependencies: true,
|
|
1535
|
+
refreshProjects: messageType !== "task:updated",
|
|
1536
|
+
});
|
|
1583
1537
|
});
|
|
1584
1538
|
return () => {
|
|
1585
1539
|
unsubscribe();
|
|
@@ -1588,7 +1542,7 @@ export function TaskBoardWorkspace() {
|
|
|
1588
1542
|
// Clearing it here was the bug: editContext changes caused cleanup to
|
|
1589
1543
|
// cancel the pending debounced refresh before it could fire.
|
|
1590
1544
|
};
|
|
1591
|
-
}, [editContext]);
|
|
1545
|
+
}, [editContext, isProjectWithinSelectedTree, queueSelectedProjectRefresh, queueSubprojectRefresh]);
|
|
1592
1546
|
// Keep project dropdown in sync when projects are created elsewhere (e.g. by agents).
|
|
1593
1547
|
useEffect(() => {
|
|
1594
1548
|
const addListener = editContext?.addSocketMessageListener;
|
|
@@ -1612,6 +1566,15 @@ export function TaskBoardWorkspace() {
|
|
|
1612
1566
|
window.clearTimeout(wsSubprojectRefreshTimeoutRef.current);
|
|
1613
1567
|
wsSubprojectRefreshTimeoutRef.current = null;
|
|
1614
1568
|
}
|
|
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;
|
|
1615
1578
|
if (wizardCloseTransitionTimeoutRef.current !== null) {
|
|
1616
1579
|
window.clearTimeout(wizardCloseTransitionTimeoutRef.current);
|
|
1617
1580
|
wizardCloseTransitionTimeoutRef.current = null;
|
|
@@ -1707,7 +1670,7 @@ export function TaskBoardWorkspace() {
|
|
|
1707
1670
|
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..." })] }) }));
|
|
1708
1671
|
}
|
|
1709
1672
|
if (!selectedProjectId || (!selectedProject && !isProjectsLoading)) {
|
|
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
|
|
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 min-h-0 w-full max-w-7xl flex-1", children: _jsx(ProjectOverviewContent, { nav: nav }) }) }));
|
|
1711
1674
|
}
|
|
1712
1675
|
if (isWizardMode) {
|
|
1713
1676
|
return (_jsx(WizardView, { projectId: selectedProjectId, tasks: tasksWithDisplayAssignees, projectTasksLoading: isTasksLoading, dependencies: dependencies, subprojectTaskLists: wizardSubprojectTaskLists, subprojectTasksLoading: subprojectCountsLoading, selectedTaskId: wizardDisplayedTask?.taskId ?? null, onSelectTask: (id) => {
|
|
@@ -1721,7 +1684,7 @@ export function TaskBoardWorkspace() {
|
|
|
1721
1684
|
}, projectId: selectedProjectId, permission: selectedProject?.permission })] }));
|
|
1722
1685
|
}
|
|
1723
1686
|
if (isGraphView) {
|
|
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
|
|
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", autoLayoutStrategy: "hierarchy", showOrientationToggle: true, savedLayout: graphLayout, selectedTaskId: selectedTaskId, onSelectTask: (id) => setTaskSelection(id, { source: "user" }), permission: selectedProject?.permission, onLayoutSaved: (layout) => setGraphLayout(layout && selectedProjectId
|
|
1725
1688
|
? {
|
|
1726
1689
|
projectId: selectedProjectId,
|
|
1727
1690
|
...layout,
|
|
@@ -1763,7 +1726,7 @@ export function TaskBoardWorkspace() {
|
|
|
1763
1726
|
setTaskSelection,
|
|
1764
1727
|
refreshVisibleTaskData,
|
|
1765
1728
|
]);
|
|
1766
|
-
const taskDetailPanel = useMemo(() => (_jsx(TaskDetailPanel, { project: selectedTaskProject, task: selectedTask, allTasks: taskSelectionUniverse, dependencies: dependencies, onTaskChanged: () => {
|
|
1729
|
+
const taskDetailPanel = useMemo(() => (_jsx(TaskDetailPanel, { project: selectedTaskProject, projects: projects, task: selectedTask, allTasks: taskSelectionUniverse, dependencies: dependencies, onTaskChanged: () => {
|
|
1767
1730
|
void refreshVisibleTaskData();
|
|
1768
1731
|
}, onSelectTask: (taskId) => setTaskSelection(taskId, { source: "user" }), onClose: () => setTaskSelection(null), variant: "panel" })), [
|
|
1769
1732
|
selectedTaskProject,
|
|
@@ -1805,161 +1768,6 @@ export function TaskBoardWorkspace() {
|
|
|
1805
1768
|
selectedTask,
|
|
1806
1769
|
handleReopenSelectedTask,
|
|
1807
1770
|
]);
|
|
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
|
-
]);
|
|
1963
1771
|
const itemPreviewPanel = useMemo(() => {
|
|
1964
1772
|
const hasCurrentItem = !!currentItemDescriptor;
|
|
1965
1773
|
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" }) }) }));
|
|
@@ -2132,7 +1940,7 @@ export function TaskBoardWorkspace() {
|
|
|
2132
1940
|
id: "agent",
|
|
2133
1941
|
label: "Agent",
|
|
2134
1942
|
content: null,
|
|
2135
|
-
disabled: !
|
|
1943
|
+
disabled: !displayAgentId || shouldHideAgentPanelForSelectedTask,
|
|
2136
1944
|
},
|
|
2137
1945
|
...(showEditorPanel
|
|
2138
1946
|
? [{ id: "editor", label: "Editor", content: null }]
|
|
@@ -2158,7 +1966,10 @@ export function TaskBoardWorkspace() {
|
|
|
2158
1966
|
} }), _jsx(ProjectSettingsDialog, { open: !!settingsProjectId, onOpenChange: (open) => {
|
|
2159
1967
|
if (!open)
|
|
2160
1968
|
setSettingsProjectId(null);
|
|
2161
|
-
}, projectId: settingsProjectId, selectedProject: settingsProject,
|
|
1969
|
+
}, projectId: settingsProjectId, selectedProject: settingsProject, projects: projects, onChanged: async () => {
|
|
1970
|
+
await refreshProjects();
|
|
1971
|
+
await refreshVisibleTaskData();
|
|
1972
|
+
} }), _jsx(AssignAgentDialog, { open: assignAgentDialogOpen, task: selectedTask, onOpenChange: setAssignAgentDialogOpen, onAssigned: async () => {
|
|
2162
1973
|
if (!selectedProjectId)
|
|
2163
1974
|
return;
|
|
2164
1975
|
await refreshTasks(selectedProjectId);
|