feat: Update task and project ID formats, add populateSeedData function, and enhance user ID handling
This commit is contained in:
@@ -23,7 +23,14 @@ const ModalNewTask = ({ isOpen, onClose, id = null }: Props) => {
|
|||||||
const [projectId, setProjectId] = useState("");
|
const [projectId, setProjectId] = useState("");
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (!title || !authorUserId || !(id !== null || projectId)) return;
|
console.log(title, authorUserId, id, projectId);
|
||||||
|
|
||||||
|
console.log("Creating task 1..");
|
||||||
|
if (
|
||||||
|
!(title && authorUserId && assignedUserId && (id !== null || projectId))
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
console.log("Creating task 2...");
|
||||||
|
|
||||||
const formattedStartDate = formatISO(new Date(startDate), {
|
const formattedStartDate = formatISO(new Date(startDate), {
|
||||||
representation: "complete",
|
representation: "complete",
|
||||||
@@ -40,14 +47,17 @@ const ModalNewTask = ({ isOpen, onClose, id = null }: Props) => {
|
|||||||
tags,
|
tags,
|
||||||
startDate: formattedStartDate,
|
startDate: formattedStartDate,
|
||||||
dueDate: formattedDueDate,
|
dueDate: formattedDueDate,
|
||||||
authorUserId: parseInt(authorUserId),
|
authorUserId: authorUserId,
|
||||||
assignedUserId: parseInt(assignedUserId),
|
assignedUserId: assignedUserId,
|
||||||
projectId: id !== null ? Number(id) : Number(projectId),
|
projectId: id !== null ? id : projectId,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const isFormValid = () => {
|
const isFormValid = () => {
|
||||||
return title && authorUserId && !(id !== null || projectId);
|
console.log(title, authorUserId, id, projectId);
|
||||||
|
return (
|
||||||
|
title && authorUserId && assignedUserId && (id !== null || projectId)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectStyles =
|
const selectStyles =
|
||||||
@@ -87,7 +97,7 @@ const ModalNewTask = ({ isOpen, onClose, id = null }: Props) => {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<option value="">Select Status</option>
|
<option value="">Select Status</option>
|
||||||
<option value={Status.ToDo}>Backlog</option>
|
<option value={Status.ToDo}>To Do</option>
|
||||||
<option value={Status.InProgress}>In Progress</option>
|
<option value={Status.InProgress}>In Progress</option>
|
||||||
<option value={Status.TestReview}>Test/Review</option>
|
<option value={Status.TestReview}>Test/Review</option>
|
||||||
<option value={Status.Done}>Done</option>
|
<option value={Status.Done}>Done</option>
|
||||||
|
|||||||
@@ -93,7 +93,6 @@ const Sidebar = () => {
|
|||||||
<button
|
<button
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setShowProjects((prev) => {
|
setShowProjects((prev) => {
|
||||||
console.log(prev);
|
|
||||||
return !prev;
|
return !prev;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -109,10 +108,10 @@ const Sidebar = () => {
|
|||||||
{showProjects &&
|
{showProjects &&
|
||||||
projects?.map((project) => (
|
projects?.map((project) => (
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
key={project.id}
|
key={project.projectId}
|
||||||
icon={Briefcase}
|
icon={Briefcase}
|
||||||
label={project.name}
|
label={project.name}
|
||||||
href={`/projects/${project.id}`}
|
href={`/projects/${project.projectId}`}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ const TaskCard = ({ task }: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<p>
|
<p>
|
||||||
<strong>ID:</strong> {task.id}
|
<strong>ID:</strong> {task.taskId}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<strong>Title:</strong> {task.title}
|
<strong>Title:</strong> {task.title}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
Priority,
|
Priority,
|
||||||
Project,
|
Project,
|
||||||
Task,
|
Task,
|
||||||
|
useGetAuthUserQuery,
|
||||||
useGetProjectsQuery,
|
useGetProjectsQuery,
|
||||||
useGetTasksByUserQuery,
|
useGetTasksByUserQuery,
|
||||||
} from "@/state/api";
|
} from "@/state/api";
|
||||||
@@ -77,12 +78,13 @@ const taskColumns: GridColDef[] = [
|
|||||||
const statusColors = ["#0088FE", "#00C49F", "#FFBB28", "#FF8042"];
|
const statusColors = ["#0088FE", "#00C49F", "#FFBB28", "#FF8042"];
|
||||||
|
|
||||||
const HomePage = () => {
|
const HomePage = () => {
|
||||||
const userId = 1;
|
const { data: currentUser } = useGetAuthUserQuery({});
|
||||||
|
const userId = currentUser?.userDetails?.userId ?? null;
|
||||||
const {
|
const {
|
||||||
data: tasks,
|
data: tasks,
|
||||||
isLoading: tasksLoading,
|
isLoading: tasksLoading,
|
||||||
isError: tasksError,
|
isError: tasksError,
|
||||||
} = useGetTasksByUserQuery(userId || 0, {
|
} = useGetTasksByUserQuery(userId || "", {
|
||||||
skip: userId === null,
|
skip: userId === null,
|
||||||
});
|
});
|
||||||
const { data: projects, isLoading: isProjectsLoading } =
|
const { data: projects, isLoading: isProjectsLoading } =
|
||||||
@@ -191,6 +193,7 @@ const HomePage = () => {
|
|||||||
columns={taskColumns}
|
columns={taskColumns}
|
||||||
checkboxSelection
|
checkboxSelection
|
||||||
loading={tasksLoading}
|
loading={tasksLoading}
|
||||||
|
getRowId={(row) => row.taskId}
|
||||||
getRowClassName={() => "data-grid-row"}
|
getRowClassName={() => "data-grid-row"}
|
||||||
getCellClassName={() => "data-grid-cell"}
|
getCellClassName={() => "data-grid-cell"}
|
||||||
className="border border-gray-200 bg-white shadow dark:border-stroke-dark dark:bg-dark-secondary dark:text-gray-200"
|
className="border border-gray-200 bg-white shadow dark:border-stroke-dark dark:bg-dark-secondary dark:text-gray-200"
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ const ReusablePriorityPage = ({ priority }: Props) => {
|
|||||||
data: tasks,
|
data: tasks,
|
||||||
isLoading,
|
isLoading,
|
||||||
isError: isTasksError,
|
isError: isTasksError,
|
||||||
} = useGetTasksByUserQuery(userId || 0, {
|
} = useGetTasksByUserQuery(userId || "", {
|
||||||
skip: userId === null,
|
skip: userId === null,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ const ReusablePriorityPage = ({ priority }: Props) => {
|
|||||||
) : view === "list" ? (
|
) : view === "list" ? (
|
||||||
<div className="grid grid-cols-1 gap-4">
|
<div className="grid grid-cols-1 gap-4">
|
||||||
{filteredTasks?.map((task: Task) => (
|
{filteredTasks?.map((task: Task) => (
|
||||||
<TaskCard key={task.id} task={task} />
|
<TaskCard key={task.taskId} task={task} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
@@ -146,7 +146,7 @@ const ReusablePriorityPage = ({ priority }: Props) => {
|
|||||||
rows={filteredTasks}
|
rows={filteredTasks}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
checkboxSelection
|
checkboxSelection
|
||||||
getRowId={(row) => row.id}
|
getRowId={(row) => row.taskId}
|
||||||
className="border border-gray-200 bg-white shadow dark:border-stroke-dark dark:bg-dark-secondary dark:text-gray-200"
|
className="border border-gray-200 bg-white shadow dark:border-stroke-dark dark:bg-dark-secondary dark:text-gray-200"
|
||||||
sx={dataGridSxStyles(isDarkMode)}
|
sx={dataGridSxStyles(isDarkMode)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { useGetTasksQuery, useUpdateTaskStatusMutation } from "@/state/api";
|
import {
|
||||||
import React from "react";
|
Status,
|
||||||
|
useGetTasksQuery,
|
||||||
|
useUpdateTaskStatusMutation,
|
||||||
|
} from "@/state/api";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
import { DndProvider, useDrag, useDrop } from "react-dnd";
|
import { DndProvider, useDrag, useDrop } from "react-dnd";
|
||||||
import { HTML5Backend } from "react-dnd-html5-backend";
|
import { HTML5Backend } from "react-dnd-html5-backend";
|
||||||
import { Task as TaskType } from "@/state/api";
|
import { Task as TaskType } from "@/state/api";
|
||||||
@@ -9,22 +13,40 @@ import { format } from "date-fns";
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
|
||||||
type BoardProps = {
|
type BoardProps = {
|
||||||
id: string;
|
projectId: string;
|
||||||
setIsModalNewTaskOpen: (isOpen: boolean) => void;
|
setIsModalNewTaskOpen: (isOpen: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const taskStatus = ["To Do", "In Progress", "Test/Review", "Done"];
|
const taskStatus = ["To Do", "In Progress", "Test/Review", "Done"];
|
||||||
|
|
||||||
const BoardView = ({ id, setIsModalNewTaskOpen }: BoardProps) => {
|
const BoardView = ({ projectId, setIsModalNewTaskOpen }: BoardProps) => {
|
||||||
const {
|
const {
|
||||||
data: tasks,
|
data: fetchedTasks,
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
} = useGetTasksQuery({ projectId: Number(id) });
|
} = useGetTasksQuery({ projectId });
|
||||||
const [updateTaskStatus] = useUpdateTaskStatusMutation();
|
const [updateTaskStatus] = useUpdateTaskStatusMutation();
|
||||||
|
const [tasks, setTasks] = useState<TaskType[]>([]);
|
||||||
|
|
||||||
const moveTask = (taskId: number, toStatus: string) => {
|
useEffect(() => {
|
||||||
updateTaskStatus({ taskId, status: toStatus });
|
if (fetchedTasks) {
|
||||||
|
setTasks(fetchedTasks);
|
||||||
|
}
|
||||||
|
}, [fetchedTasks]);
|
||||||
|
|
||||||
|
const moveTask = async (taskId: string, toStatus: string) => {
|
||||||
|
setTasks((prevTasks) =>
|
||||||
|
prevTasks.map((task) =>
|
||||||
|
task.taskId === taskId ? { ...task, status: toStatus as Status } : task,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await updateTaskStatus({ taskId, status: toStatus });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to update task status:", error);
|
||||||
|
setTasks(fetchedTasks || []);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isLoading) return <div>Loading...</div>;
|
if (isLoading) return <div>Loading...</div>;
|
||||||
@@ -50,7 +72,7 @@ const BoardView = ({ id, setIsModalNewTaskOpen }: BoardProps) => {
|
|||||||
type TaskColumnProps = {
|
type TaskColumnProps = {
|
||||||
status: string;
|
status: string;
|
||||||
tasks: TaskType[];
|
tasks: TaskType[];
|
||||||
moveTask: (taskId: number, toStatus: string) => void;
|
moveTask: (taskId: string, toStatus: string) => void;
|
||||||
setIsModalNewTaskOpen: (isOpen: boolean) => void;
|
setIsModalNewTaskOpen: (isOpen: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -62,7 +84,7 @@ const TaskColumn = ({
|
|||||||
}: TaskColumnProps) => {
|
}: TaskColumnProps) => {
|
||||||
const [{ isOver }, drop] = useDrop(() => ({
|
const [{ isOver }, drop] = useDrop(() => ({
|
||||||
accept: "task",
|
accept: "task",
|
||||||
drop: (item: { id: number }) => moveTask(item.id, status),
|
drop: (item: { id: string }) => moveTask(item.id, status),
|
||||||
collect: (monitor: any) => ({
|
collect: (monitor: any) => ({
|
||||||
isOver: !!monitor.isOver(),
|
isOver: !!monitor.isOver(),
|
||||||
}),
|
}),
|
||||||
@@ -116,7 +138,7 @@ const TaskColumn = ({
|
|||||||
{tasks
|
{tasks
|
||||||
.filter((task) => task.status === status)
|
.filter((task) => task.status === status)
|
||||||
.map((task) => (
|
.map((task) => (
|
||||||
<Task key={task.id} task={task} />
|
<Task key={task.taskId} task={task} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -129,7 +151,7 @@ type TaskProps = {
|
|||||||
const Task = ({ task }: TaskProps) => {
|
const Task = ({ task }: TaskProps) => {
|
||||||
const [{ isDragging }, drag] = useDrag(() => ({
|
const [{ isDragging }, drag] = useDrag(() => ({
|
||||||
type: "task",
|
type: "task",
|
||||||
item: { id: task.id },
|
item: { id: task.taskId },
|
||||||
collect: (monitor: any) => ({
|
collect: (monitor: any) => ({
|
||||||
isDragging: !!monitor.isDragging(),
|
isDragging: !!monitor.isDragging(),
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -4,16 +4,12 @@ import { Task, useGetTasksQuery } from "@/state/api";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
id: string;
|
projectId: string;
|
||||||
setIsModalNewTaskOpen: (isOpen: boolean) => void;
|
setIsModalNewTaskOpen: (isOpen: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ListView = ({ id, setIsModalNewTaskOpen }: Props) => {
|
const ListView = ({ projectId, setIsModalNewTaskOpen }: Props) => {
|
||||||
const {
|
const { data: tasks, error, isLoading } = useGetTasksQuery({ projectId });
|
||||||
data: tasks,
|
|
||||||
error,
|
|
||||||
isLoading,
|
|
||||||
} = useGetTasksQuery({ projectId: Number(id) });
|
|
||||||
|
|
||||||
if (isLoading) return <div>Loading...</div>;
|
if (isLoading) return <div>Loading...</div>;
|
||||||
if (error) return <div>An error occurred while fetching tasks</div>;
|
if (error) return <div>An error occurred while fetching tasks</div>;
|
||||||
@@ -35,7 +31,7 @@ const ListView = ({ id, setIsModalNewTaskOpen }: Props) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3 lg:gap-6">
|
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3 lg:gap-6">
|
||||||
{tasks?.map((task: Task) => <TaskCard key={task.id} task={task} />)}
|
{tasks?.map((task: Task) => <TaskCard key={task.taskId} task={task} />)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { DataGrid, GridColDef } from "@mui/x-data-grid";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
id: string;
|
projectId: string;
|
||||||
setIsModalNewTaskOpen: (isOpen: boolean) => void;
|
setIsModalNewTaskOpen: (isOpen: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ const columns: GridColDef[] = [
|
|||||||
renderCell: (params) => (
|
renderCell: (params) => (
|
||||||
<span
|
<span
|
||||||
className={`inline-flex rounded-full px-2 text-xs font-semibold leading-5 ${
|
className={`inline-flex rounded-full px-2 text-xs font-semibold leading-5 ${
|
||||||
params.value === "In Progress"
|
params.value === "Work In Progress"
|
||||||
? "bg-green-200 text-green-600"
|
? "bg-green-200 text-green-600"
|
||||||
: params.value === "Test/Review"
|
: params.value === "Test/Review"
|
||||||
? "bg-green-200 text-green-600"
|
? "bg-green-200 text-green-600"
|
||||||
@@ -93,13 +93,9 @@ const columns: GridColDef[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const TableView = ({ id, setIsModalNewTaskOpen }: Props) => {
|
const TableView = ({ projectId, setIsModalNewTaskOpen }: Props) => {
|
||||||
const isDarkMode = useAppSelector((state) => state.global.isDarkMode);
|
const isDarkMode = useAppSelector((state) => state.global.isDarkMode);
|
||||||
const {
|
const { data: tasks, error, isLoading } = useGetTasksQuery({ projectId });
|
||||||
data: tasks,
|
|
||||||
error,
|
|
||||||
isLoading,
|
|
||||||
} = useGetTasksQuery({ projectId: Number(id) });
|
|
||||||
|
|
||||||
if (isLoading) return <div>Loading...</div>;
|
if (isLoading) return <div>Loading...</div>;
|
||||||
if (error || !tasks) return <div>An error occurred while fetching tasks</div>;
|
if (error || !tasks) return <div>An error occurred while fetching tasks</div>;
|
||||||
@@ -123,6 +119,7 @@ const TableView = ({ id, setIsModalNewTaskOpen }: Props) => {
|
|||||||
<DataGrid
|
<DataGrid
|
||||||
rows={tasks || []}
|
rows={tasks || []}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
|
getRowId={(row) => row.taskId}
|
||||||
className="border border-gray-200 bg-white shadow dark:border-stroke-dark dark:bg-dark-secondary dark:text-gray-200"
|
className="border border-gray-200 bg-white shadow dark:border-stroke-dark dark:bg-dark-secondary dark:text-gray-200"
|
||||||
sx={dataGridSxStyles(isDarkMode)}
|
sx={dataGridSxStyles(isDarkMode)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -5,19 +5,15 @@ import "gantt-task-react/dist/index.css";
|
|||||||
import React, { useMemo, useState } from "react";
|
import React, { useMemo, useState } from "react";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
id: string;
|
projectId: string;
|
||||||
setIsModalNewTaskOpen: (isOpen: boolean) => void;
|
setIsModalNewTaskOpen: (isOpen: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
type TaskTypeItems = "task" | "milestone" | "project";
|
type TaskTypeItems = "task" | "milestone" | "project";
|
||||||
|
|
||||||
const Timeline = ({ id, setIsModalNewTaskOpen }: Props) => {
|
const Timeline = ({ projectId, setIsModalNewTaskOpen }: Props) => {
|
||||||
const isDarkMode = useAppSelector((state) => state.global.isDarkMode);
|
const isDarkMode = useAppSelector((state) => state.global.isDarkMode);
|
||||||
const {
|
const { data: tasks, error, isLoading } = useGetTasksQuery({ projectId });
|
||||||
data: tasks,
|
|
||||||
error,
|
|
||||||
isLoading,
|
|
||||||
} = useGetTasksQuery({ projectId: Number(id) });
|
|
||||||
|
|
||||||
const [displayOptions, setDisplayOptions] = useState<DisplayOption>({
|
const [displayOptions, setDisplayOptions] = useState<DisplayOption>({
|
||||||
viewMode: ViewMode.Month,
|
viewMode: ViewMode.Month,
|
||||||
@@ -30,7 +26,7 @@ const Timeline = ({ id, setIsModalNewTaskOpen }: Props) => {
|
|||||||
start: new Date(task.startDate as string),
|
start: new Date(task.startDate as string),
|
||||||
end: new Date(task.dueDate as string),
|
end: new Date(task.dueDate as string),
|
||||||
name: task.title,
|
name: task.title,
|
||||||
id: `Task-${task.id}`,
|
id: `Task-${task.taskId}`,
|
||||||
type: "task" as TaskTypeItems,
|
type: "task" as TaskTypeItems,
|
||||||
progress: task.points ? (task.points / 10) * 100 : 0,
|
progress: task.points ? (task.points / 10) * 100 : 0,
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
|
|||||||
@@ -26,16 +26,19 @@ const Project = ({ params }: Props) => {
|
|||||||
/>
|
/>
|
||||||
<ProjectHeader activeTab={activeTab} setActiveTab={setActiveTab} />
|
<ProjectHeader activeTab={activeTab} setActiveTab={setActiveTab} />
|
||||||
{activeTab === "Board" && (
|
{activeTab === "Board" && (
|
||||||
<Board id={id} setIsModalNewTaskOpen={setIsModalNewTaskOpen} />
|
<Board projectId={id} setIsModalNewTaskOpen={setIsModalNewTaskOpen} />
|
||||||
)}
|
)}
|
||||||
{activeTab === "List" && (
|
{activeTab === "List" && (
|
||||||
<List id={id} setIsModalNewTaskOpen={setIsModalNewTaskOpen} />
|
<List projectId={id} setIsModalNewTaskOpen={setIsModalNewTaskOpen} />
|
||||||
)}
|
)}
|
||||||
{activeTab === "Timeline" && (
|
{activeTab === "Timeline" && (
|
||||||
<Timeline id={id} setIsModalNewTaskOpen={setIsModalNewTaskOpen} />
|
<Timeline
|
||||||
|
projectId={id}
|
||||||
|
setIsModalNewTaskOpen={setIsModalNewTaskOpen}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
{activeTab === "Table" && (
|
{activeTab === "Table" && (
|
||||||
<Table id={id} setIsModalNewTaskOpen={setIsModalNewTaskOpen} />
|
<Table projectId={id} setIsModalNewTaskOpen={setIsModalNewTaskOpen} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -49,14 +49,14 @@ const Search = () => {
|
|||||||
<h2>Tasks</h2>
|
<h2>Tasks</h2>
|
||||||
)}
|
)}
|
||||||
{searchResults.tasks?.map((task) => (
|
{searchResults.tasks?.map((task) => (
|
||||||
<TaskCard key={task.id} task={task} />
|
<TaskCard key={task.taskId} task={task} />
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{searchResults.projects && searchResults.projects?.length > 0 && (
|
{searchResults.projects && searchResults.projects?.length > 0 && (
|
||||||
<h2>Projects</h2>
|
<h2>Projects</h2>
|
||||||
)}
|
)}
|
||||||
{searchResults.projects?.map((project) => (
|
{searchResults.projects?.map((project) => (
|
||||||
<ProjectCard key={project.id} project={project} />
|
<ProjectCard key={project.projectId} project={project} />
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{searchResults.users && searchResults.users?.length > 0 && (
|
{searchResults.users && searchResults.users?.length > 0 && (
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ const CustomToolbar = () => (
|
|||||||
);
|
);
|
||||||
|
|
||||||
const columns: GridColDef[] = [
|
const columns: GridColDef[] = [
|
||||||
{ field: "id", headerName: "Team ID", width: 100 },
|
{ field: "teamId", headerName: "Team ID", width: 100 },
|
||||||
{ field: "teamName", headerName: "Team Name", width: 200 },
|
{ field: "teamName", headerName: "Team Name", width: 200 },
|
||||||
{ field: "productOwnerUsername", headerName: "Product Owner", width: 200 },
|
{ field: "productOwnerUsername", headerName: "Product Owner", width: 200 },
|
||||||
{
|
{
|
||||||
@@ -48,6 +48,7 @@ const Teams = () => {
|
|||||||
slots={{
|
slots={{
|
||||||
toolbar: CustomToolbar,
|
toolbar: CustomToolbar,
|
||||||
}}
|
}}
|
||||||
|
getRowId={(row) => row.teamId}
|
||||||
className="border border-gray-200 bg-white shadow dark:border-stroke-dark dark:bg-dark-secondary dark:text-gray-200"
|
className="border border-gray-200 bg-white shadow dark:border-stroke-dark dark:bg-dark-secondary dark:text-gray-200"
|
||||||
sx={dataGridSxStyles(isDarkMode)}
|
sx={dataGridSxStyles(isDarkMode)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const Timeline = () => {
|
|||||||
start: new Date(project.startDate as string),
|
start: new Date(project.startDate as string),
|
||||||
end: new Date(project.endDate as string),
|
end: new Date(project.endDate as string),
|
||||||
name: project.name,
|
name: project.name,
|
||||||
id: `Project-${project.id}`,
|
id: `Project-${project.projectId}`,
|
||||||
type: "project" as TaskTypeItems,
|
type: "project" as TaskTypeItems,
|
||||||
progress: 50,
|
progress: 50,
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
|
|||||||
1181
tasker-server/seed/populateSeedData.ts
Normal file
1181
tasker-server/seed/populateSeedData.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,11 @@ provider:
|
|||||||
- "arn:aws:execute-api:${self:provider.region}:*:*/*/POST/users"
|
- "arn:aws:execute-api:${self:provider.region}:*:*/*/POST/users"
|
||||||
|
|
||||||
functions:
|
functions:
|
||||||
|
populateSeedData:
|
||||||
|
handler: seed/populateSeedData.handler
|
||||||
|
memorySize: 1024
|
||||||
|
timeout: 60
|
||||||
|
|
||||||
# POST /users or triggered by Cognito
|
# POST /users or triggered by Cognito
|
||||||
createUser:
|
createUser:
|
||||||
handler: src/handlers/createUser.handler
|
handler: src/handlers/createUser.handler
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export const handler = async (event: any): Promise<any> => {
|
|||||||
try {
|
try {
|
||||||
const newProject = {
|
const newProject = {
|
||||||
category: "projects",
|
category: "projects",
|
||||||
projectId: `project#${uuidv4()}`,
|
projectId: `project_${uuidv4()}`,
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
startDate,
|
startDate,
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export const handler = async (event: any): Promise<any> => {
|
|||||||
try {
|
try {
|
||||||
const newTask = {
|
const newTask = {
|
||||||
category: "tasks",
|
category: "tasks",
|
||||||
taskId: `task#${uuidv4()}`,
|
taskId: `task_${uuidv4()}`,
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
status,
|
status,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ const client = new DynamoDBClient({ region: SLS_REGION });
|
|||||||
const docClient = DynamoDBDocument.from(client);
|
const docClient = DynamoDBDocument.from(client);
|
||||||
|
|
||||||
export const handler = async (event: any): Promise<any> => {
|
export const handler = async (event: any): Promise<any> => {
|
||||||
|
console.info(`Event: ${JSON.stringify(event)}`);
|
||||||
const username =
|
const username =
|
||||||
event.request.userAttributes["preferred_username"] || event.userName;
|
event.request.userAttributes["preferred_username"] || event.userName;
|
||||||
const cognitoId = event.userName;
|
const cognitoId = event.userName;
|
||||||
@@ -19,9 +20,9 @@ export const handler = async (event: any): Promise<any> => {
|
|||||||
const newUser = {
|
const newUser = {
|
||||||
category: "users",
|
category: "users",
|
||||||
cognitoId,
|
cognitoId,
|
||||||
userId: `user#${uuidv4()}`,
|
userId: `user_${uuidv4()}`,
|
||||||
username,
|
username,
|
||||||
profilePictureUrl: "i0.jpg",
|
profilePictureUrl: "p0.jpeg",
|
||||||
teamId,
|
teamId,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
import https from "https";
|
|
||||||
import path from "path";
|
|
||||||
|
|
||||||
const API_BASE_URL = process.env.API_BASE_URL || "";
|
|
||||||
|
|
||||||
export const handler = async (event: any): Promise<any> => {
|
|
||||||
const postData = JSON.stringify({
|
|
||||||
username:
|
|
||||||
event.request.userAttributes["preferred_username"] || event.userName,
|
|
||||||
cognitoId: event.userName,
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(postData);
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
hostname: API_BASE_URL ? new URL(API_BASE_URL).hostname : "",
|
|
||||||
port: 443,
|
|
||||||
path: API_BASE_URL
|
|
||||||
? path.join(new URL(API_BASE_URL).pathname, "/users")
|
|
||||||
: "",
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-category": "application/json",
|
|
||||||
"Content-Length": Buffer.byteLength(postData),
|
|
||||||
"Allow-Control-Allow-Origin": "*",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const responseBody = await new Promise((resolve, reject) => {
|
|
||||||
const req = https.request(options, (res) => {
|
|
||||||
res.setEncoding("utf8");
|
|
||||||
let responseBody = "";
|
|
||||||
res.on("data", (chunk) => (responseBody += chunk));
|
|
||||||
res.on("end", () => resolve(responseBody));
|
|
||||||
});
|
|
||||||
req.on("error", (error) => reject(error));
|
|
||||||
req.write(postData);
|
|
||||||
req.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(responseBody);
|
|
||||||
|
|
||||||
return event;
|
|
||||||
};
|
|
||||||
@@ -2,7 +2,7 @@ import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
|
|||||||
import { DynamoDBDocument, QueryCommandInput } from "@aws-sdk/lib-dynamodb";
|
import { DynamoDBDocument, QueryCommandInput } from "@aws-sdk/lib-dynamodb";
|
||||||
|
|
||||||
const SLS_REGION = process.env.SLS_REGION;
|
const SLS_REGION = process.env.SLS_REGION;
|
||||||
const TASKER_PROJECT_TABLE_NAME = process.env.TASKER_PROJECT_TABLE_NAME || "";
|
const TASKER_TEAM_TABLE_NAME = process.env.TASKER_TEAM_TABLE_NAME || "";
|
||||||
const TASKER_USER_TABLE_NAME = process.env.TASKER_USER_TABLE_NAME || "";
|
const TASKER_USER_TABLE_NAME = process.env.TASKER_USER_TABLE_NAME || "";
|
||||||
const TASKER_TASK_TABLE_NAME = process.env.TASKER_TASK_TABLE_NAME || "";
|
const TASKER_TASK_TABLE_NAME = process.env.TASKER_TASK_TABLE_NAME || "";
|
||||||
const TASKER_TASK_EXTRA_TABLE_NAME =
|
const TASKER_TASK_EXTRA_TABLE_NAME =
|
||||||
@@ -13,20 +13,20 @@ const docClient = DynamoDBDocument.from(client);
|
|||||||
|
|
||||||
export const fetchRandomTeamId = async () => {
|
export const fetchRandomTeamId = async () => {
|
||||||
const params = {
|
const params = {
|
||||||
TableName: TASKER_PROJECT_TABLE_NAME,
|
TableName: TASKER_TEAM_TABLE_NAME,
|
||||||
KeyConditionExpression: "category = :category",
|
KeyConditionExpression: "category = :category",
|
||||||
ExpressionAttributeValues: {
|
ExpressionAttributeValues: {
|
||||||
":category": "teams",
|
":category": "teams",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const projects = await docClient.query(params);
|
const teams = await docClient.query(params);
|
||||||
if (!projects.Items) {
|
if (!teams.Items) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const randomProject =
|
const randomTeam =
|
||||||
projects.Items[Math.floor(Math.random() * projects.Items.length)];
|
teams.Items[Math.floor(Math.random() * teams.Items.length)];
|
||||||
return randomProject.id;
|
return randomTeam.teamId;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchUserWithUserId = async (userId: string): Promise<any> => {
|
export const fetchUserWithUserId = async (userId: string): Promise<any> => {
|
||||||
|
|||||||
@@ -1,11 +1,22 @@
|
|||||||
resource "aws_s3_bucket" "tasker_public_images" {
|
resource "aws_s3_bucket" "tasker_public_images" {
|
||||||
bucket = "tasker-public-images"
|
bucket = "tasker-public-images"
|
||||||
|
|
||||||
tags = {
|
|
||||||
Environment = "Dev"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource "aws_s3_bucket_policy" "public_read_policy" {
|
||||||
|
bucket = aws_s3_bucket.tasker_public_images.id
|
||||||
|
policy = data.aws_iam_policy_document.public_read_policy.json
|
||||||
|
}
|
||||||
|
|
||||||
|
data "aws_iam_policy_document" "public_read_policy" {
|
||||||
|
statement {
|
||||||
|
actions = ["s3:GetObject"]
|
||||||
|
resources = ["${aws_s3_bucket.tasker_public_images.arn}/*"]
|
||||||
|
principals {
|
||||||
|
type = "AWS"
|
||||||
|
identifiers = ["*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
resource "aws_s3_bucket_ownership_controls" "tasker_public_images_ownership_controls" {
|
resource "aws_s3_bucket_ownership_controls" "tasker_public_images_ownership_controls" {
|
||||||
bucket = aws_s3_bucket.tasker_public_images.id
|
bucket = aws_s3_bucket.tasker_public_images.id
|
||||||
|
|||||||
Reference in New Issue
Block a user