Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/dashboard update #138

Merged
merged 8 commits into from
Aug 12, 2024
23 changes: 23 additions & 0 deletions src/frontend/src/api/dashboard.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable import/prefer-default-export */
import { UseQueryOptions, useQuery } from '@tanstack/react-query';
import { getRequestedTasks } from '@Services/project';
import { getTaskList, getTaskStatistics } from '@Services/dashboard';

export const useGetRequestedTasksListQuery = (
queryOptions?: Partial<UseQueryOptions>,
Expand All @@ -12,3 +13,25 @@ export const useGetRequestedTasksListQuery = (
...queryOptions,
});
};

export const useGetDashboardTaskStaticsQuery = (
queryOptions?: Partial<UseQueryOptions>,
) => {
return useQuery({
queryKey: ['task-statistics'],
queryFn: getTaskStatistics,
select: (res: any) => res.data,
...queryOptions,
});
};

export const useGetTaskListQuery = (
queryOptions?: Partial<UseQueryOptions>,
) => {
return useQuery({
queryKey: ['task-list'],
queryFn: getTaskList,
select: (res: any) => res.data,
...queryOptions,
});
};
18 changes: 15 additions & 3 deletions src/frontend/src/components/Dashboard/DashboardCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,25 @@ import graphImage from '@Assets/images/graph.svg';

interface IDashboardCardProps {
title: string;
value: number;
count: number;
active: boolean;
}

export const DashboardCardSkeleton = () => {
return (
<div className="naxatw-flex naxatw-h-[130px] naxatw-w-full naxatw-animate-pulse naxatw-items-center naxatw-gap-3 naxatw-rounded-xl naxatw-bg-gray-200 naxatw-px-2">
<div className="naxatw-h-10 naxatw-w-10 naxatw-rounded-full naxatw-bg-gray-300" />
<div className="naxatw-flex naxatw-w-[140px] naxatw-flex-col naxatw-gap-2">
<div className="naxatw-h-9 naxatw-w-[50px] naxatw-bg-gray-300" />
<div className="naxatw-h-5 naxatw-w-full naxatw-bg-gray-300" />
</div>
</div>
);
};

