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
15 changes: 13 additions & 2 deletions backend/app/services/TaskService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ class TaskService @Inject()(taskRepository: TaskRepository,

def updatePosition(taskId: Int, req: UpdateTaskPositionRequest, userId: Int): Future[Int] = {
val action = for {
(task, _) <- getTaskAndProjectByTaskId(taskId, userId)
(task, projectId) <- getTaskAndProjectByTaskId(taskId, userId)

_ <- if (task.status == TaskStatus.active) {
DBIO.successful(())
Expand All @@ -332,8 +332,19 @@ class TaskService @Inject()(taskRepository: TaskRepository,
}

updatedRows <- taskRepository.updatePosition(taskId, req.position, req.columnId)
_ <- updatedRows match {
case 1 =>
broadcastService.broadcastToProject(
projectId,
TaskMoved(TaskMovedPayload(taskId, task.columnId, req.columnId, req.position)))
DBIO.successful(())
case 0 =>
DBIO.failed(AppException(
message = s"Failed to update task position",
statusCode = Status.BAD_REQUEST
))
}
} yield updatedRows

db.run(action.transactionally)
}

Expand Down
20 changes: 14 additions & 6 deletions frontend/src/components/board/AddTask.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Plus, X } from "lucide-react";

Check failure on line 1 in frontend/src/components/board/AddTask.tsx

View workflow job for this annotation

GitHub Actions / build-and-deploy

Replace `"lucide-react"` with `'lucide-react'`
import UrlPreview from "./UrlPreview";

Check failure on line 2 in frontend/src/components/board/AddTask.tsx

View workflow job for this annotation

GitHub Actions / build-and-deploy

Replace `"./UrlPreview"` with `'./UrlPreview'`
import { useSelector } from "react-redux";

Check failure on line 3 in frontend/src/components/board/AddTask.tsx

View workflow job for this annotation

GitHub Actions / build-and-deploy

Replace `"react-redux"` with `'react-redux'`
import { selectColumnToggleStates } from "@/store/selectors/modalSelector";

Check failure on line 4 in frontend/src/components/board/AddTask.tsx

View workflow job for this annotation

GitHub Actions / build-and-deploy

Replace `"@/store/selectors/modalSelector"` with `'@/store/selectors/modalSelector'`
import { useCallback, useEffect, useMemo, useRef, useState } from "react";

Check failure on line 5 in frontend/src/components/board/AddTask.tsx

View workflow job for this annotation

GitHub Actions / build-and-deploy

Replace `"react"` with `'react'`
import { detectUrl } from "@/utils/UrlPreviewUtils";

Check failure on line 6 in frontend/src/components/board/AddTask.tsx

View workflow job for this annotation

GitHub Actions / build-and-deploy

Replace `"@/utils/UrlPreviewUtils"` with `'@/utils/UrlPreviewUtils'`
import { resetcolumnToggleStates, showAddTaskForm } from "@/store/slices/columnToggleStatesSlice";
import { useAppDispatch } from "@/store";
import taskService from "@/services/taskService";
Expand All @@ -18,6 +18,7 @@
const [taskTitle, setTaskTitle] = useState("");
const [detectedUrl, setDetectedUrl] = useState<string | null>(null);
const inputRef = useRef<HTMLTextAreaElement>(null);
const formRef = useRef<HTMLDivElement>(null);

const { isAddingTask, columnId: currentToggleColumn } = useSelector(selectColumnToggleStates);
const maxPosition = useSelector(selectMaxTaskPositionByColumn(columnId));
Expand All @@ -35,10 +36,11 @@
const result = await taskService.createTask(columnId, taskTitle.trim(), newPosition);
notify.success(result.message);
setTaskTitle("");
dispatch(resetcolumnToggleStates());
} catch (error: any) {
notify.error(error.response?.data?.message || "Failed to create card");
}
}, [columnId, maxPosition, taskTitle]);
}, [columnId, maxPosition, taskTitle, dispatch]);

const handleRemoveUrlPreview = useCallback(() => {
if (detectedUrl) {
Expand Down Expand Up @@ -70,9 +72,16 @@
[handleSubmitAddTask, cancelAddingTask]
);

const handleBlur = useCallback(() => {
dispatch(resetcolumnToggleStates());
}, []);
// Cancel adding task when clicking outside
useEffect(() => {
const handleClickOutside = (e: MouseEvent) => {
if (formRef.current && !formRef.current.contains(e.target as Node)) {
dispatch(resetcolumnToggleStates());
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => document.removeEventListener("mousedown", handleClickOutside);
}, [dispatch]);

useEffect(() => {
if (isAddingTask) {
Expand All @@ -94,7 +103,6 @@
value={taskTitle}
onChange={(e) => setTaskTitle(e.target.value)}
onKeyDown={handleKeyDown}
onBlur={handleBlur}
placeholder="Enter a title or paste a link"
className="w-full p-2 text-sm bg-[#22272B] text-[#B6C2CF] border border-[#394B59] rounded-lg resize-none focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
rows={3}
Expand Down Expand Up @@ -128,4 +136,4 @@
);
};

export default AddTask;
export default AddTask;
Loading
Loading