|
- "use client";
-
- import Card from "@mui/material/Card";
- import CardContent from "@mui/material/CardContent";
- import Grid from "@mui/material/Grid";
- import Typography from "@mui/material/Typography";
- import { useTranslation } from "react-i18next";
- import TransferList from "../TransferList";
- import Button from "@mui/material/Button";
- import React, { useCallback, useMemo, useState } from "react";
- import CardActions from "@mui/material/CardActions";
- import RestartAlt from "@mui/icons-material/RestartAlt";
- import FormControl from "@mui/material/FormControl";
- import Select, { SelectChangeEvent } from "@mui/material/Select";
- import MenuItem from "@mui/material/MenuItem";
- import InputLabel from "@mui/material/InputLabel";
- import { Task, TaskTemplate } from "@/app/api/tasks";
- import { useFormContext } from "react-hook-form";
- import { CreateProjectInputs } from "@/app/api/projects/actions";
- import isNumber from "lodash/isNumber";
- import intersectionWith from "lodash/intersectionWith";
-
- interface Props {
- allTasks: Task[];
- taskTemplates: TaskTemplate[];
- isActive: boolean;
- }
-
- const TaskSetup: React.FC<Props> = ({
- allTasks: tasks,
- taskTemplates,
- isActive,
- }) => {
- const { t } = useTranslation();
- const { setValue, watch } = useFormContext<CreateProjectInputs>();
- const currentTaskGroups = watch("taskGroups");
- const currentTaskIds = Object.values(currentTaskGroups).reduce<Task["id"][]>(
- (acc, group) => {
- return [...acc, ...group.taskIds];
- },
- [],
- );
-
- const onReset = useCallback(() => {
- setValue("taskGroups", {});
- }, [setValue]);
-
- const [selectedTaskTemplateId, setSelectedTaskTemplateId] = useState<
- "All" | number
- >("All");
- const onSelectTaskTemplate = useCallback(
- (e: SelectChangeEvent<number | "All">) => {
- if (e.target.value === "All" || isNumber(e.target.value)) {
- setSelectedTaskTemplateId(e.target.value);
- // onReset();
- }
- },
- [onReset],
- );
-
- const items = useMemo(() => {
- const taskList =
- selectedTaskTemplateId === "All"
- ? tasks
- : taskTemplates.find(
- (template) => template.id === selectedTaskTemplateId,
- )?.tasks || tasks;
-
- return taskList.map((t) => ({
- id: t.id,
- label: t.name,
- group: t.taskGroup,
- }));
- }, [tasks, selectedTaskTemplateId, taskTemplates]);
-
- const selectedItems = useMemo(() => {
- return intersectionWith(
- tasks,
- currentTaskIds,
- (task, taskId) => task.id === taskId,
- ).map((t) => ({ id: t.id, label: t.name, group: t.taskGroup }));
- }, [currentTaskIds, tasks]);
-
- return (
- <Card sx={{ display: isActive ? "block" : "none" }}>
- <CardContent sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
- <Typography variant="overline" display="block" marginBlockEnd={1}>
- {t("Task List Setup")}
- </Typography>
- <Grid
- container
- spacing={2}
- columns={{ xs: 6, sm: 12 }}
- marginBlockEnd={1}
- >
- <Grid item xs={6}>
- <FormControl fullWidth>
- <InputLabel>{t("Task List Source")}</InputLabel>
- <Select<"All" | number>
- label={t("Task List Source")}
- value={selectedTaskTemplateId}
- onChange={onSelectTaskTemplate}
- >
- <MenuItem value={"All"}>{t("All tasks")}</MenuItem>
- {taskTemplates.map((template, index) => (
- <MenuItem key={`${template.id}-${index}`} value={template.id}>
- {template.name}
- </MenuItem>
- ))}
- </Select>
- </FormControl>
- </Grid>
- </Grid>
- <TransferList
- allItems={items}
- selectedItems={selectedItems}
- onChange={(selectedTasks) => {
- const newTaskGroups = selectedTasks.reduce<
- CreateProjectInputs["taskGroups"]
- >((acc, item) => {
- if (!item.group) {
- // TODO: this should not happen (all tasks are part of a group)
- return acc;
- }
- if (!acc[item.group.id]) {
- return {
- ...acc,
- [item.group.id]: {
- taskIds: [item.id],
- percentAllocation:
- currentTaskGroups[item.group.id]?.percentAllocation || 0,
- },
- };
- }
- return {
- ...acc,
- [item.group.id]: {
- ...acc[item.group.id],
- taskIds: [...acc[item.group.id].taskIds, item.id],
- },
- };
- }, {});
-
- setValue("taskGroups", newTaskGroups);
- }}
- allItemsLabel={t("Task Pool")}
- selectedItemsLabel={t("Project Task List")}
- />
- <CardActions sx={{ justifyContent: "flex-end" }}>
- <Button variant="text" startIcon={<RestartAlt />} onClick={onReset}>
- {t("Reset")}
- </Button>
- </CardActions>
- </CardContent>
- </Card>
- );
- };
-
- export default TaskSetup;
|