export default function DashboardCard({
title,
value,
count,
active,
}: IDashboardCardProps) {
return (
Expand All @@ -19,7 +31,7 @@ export default function DashboardCard({
>
<Image src={graphImage} />
<FlexColumn>
<h2>{value}</h2>
<h2>{count}</h2>
<p>{title}</p>
</FlexColumn>
</FlexRow>
Expand Down
60 changes: 60 additions & 0 deletions src/frontend/src/components/Dashboard/TaskLogs/TaskLogsTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { format } from 'date-fns';
import { useNavigate } from 'react-router-dom';

interface ITaskLogsTableProps {
data: any[];
}

const TaskLogsTable = ({ data: taskList }: ITaskLogsTableProps) => {
const navigate = useNavigate();
return (
<div className="flex">
<table className="naxatw-w-full naxatw-overflow-hidden naxatw-rounded-lg">
<thead>
<tr className="naxatw-bg-red naxatw-text-left naxatw-font-normal naxatw-text-white">
<td className="naxatw-w-80 naxatw-border-r-2 naxatw-px-2 naxatw-py-1">
ID
</td>
<td className="naxatw-border-r-2 naxatw-px-2 naxatw-py-1">
Total task area
</td>
<td className="naxatw-border-r-2 naxatw-px-2 naxatw-py-1">
Est.flight time
</td>
<td className="naxatw-border-r-2 naxatw-px-2 naxatw-py-1">
Created Date
</td>
<td className="naxatw-border-r-2 naxatw-px-2 naxatw-py-1">
Status
</td>
<td className="naxatw-w-12" />
</tr>
</thead>
<tbody>
{taskList?.map(task => (
<tr key={task.task_id}>
<td className="naxatw-px-2 naxatw-py-1">{task.task_id}</td>
<td className="naxatw-px-2 naxatw-py-1">{task.task_area}</td>
<td className="naxatw-px-2 naxatw-py-1">-</td>
<td className="naxatw-px-2 naxatw-py-1">
{format(new Date(task.created_at), 'yyyy-MM-dd')}
</td>
<td className="naxatw-px-2">{task.state}</td>
<td className="naxatw-flex naxatw-items-center naxatw-px-2">
<div
className="naxatw-flex naxatw-h-8 naxatw-w-8 naxatw-cursor-pointer naxatw-items-center naxatw-justify-center naxatw-rounded-lg hover:naxatw-bg-gray-200"
role="presentation"
onClick={() => navigate(`/tasks/${task.task_id}`)}
>
<i className="material-icons-outlined">zoom_in</i>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
};

export default TaskLogsTable;
25 changes: 24 additions & 1 deletion src/frontend/src/components/Dashboard/TaskLogs/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
import { useMemo } from 'react';
import { useGetTaskListQuery } from '@Api/dashboard';
import TaskLogsTable from './TaskLogsTable';

interface TaskLogsProps {
title: string;
}

const getStatusByTitle = (title: string): string => {
if (title === 'Ongoing Tasks') return 'ongoing';
if (title === 'Request Logs') return 'request logs';
if (title === 'Unflyable Tasks') return 'unflyable task';
if (title === 'Completed Tasks') return 'completed';

return '';
};

const TaskLogs = ({ title }: TaskLogsProps) => {
const { data: taskList }: any = useGetTaskListQuery();

const filteredData = useMemo(
() =>
taskList?.filter(
(task: Record<string, any>) => task?.state === getStatusByTitle(title),
),
[title, taskList],
);

return (
<div className="naxatw-mt-8 naxatw-flex-col">
<h4 className="naxatw-py-2 naxatw-text-base naxatw-font-bold naxatw-text-gray-800">
{title}
</h4>
{/* <FlexColumn className="naxatw-max-h-[24.4rem] naxatw-gap-2 naxatw-overflow-y-auto"></FlexColumn> */}
<TaskLogsTable data={filteredData} />
</div>
);
};
Expand Down
14 changes: 7 additions & 7 deletions src/frontend/src/constants/dashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ export const dashboardCardsForProjectCreator = [
},
{
id: 2,
title: 'Un-flyable Tasks',
value: 'un-flyable_tasks',
title: 'Ongoing Tasks',
value: 'ongoing_tasks',
},
{
id: 3,
title: 'Ongoing Tasks',
value: 'ongoing_task',
title: 'Unflyable Tasks',
value: 'unflyable_tasks',
},
{
id: 4,
title: 'Completed Tasks',
value: 'complete_tasks',
value: 'completed_tasks',
},
];

Expand All @@ -29,8 +29,8 @@ export const dashboardCardsForDroneOperator = [
},
{
id: 2,
title: 'Tasks Mapped',
value: 'tasks_mapped',
title: 'Unflyable Tasks',
value: 'unflyable_tasks',
},
{
id: 3,
Expand Down
6 changes: 6 additions & 0 deletions src/frontend/src/services/dashboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { authenticated, api } from '.';

export const getTaskStatistics = () =>
authenticated(api).get('/tasks/statistics/');

export const getTaskList = () => authenticated(api).get('/tasks/');
65 changes: 39 additions & 26 deletions src/frontend/src/views/Dashboard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useGetRequestedTasksListQuery } from '@Api/dashboard';
import { useGetDashboardTaskStaticsQuery } from '@Api/dashboard';
import { FlexRow } from '@Components/common/Layouts';
import { DashboardSidebar, DashboardCard } from '@Components/Dashboard';
import { DashboardCardSkeleton } from '@Components/Dashboard/DashboardCard';
import RequestLogs from '@Components/Dashboard/RequestLogs';
import TaskLogs from '@Components/Dashboard/TaskLogs';
import {
Expand Down Expand Up @@ -32,9 +33,16 @@ export default function Dashboard() {
? dashboardCardsForProjectCreator
: dashboardCardsForDroneOperator;

const { data: requestedTasks } = useGetRequestedTasksListQuery({
select: (data: any) => data.data,
});
const { data: taskStatistics, isLoading }: Record<string, any> =
useGetDashboardTaskStaticsQuery({
select: (data: any) => {
const taskCounts: Record<string, any> = data?.data;
return dashboardCards?.map(card => ({
...card,
count: taskCounts?.[`${card?.value}`],
}));
},
});

return (
<section className="naxatw-h-screen-nav naxatw-bg-grey-50 naxatw-px-16 naxatw-pt-8">
Expand All @@ -45,29 +53,34 @@ export default function Dashboard() {
<DashboardSidebar />
<div className="naxatw-col-span-4">
<div className="naxatw-grid naxatw-grid-cols-4 naxatw-gap-5">
{dashboardCards.map(card => (
<div
key={card.id}
tabIndex={0}
role="button"
onKeyUp={() =>
setActiveTab({ value: card.value, title: card.title })
}
onClick={() =>
setActiveTab({ value: card.value, title: card.title })
}
className="naxatw-cursor-pointer"
>
<DashboardCard
title={card.title}
value={
// @ts-ignore
card?.value === 'request_logs' ? requestedTasks?.length : 0
{isLoading ? (
<>
{Array.from({ length: 4 }, (_, index) => (
<DashboardCardSkeleton key={index} />
))}
</>
) : (
taskStatistics?.map((task: any) => (
<div
key={task.id}
tabIndex={0}
role="button"
onKeyUp={() =>
setActiveTab({ value: task.value, title: task.title })
}
active={card.value === activeTab.value}
/>
</div>
))}
onClick={() =>
setActiveTab({ value: task.value, title: task.title })
}
className="naxatw-cursor-pointer"
>
<DashboardCard
title={task.title}
count={task?.count}
active={task.value === activeTab.value}
/>
</div>
))
)}
</div>
{getContent(activeTab.value, activeTab.title)}
</div>
Expand Down