Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions backend/app/controllers/ProjectController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,7 @@ import dto.response.ApiResponse
import play.api.i18n.I18nSupport.RequestWithMessagesApi
import play.api.i18n.Messages
import play.api.libs.json.{JsValue, Json}
import play.api.mvc.{
Action,
AnyContent,
MessagesAbstractController,
MessagesControllerComponents
}
import play.api.mvc.{Action, AnyContent, MessagesAbstractController, MessagesControllerComponents}
import services.ProjectService
import utils.WritesExtras.unitWrites
import validations.ValidationHandler
Expand Down Expand Up @@ -124,4 +119,14 @@ class ProjectController @Inject()(
Ok(Json.toJson(apiResponse))
}
}

def getProjectsByUser: Action[AnyContent] =
authenticatedActionWithUser.async { request =>
val userId = request.userToken.userId
projectService.getProjectsByUserId(userId).map { projects =>
val apiResponse =
ApiResponse.success("Projects retrieved", projects)
Ok(Json.toJson(apiResponse))
}
}
}
2 changes: 2 additions & 0 deletions backend/app/dto/response/task/TaskSearchResponse.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package dto.response.task

import models.Enums.TaskStatus.TaskStatus
import play.api.libs.json.{Format, Json}

import java.time.Instant

case class TaskSearchResponse(taskId: Int,
taskName: String,
taskDescription: Option[String],
taskStatus: TaskStatus,
projectId: Int,
projectName: String,
columnName: String,
Expand Down
12 changes: 12 additions & 0 deletions backend/app/mappers/ProjectMapper.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package mappers

object ProjectMapper {

def toProjectResponse(entity: models.entities.Project): dto.response.project.ProjectResponse =
dto.response.project.ProjectResponse(
id = entity.id.getOrElse(0),
name = entity.name,
status = entity.status
)

}
11 changes: 11 additions & 0 deletions backend/app/repositories/ProjectRepository.scala
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,15 @@ class ProjectRepository @Inject()(
val action = insertQuery ++= entries
db.run(action)
}

def getProjectsByUser(userId: Int): DBIO[Seq[Project]] = {
val q = for {
up <- userProjects
if up.userId === userId && (up.role === UserProjectRole.owner || up.role === UserProjectRole.member)
p <- projects if p.id === up.projectId && p.status =!= ProjectStatus.deleted
w <- workspaces if w.id === p.workspaceId && !w.isDeleted
} yield p

q.result
}
}
10 changes: 7 additions & 3 deletions backend/app/repositories/TaskRepository.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package repositories

import db.MyPostgresProfile.api.{columnStatusTypeMapper, projectStatusTypeMapper, taskStatusTypeMapper}
import dto.response.task.{AssignMemberToTaskResponse, AssignedMemberResponse, TaskSummaryResponse}
import dto.response.task.AssignMemberToTaskResponse
import dto.response.task.TaskSummaryResponse
import models.Enums.TaskStatus.TaskStatus
import models.Enums.{ColumnStatus, ProjectStatus, TaskStatus}
import models.entities.{Task, UserTask}
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
Expand Down Expand Up @@ -131,11 +134,12 @@ class TaskRepository@Inject()(
): Query[(Rep[Int],
Rep[String],
Rep[Option[String]],
Rep[TaskStatus],
Rep[Int],
Rep[String],
Rep[String],
Rep[Instant]),
(Int, String, Option[String], Int, String, String, Instant),
(Int, String, Option[String], TaskStatus, Int, String, String, Instant),
Seq] = {

val baseQuery =
Expand All @@ -147,7 +151,7 @@ class TaskRepository@Inject()(
.on(_._2.projectId === _.id)
.join(userProjects)
.on(_._2.id === _.projectId)
if up.userId === userId
if up.userId === userId && t.status =!= TaskStatus.deleted && p.status =!= ProjectStatus.deleted && c.status =!= ColumnStatus.deleted
} yield (t, c, p)

val filtered = baseQuery
Expand All @@ -164,7 +168,7 @@ class TaskRepository@Inject()(
.sortBy { case (t, _, _) => t.updatedAt.desc }
.map {
case (t, c, p) =>
(t.id, t.name, t.description, p.id, p.name, c.name, t.updatedAt)
(t.id, t.name, t.description, t.status, p.id, p.name, c.name, t.updatedAt)
}
}

Expand Down
7 changes: 7 additions & 0 deletions backend/app/services/ProjectService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import dto.request.project.CreateProjectRequest
import dto.response.project.{ProjectResponse, ProjectSummariesResponse}
import dto.response.user.UserInProjectResponse
import exception.AppException
import mappers.ProjectMapper
import models.Enums.ProjectStatus.ProjectStatus
import models.Enums.{ProjectStatus, ProjectVisibility}
import models.entities.Project
Expand Down Expand Up @@ -207,4 +208,10 @@ class ProjectService @Inject()(
db.run(projectRepository.isUserInActiveProject(userId, projectId))
}

def getProjectsByUserId(userId: Int): Future[Seq[ProjectResponse]] = {
db.run(projectRepository.getProjectsByUser(userId)).map {
_.map(ProjectMapper.toProjectResponse)
}
}

}
4 changes: 2 additions & 2 deletions backend/app/services/TaskService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@ class TaskService @Inject()(taskRepository: TaskRepository,
.take(size)

db.run(query.result).map(_.map {
case (taskId, taskName, taskDesc, projectId, projectName, columnName, updatedAt) =>
TaskSearchResponse(taskId, taskName, taskDesc, projectId, projectName, columnName, updatedAt)
case (taskId, taskName, taskDesc, taskStatus, projectId, projectName, columnName, updatedAt) =>
TaskSearchResponse(taskId, taskName, taskDesc, taskStatus, projectId, projectName, columnName, updatedAt)
})
}

Expand Down
1 change: 1 addition & 0 deletions backend/conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ PATCH /api/projects/:projectId/reopen controllers.ProjectController.reopen
GET /api/projects/completed controllers.ProjectController.getCompletedProjectsByUser
GET /api/projects/:projectId/members controllers.ProjectController.getAllMembersInProject(projectId: Int)
GET /api/projects/:projectId controllers.ProjectController.getProjectById(projectId: Int)
GET /api/projects controllers.ProjectController.getProjectsByUser

# Column routes
POST /api/projects/:projectId/columns controllers.ColumnController.create(projectId: Int)
Expand Down
9 changes: 9 additions & 0 deletions backend/test/controllers/ProjectControllerSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -222,5 +222,14 @@ class ProjectControllerSpec
status(result) mustBe OK
(contentAsJson(result) \ "message").as[String] mustBe "Project deleted successfully"
}

"get all projects by user successfully" in {
val request = FakeRequest(GET, s"/api/projects")
.withCookies(Cookie(cookieName, fakeToken))
val result = route(app, request).get

status(result) mustBe OK
(contentAsJson(result) \ "message").as[String] mustBe "Projects retrieved"
}
}
}
2 changes: 1 addition & 1 deletion frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
<title>Smart Taskhub</title>
</head>
<body>
<div id="root"></div>
Expand Down
Loading
Loading