diff --git a/apps/desktop/src/renderer/components/tasks/task-card-skeleton.tsx b/apps/desktop/src/renderer/components/tasks/task-card-skeleton.tsx new file mode 100644 index 00000000..4d278e8e --- /dev/null +++ b/apps/desktop/src/renderer/components/tasks/task-card-skeleton.tsx @@ -0,0 +1,24 @@ +import { Skeleton } from '@/renderer/components/ui/skeleton'; + +export const TaskCardSkeleton = () => { + return ( +
+
+ +
+
+ + +
+
+
+ +
+
+
+ + +
+
+ ); +}; diff --git a/apps/desktop/src/renderer/components/tasks/task-container.tsx b/apps/desktop/src/renderer/components/tasks/task-container.tsx index 76f11b69..b99b7b6f 100644 --- a/apps/desktop/src/renderer/components/tasks/task-container.tsx +++ b/apps/desktop/src/renderer/components/tasks/task-container.tsx @@ -1,18 +1,9 @@ -import { - formatDuration, - formatTaskStatus, - formatTaskType, - timeAgo, -} from '@colanode/core'; -import { Clock, Calendar } from 'lucide-react'; - import { Container, ContainerBody } from '@/renderer/components/ui/container'; import { useWorkspace } from '@/renderer/contexts/workspace'; import { useQuery } from '@/renderer/hooks/use-query'; -import { TaskLogs } from '@/renderer/components/tasks/task-logs'; -import { TaskArtifacts } from '@/renderer/components/tasks/task-artifacts'; import { TaskNotFound } from '@/renderer/components/tasks/task-not-found'; -import { TaskStatusBadge } from '@/renderer/components/tasks/task-status-badge'; +import { TaskDetails } from '@/renderer/components/tasks/task-details'; +import { TaskSkeleton } from '@/renderer/components/tasks/task-skeleton'; interface TaskContainerProps { taskId: string; @@ -28,89 +19,20 @@ export const TaskContainer = ({ taskId }: TaskContainerProps) => { taskId: taskId, }); - if (isPending) { - return
Loading...
; - } - - if (!data) { - return ; - } - - const duration = formatDuration(data.task.createdAt, data.task.completedAt); - const createdAtAgo = timeAgo(data.task.createdAt); - return ( -
-
-
-
- -
-

{data.task.name}

-

- {data.task.description} -

-
-
-
-
-
- Type - - {formatTaskType(data.task.attributes.type)} - -
-
- - Status - - - {formatTaskStatus(data.task.status)} - -
-
- - Started - -
- - {createdAtAgo} -
-
-
- - Duration - -
- - {duration} -
-
-
- - Artifacts - - - {data.artifacts.length} - -
-
-
-
-
-

Logs

- -
-
-
-
-

Artifacts

- -
-
-
+ {isPending ? ( + + ) : data ? ( + + ) : ( + + )}
); diff --git a/apps/desktop/src/renderer/components/tasks/task-details.tsx b/apps/desktop/src/renderer/components/tasks/task-details.tsx new file mode 100644 index 00000000..f0b78a92 --- /dev/null +++ b/apps/desktop/src/renderer/components/tasks/task-details.tsx @@ -0,0 +1,87 @@ +import { + formatDuration, + formatTaskStatus, + formatTaskType, + TaskArtifactOutput, + TaskLogOutput, + TaskOutput, + timeAgo, +} from '@colanode/core'; +import { Clock, Calendar } from 'lucide-react'; + +import { TaskLogs } from '@/renderer/components/tasks/task-logs'; +import { TaskArtifacts } from '@/renderer/components/tasks/task-artifacts'; +import { TaskStatusBadge } from '@/renderer/components/tasks/task-status-badge'; + +interface TaskDetailsProps { + task: TaskOutput; + logs: TaskLogOutput[]; + artifacts: TaskArtifactOutput[]; +} + +export const TaskDetails = ({ task, logs, artifacts }: TaskDetailsProps) => { + const duration = formatDuration(task.createdAt, task.completedAt); + const createdAtAgo = timeAgo(task.createdAt); + + return ( +
+
+
+
+ +
+

{task.name}

+

+ {task.description} +

+
+
+
+
+
+ Type + + {formatTaskType(task.attributes.type)} + +
+
+ Status + + {formatTaskStatus(task.status)} + +
+
+ Started +
+ + {createdAtAgo} +
+
+
+ Duration +
+ + {duration} +
+
+
+ Artifacts + {artifacts.length} +
+
+
+
+
+

Logs

+ +
+
+
+
+

Artifacts

+ +
+
+
+ ); +}; diff --git a/apps/desktop/src/renderer/components/tasks/task-list.tsx b/apps/desktop/src/renderer/components/tasks/task-list.tsx index 78a6236a..106245a0 100644 --- a/apps/desktop/src/renderer/components/tasks/task-list.tsx +++ b/apps/desktop/src/renderer/components/tasks/task-list.tsx @@ -4,8 +4,8 @@ import { useQuery } from '@/renderer/hooks/use-query'; import { useWorkspace } from '@/renderer/contexts/workspace'; import { Button } from '@/renderer/components/ui/button'; import { TaskCreateDialog } from '@/renderer/components/tasks/task-create-dialog'; -import { Spinner } from '@/renderer/components/ui/spinner'; import { TaskCard } from '@/renderer/components/tasks/task-card'; +import { TaskCardSkeleton } from '@/renderer/components/tasks/task-card-skeleton'; export const TaskList = () => { const workspace = useWorkspace(); @@ -30,10 +30,14 @@ export const TaskList = () => {
- {isPending && } - {tasks.map((t) => ( - - ))} + {isPending && ( + <> + + + + + )} + {!isPending && tasks.map((t) => )}
{ + return ( +
+
+
+
+ +
+ + +
+
+
+
+ {Array.from({ length: 5 }).map((_, index) => ( +
+ + +
+ ))} +
+
+
+
+ + +
+
+
+
+ + +
+
+
+ ); +};