+
e.stopPropagation()}>
{isEditTodoVisible && }
diff --git a/src/components/users/user-and-team-search.tsx b/src/components/users/user-and-team-search.tsx
index d359263..7645c9a 100644
--- a/src/components/users/user-and-team-search.tsx
+++ b/src/components/users/user-and-team-search.tsx
@@ -42,6 +42,7 @@ type UserAndTeamSearchProps = {
placeholder?: string
value: TUserOrTeamOption | null
onChange: (value: TUserOrTeamOption | null) => void
+ disabled: boolean
}
const mapUserToOption = (user: { id: string; name: string }): TUserOrTeamOption => ({
@@ -82,6 +83,7 @@ export const UserAndTeamSearch = ({
value,
onChange,
placeholder = 'Select assignee...',
+ disabled,
}: UserAndTeamSearchProps) => {
const { user: currentUser } = useAuth()
const teamMatch = useMatch({ from: '/_internal/teams/$teamId', shouldThrow: false })
@@ -125,6 +127,7 @@ export const UserAndTeamSearch = ({
})
const handleSelect = (option: TUserOrTeamOption) => {
+ if (disabled) return
setSelectedOption(option)
onChange(option)
setOpen(false)
@@ -132,6 +135,7 @@ export const UserAndTeamSearch = ({
}
const handleClear = () => {
+ if (disabled) return
setSelectedOption(null)
onChange(null)
setOpen(false)
@@ -156,6 +160,7 @@ export const UserAndTeamSearch = ({
variant="outline"
role="combobox"
aria-expanded={open}
+ disabled={disabled}
className="w-full justify-between"
>
{selectedOption ? (
diff --git a/src/hooks/useUpdateTask.ts b/src/hooks/useUpdateTask.ts
new file mode 100644
index 0000000..bb1a09f
--- /dev/null
+++ b/src/hooks/useUpdateTask.ts
@@ -0,0 +1,70 @@
+import { USER_TYPE_ENUM } from '@/api/common/common-enum'
+import { TasksApi } from '@/api/tasks/tasks.api'
+import { TASK_STATUS_ENUM } from '@/api/tasks/tasks.enum'
+import { TTask } from '@/api/tasks/tasks.types'
+import { TTodoFormData } from '@/components/todos/todo-form'
+import { TodoUtil } from '@/lib/todo-util'
+import { useMutation, useQueryClient } from '@tanstack/react-query'
+import { toast } from 'sonner'
+
+type UseUpdateTaskOptions = {
+ todo: TTask
+ teamId?: string
+}
+
+export const useUpdateTask = ({ todo, teamId }: UseUpdateTaskOptions) => {
+ const queryClient = useQueryClient()
+
+ const mutation = useMutation({
+ mutationFn: TasksApi.updateTask.fn,
+ onSuccess: (res) => {
+ const wasTaskDeferred = todo.status === TASK_STATUS_ENUM.DEFERRED
+ const isTaskDeferred = res.status === TASK_STATUS_ENUM.DEFERRED
+ void queryClient.invalidateQueries({ queryKey: TasksApi.getTasks.key() })
+ void queryClient.invalidateQueries({ queryKey: TasksApi.getWatchListTasks.key })
+ if (wasTaskDeferred || isTaskDeferred) {
+ void queryClient.invalidateQueries({
+ queryKey: TasksApi.getTasks.key({ status: TASK_STATUS_ENUM.DEFERRED }),
+ })
+ }
+
+ if (res.assignee?.user_type === USER_TYPE_ENUM.TEAM) {
+ void queryClient.invalidateQueries({
+ queryKey: TasksApi.getTasks.key({ teamId: res.assignee.assignee_id }),
+ })
+ }
+
+ if (teamId) {
+ void queryClient.invalidateQueries({ queryKey: TasksApi.getTasks.key({ teamId }) })
+ }
+
+ toast.success('Todo updated successfully')
+ },
+ onError: () => {
+ toast.error('Failed to update todo, please try again')
+ },
+ })
+
+ const handleSubmission = (todoDetails: TTodoFormData, customOnSuccess?: () => void) => {
+ const updateDetails = TodoUtil.getUpdateTodoDetails(todoDetails, todo)
+
+ if (Object.keys(updateDetails).length > 0) {
+ mutation.mutate(
+ {
+ id: todo.id,
+ ...updateDetails,
+ },
+ {
+ onSuccess: () => {
+ customOnSuccess?.()
+ },
+ },
+ )
+ }
+ }
+
+ return {
+ mutation,
+ handleSubmission,
+ }
+}
diff --git a/src/lib/todo-util.ts b/src/lib/todo-util.ts
index 716bb4d..e2e1be6 100644
--- a/src/lib/todo-util.ts
+++ b/src/lib/todo-util.ts
@@ -1,5 +1,5 @@
import { TTask, UpdateTaskDto } from '@/api/tasks/tasks.types'
-import { TTodoFormData } from '@/components/todos/create-edit-todo-form'
+import { TTodoFormData } from '@/components/todos/todo-form'
export class TodoUtil {
static getUpdateTodoDetails = (
diff --git a/src/modules/dashboard/components/multi-labels-select.tsx b/src/modules/dashboard/components/multi-labels-select.tsx
index 8ab9581..c2c7a31 100644
--- a/src/modules/dashboard/components/multi-labels-select.tsx
+++ b/src/modules/dashboard/components/multi-labels-select.tsx
@@ -20,6 +20,7 @@ interface LabelMultiSelectProps {
onSelectionChange: (labels: Label[]) => void
placeholder?: string
className?: string
+ disabled: boolean
}
export function LabelMultiSelect({
@@ -28,10 +29,12 @@ export function LabelMultiSelect({
onSelectionChange,
placeholder = 'Select labels...',
className,
+ disabled,
}: LabelMultiSelectProps) {
const [open, setOpen] = React.useState(false)
const handleSelect = (label: Label) => {
+ if (disabled) return
const isSelected = selectedLabels.some((selected) => selected.id === label.id)
if (isSelected) {
@@ -53,6 +56,7 @@ export function LabelMultiSelect({
variant="outline"
role="combobox"
aria-expanded={open}
+ disabled={disabled}
className="h-auto min-h-8 w-full justify-between bg-transparent"
>
diff --git a/src/modules/dashboard/components/select-labels.tsx b/src/modules/dashboard/components/select-labels.tsx
index ee798d0..62fd3ac 100644
--- a/src/modules/dashboard/components/select-labels.tsx
+++ b/src/modules/dashboard/components/select-labels.tsx
@@ -5,9 +5,10 @@ type SelectLabelsProps = {
labelData: Label[]
value: string[] // array of label IDs
onChange: (ids: string[]) => void
+ disabled: boolean
}
-export function SelectLabels({ labelData, value, onChange }: SelectLabelsProps) {
+export function SelectLabels({ labelData, value, onChange, disabled }: SelectLabelsProps) {
const selectedLabels = labelData.filter((label) => value?.includes(label.id))
const handleSelectionChange = (labels: Label[]) => {
@@ -20,6 +21,7 @@ export function SelectLabels({ labelData, value, onChange }: SelectLabelsProps)
selectedLabels={selectedLabels}
onSelectionChange={handleSelectionChange}
placeholder="Select labels for this task..."
+ disabled={disabled}
/>
)
}
diff --git a/src/modules/teams/team-tasks.tsx b/src/modules/teams/team-tasks.tsx
index 46cfe35..5a676d1 100644
--- a/src/modules/teams/team-tasks.tsx
+++ b/src/modules/teams/team-tasks.tsx
@@ -8,6 +8,8 @@ import { Searchbar } from '@/components/common/searchbar'
import { EditTodoButton } from '@/components/todos/edit-task-button'
import { IncludeDoneSwitch } from '@/components/todos/include-done-switch'
import { TaskPriorityLabel } from '@/components/todos/task-priority-label'
+import { TodoDialog } from '@/components/todos/todo-dialog'
+import { TTodoFormData } from '@/components/todos/todo-form'
import { TodoLabelsList } from '@/components/todos/todo-labels-list'
import { TodoListTableHeader, TodoListTableRowShimmer } from '@/components/todos/todo-list-table'
import { TodoStatusTable } from '@/components/todos/todo-status-table'
@@ -15,9 +17,12 @@ import { WatchListButton } from '@/components/todos/watchlist-button'
import { Table, TableBody, TableCell, TableRow } from '@/components/ui/table'
import { ReassignUser } from '@/components/users/reassign-user'
import { useAuth } from '@/hooks/useAuth'
+import { useUpdateTask } from '@/hooks/useUpdateTask'
import { DateFormats, DateUtil } from '@/lib/date-util'
+import { TodoUtil } from '@/lib/todo-util'
import { useQuery } from '@tanstack/react-query'
import { useNavigate, useSearch } from '@tanstack/react-router'
+import { useState } from 'react'
type TodoListTableRowProps = {
todo: TTask
@@ -29,11 +34,42 @@ const TodoListTableRow = ({ todo, team }: TodoListTableRowProps) => {
const isRessignTodoCtaVisible =
todo.assignee?.user_type === USER_TYPE_ENUM.TEAM && team?.poc_id === user.id
const isEditTodoVisible = todo.assignee?.assignee_id === user.id
+ const [showViewTodoModal, setShowViewTodoModal] = useState(false)
+
+ const { mutation, handleSubmission } = useUpdateTask({
+ todo,
+ teamId: team?.id,
+ })
+
+ const handleSubmit = (todoDetails: TTodoFormData) => {
+ handleSubmission(todoDetails, () => {
+ setShowViewTodoModal(false)
+ })
+ }
return (
- {todo.title}
-
+ {isEditTodoVisible ? (
+
+ {todo.title}
+
+ ) : (
+
+ {todo.title}
+
+ )}
@@ -54,7 +90,7 @@ const TodoListTableRow = ({ todo, team }: TodoListTableRowProps) => {
{todo.dueAt ? new DateUtil(todo.dueAt).format(DateFormats.D_MMM_YYYY) : '--'}
-
+ e.stopPropagation()}>
{isRessignTodoCtaVisible && }
{isEditTodoVisible && }
{!isRessignTodoCtaVisible && (