diff --git a/public/locales/en.json b/public/locales/en.json index 1e0e2b7e3..1a1a4f95d 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -4972,6 +4972,21 @@ "trigger": "Trigger", "when": "When" }, + "groupJoinRequest": { + "title": "Group Join Request", + "approve": "Approve", + "decline": "Decline", + "requester": "Requester", + "group": "Group", + "requestedDate": "Requested", + "message": "Message from requester", + "resolved": "This join request task is closed.", + "declineTitle": "Decline Join Request", + "declinePrompt": "Optionally provide a reason for declining this join request.", + "reasonOptional": "Reason (optional)", + "approveError": "Unable to approve join request.", + "declineError": "Unable to decline join request." + }, "myCards": { "noCards": "You have no assigned cards.", "title": "My Cards" @@ -5145,4 +5160,4 @@ "title": "Workflows" } } -} +} \ No newline at end of file diff --git a/src/dashboard/DashboardPage.tsx b/src/dashboard/DashboardPage.tsx index d141cbadd..be1839f80 100644 --- a/src/dashboard/DashboardPage.tsx +++ b/src/dashboard/DashboardPage.tsx @@ -60,7 +60,7 @@ export const DashboardPage = () => { - + diff --git a/src/serving/tasks/TaskPage.tsx b/src/serving/tasks/TaskPage.tsx index c968f39ad..c738abc78 100644 --- a/src/serving/tasks/TaskPage.tsx +++ b/src/serving/tasks/TaskPage.tsx @@ -7,6 +7,7 @@ import { HeaderPrimaryButton, HeaderSecondaryButton } from "../../components/ui" import { ContentPicker } from "./components/ContentPicker"; import UserContext from "../../UserContext"; import { RequestedChanges } from "./components/RequestedChanges"; +import { GroupJoinRequestTask } from "./components/GroupJoinRequestTask"; import { TaskReminderEdit } from "./components/TaskReminderEdit"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { Person as PersonIcon, Group as GroupIcon, CheckCircle as CompletedIcon, RadioButtonUnchecked as OpenIcon, Checklist as ChecklistIcon } from "@mui/icons-material"; @@ -99,7 +100,7 @@ export const TaskPage = () => { } title={`#${task.data.taskNumber} - ${task.data?.title}`} - subtitle={`${Locale.label("tasks.taskPage.created")} ${DateHelper.getDisplayDuration(DateHelper.toDate(task.data?.dateCreated))} ${Locale.label("tasks.taskPage.ago")} ${Locale.label("tasks.taskPage.by")} ${task.data.createdByLabel} • ${Locale.label("tasks.taskPage.associated")}: ${task.data.associatedWithLabel || Locale.label("tasks.taskPage.notSpec")} • ${Locale.label("tasks.taskPage.assigned")}: ${task.data.assignedToLabel || Locale.label("tasks.taskPage.unassigned")}`}> + subtitle={`${Locale.label("tasks.taskPage.created")} ${task.data?.dateCreated ? `${DateHelper.getDisplayDuration(new Date(task.data.dateCreated))} ${Locale.label("tasks.taskPage.ago")}` : ""}${task.data?.createdByLabel ? ` ${Locale.label("tasks.taskPage.by")} ${task.data.createdByLabel}` : ""} • ${Locale.label("tasks.taskPage.associated")}: ${task.data?.associatedWithLabel || Locale.label("tasks.taskPage.notSpec")} • ${Locale.label("tasks.taskPage.assigned")}: ${task.data?.assignedToLabel || Locale.label("tasks.taskPage.unassigned")}`}> + + + )} + + + {error && setError("")}>{error}} + + + + + + + {Locale.label("tasks.groupJoinRequest.requester") || "Requester"}:{" "} + {personId ? ( + + {personName} + + ) : ( + personName + )} + + + + + + + {Locale.label("tasks.groupJoinRequest.group") || "Group"}:{" "} + {groupId ? ( + + {groupName} + + ) : ( + groupName + )} + + + + {task.dateCreated && ( + + + + {Locale.label("tasks.groupJoinRequest.requestedDate") || "Requested"}: {DateHelper.getDisplayDuration(new Date(task.dateCreated))} {Locale.label("tasks.taskPage.ago")} ({new Date(task.dateCreated).toLocaleString()}) + + + )} + + {message && ( + + + + + + {Locale.label("tasks.groupJoinRequest.message") || "Message from requester"}: + + + "{message}" + + + + + )} + + + + {isClosed && ( + + + {Locale.label("tasks.groupJoinRequest.resolved") || "This join request task is closed."} + + + )} + + + + setDeclineOpen(false)} fullWidth maxWidth="sm" data-testid="decline-dialog"> + {Locale.label("tasks.groupJoinRequest.declineTitle") || "Decline Join Request"} + + + {Locale.label("tasks.groupJoinRequest.declinePrompt") || "Optionally provide a reason for declining this join request."} + + setDeclineReason(e.target.value)} + slotProps={{ htmlInput: { maxLength: 500 } }} + data-testid="decline-reason-input" + /> + + + + + + + + ); +}; diff --git a/src/serving/tasks/components/TaskList.tsx b/src/serving/tasks/components/TaskList.tsx index 92d10536f..5f6887990 100644 --- a/src/serving/tasks/components/TaskList.tsx +++ b/src/serving/tasks/components/TaskList.tsx @@ -38,9 +38,11 @@ export const TaskList = memo((props: Props) => { const [showAdd, setShowAdd] = React.useState(false); const [tab, setTab] = React.useState(0); const context = React.useContext(UserContext); + const isClosed = props.status === "Closed" || props.status === Locale.label("tasks.taskPage.closed"); + const queryStatus = isClosed ? "Closed" : "Open"; const tasks = useQuery({ - queryKey: props.status === Locale.label("tasks.taskPage.closed") ? ["/tasks/closed", "DoingApi"] : ["/tasks", "DoingApi"], + queryKey: isClosed ? ["/tasks/closed", "DoingApi"] : ["/tasks", "DoingApi"], placeholderData: [] }); @@ -58,12 +60,12 @@ export const TaskList = memo((props: Props) => { }, [groupMembers.data]); const groupTasks = useQuery({ - queryKey: ["/tasks/loadForGroups", "DoingApi", groupIds, props.status], + queryKey: ["/tasks/loadForGroups", "DoingApi", groupIds, queryStatus], enabled: groupIds.length > 0, placeholderData: [], queryFn: async () => { if (groupIds.length === 0) return []; - return ApiHelper.post("/tasks/loadForGroups", { groupIds, status: props.status }, "DoingApi"); + return ApiHelper.post("/tasks/loadForGroups", { groupIds, status: queryStatus }, "DoingApi"); } }); @@ -135,8 +137,9 @@ export const TaskList = memo((props: Props) => { - #{task.taskNumber} {Locale.label("tasks.taskPage.opened")} {DateHelper.getDisplayDuration(DateHelper.toDate(task.dateCreated))} {Locale.label("tasks.taskPage.ago")}{" "} - {Locale.label("tasks.taskPage.by")} {task.createdByLabel} + #{task.taskNumber} {Locale.label("tasks.taskPage.opened")}{" "} + {task.dateCreated ? `${DateHelper.getDisplayDuration(new Date(task.dateCreated))} ${Locale.label("tasks.taskPage.ago")}` : ""} + {task.createdByLabel ? ` ${Locale.label("tasks.taskPage.by")} ${task.createdByLabel}` : ` ${Locale.label("tasks.taskPage.by")} ${task.associatedWithLabel}`} diff --git a/src/serving/tasks/components/index.ts b/src/serving/tasks/components/index.ts index 7947250b7..63890f1ae 100644 --- a/src/serving/tasks/components/index.ts +++ b/src/serving/tasks/components/index.ts @@ -1,3 +1,6 @@ export * from "../../../components"; export { NewTask } from "./NewTask"; export { SelectGroup } from "./SelectGroup"; +export { GroupJoinRequestTask } from "./GroupJoinRequestTask"; +export { RequestedChanges } from "./RequestedChanges"; +