manager users
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { type FC, useEffect, useState } from "react";
|
||||
import { type FC, useEffect, useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { toast } from "react-toastify";
|
||||
import { useGetUsers } from "../../../users/hooks/useUserData";
|
||||
import TaskDetailAttachmentPopover from "./attachment/TaskDetailAttachmentPopover";
|
||||
import { DEFAULT_DATE_RANGE } from "./date/constants";
|
||||
import TaskDetailDatePopover from "./date/TaskDetailDatePopover";
|
||||
@@ -16,10 +17,9 @@ import type { LabelsView, TaskLabel } from "./labels/types";
|
||||
import TaskDetailActionBar from "./TaskDetailActionBar";
|
||||
import TaskDetailMetadataPreview from "./TaskDetailMetadataPreview";
|
||||
import type { TaskDetailTab } from "./types";
|
||||
import { DEFAULT_USERS } from "./users/constants";
|
||||
import TaskDetailUsersPopover from "./users/TaskDetailUsersPopover";
|
||||
import type { TaskDetailType } from "../../task/types/TaskTypes";
|
||||
import { useCreateTaskRemark } from "../../task/hooks/useTaskData";
|
||||
import { useCreateTaskRemark, useUpdateTask } from "../../task/hooks/useTaskData";
|
||||
import { ErrorType } from "../../../../helpers/types";
|
||||
|
||||
type Props = {
|
||||
@@ -38,10 +38,12 @@ const parseDate = (value?: string): DateObject | null => {
|
||||
const TaskDetailToolbar: FC<Props> = ({ activeTab, onTabChange, taskDetail, taskId }) => {
|
||||
const { t } = useTranslation("global");
|
||||
const createTaskRemark = useCreateTaskRemark();
|
||||
const updateTask = useUpdateTask();
|
||||
const getUsers = useGetUsers("");
|
||||
const [labelsView, setLabelsView] = useState<LabelsView>("list");
|
||||
const [labels, setLabels] = useState<TaskLabel[]>([]);
|
||||
const [selectedLabelIds, setSelectedLabelIds] = useState<Set<string>>(new Set());
|
||||
const [selectedUserIds, setSelectedUserIds] = useState<Set<string>>(new Set(["1"]));
|
||||
const [selectedUserIds, setSelectedUserIds] = useState<Set<string>>(new Set());
|
||||
const [checklists, setChecklists] = useState<TaskChecklist[]>(DEFAULT_CHECKLISTS);
|
||||
const [startDate, setStartDate] = useState<DateObject | null>(DEFAULT_DATE_RANGE.startDate);
|
||||
const [endDate, setEndDate] = useState<DateObject | null>(DEFAULT_DATE_RANGE.endDate);
|
||||
@@ -61,6 +63,8 @@ const TaskDetailToolbar: FC<Props> = ({ activeTab, onTabChange, taskDetail, task
|
||||
|
||||
if (taskDetail.users?.length) {
|
||||
setSelectedUserIds(new Set(taskDetail.users.map((user) => user.id)));
|
||||
} else {
|
||||
setSelectedUserIds(new Set());
|
||||
}
|
||||
|
||||
if (taskDetail.checklists?.length) {
|
||||
@@ -74,12 +78,27 @@ const TaskDetailToolbar: FC<Props> = ({ activeTab, onTabChange, taskDetail, task
|
||||
}, [taskDetail]);
|
||||
|
||||
const selectedLabels = labels.filter((label) => selectedLabelIds.has(label.id));
|
||||
const users = taskDetail?.users?.length
|
||||
? taskDetail.users.map((user) => ({
|
||||
const users = useMemo(() => {
|
||||
const apiUsers =
|
||||
getUsers.data?.data?.users?.map((user) => ({
|
||||
id: user.id,
|
||||
name: `${user.firstName} ${user.lastName}`.trim(),
|
||||
}))
|
||||
: DEFAULT_USERS;
|
||||
})) ?? [];
|
||||
const taskUsers =
|
||||
taskDetail?.users?.map((user) => ({
|
||||
id: user.id,
|
||||
name: `${user.firstName} ${user.lastName}`.trim(),
|
||||
})) ?? [];
|
||||
const userMap = new Map(apiUsers.map((user) => [user.id, user]));
|
||||
|
||||
taskUsers.forEach((user) => {
|
||||
if (!userMap.has(user.id)) {
|
||||
userMap.set(user.id, user);
|
||||
}
|
||||
});
|
||||
|
||||
return Array.from(userMap.values());
|
||||
}, [getUsers.data, taskDetail?.users]);
|
||||
const selectedUsers = users.filter((user) => selectedUserIds.has(user.id));
|
||||
const isLabelsOpen = activeTab === "labels";
|
||||
const isUsersOpen = activeTab === "users";
|
||||
@@ -107,15 +126,31 @@ const TaskDetailToolbar: FC<Props> = ({ activeTab, onTabChange, taskDetail, task
|
||||
};
|
||||
|
||||
const handleUserToggle = (id: string) => {
|
||||
setSelectedUserIds((prev) => {
|
||||
const next = new Set(prev);
|
||||
if (next.has(id)) {
|
||||
next.delete(id);
|
||||
} else {
|
||||
next.add(id);
|
||||
}
|
||||
return next;
|
||||
});
|
||||
const effectiveTaskId = taskId || taskDetail?.id;
|
||||
if (!effectiveTaskId) return;
|
||||
|
||||
const previous = selectedUserIds;
|
||||
const next = new Set(previous);
|
||||
if (next.has(id)) {
|
||||
next.delete(id);
|
||||
} else {
|
||||
next.add(id);
|
||||
}
|
||||
|
||||
setSelectedUserIds(next);
|
||||
|
||||
updateTask.mutate(
|
||||
{ id: effectiveTaskId, params: { userIds: Array.from(next) } },
|
||||
{
|
||||
onSuccess: () => {
|
||||
toast.success(t("success"));
|
||||
},
|
||||
onError: (error: ErrorType) => {
|
||||
toast.error(error.response?.data?.error.message[0]);
|
||||
setSelectedUserIds(previous);
|
||||
},
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const handleCreate = (title: string, color: string) => {
|
||||
@@ -200,7 +235,13 @@ const TaskDetailToolbar: FC<Props> = ({ activeTab, onTabChange, taskDetail, task
|
||||
}
|
||||
usersPopover={
|
||||
isUsersOpen ? (
|
||||
<TaskDetailUsersPopover users={users} selectedIds={selectedUserIds} onToggle={handleUserToggle} />
|
||||
<TaskDetailUsersPopover
|
||||
users={users}
|
||||
selectedIds={selectedUserIds}
|
||||
onToggle={handleUserToggle}
|
||||
isLoading={getUsers.isPending}
|
||||
isSubmitting={updateTask.isPending}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
checklistPopover={
|
||||
|
||||
Reference in New Issue
Block a user