Skip to content

Commit 32f43df

Browse files
committed
clean up left panel
1 parent b4d690b commit 32f43df

File tree

5 files changed

+145
-129
lines changed

5 files changed

+145
-129
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import PanelLeft from "@/coral/components/Panels/PanelLeft";
2+
import PanelLeftToolbar from "@/coral/components/Panels/PanelLeftToolbar";
3+
import { Button, Spinner, Toast, ToastBody, ToastTitle, useToastController } from "@fluentui/react-components";
4+
import { Add20Regular, ErrorCircle20Regular } from "@fluentui/react-icons";
5+
import TaskList from "./TaskList";
6+
import { useCallback, useEffect, useState } from "react";
7+
import { useNavigate } from "react-router-dom";
8+
import { PlanPanelLefProps, PlanWithSteps, Task } from "@/models";
9+
import { apiService } from "@/api";
10+
import { TaskService } from "@/services";
11+
12+
const PlanPanelLeft: React.FC<PlanPanelLefProps> = ({
13+
onNewTaskButton,
14+
}) => {
15+
16+
const { dispatchToast } = useToastController('toast'); // State for task lists
17+
const navigate = useNavigate();
18+
const [inProgressTasks, setInProgressTasks] = useState<Task[]>([]);
19+
const [completedTasks, setCompletedTasks] = useState<Task[]>([]);
20+
21+
// State for API calls
22+
const [plans, setPlans] = useState<PlanWithSteps[] | null>(null);
23+
const [plansLoading, setPlansLoading] = useState<boolean>(false);
24+
const [plansError, setPlansError] = useState<Error | null>(null);
25+
26+
/**
27+
* Load plans data and update task lists
28+
*/
29+
const loadPlansData = useCallback(async (forceRefresh = false) => {
30+
try {
31+
setPlansLoading(true);
32+
setPlansError(null);
33+
34+
// Call the apiService directly
35+
const plansData = await apiService.getPlans(undefined, !forceRefresh);
36+
setPlans(plansData);
37+
} catch (error) {
38+
console.error('Failed to load plans:', error);
39+
setPlansError(error instanceof Error ? error : new Error('Failed to load plans'));
40+
} finally {
41+
setPlansLoading(false);
42+
}
43+
}, []);
44+
45+
// Load data on component mount
46+
useEffect(() => {
47+
loadPlansData();
48+
}, [loadPlansData]);
49+
50+
51+
const handleTaskSelect = useCallback((taskId: string) => {
52+
console.log('Selected task ID:', taskId);
53+
54+
// Find the plan by session_id to get the plan_id
55+
const selectedPlan = plans?.find((plan: PlanWithSteps) => plan.session_id === taskId);
56+
if (selectedPlan) {
57+
navigate(`/plan/${selectedPlan.id}`);
58+
}
59+
}, [plans, navigate]);// Transform plans data when it changes
60+
useEffect(() => {
61+
if (plans) {
62+
const { inProgress, completed } = TaskService.transformPlansToTasks(plans);
63+
setInProgressTasks(inProgress);
64+
setCompletedTasks(completed);
65+
}
66+
}, [plans]);
67+
68+
69+
// Handle API errors
70+
useEffect(() => {
71+
if (plansError) {
72+
dispatchToast(
73+
<Toast>
74+
<ToastTitle>
75+
<ErrorCircle20Regular />
76+
Failed to load tasks
77+
</ToastTitle>
78+
<ToastBody>
79+
{plansError.message}
80+
</ToastBody>
81+
</Toast>,
82+
{ intent: 'error' }
83+
);
84+
}
85+
}, [plansError, dispatchToast]);
86+
87+
return (
88+
<div style={{ flexShrink: 0, display: "flex", overflow: "hidden" }}>
89+
<PanelLeft
90+
panelWidth={280}
91+
panelResize={true}>
92+
<PanelLeftToolbar panelTitle="Tasks" panelIcon={null}>
93+
<Button
94+
icon={<Add20Regular />}
95+
onClick={onNewTaskButton}
96+
disabled={plansLoading}
97+
>
98+
New task
99+
</Button>
100+
</PanelLeftToolbar>
101+
{plansLoading && (!inProgressTasks.length && !completedTasks.length) ? (
102+
<div style={{ padding: '20px', textAlign: 'center' }}>
103+
<Spinner size="medium" label="Loading tasks..." />
104+
</div>
105+
) : (
106+
<TaskList
107+
inProgressTasks={inProgressTasks}
108+
completedTasks={completedTasks}
109+
onTaskSelect={handleTaskSelect}
110+
/>
111+
)}
112+
</PanelLeft>
113+
</div>
114+
);
115+
};
116+
117+
export default PlanPanelLeft;

