@parhelia/core 0.3.12816 → 0.3.12818
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/editor/ContentTree.d.ts +1 -1
- package/dist/editor/ContentTree.js +25 -3
- package/dist/editor/ContentTree.js.map +1 -1
- package/dist/editor/ai/terminal/useAgentStopCommand.js +16 -14
- package/dist/editor/ai/terminal/useAgentStopCommand.js.map +1 -1
- package/dist/editor/client/operations.js +12 -3
- package/dist/editor/client/operations.js.map +1 -1
- package/dist/editor/media-selector/Thumbnails.js +23 -10
- package/dist/editor/media-selector/Thumbnails.js.map +1 -1
- package/dist/editor/media-selector/mediaItemDrag.d.ts +22 -5
- package/dist/editor/media-selector/mediaItemDrag.js +108 -10
- package/dist/editor/media-selector/mediaItemDrag.js.map +1 -1
- package/dist/editor/settings/panels/ProjectTemplatesPanel.js +45 -1
- package/dist/editor/settings/panels/ProjectTemplatesPanel.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/task-board/TaskBoardWorkspace.js +186 -7
- package/dist/task-board/TaskBoardWorkspace.js.map +1 -1
- package/dist/task-board/components/CreateTaskDialog.d.ts +2 -0
- package/dist/task-board/components/CreateTaskDialog.js +6 -3
- package/dist/task-board/components/CreateTaskDialog.js.map +1 -1
- package/dist/task-board/components/GoalCoverageBar.d.ts +4 -0
- package/dist/task-board/components/GoalCoverageBar.js +22 -0
- package/dist/task-board/components/GoalCoverageBar.js.map +1 -0
- package/dist/task-board/components/GoalDataView.d.ts +39 -0
- package/dist/task-board/components/GoalDataView.js +385 -0
- package/dist/task-board/components/GoalDataView.js.map +1 -0
- package/dist/task-board/components/GoalsMatrix.d.ts +16 -0
- package/dist/task-board/components/GoalsMatrix.js +129 -0
- package/dist/task-board/components/GoalsMatrix.js.map +1 -0
- package/dist/task-board/components/ProjectDashboard.d.ts +1 -1
- package/dist/task-board/components/ProjectGoalsPanel.d.ts +16 -0
- package/dist/task-board/components/ProjectGoalsPanel.js +74 -113
- package/dist/task-board/components/ProjectGoalsPanel.js.map +1 -1
- package/dist/task-board/components/SubgoalStatusIcon.d.ts +4 -0
- package/dist/task-board/components/SubgoalStatusIcon.js +19 -0
- package/dist/task-board/components/SubgoalStatusIcon.js.map +1 -0
- package/dist/task-board/components/goalDisplaySpec.d.ts +19 -0
- package/dist/task-board/components/goalDisplaySpec.js +72 -0
- package/dist/task-board/components/goalDisplaySpec.js.map +1 -0
- package/dist/task-board/goalRefreshState.d.ts +6 -0
- package/dist/task-board/goalRefreshState.js +11 -0
- package/dist/task-board/goalRefreshState.js.map +1 -0
- package/dist/task-board/goalTaskNavigationState.d.ts +43 -0
- package/dist/task-board/goalTaskNavigationState.js +65 -0
- package/dist/task-board/goalTaskNavigationState.js.map +1 -0
- package/dist/task-board/types.d.ts +6 -0
- package/package.json +1 -1
|
@@ -37,6 +37,8 @@ import { WizardCommunicationCenter } from "./components/WizardCommunicationCente
|
|
|
37
37
|
import { Loader2 } from "lucide-react";
|
|
38
38
|
import { MainContentTree } from "../editor/sidebar/MainContentTree";
|
|
39
39
|
import { useTaskBoardAgentPanelState } from "./useTaskBoardAgentPanelState";
|
|
40
|
+
import { goalScopesMatch } from "./goalRefreshState";
|
|
41
|
+
import { initialGoalTaskNavigationState, reduceGoalTaskNavigation, } from "./goalTaskNavigationState";
|
|
40
42
|
const DependencyGraphView = lazy(() => import("./views/DependencyGraphView").then((module) => ({
|
|
41
43
|
default: module.DependencyGraphView,
|
|
42
44
|
})));
|
|
@@ -177,10 +179,15 @@ export function TaskBoardWorkspace() {
|
|
|
177
179
|
const [tasks, setTasks] = useState([]);
|
|
178
180
|
const [goals, setGoals] = useState([]);
|
|
179
181
|
const [goalsLoading, setGoalsLoading] = useState(false);
|
|
182
|
+
const [goalsError, setGoalsError] = useState(null);
|
|
180
183
|
const [goalCatalog, setGoalCatalog] = useState([]);
|
|
181
184
|
const [goalPermissions, setGoalPermissions] = useState({});
|
|
185
|
+
const [goalDisplaySpecs, setGoalDisplaySpecs] = useState({});
|
|
186
|
+
const [goalStateScope, setGoalStateScope] = useState(null);
|
|
182
187
|
const [includeGoalSubprojects, setIncludeGoalSubprojects] = useState(false);
|
|
183
188
|
const latestGoalsProjectIdRef = useRef(null);
|
|
189
|
+
const goalsRequestGenerationRef = useRef(0);
|
|
190
|
+
const wsGoalRefreshTimeoutRef = useRef(null);
|
|
184
191
|
const refreshGoalsRef = useRef(null);
|
|
185
192
|
const includeGoalSubprojectsRef = useRef(false);
|
|
186
193
|
const [isTasksLoading, setIsTasksLoading] = useState(false);
|
|
@@ -250,6 +257,14 @@ export function TaskBoardWorkspace() {
|
|
|
250
257
|
const projectsRequestCountRef = useRef(0);
|
|
251
258
|
const tasksRequestCountRef = useRef(0);
|
|
252
259
|
const latestTasksProjectIdRef = useRef(null);
|
|
260
|
+
const taskRequestGenerationByProjectRef = useRef(new Map());
|
|
261
|
+
const taskRequestInFlightByProjectRef = useRef(new Map());
|
|
262
|
+
const goalTaskNavigationStateRef = useRef(initialGoalTaskNavigationState);
|
|
263
|
+
const transitionGoalTaskNavigation = useCallback((action) => {
|
|
264
|
+
const next = reduceGoalTaskNavigation(goalTaskNavigationStateRef.current, action);
|
|
265
|
+
goalTaskNavigationStateRef.current = next;
|
|
266
|
+
return next.outcome;
|
|
267
|
+
}, []);
|
|
253
268
|
const latestDependenciesProjectIdRef = useRef(null);
|
|
254
269
|
const latestGraphLayoutProjectIdRef = useRef(null);
|
|
255
270
|
const latestSubprojectCountsProjectIdRef = useRef(null);
|
|
@@ -798,6 +813,9 @@ export function TaskBoardWorkspace() {
|
|
|
798
813
|
return () => window.removeEventListener("popstate", handlePopState);
|
|
799
814
|
}, [syncTaskBoardStateFromUrl]);
|
|
800
815
|
const refreshTasks = useCallback(async (projectId) => {
|
|
816
|
+
const generation = (taskRequestGenerationByProjectRef.current.get(projectId) ?? 0) + 1;
|
|
817
|
+
taskRequestGenerationByProjectRef.current.set(projectId, generation);
|
|
818
|
+
taskRequestInFlightByProjectRef.current.set(projectId, generation);
|
|
801
819
|
tasksRequestCountRef.current += 1;
|
|
802
820
|
latestTasksProjectIdRef.current = projectId;
|
|
803
821
|
const requestProjectId = projectId;
|
|
@@ -813,14 +831,29 @@ export function TaskBoardWorkspace() {
|
|
|
813
831
|
}
|
|
814
832
|
const nextTasks = result.data || [];
|
|
815
833
|
setTasks(nextTasks);
|
|
834
|
+
const navigationOutcome = transitionGoalTaskNavigation({
|
|
835
|
+
type: "tasksLoaded",
|
|
836
|
+
projectId,
|
|
837
|
+
generation,
|
|
838
|
+
taskIds: nextTasks.map((task) => task.taskId),
|
|
839
|
+
});
|
|
840
|
+
if (navigationOutcome.kind === "select") {
|
|
841
|
+
setTaskSelection(navigationOutcome.taskId, { source: "user" });
|
|
842
|
+
}
|
|
843
|
+
else if (navigationOutcome.kind === "missing") {
|
|
844
|
+
toast.error("The referenced task is not available in this project");
|
|
845
|
+
}
|
|
816
846
|
}
|
|
817
847
|
finally {
|
|
848
|
+
if (taskRequestInFlightByProjectRef.current.get(projectId) === generation) {
|
|
849
|
+
taskRequestInFlightByProjectRef.current.delete(projectId);
|
|
850
|
+
}
|
|
818
851
|
tasksRequestCountRef.current = Math.max(0, tasksRequestCountRef.current - 1);
|
|
819
852
|
if (tasksRequestCountRef.current === 0) {
|
|
820
853
|
setIsTasksLoading(false);
|
|
821
854
|
}
|
|
822
855
|
}
|
|
823
|
-
}, []);
|
|
856
|
+
}, [setTaskSelection, transitionGoalTaskNavigation]);
|
|
824
857
|
const refreshExecutionState = useCallback(async (projectId) => {
|
|
825
858
|
const result = await getExecutionState({ projectId });
|
|
826
859
|
if (result.type !== "success") {
|
|
@@ -832,22 +865,36 @@ export function TaskBoardWorkspace() {
|
|
|
832
865
|
setExecutionRecordsByTaskId(indexed);
|
|
833
866
|
}, []);
|
|
834
867
|
const refreshGoals = useCallback(async (projectId, includeDescendants) => {
|
|
868
|
+
const generation = ++goalsRequestGenerationRef.current;
|
|
835
869
|
latestGoalsProjectIdRef.current = projectId;
|
|
836
870
|
setGoalsLoading(true);
|
|
871
|
+
setGoalsError(null);
|
|
837
872
|
try {
|
|
838
873
|
const result = await getProjectGoals(projectId, includeDescendants);
|
|
839
|
-
if (latestGoalsProjectIdRef.current !== projectId
|
|
874
|
+
if (latestGoalsProjectIdRef.current !== projectId ||
|
|
875
|
+
generation !== goalsRequestGenerationRef.current)
|
|
840
876
|
return;
|
|
841
877
|
if (result.type !== "success") {
|
|
842
|
-
|
|
878
|
+
const message = result.summary || "Failed to load goals";
|
|
879
|
+
setGoals([]);
|
|
880
|
+
setGoalCatalog([]);
|
|
881
|
+
setGoalPermissions({});
|
|
882
|
+
setGoalDisplaySpecs({});
|
|
883
|
+
setGoalStateScope({ projectId, includeDescendants });
|
|
884
|
+
setGoalsError(message);
|
|
885
|
+
toast.error(message);
|
|
843
886
|
return;
|
|
844
887
|
}
|
|
845
888
|
setGoals(result.data?.goals ?? []);
|
|
846
889
|
setGoalCatalog(result.data?.catalog ?? []);
|
|
847
890
|
setGoalPermissions(result.data?.permissions ?? {});
|
|
891
|
+
setGoalDisplaySpecs(result.data?.displaySpecs ?? {});
|
|
892
|
+
setGoalStateScope({ projectId, includeDescendants });
|
|
893
|
+
setGoalsError(null);
|
|
848
894
|
}
|
|
849
895
|
finally {
|
|
850
|
-
if (latestGoalsProjectIdRef.current === projectId
|
|
896
|
+
if (latestGoalsProjectIdRef.current === projectId &&
|
|
897
|
+
generation === goalsRequestGenerationRef.current) {
|
|
851
898
|
setGoalsLoading(false);
|
|
852
899
|
}
|
|
853
900
|
}
|
|
@@ -868,6 +915,14 @@ export function TaskBoardWorkspace() {
|
|
|
868
915
|
return;
|
|
869
916
|
void refreshGoals(selectedProjectId, includeGoalSubprojects);
|
|
870
917
|
}, [isGoalsView, selectedProjectId, includeGoalSubprojects, refreshGoals]);
|
|
918
|
+
useEffect(() => {
|
|
919
|
+
return () => {
|
|
920
|
+
if (wsGoalRefreshTimeoutRef.current !== null) {
|
|
921
|
+
window.clearTimeout(wsGoalRefreshTimeoutRef.current);
|
|
922
|
+
wsGoalRefreshTimeoutRef.current = null;
|
|
923
|
+
}
|
|
924
|
+
};
|
|
925
|
+
}, [selectedProjectId, includeGoalSubprojects]);
|
|
871
926
|
const refreshGraphLayout = useCallback(async (projectId) => {
|
|
872
927
|
latestGraphLayoutProjectIdRef.current = projectId;
|
|
873
928
|
const requestProjectId = projectId;
|
|
@@ -1701,7 +1756,11 @@ export function TaskBoardWorkspace() {
|
|
|
1701
1756
|
useEffect(() => {
|
|
1702
1757
|
previousTaskStatusesRef.current = {};
|
|
1703
1758
|
previousWizardAttentionSignatureRef.current = "";
|
|
1704
|
-
|
|
1759
|
+
transitionGoalTaskNavigation({
|
|
1760
|
+
type: "projectSelected",
|
|
1761
|
+
projectId: selectedProjectId,
|
|
1762
|
+
});
|
|
1763
|
+
}, [selectedProjectId, transitionGoalTaskNavigation]);
|
|
1705
1764
|
useEffect(() => {
|
|
1706
1765
|
if (!selectedProjectId)
|
|
1707
1766
|
return;
|
|
@@ -1846,7 +1905,13 @@ export function TaskBoardWorkspace() {
|
|
|
1846
1905
|
!isProjectWithinSelectedTree(projectId, currentProjectId)) {
|
|
1847
1906
|
return;
|
|
1848
1907
|
}
|
|
1849
|
-
|
|
1908
|
+
if (wsGoalRefreshTimeoutRef.current !== null) {
|
|
1909
|
+
window.clearTimeout(wsGoalRefreshTimeoutRef.current);
|
|
1910
|
+
}
|
|
1911
|
+
wsGoalRefreshTimeoutRef.current = window.setTimeout(() => {
|
|
1912
|
+
wsGoalRefreshTimeoutRef.current = null;
|
|
1913
|
+
refreshGoalsRef.current?.();
|
|
1914
|
+
}, WS_REFRESH_DELAY_MS);
|
|
1850
1915
|
return;
|
|
1851
1916
|
}
|
|
1852
1917
|
if (messageType !== "task:updated" &&
|
|
@@ -2056,6 +2121,105 @@ export function TaskBoardWorkspace() {
|
|
|
2056
2121
|
wizardNextReviewTaskId,
|
|
2057
2122
|
]);
|
|
2058
2123
|
const isProjectViewLoading = !!selectedProjectId && projectViewLoadingId === selectedProjectId;
|
|
2124
|
+
const goalScopeMatches = goalScopesMatch(goalStateScope, {
|
|
2125
|
+
projectId: selectedProjectId ?? "",
|
|
2126
|
+
includeDescendants: includeGoalSubprojects,
|
|
2127
|
+
});
|
|
2128
|
+
const goalProjectLabels = useMemo(() => {
|
|
2129
|
+
const byId = new Map(projects.map((entry) => [entry.project.projectId, entry.project]));
|
|
2130
|
+
const labels = {};
|
|
2131
|
+
for (const entry of projects) {
|
|
2132
|
+
const project = entry.project;
|
|
2133
|
+
const titles = [];
|
|
2134
|
+
const seen = new Set();
|
|
2135
|
+
let cursorId = project.projectId;
|
|
2136
|
+
while (cursorId && !seen.has(cursorId)) {
|
|
2137
|
+
const cursor = byId.get(cursorId);
|
|
2138
|
+
if (!cursor)
|
|
2139
|
+
break;
|
|
2140
|
+
seen.add(cursorId);
|
|
2141
|
+
titles.unshift(cursor.title);
|
|
2142
|
+
cursorId = cursor.parentProjectId ?? null;
|
|
2143
|
+
}
|
|
2144
|
+
labels[project.projectId] = {
|
|
2145
|
+
title: project.title,
|
|
2146
|
+
path: titles.join(" / "),
|
|
2147
|
+
};
|
|
2148
|
+
}
|
|
2149
|
+
return labels;
|
|
2150
|
+
}, [projects]);
|
|
2151
|
+
const handleGoalOpenItem = useCallback(async (ref) => {
|
|
2152
|
+
if (!editContext)
|
|
2153
|
+
return;
|
|
2154
|
+
try {
|
|
2155
|
+
const loaded = await editContext.loadItem({
|
|
2156
|
+
id: ref.itemId,
|
|
2157
|
+
language: ref.language ?? editContext.currentItemDescriptor?.language ?? "en",
|
|
2158
|
+
version: 0,
|
|
2159
|
+
});
|
|
2160
|
+
if (!loaded) {
|
|
2161
|
+
toast.error("The referenced item could not be opened");
|
|
2162
|
+
return;
|
|
2163
|
+
}
|
|
2164
|
+
editContext.setShowAgentsWorkspaceEditor(true);
|
|
2165
|
+
}
|
|
2166
|
+
catch {
|
|
2167
|
+
toast.error("The referenced item could not be opened");
|
|
2168
|
+
}
|
|
2169
|
+
}, [editContext]);
|
|
2170
|
+
const handleGoalSelectTask = useCallback((ref) => {
|
|
2171
|
+
const targetProjectId = ref.projectId ?? selectedProjectIdRef.current;
|
|
2172
|
+
if (!targetProjectId)
|
|
2173
|
+
return;
|
|
2174
|
+
const project = projectsRef.current.find((entry) => entry.project.projectId.toLowerCase() ===
|
|
2175
|
+
targetProjectId.toLowerCase());
|
|
2176
|
+
if (!project) {
|
|
2177
|
+
toast.error("The referenced task project is not available");
|
|
2178
|
+
return;
|
|
2179
|
+
}
|
|
2180
|
+
const resolvedProjectId = project.project.projectId;
|
|
2181
|
+
const currentProjectId = selectedProjectIdRef.current;
|
|
2182
|
+
const inFlightGeneration = taskRequestInFlightByProjectRef.current.get(resolvedProjectId);
|
|
2183
|
+
const latestIssued = taskRequestGenerationByProjectRef.current.get(resolvedProjectId) ?? 0;
|
|
2184
|
+
const navigationOutcome = transitionGoalTaskNavigation({
|
|
2185
|
+
type: "request",
|
|
2186
|
+
projectId: resolvedProjectId,
|
|
2187
|
+
taskId: ref.taskId,
|
|
2188
|
+
currentProjectId,
|
|
2189
|
+
currentTaskIds: tasksRef.current.map((task) => task.taskId),
|
|
2190
|
+
inFlightGeneration,
|
|
2191
|
+
latestIssuedGeneration: latestIssued,
|
|
2192
|
+
});
|
|
2193
|
+
if (navigationOutcome.kind === "select") {
|
|
2194
|
+
setTaskSelection(navigationOutcome.taskId, { source: "user" });
|
|
2195
|
+
return;
|
|
2196
|
+
}
|
|
2197
|
+
if (navigationOutcome.kind === "missing") {
|
|
2198
|
+
toast.error("The referenced task is not available in this project");
|
|
2199
|
+
return;
|
|
2200
|
+
}
|
|
2201
|
+
if (navigationOutcome.kind === "load") {
|
|
2202
|
+
if (navigationOutcome.switchProject) {
|
|
2203
|
+
handleSelectProject(navigationOutcome.projectId);
|
|
2204
|
+
}
|
|
2205
|
+
else if (navigationOutcome.refresh) {
|
|
2206
|
+
void refreshTasks(navigationOutcome.projectId);
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
}, [
|
|
2210
|
+
handleSelectProject,
|
|
2211
|
+
refreshTasks,
|
|
2212
|
+
setTaskSelection,
|
|
2213
|
+
transitionGoalTaskNavigation,
|
|
2214
|
+
]);
|
|
2215
|
+
const handleGoalTaskCreated = useCallback((projectId) => {
|
|
2216
|
+
if (projectId === selectedProjectIdRef.current) {
|
|
2217
|
+
void refreshVisibleTaskData();
|
|
2218
|
+
}
|
|
2219
|
+
else if (directSubprojectIdsRef.current.has(projectId)) {
|
|
2220
|
+
void refreshSubprojectTaskCountsRef.current?.();
|
|
2221
|
+
}
|
|
2222
|
+
}, [refreshVisibleTaskData]);
|
|
2059
2223
|
const taskBoardContent = useMemo(() => {
|
|
2060
2224
|
if (isProjectViewLoading) {
|
|
2061
2225
|
return (_jsx("div", { className: "border-border-default bg-neutral-grey-5/70 flex h-full min-h-[240px] items-center justify-center rounded-lg border border-dashed", "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, { strokeWidth: 1, className: "h-6 w-6 animate-spin" }), _jsx("div", { children: "Loading project..." })] }) }));
|
|
@@ -2076,7 +2240,14 @@ export function TaskBoardWorkspace() {
|
|
|
2076
2240
|
} }) })] }));
|
|
2077
2241
|
}
|
|
2078
2242
|
if (isGoalsView) {
|
|
2079
|
-
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, selectedProjectCostUsed: selectedProjectCumulativeCostUsed, selectedProjectCostLimit: selectedProject?.project.costLimit ?? null, selectedProjectTaskCounts: selectedProjectTaskCounts, subprojects: directSubprojects, taskCountsByProjectId: subprojectTaskCounts, parentProjectId: parentProject?.project.projectId ?? null, parentProjectTitle: parentProject?.project.title ?? null, onSelectProject: handleSelectProject, canCreateTask: canEditTasks, onCreateTask: () => setCreateDialogOpen(true), showCreateTaskButton: false }), sharedViewSwitcher, _jsx("div", { className: "mt-3
|
|
2243
|
+
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, selectedProjectCostUsed: selectedProjectCumulativeCostUsed, selectedProjectCostLimit: selectedProject?.project.costLimit ?? null, selectedProjectTaskCounts: selectedProjectTaskCounts, subprojects: directSubprojects, taskCountsByProjectId: subprojectTaskCounts, parentProjectId: parentProject?.project.projectId ?? null, parentProjectTitle: parentProject?.project.title ?? null, onSelectProject: handleSelectProject, canCreateTask: canEditTasks, onCreateTask: () => setCreateDialogOpen(true), showCreateTaskButton: false }), sharedViewSwitcher, _jsx("div", { className: "mt-3 min-w-0", children: _jsx(ProjectGoalsPanel, { goals: goalScopeMatches ? goals : [], catalog: goalScopeMatches ? goalCatalog : [], loading: goalsLoading || !goalScopeMatches, error: goalScopeMatches ? goalsError : null, onRetry: () => {
|
|
2244
|
+
if (selectedProjectId) {
|
|
2245
|
+
void refreshGoals(selectedProjectId, includeGoalSubprojects);
|
|
2246
|
+
}
|
|
2247
|
+
}, hasSubprojects: hasDirectSubprojects, includeDescendants: includeGoalSubprojects, onToggleIncludeDescendants: setIncludeGoalSubprojects, selectedProjectId: selectedProjectId, permissions: goalScopeMatches ? goalPermissions : {}, goalDisplaySpecs: goalScopeMatches ? goalDisplaySpecs : {}, projectLabels: goalProjectLabels, onOpenItem: (ref) => void handleGoalOpenItem(ref), onSelectTask: handleGoalSelectTask, onTaskCreated: handleGoalTaskCreated, onChanged: () => {
|
|
2248
|
+
if (goalScopeMatches)
|
|
2249
|
+
refreshGoalsRef.current?.();
|
|
2250
|
+
} }) })] }));
|
|
2080
2251
|
}
|
|
2081
2252
|
if (isKpisView) {
|
|
2082
2253
|
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, selectedProjectCostUsed: selectedProjectCumulativeCostUsed, selectedProjectCostLimit: selectedProject?.project.costLimit ?? null, selectedProjectTaskCounts: selectedProjectTaskCounts, subprojects: directSubprojects, taskCountsByProjectId: subprojectTaskCounts, parentProjectId: parentProject?.project.projectId ?? null, parentProjectTitle: parentProject?.project.title ?? null, onSelectProject: handleSelectProject, canCreateTask: canEditTasks, onCreateTask: () => setCreateDialogOpen(true), showCreateTaskButton: false }), sharedViewSwitcher, _jsx("div", { className: "mt-3 max-w-[1000px]", children: _jsx(ProjectKpisPanel, { selectedProjectCostUsed: selectedProjectCumulativeCostUsed, selectedProjectCostLimit: selectedProject?.project.costLimit ?? null, selectedProjectTaskCounts: selectedProjectTaskCounts, selectedProjectAttention: selectedProject?.overview?.attention, subprojects: directSubprojects, taskCountsByProjectId: subprojectTaskCounts, attentionTaskGroups: kpiAttentionTaskGroups, attentionDetailsLoading: subprojectCountsLoading, onSelectAttentionTask: (taskId) => setTaskSelection(taskId, { source: "user" }) }) })] }));
|
|
@@ -2114,8 +2285,12 @@ export function TaskBoardWorkspace() {
|
|
|
2114
2285
|
isGoalsView,
|
|
2115
2286
|
goals,
|
|
2116
2287
|
goalsLoading,
|
|
2288
|
+
goalsError,
|
|
2117
2289
|
goalCatalog,
|
|
2118
2290
|
goalPermissions,
|
|
2291
|
+
goalDisplaySpecs,
|
|
2292
|
+
goalScopeMatches,
|
|
2293
|
+
goalProjectLabels,
|
|
2119
2294
|
includeGoalSubprojects,
|
|
2120
2295
|
hasDirectSubprojects,
|
|
2121
2296
|
graphLayout,
|
|
@@ -2145,7 +2320,11 @@ export function TaskBoardWorkspace() {
|
|
|
2145
2320
|
wizardCommunicationPanel,
|
|
2146
2321
|
setTaskSelection,
|
|
2147
2322
|
refreshProjects,
|
|
2323
|
+
refreshGoals,
|
|
2148
2324
|
refreshVisibleTaskData,
|
|
2325
|
+
handleGoalOpenItem,
|
|
2326
|
+
handleGoalSelectTask,
|
|
2327
|
+
handleGoalTaskCreated,
|
|
2149
2328
|
]);
|
|
2150
2329
|
const taskDetailAgentLaunch = useMemo(() => {
|
|
2151
2330
|
if (!selectedTask)
|