@parhelia/core 0.1.12347 → 0.1.12368
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 +3 -0
- package/dist/config/config.js.map +1 -1
- package/dist/editor/FieldListField.js +6 -4
- package/dist/editor/FieldListField.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/UtilityControls.js +10 -1
- package/dist/editor/menubar/toolbar-sections/UtilityControls.js.map +1 -1
- package/dist/editor/settings/panels/ModelsPanel.js +20 -3
- package/dist/editor/settings/panels/ModelsPanel.js.map +1 -1
- package/dist/editor/sidebar/WorkspaceRailMobile.d.ts +1 -3
- package/dist/editor/sidebar/WorkspaceRailMobile.js +3 -5
- package/dist/editor/sidebar/WorkspaceRailMobile.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/setup/services/setupWizardService.d.ts +5 -0
- package/dist/setup/services/setupWizardService.js.map +1 -1
- package/dist/setup/wizard/steps/ImportModelDialog.js +15 -2
- package/dist/setup/wizard/steps/ImportModelDialog.js.map +1 -1
- package/dist/splash-screen/ParheliaLogo.js +87 -37
- package/dist/splash-screen/ParheliaLogo.js.map +1 -1
- package/dist/task-board/TaskBoardWorkspace.js +132 -64
- package/dist/task-board/TaskBoardWorkspace.js.map +1 -1
- package/dist/task-board/components/ProjectPropertiesPanel.js +3 -3
- package/dist/task-board/components/ProjectPropertiesPanel.js.map +1 -1
- package/dist/task-board/components/TaskAttachmentsSection.js +1 -1
- package/dist/task-board/components/TaskAttachmentsSection.js.map +1 -1
- package/dist/task-board/components/TaskBoardTitlebar.js +1 -1
- package/dist/task-board/components/TaskBoardTitlebar.js.map +1 -1
- package/dist/task-board/components/WizardCommunicationCenter.d.ts +2 -0
- package/dist/task-board/components/WizardCommunicationCenter.js +9 -4
- package/dist/task-board/components/WizardCommunicationCenter.js.map +1 -1
- package/dist/task-board/components/WizardTaskDetailsPanel.js +1 -1
- package/dist/task-board/components/WizardTaskDetailsPanel.js.map +1 -1
- package/dist/task-board/index.d.ts +1 -0
- package/dist/task-board/index.js +1 -0
- package/dist/task-board/index.js.map +1 -1
- package/dist/task-board/services/taskService.d.ts +3 -1
- package/dist/task-board/services/taskService.js +6 -0
- package/dist/task-board/services/taskService.js.map +1 -1
- package/dist/task-board/types.d.ts +21 -0
- package/dist/task-board/views/DependencyGraphView.d.ts +12 -0
- package/dist/task-board/views/DependencyGraphView.js +383 -0
- package/dist/task-board/views/DependencyGraphView.js.map +1 -0
- package/dist/task-board/views/KanbanView.d.ts +0 -4
- package/dist/task-board/views/KanbanView.js +4 -10
- package/dist/task-board/views/KanbanView.js.map +1 -1
- package/dist/task-board/views/ListView.d.ts +0 -4
- package/dist/task-board/views/ListView.js +3 -9
- package/dist/task-board/views/ListView.js.map +1 -1
- package/dist/task-board/views/WizardView.js +4 -4
- package/dist/task-board/views/WizardView.js.map +1 -1
- package/package.json +5 -2
|
@@ -3,12 +3,13 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
|
3
3
|
import { toast } from "sonner";
|
|
4
4
|
import { cn } from "../lib/utils";
|
|
5
5
|
import { Splitter } from "../editor/ui/Splitter";
|
|
6
|
-
import { deleteProject, getExecutionState, getProjects, getTasks, getDependencies, runOrchestrator, triggerPlanning, updateProject, updateTask, } from "./services/taskService";
|
|
6
|
+
import { deleteProject, getExecutionState, getGraphLayout, getProjects, getTasks, getDependencies, runOrchestrator, triggerPlanning, updateProject, updateTask, } from "./services/taskService";
|
|
7
7
|
import { getAgent, } from "../editor/services/agentService";
|
|
8
8
|
import { loadAiProfiles } from "../editor/services/aiService";
|
|
9
9
|
import { useEditContext } from "../editor/client/editContext";
|
|
10
10
|
import { KanbanView } from "./views/KanbanView";
|
|
11
11
|
import { ListView } from "./views/ListView";
|
|
12
|
+
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";
|
|
@@ -31,7 +32,8 @@ import { normalizeTaskStatus } from "./taskStatus";
|
|
|
31
32
|
import { getTaskExecutionDisplay, } from "./taskExecutionStatus";
|
|
32
33
|
import { indexTaskExecutionRecords, overlayTaskExecutionList, } from "./taskExecutionRecords";
|
|
33
34
|
import { WizardCommunicationCenter } from "./components/WizardCommunicationCenter";
|
|
34
|
-
import {
|
|
35
|
+
import { Button } from "../components/ui/button";
|
|
36
|
+
import { Loader2, Plus } from "lucide-react";
|
|
35
37
|
import { MainContentTree } from "../editor/sidebar/MainContentTree";
|
|
36
38
|
function TaskboardPreviewEditor({ itemDescriptor, }) {
|
|
37
39
|
const slotContext = useEditorSlotContext({
|
|
@@ -55,7 +57,11 @@ function getInitialQueryValue(queryKey) {
|
|
|
55
57
|
}
|
|
56
58
|
function getInitialViewTabIndex() {
|
|
57
59
|
const view = getInitialQueryValue(TASKBOARD_VIEW_QUERY_KEY)?.toLowerCase();
|
|
58
|
-
|
|
60
|
+
if (view === "list")
|
|
61
|
+
return 1;
|
|
62
|
+
if (view === "graph")
|
|
63
|
+
return 2;
|
|
64
|
+
return 0;
|
|
59
65
|
}
|
|
60
66
|
function getInitialWizardMode() {
|
|
61
67
|
const value = getInitialQueryValue(TASKBOARD_WIZARD_QUERY_KEY)?.toLowerCase();
|
|
@@ -134,6 +140,7 @@ export function TaskBoardWorkspace() {
|
|
|
134
140
|
const [tasks, setTasks] = useState([]);
|
|
135
141
|
const [isTasksLoading, setIsTasksLoading] = useState(false);
|
|
136
142
|
const [dependencies, setDependencies] = useState([]);
|
|
143
|
+
const [graphLayout, setGraphLayout] = useState(null);
|
|
137
144
|
const [executionRecordsByTaskId, setExecutionRecordsByTaskId] = useState({});
|
|
138
145
|
const [selectedTaskId, setSelectedTaskId] = useState(() => getInitialQueryValue(TASKBOARD_TASK_QUERY_KEY));
|
|
139
146
|
const [selectedTaskSource, setSelectedTaskSource] = useState(() => getInitialQueryValue(TASKBOARD_TASK_QUERY_KEY) ? "system" : null);
|
|
@@ -159,7 +166,7 @@ export function TaskBoardWorkspace() {
|
|
|
159
166
|
const [contextItemNamesByKey, setContextItemNamesByKey] = useState({});
|
|
160
167
|
const [contextItemPathsByKey, setContextItemPathsByKey] = useState({});
|
|
161
168
|
const [wizardPinnedTaskId, setWizardPinnedTaskId] = useState(null);
|
|
162
|
-
const [
|
|
169
|
+
const [, setWizardPinnedTaskSource] = useState(null);
|
|
163
170
|
const [wizardForceOverview, setWizardForceOverview] = useState(false);
|
|
164
171
|
const setWizardPinnedTask = useCallback((taskId, source = null) => {
|
|
165
172
|
setWizardPinnedTaskId(taskId);
|
|
@@ -180,11 +187,13 @@ export function TaskBoardWorkspace() {
|
|
|
180
187
|
const tasksRequestCountRef = useRef(0);
|
|
181
188
|
const latestTasksProjectIdRef = useRef(null);
|
|
182
189
|
const latestDependenciesProjectIdRef = useRef(null);
|
|
190
|
+
const latestGraphLayoutProjectIdRef = useRef(null);
|
|
183
191
|
const latestSubprojectCountsProjectIdRef = useRef(null);
|
|
184
192
|
const refreshProjectsRef = useRef(null);
|
|
185
193
|
const refreshTasksRef = useRef(null);
|
|
186
194
|
const refreshExecutionStateRef = useRef(null);
|
|
187
195
|
const refreshDependenciesRef = useRef(null);
|
|
196
|
+
const refreshGraphLayoutRef = useRef(null);
|
|
188
197
|
const refreshSubprojectTaskCountsRef = useRef(null);
|
|
189
198
|
const selectedProjectIdRef = useRef(null);
|
|
190
199
|
const directSubprojectIdsRef = useRef(new Set());
|
|
@@ -345,8 +354,15 @@ export function TaskBoardWorkspace() {
|
|
|
345
354
|
const canCreate = selectedProject?.permission === "Owner" ||
|
|
346
355
|
selectedProject?.permission === "Editor";
|
|
347
356
|
const canEditTasks = canCreate;
|
|
348
|
-
const
|
|
357
|
+
const viewTabs = useMemo(() => [
|
|
358
|
+
{ id: "kanban", label: "Kanban", content: null },
|
|
359
|
+
{ id: "list", label: "List", content: null },
|
|
360
|
+
{ id: "graph", label: "Graph", content: null },
|
|
361
|
+
], []);
|
|
362
|
+
const viewTabIds = useMemo(() => ["kanban", "list", "graph"], []);
|
|
349
363
|
const isListView = viewTabIds[activeTab] === "list";
|
|
364
|
+
const isGraphView = viewTabIds[activeTab] === "graph";
|
|
365
|
+
const sharedViewSwitcher = useMemo(() => (_jsxs("div", { className: "flex items-center justify-end gap-2", children: [_jsx(SimpleTabs, { tabs: viewTabs, activeTab: activeTab, setActiveTab: setActiveTab, hideContent: true, className: "rounded-lg border-0 bg-slate-100/50 p-1" }), _jsxs(Button, { size: "sm", onClick: () => setCreateDialogOpen(true), disabled: !canEditTasks, className: "h-8 px-3", "data-testid": "taskboard-create-task-button", children: [_jsx(Plus, { className: "h-4 w-4 sm:mr-1.5" }), _jsx("span", { className: "hidden sm:inline", children: "New Task" })] })] })), [activeTab, canEditTasks, viewTabs]);
|
|
350
366
|
const handleSelectProject = useCallback((projectId) => {
|
|
351
367
|
setSelectedProjectId((previousProjectId) => {
|
|
352
368
|
if (previousProjectId !== projectId) {
|
|
@@ -359,6 +375,7 @@ export function TaskBoardWorkspace() {
|
|
|
359
375
|
const clearSelectedProjectData = useCallback(() => {
|
|
360
376
|
setTasks([]);
|
|
361
377
|
setDependencies([]);
|
|
378
|
+
setGraphLayout(null);
|
|
362
379
|
setExecutionRecordsByTaskId({});
|
|
363
380
|
setSubprojectTaskCounts({});
|
|
364
381
|
setSubprojectTasksByProjectId({});
|
|
@@ -374,9 +391,6 @@ export function TaskBoardWorkspace() {
|
|
|
374
391
|
return selectedProject;
|
|
375
392
|
return (projects.find((project) => project.project.projectId === selectedTask.projectId) ?? selectedProject);
|
|
376
393
|
}, [projects, selectedProject, selectedTask]);
|
|
377
|
-
const planningTask = useMemo(() => tasksWithDisplayAssignees.find((t) => String(t.taskType ?? "").toLowerCase() === "plan") ??
|
|
378
|
-
tasksWithDisplayAssignees.find((t) => t.title === "Project Plan") ??
|
|
379
|
-
null, [tasksWithDisplayAssignees]);
|
|
380
394
|
const selectedTaskIsPlan = useMemo(() => {
|
|
381
395
|
const taskType = String(selectedTask?.taskType ?? "").toLowerCase();
|
|
382
396
|
return taskType === "plan" || selectedTask?.title === "Project Plan";
|
|
@@ -673,7 +687,7 @@ export function TaskBoardWorkspace() {
|
|
|
673
687
|
if (typeof window === "undefined")
|
|
674
688
|
return;
|
|
675
689
|
const current = new URLSearchParams(window.location.search);
|
|
676
|
-
const view = activeTab
|
|
690
|
+
const view = viewTabIds[activeTab] ?? "kanban";
|
|
677
691
|
if (selectedProjectId) {
|
|
678
692
|
current.set(TASKBOARD_PROJECT_QUERY_KEY, selectedProjectId);
|
|
679
693
|
}
|
|
@@ -702,7 +716,7 @@ export function TaskBoardWorkspace() {
|
|
|
702
716
|
if (newUrl !== oldUrl) {
|
|
703
717
|
window.history.replaceState(null, "", newUrl);
|
|
704
718
|
}
|
|
705
|
-
}, [selectedProjectId, selectedTaskId, activeTab, isWizardMode]);
|
|
719
|
+
}, [selectedProjectId, selectedTaskId, activeTab, isWizardMode, viewTabIds]);
|
|
706
720
|
useEffect(() => {
|
|
707
721
|
const handlePopState = () => {
|
|
708
722
|
syncTaskBoardStateFromUrl();
|
|
@@ -743,6 +757,19 @@ export function TaskBoardWorkspace() {
|
|
|
743
757
|
const indexed = indexTaskExecutionRecords(records);
|
|
744
758
|
setExecutionRecordsByTaskId(indexed);
|
|
745
759
|
}, []);
|
|
760
|
+
const refreshGraphLayout = useCallback(async (projectId) => {
|
|
761
|
+
latestGraphLayoutProjectIdRef.current = projectId;
|
|
762
|
+
const requestProjectId = projectId;
|
|
763
|
+
const result = await getGraphLayout(projectId);
|
|
764
|
+
if (latestGraphLayoutProjectIdRef.current !== requestProjectId) {
|
|
765
|
+
return;
|
|
766
|
+
}
|
|
767
|
+
if (result.type !== "success") {
|
|
768
|
+
toast.error(result.summary || "Failed to load graph layout");
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
setGraphLayout(result.data ?? null);
|
|
772
|
+
}, []);
|
|
746
773
|
const refreshSubprojectTaskCounts = useCallback(async () => {
|
|
747
774
|
const requestProjectId = selectedProjectId;
|
|
748
775
|
latestSubprojectCountsProjectIdRef.current = requestProjectId;
|
|
@@ -978,6 +1005,7 @@ export function TaskBoardWorkspace() {
|
|
|
978
1005
|
refreshTasksRef.current = refreshTasks;
|
|
979
1006
|
refreshExecutionStateRef.current = refreshExecutionState;
|
|
980
1007
|
refreshDependenciesRef.current = refreshDependencies;
|
|
1008
|
+
refreshGraphLayoutRef.current = refreshGraphLayout;
|
|
981
1009
|
refreshSubprojectTaskCountsRef.current = refreshSubprojectTaskCounts;
|
|
982
1010
|
selectedProjectIdRef.current = selectedProjectId;
|
|
983
1011
|
directSubprojectIdsRef.current = new Set(directSubprojects.map((subproject) => subproject.project.projectId));
|
|
@@ -987,6 +1015,7 @@ export function TaskBoardWorkspace() {
|
|
|
987
1015
|
refreshTasks,
|
|
988
1016
|
refreshExecutionState,
|
|
989
1017
|
refreshDependencies,
|
|
1018
|
+
refreshGraphLayout,
|
|
990
1019
|
refreshSubprojectTaskCounts,
|
|
991
1020
|
selectedProjectId,
|
|
992
1021
|
directSubprojects,
|
|
@@ -1236,7 +1265,7 @@ export function TaskBoardWorkspace() {
|
|
|
1236
1265
|
if (editContext?.confirm) {
|
|
1237
1266
|
editContext.confirm({
|
|
1238
1267
|
header: "Delete project",
|
|
1239
|
-
message: `Are you sure you want to delete
|
|
1268
|
+
message: `Are you sure you want to delete "${title}"?\n\nAny subprojects under this project will also be deleted. This action cannot be undone.`,
|
|
1240
1269
|
acceptLabel: "Delete",
|
|
1241
1270
|
showCancel: true,
|
|
1242
1271
|
accept: () => {
|
|
@@ -1275,6 +1304,7 @@ export function TaskBoardWorkspace() {
|
|
|
1275
1304
|
handleSelectMyTask,
|
|
1276
1305
|
handleSelectProject,
|
|
1277
1306
|
handleRunOrchestrator,
|
|
1307
|
+
selectedProject,
|
|
1278
1308
|
]);
|
|
1279
1309
|
useEffect(() => {
|
|
1280
1310
|
return () => {
|
|
@@ -1296,10 +1326,12 @@ export function TaskBoardWorkspace() {
|
|
|
1296
1326
|
const refreshTasksFn = refreshTasksRef.current;
|
|
1297
1327
|
const refreshExecutionStateFn = refreshExecutionStateRef.current;
|
|
1298
1328
|
const refreshDependenciesFn = refreshDependenciesRef.current;
|
|
1329
|
+
const refreshGraphLayoutFn = refreshGraphLayoutRef.current;
|
|
1299
1330
|
void Promise.all([
|
|
1300
1331
|
refreshTasksFn?.(selectedProjectId),
|
|
1301
1332
|
refreshExecutionStateFn?.(selectedProjectId),
|
|
1302
1333
|
refreshDependenciesFn?.(selectedProjectId),
|
|
1334
|
+
refreshGraphLayoutFn?.(selectedProjectId),
|
|
1303
1335
|
]).finally(() => {
|
|
1304
1336
|
if (cancelled)
|
|
1305
1337
|
return;
|
|
@@ -1369,6 +1401,19 @@ export function TaskBoardWorkspace() {
|
|
|
1369
1401
|
return;
|
|
1370
1402
|
const unsubscribe = addListener((message) => {
|
|
1371
1403
|
const messageType = message?.type;
|
|
1404
|
+
if (messageType === "project:properties:updated") {
|
|
1405
|
+
const payload = message?.payload;
|
|
1406
|
+
const projectId = payload?.projectId ?? payload?.ProjectId;
|
|
1407
|
+
const currentProjectId = selectedProjectIdRef.current;
|
|
1408
|
+
const refreshGraphLayoutFn = refreshGraphLayoutRef.current;
|
|
1409
|
+
if (projectId &&
|
|
1410
|
+
currentProjectId &&
|
|
1411
|
+
projectId === currentProjectId &&
|
|
1412
|
+
refreshGraphLayoutFn) {
|
|
1413
|
+
void refreshGraphLayoutFn(projectId);
|
|
1414
|
+
}
|
|
1415
|
+
return;
|
|
1416
|
+
}
|
|
1372
1417
|
if (messageType === "task:state-changed") {
|
|
1373
1418
|
const payload = message?.payload;
|
|
1374
1419
|
const projectId = payload?.projectId ??
|
|
@@ -1578,21 +1623,20 @@ export function TaskBoardWorkspace() {
|
|
|
1578
1623
|
clearWizardCloseTransitionTimeout();
|
|
1579
1624
|
setWizardForceOverview(false);
|
|
1580
1625
|
setTaskSelection(taskId, { source: "user", pinInWizard: true });
|
|
1581
|
-
} })), [
|
|
1582
|
-
wizardAttentionState,
|
|
1626
|
+
}, onOpenAgentTab: isMobile ? () => setMobileActiveTab(2) : undefined })), [
|
|
1583
1627
|
wizardDisplayedTask,
|
|
1584
1628
|
wizardDisplayedAgentId,
|
|
1585
1629
|
wizardDisplayedExecutionDisplay,
|
|
1630
|
+
wizardAttentionState.summaryState,
|
|
1631
|
+
wizardAttentionState.stats,
|
|
1632
|
+
wizardTasksWithDisplayAssignees,
|
|
1633
|
+
dependencies,
|
|
1586
1634
|
canEditTasks,
|
|
1587
|
-
|
|
1588
|
-
directSubprojects,
|
|
1635
|
+
isMobile,
|
|
1589
1636
|
refreshVisibleTaskData,
|
|
1590
|
-
clearWizardCloseTransitionTimeout,
|
|
1591
1637
|
handleCloseWizardTask,
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
selectedProject?.project.title,
|
|
1595
|
-
selectedProject?.project.description,
|
|
1638
|
+
clearWizardCloseTransitionTimeout,
|
|
1639
|
+
setTaskSelection,
|
|
1596
1640
|
]);
|
|
1597
1641
|
const isProjectViewLoading = !!selectedProjectId && projectViewLoadingId === selectedProjectId;
|
|
1598
1642
|
const taskBoardContent = useMemo(() => {
|
|
@@ -1609,58 +1653,47 @@ export function TaskBoardWorkspace() {
|
|
|
1609
1653
|
}, projectTitle: selectedProject?.project.title ?? "No project selected", projectDescription: selectedProject?.project.description, projectCostUsed: selectedProjectCumulativeCostUsed, projectCostLimit: selectedProject?.project.costLimit ?? null, canEditProperties: selectedProject?.permission === "Owner", communicationPanel: wizardCommunicationPanel }));
|
|
1610
1654
|
}
|
|
1611
1655
|
if (isListView) {
|
|
1612
|
-
return (_jsxs("div", { className: "grid 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" }), _jsx(ListView, { tasks: tasksWithDisplayAssignees, onSelectTask: (id) => setTaskSelection(id, { source: "user" }), selectedTaskId: selectedTaskId, onTasksChanged: () => {
|
|
1656
|
+
return (_jsxs("div", { className: "grid 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(ListView, { tasks: tasksWithDisplayAssignees, onSelectTask: (id) => setTaskSelection(id, { source: "user" }), selectedTaskId: selectedTaskId, onTasksChanged: () => {
|
|
1613
1657
|
void refreshVisibleTaskData();
|
|
1614
|
-
}, projectId: selectedProjectId, permission: selectedProject?.permission
|
|
1658
|
+
}, projectId: selectedProjectId, permission: selectedProject?.permission })] }));
|
|
1659
|
+
}
|
|
1660
|
+
if (isGraphView) {
|
|
1661
|
+
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, savedLayout: graphLayout, selectedTaskId: selectedTaskId, onSelectTask: (id) => setTaskSelection(id, { source: "user" }), permission: selectedProject?.permission, onLayoutSaved: setGraphLayout }) })] }));
|
|
1615
1662
|
}
|
|
1616
|
-
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" }), _jsx(KanbanView, { tasks: tasksWithDisplayAssignees, dependencies: dependencies, onSelectTask: (id) => setTaskSelection(id, { source: "user" }), selectedTaskId: selectedTaskId, onTasksChanged: () => {
|
|
1663
|
+
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(KanbanView, { tasks: tasksWithDisplayAssignees, dependencies: dependencies, onSelectTask: (id) => setTaskSelection(id, { source: "user" }), selectedTaskId: selectedTaskId, onTasksChanged: () => {
|
|
1617
1664
|
void refreshVisibleTaskData();
|
|
1618
|
-
}, projectId: selectedProjectId, permission: selectedProject?.permission
|
|
1665
|
+
}, projectId: selectedProjectId, permission: selectedProject?.permission })] }));
|
|
1619
1666
|
}, [
|
|
1620
1667
|
isProjectViewLoading,
|
|
1621
1668
|
selectedProjectId,
|
|
1622
1669
|
selectedProject,
|
|
1623
|
-
|
|
1670
|
+
isProjectsLoading,
|
|
1624
1671
|
isWizardMode,
|
|
1625
1672
|
isListView,
|
|
1626
|
-
|
|
1627
|
-
isProjectsLoading,
|
|
1628
|
-
tasksWithDisplayAssignees,
|
|
1629
|
-
wizardSubprojectTaskLists,
|
|
1630
|
-
selectedTaskId,
|
|
1631
|
-
wizardDisplayedTask?.taskId,
|
|
1632
|
-
refreshVisibleTaskData,
|
|
1633
|
-
selectedProject?.permission,
|
|
1634
|
-
selectedProject?.project.description,
|
|
1635
|
-
selectedProject?.project.status,
|
|
1636
|
-
selectedProject?.project.costLimit,
|
|
1673
|
+
isGraphView,
|
|
1637
1674
|
selectedProjectCumulativeCostUsed,
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
parentProject?.project.projectId,
|
|
1641
|
-
parentProject?.project.title,
|
|
1642
|
-
selectedProject?.project.title,
|
|
1675
|
+
savingProjectStatus,
|
|
1676
|
+
handleProjectStatusChange,
|
|
1643
1677
|
selectedProjectTaskCounts,
|
|
1678
|
+
directSubprojects,
|
|
1644
1679
|
subprojectTaskCounts,
|
|
1645
1680
|
subprojectCountsLoading,
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
handleProjectStatusChange,
|
|
1649
|
-
activeTab,
|
|
1681
|
+
parentProject?.project.projectId,
|
|
1682
|
+
parentProject?.project.title,
|
|
1650
1683
|
handleSelectProject,
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
runAssignedAgentDisabledReason,
|
|
1657
|
-
handleRunSelectedTaskAgent,
|
|
1658
|
-
isPlanning,
|
|
1659
|
-
handleStartPlanning,
|
|
1660
|
-
selectedTaskIsBlocked,
|
|
1684
|
+
sharedViewSwitcher,
|
|
1685
|
+
tasksWithDisplayAssignees,
|
|
1686
|
+
dependencies,
|
|
1687
|
+
selectedTaskId,
|
|
1688
|
+
activeTab,
|
|
1661
1689
|
canEditTasks,
|
|
1662
|
-
|
|
1663
|
-
|
|
1690
|
+
nav,
|
|
1691
|
+
isTasksLoading,
|
|
1692
|
+
wizardSubprojectTaskLists,
|
|
1693
|
+
wizardDisplayedTask?.taskId,
|
|
1694
|
+
wizardCommunicationPanel,
|
|
1695
|
+
setTaskSelection,
|
|
1696
|
+
refreshVisibleTaskData,
|
|
1664
1697
|
]);
|
|
1665
1698
|
const taskDetailPanel = useMemo(() => (_jsx(TaskDetailPanel, { project: selectedTaskProject, task: selectedTask, allTasks: taskSelectionUniverse, dependencies: dependencies, onTaskChanged: () => {
|
|
1666
1699
|
void refreshVisibleTaskData();
|
|
@@ -1670,6 +1703,7 @@ export function TaskBoardWorkspace() {
|
|
|
1670
1703
|
taskSelectionUniverse,
|
|
1671
1704
|
dependencies,
|
|
1672
1705
|
refreshVisibleTaskData,
|
|
1706
|
+
setTaskSelection,
|
|
1673
1707
|
]);
|
|
1674
1708
|
const agentTerminalPanel = useMemo(() => (_jsx(TaskAgentPanel, { agentId: displayAgentId, mode: agentPanelMode, label: selectedTaskIsPlan ? "Planner" : "Task Agent", hasAssignedAgentProfile: !selectedTaskIsPlan && selectedTaskHasAssignedAgentProfile, assignedAgentProfileName: !selectedTaskIsPlan && selectedTaskHasAssignedAgentProfile
|
|
1675
1709
|
? selectedTask?.assigneeDisplayName ||
|
|
@@ -1872,20 +1906,21 @@ export function TaskBoardWorkspace() {
|
|
|
1872
1906
|
defaultSize: "auto",
|
|
1873
1907
|
content: (_jsx("div", { className: "h-full min-h-0 min-w-0 overflow-hidden bg-gray-50", children: editorContent })),
|
|
1874
1908
|
},
|
|
1875
|
-
], splitterClassName: "bg-gray-200 hover:bg-gray-300 w-[6px]", className: "h-full" }));
|
|
1909
|
+
], splitterClassName: "bg-gray-200 hover:bg-gray-300 w-[6px]", className: "h-full", direction: isMobile ? "vertical" : "horizontal" }));
|
|
1876
1910
|
if (!currentItemDescriptor) {
|
|
1877
1911
|
return (_jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [_jsx("div", { className: "border-b border-gray-200 bg-white px-3 py-2", children: hasCurrentItem ? (_jsxs("div", { className: "min-w-0", children: [hasMultipleContextItems ? (_jsx(Select, { value: selectedContextItemValue, onValueChange: handleSelectContextItem, options: contextItemOptions, placeholder: "Select context item", size: "xs", searchable: true, className: "h-7 rounded-md bg-white", maxWidth: 420, "data-testid": "taskboard-context-item-selector" })) : (_jsx("div", { className: "truncate text-sm font-medium text-slate-900", children: previewItemName || "Loading item..." })), _jsxs("div", { className: "mt-0.5 flex items-center gap-2", children: [_jsx("span", { className: "truncate text-xs text-slate-500", children: previewItemPath || "Path unavailable" }), _jsx("span", { className: "shrink-0 rounded bg-slate-100 px-1.5 py-0.5 text-[10px] font-medium text-slate-600", children: selectedContextItemValue.split("|")[1] || "" }), previewItemVersion != null && (_jsxs("span", { className: "shrink-0 rounded bg-slate-100 px-1.5 py-0.5 text-[10px] font-medium text-slate-600", children: ["v", previewItemVersion] }))] })] })) : (_jsx("div", { className: "text-xs text-slate-500", children: "No item loaded" })) }), _jsx("div", { className: "min-h-0 flex-1 overflow-hidden bg-gray-50", children: renderPreviewSplit(_jsxs("div", { className: "flex h-full min-h-0 flex-col items-center justify-center gap-3 p-6 text-center", children: [_jsx("div", { className: "text-muted-foreground text-sm font-medium", children: "Editor preview unavailable" }), _jsx("div", { className: "text-muted-foreground text-xs", children: "Open the editor context item to preview and edit it here." })] })) })] }));
|
|
1878
1912
|
}
|
|
1879
1913
|
return (_jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [_jsx("div", { className: "border-b border-gray-200 bg-white px-3 py-2", children: hasCurrentItem ? (_jsxs("div", { className: "min-w-0", children: [hasMultipleContextItems ? (_jsx(Select, { value: selectedContextItemValue, onValueChange: handleSelectContextItem, options: contextItemOptions, placeholder: "Select context item", size: "xs", searchable: true, className: "h-7 rounded-md bg-white", maxWidth: 420, "data-testid": "taskboard-context-item-selector" })) : (_jsx("div", { className: "truncate text-sm font-medium text-slate-900", children: previewItemName || "Loading item..." })), _jsxs("div", { className: "mt-0.5 flex items-center gap-2", children: [_jsx("span", { className: "truncate text-xs text-slate-500", children: previewItemPath || "Path unavailable" }), _jsx("span", { className: "shrink-0 rounded bg-slate-100 px-1.5 py-0.5 text-[10px] font-medium text-slate-600", children: currentItemDescriptor?.language }), previewItemVersion != null && (_jsxs("span", { className: "shrink-0 rounded bg-slate-100 px-1.5 py-0.5 text-[10px] font-medium text-slate-600", children: ["v", previewItemVersion] }))] })] })) : (_jsx("div", { className: "text-xs text-slate-500", children: "No item loaded" })) }), _jsx("div", { className: "min-h-0 flex-1 overflow-hidden bg-gray-50", children: renderPreviewSplit(_jsx(TaskboardPreviewEditor, { itemDescriptor: currentItemDescriptor })) })] }));
|
|
1880
1914
|
}, [
|
|
1881
1915
|
currentItemDescriptor,
|
|
1882
|
-
contextItemOptions,
|
|
1883
1916
|
hasMultipleContextItems,
|
|
1884
|
-
handleSelectContextItem,
|
|
1885
1917
|
selectedContextItemValue,
|
|
1918
|
+
handleSelectContextItem,
|
|
1919
|
+
contextItemOptions,
|
|
1886
1920
|
previewItemName,
|
|
1887
1921
|
previewItemPath,
|
|
1888
1922
|
previewItemVersion,
|
|
1923
|
+
isMobile,
|
|
1889
1924
|
]);
|
|
1890
1925
|
useEffect(() => {
|
|
1891
1926
|
if (!assignAgentDialogOpen)
|
|
@@ -1924,7 +1959,7 @@ export function TaskBoardWorkspace() {
|
|
|
1924
1959
|
{
|
|
1925
1960
|
name: "task-list",
|
|
1926
1961
|
defaultSize: "auto",
|
|
1927
|
-
content: (_jsx("div", { className: "h-full overflow-x-auto overflow-y-auto bg-slate-50/50 p-2 pt-2
|
|
1962
|
+
content: (_jsx("div", { className: "h-full overflow-x-auto overflow-y-auto bg-slate-50/50 p-2 pt-2 md:p-4 md:pt-3", children: taskBoardContent })),
|
|
1928
1963
|
},
|
|
1929
1964
|
{
|
|
1930
1965
|
name: "task-details",
|
|
@@ -1948,6 +1983,35 @@ export function TaskBoardWorkspace() {
|
|
|
1948
1983
|
}
|
|
1949
1984
|
return listPanels;
|
|
1950
1985
|
}
|
|
1986
|
+
if (isGraphView) {
|
|
1987
|
+
const graphPanels = [
|
|
1988
|
+
{
|
|
1989
|
+
name: "task-list",
|
|
1990
|
+
defaultSize: "auto",
|
|
1991
|
+
content: (_jsx("div", { className: cn("flex h-full min-h-0 flex-col overflow-x-hidden overflow-y-auto bg-slate-50/50", selectedProjectId && "p-4 pt-3"), children: taskBoardContent })),
|
|
1992
|
+
},
|
|
1993
|
+
{
|
|
1994
|
+
name: "task-details",
|
|
1995
|
+
defaultSize: 420,
|
|
1996
|
+
content: taskDetailPanel,
|
|
1997
|
+
hidden: !selectedProjectId || !selectedTask,
|
|
1998
|
+
},
|
|
1999
|
+
{
|
|
2000
|
+
name: "agent-terminal",
|
|
2001
|
+
defaultSize: 560,
|
|
2002
|
+
content: agentTerminalPanel,
|
|
2003
|
+
hidden: !selectedProjectId || shouldHideAgentPanelForSelectedTask,
|
|
2004
|
+
},
|
|
2005
|
+
];
|
|
2006
|
+
if (showEditorPanel) {
|
|
2007
|
+
graphPanels.push({
|
|
2008
|
+
name: "editor-preview",
|
|
2009
|
+
defaultSize: 500,
|
|
2010
|
+
content: (_jsx("div", { className: "h-full overflow-hidden border-l border-gray-200 bg-gray-50", children: itemPreviewPanel })),
|
|
2011
|
+
});
|
|
2012
|
+
}
|
|
2013
|
+
return graphPanels;
|
|
2014
|
+
}
|
|
1951
2015
|
const kanbanPanels = [
|
|
1952
2016
|
{
|
|
1953
2017
|
name: "task-list",
|
|
@@ -1978,13 +2042,15 @@ export function TaskBoardWorkspace() {
|
|
|
1978
2042
|
}, [
|
|
1979
2043
|
isWizardMode,
|
|
1980
2044
|
isListView,
|
|
2045
|
+
isGraphView,
|
|
2046
|
+
selectedProjectId,
|
|
1981
2047
|
taskBoardContent,
|
|
1982
2048
|
taskDetailPanel,
|
|
1983
|
-
agentTerminalPanel,
|
|
1984
2049
|
selectedTask,
|
|
2050
|
+
agentTerminalPanel,
|
|
2051
|
+
shouldHideAgentPanelForSelectedTask,
|
|
1985
2052
|
showEditorPanel,
|
|
1986
2053
|
itemPreviewPanel,
|
|
1987
|
-
shouldHideAgentPanelForSelectedTask,
|
|
1988
2054
|
]);
|
|
1989
2055
|
return (_jsxs("div", { className: "text-foreground flex h-full w-full flex-col bg-white select-text", children: [_jsx("div", { className: "min-h-0 flex-1", children: isMobile ? (_jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [selectedProjectId && (_jsx("div", { className: "shrink-0 border-b border-gray-100 bg-white px-4 shadow-[0_1px_2px_rgba(0,0,0,0.03)]", children: _jsx(SimpleTabs, { tabs: [
|
|
1990
2056
|
{ id: "project", label: "Project", content: null },
|
|
@@ -2003,7 +2069,9 @@ export function TaskBoardWorkspace() {
|
|
|
2003
2069
|
...(showEditorPanel
|
|
2004
2070
|
? [{ id: "editor", label: "Editor", content: null }]
|
|
2005
2071
|
: []),
|
|
2006
|
-
], activeTab: mobileActiveTab, setActiveTab: setMobileActiveTab, hideContent: true, variant: "elegant", className: "gap-6" }) })), _jsxs("div", { className: "min-h-0 flex-1 overflow-hidden", children: [mobileActiveTab === 0 && (_jsx("div", { className: cn("flex h-full overflow-y-auto bg-slate-50/50", selectedProjectId &&
|
|
2072
|
+
], activeTab: mobileActiveTab, setActiveTab: setMobileActiveTab, hideContent: true, variant: "elegant", className: "gap-6" }) })), _jsxs("div", { className: "min-h-0 flex-1 overflow-hidden", children: [mobileActiveTab === 0 && (_jsx("div", { className: cn("flex h-full overflow-y-auto bg-slate-50/50", selectedProjectId &&
|
|
2073
|
+
!isWizardMode &&
|
|
2074
|
+
"p-2 pt-2 md:p-4 md:pt-3"), children: taskBoardContent })), mobileActiveTab === 1 && (_jsx("div", { className: "h-full overflow-y-auto bg-white", children: taskDetailPanel })), mobileActiveTab === 2 && (_jsx("div", { className: "h-full overflow-hidden bg-white", children: shouldHideAgentPanelForSelectedTask
|
|
2007
2075
|
? taskDetailPanel
|
|
2008
2076
|
: agentTerminalPanel })), mobileActiveTab === 3 && showEditorPanel && (_jsx("div", { className: "h-full overflow-hidden bg-gray-50", children: itemPreviewPanel }))] })] })) : (_jsx(Splitter, { panels: panels, direction: "horizontal", localStorageKey: isWizardMode
|
|
2009
2077
|
? "task-board-wizard-splitter-v2"
|