src/frontend_react/src/models/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@ export * from './inputTask';
1212
export * from './agentMessage';
1313
export * from './taskDetails';
1414
export * from './taskList';
15+
export * from './planPanelLeft';
16+
export * from './homeInput';
1517

1618
// Add other model exports as needed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface PlanPanelLefProps {
2+
3+
onNewTaskButton: () => void;
4+
}

src/frontend_react/src/pages/HomePage.tsx

Lines changed: 7 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -26,48 +26,17 @@ import { apiService } from '../api/apiService';
2626
import { PlanWithSteps } from '../models';
2727
import HomeInput from '@/components/content/HomeInput';
2828
import { NewTaskService } from '../services/NewTaskService';
29+
import PlanPanelLeft from '@/components/content/PlanPanelLeft';
2930

3031
/**
3132
* HomePage component - displays task lists and provides navigation
3233
* Accessible via the route "/"
3334
*/
3435
const HomePage: React.FC = () => {
35-
const navigate = useNavigate();
36-
const { dispatchToast } = useToastController('toast'); // State for task lists
37-
const [inProgressTasks, setInProgressTasks] = useState<Task[]>([]);
38-
const [completedTasks, setCompletedTasks] = useState<Task[]>([]);
39-
40-
// State for API calls
41-
const [plans, setPlans] = useState<PlanWithSteps[] | null>(null);
42-
const [plansLoading, setPlansLoading] = useState<boolean>(false);
43-
const [plansError, setPlansError] = useState<Error | null>(null);
44-
4536
/**
46-
* Load plans data and update task lists
47-
*/
48-
const loadPlansData = useCallback(async (forceRefresh = false) => {
49-
try {
50-
setPlansLoading(true);
51-
setPlansError(null);
52-
53-
// Call the apiService directly
54-
const plansData = await apiService.getPlans(undefined, !forceRefresh);
55-
setPlans(plansData);
56-
} catch (error) {
57-
console.error('Failed to load plans:', error);
58-
setPlansError(error instanceof Error ? error : new Error('Failed to load plans'));
59-
} finally {
60-
setPlansLoading(false);
61-
}
62-
}, []);
63-
64-
// Load data on component mount
65-
useEffect(() => {
66-
loadPlansData();
67-
}, [loadPlansData]); /**
68-
* Handle new task creation from the "New task" button
69-
* Resets textarea to empty state on HomePage
70-
*/
37+
* Handle new task creation from the "New task" button
38+
* Resets textarea to empty state on HomePage
39+
*/
7140
const handleNewTaskButton = useCallback(() => {
7241
NewTaskService.handleNewTaskFromHome();
7342
}, []);
@@ -79,73 +48,14 @@ const HomePage: React.FC = () => {
7948
console.log('Creating new task:', taskName);
8049
}, []);
8150

82-
83-
const handleTaskSelect = useCallback((taskId: string) => {
84-
console.log('Selected task ID:', taskId);
85-
86-
// Find the plan by session_id to get the plan_id
87-
const selectedPlan = plans?.find((plan: PlanWithSteps) => plan.session_id === taskId);
88-
if (selectedPlan) {
89-
navigate(`/plan/${selectedPlan.id}`);
90-
}
91-
}, [plans, navigate]);// Transform plans data when it changes
92-
useEffect(() => {
93-
if (plans) {
94-
const { inProgress, completed } = TaskService.transformPlansToTasks(plans);
95-
setInProgressTasks(inProgress);
96-
setCompletedTasks(completed);
97-
}
98-
}, [plans]);
99-
100-
101-
// Handle API errors
102-
useEffect(() => {
103-
if (plansError) {
104-
dispatchToast(
105-
<Toast>
106-
<ToastTitle>
107-
<ErrorCircle20Regular />
108-
Failed to load tasks
109-
</ToastTitle>
110-
<ToastBody>
111-
{plansError.message}
112-
</ToastBody>
113-
</Toast>,
114-
{ intent: 'error' }
115-
);
116-
}
117-
}, [plansError, dispatchToast]);
118-
11951
return (
12052
<>
12153
<Toaster toasterId="toast" />
12254
<CoralShellColumn>
12355
<CoralShellRow>
124-
<div style={{ flexShrink: 0, display: "flex", overflow: "hidden" }}>
125-
<PanelLeft
126-
panelWidth={280}
127-
panelResize={true}> <PanelLeftToolbar panelTitle="Tasks" panelIcon={null}>
128-
<Button
129-
icon={<Add20Regular />}
130-
onClick={handleNewTaskButton}
131-
disabled={plansLoading}
132-
>
133-
New task
134-
</Button>
135-
</PanelLeftToolbar>
136-
{plansLoading && (!inProgressTasks.length && !completedTasks.length) ? (
137-
<div style={{ padding: '20px', textAlign: 'center' }}>
138-
<Spinner size="medium" label="Loading tasks..." />
139-
</div>
140-
) : (
141-
<TaskList
142-
inProgressTasks={inProgressTasks}
143-
completedTasks={completedTasks}
144-
onTaskSelect={handleTaskSelect}
145-
/>
146-
)}
147-
</PanelLeft>
148-
</div>
56+
<PlanPanelLeft
57+
onNewTaskButton={handleNewTaskButton}
58+
/>
14959
<Content>
15060
<HomeInput
15161
onInputSubmit={handleNewTask}

src/frontend_react/src/pages/PlanPage.tsx

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import React from 'react';
1+
import React, { useCallback, useEffect, useState } from 'react';
22
import { useParams, useNavigate } from 'react-router-dom';
33
import {
44
Button,
55
Text,
66
Card,
7-
CardHeader
7+
CardHeader,
8+
useToastController,
9+
Spinner
810
} from '@fluentui/react-components';
911
import {
1012
Add20Regular,
@@ -19,6 +21,9 @@ import PanelLeft from '../coral/components/Panels/PanelLeft';
1921
import PanelLeftToolbar from '../coral/components/Panels/PanelLeftToolbar';
2022
import TaskList from '../components/content/TaskList';
2123
import { NewTaskService } from '../services/NewTaskService';
24+
import { PlanWithSteps, Task } from '@/models';
25+
import { apiService } from '@/api';
26+
import PlanPanelLeft from '@/components/content/PlanPanelLeft';
2227

2328
/**
2429
* Page component for displaying a specific plan
@@ -28,18 +33,10 @@ const PlanPage: React.FC = () => {
2833
const { planId } = useParams<{ planId: string }>();
2934
const navigate = useNavigate();
3035

31-
// Temporary placeholder data - will be replaced with API calls
32-
const inProgressTasks: any[] = [];
33-
const completedTasks: any[] = [];
3436

35-
// Handle back navigation
36-
const handleBackClick = () => {
37-
navigate(-1);
38-
};
3937

40-
const handleTaskSelect = (taskId: string) => {
41-
console.log(`Selected task ID: ${taskId}`);
42-
}; const handleNewTask = () => {
38+
39+
const handleNewTaskButton = () => {
4340
// Use NewTaskService to handle navigation to homepage and reset textarea
4441
NewTaskService.handleNewTaskFromPlan(navigate);
4542
};
@@ -57,27 +54,13 @@ const PlanPage: React.FC = () => {
5754
return (
5855
<CoralShellColumn>
5956
<CoralShellRow>
60-
<div style={{ flexShrink: 0, display: "flex", overflow: "hidden" }}>
61-
<PanelLeft
62-
panelWidth={280}
63-
panelResize={true}> <PanelLeftToolbar panelTitle="" panelIcon={null}>
64-
<Button
65-
icon={<Add20Regular />}
66-
onClick={handleNewTask}
67-
>
68-
New task
69-
</Button>
70-
</PanelLeftToolbar>
71-
<TaskList
72-
inProgressTasks={inProgressTasks}
73-
completedTasks={completedTasks}
74-
onTaskSelect={handleTaskSelect}
75-
/>
76-
</PanelLeft>
77-
<Content>
57+
<PlanPanelLeft
58+
onNewTaskButton={handleNewTaskButton}
59+
/>
60+
<Content>
61+
62+
</Content>
7863

79-
</Content>
80-
</div>
8164
</CoralShellRow>
8265
</CoralShellColumn>
8366
);

0 commit comments

Comments
 (0)