import { Button, Dialog, DialogContent, DialogFooter, DurationPicker, Input, Label, PropertyRow, Textarea, useDialogRef, type DialogRef, } from "@probo/ui"; import type { ReactNode } from "react"; import { useTranslate } from "@probo/i18n"; import { Breadcrumb } from "@probo/ui"; import { graphql } from "relay-runtime"; import { useFragment } from "react-relay"; import { z } from "zod"; import { useFormWithSchema } from "/hooks/useFormWithSchema"; import { useMutationWithToasts } from "/hooks/useMutationWithToasts"; import { useOrganizationId } from "/hooks/useOrganizationId"; import { PeopleSelectField } from "/components/form/PeopleSelectField"; import type { TaskFormDialogFragment$key } from "./__generated__/TaskFormDialogFragment.graphql"; import { MeasureSelectField } from "/components/form/MeasureSelectField"; import { Controller } from "react-hook-form"; const taskFragment = graphql` fragment TaskFormDialogFragment on Task { id description name state timeEstimate deadline assignedTo { id } measure { id } } `; const taskCreateMutation = graphql` mutation TaskFormDialogCreateMutation( $input: CreateTaskInput! $connections: [ID!]! ) { createTask(input: $input) { taskEdge @prependEdge(connections: $connections) { node { ...TaskFormDialogFragment } } } } `; export const taskUpdateMutation = graphql` mutation TaskFormDialogUpdateMutation($input: UpdateTaskInput!) { updateTask(input: $input) { task { ...TaskFormDialogFragment } } } `; const schema = z.object({ name: z.string(), description: z.string(), timeEstimate: z.string().nullable(), assignedToId: z.string(), measureId: z.string(), deadline: z .date({ coerce: true, }) .nullable(), }); type Props = { children?: ReactNode; task?: TaskFormDialogFragment$key; connection?: string; ref?: DialogRef; measureId?: string; }; export default function TaskFormDialog(props: Props) { const { __ } = useTranslate(); const dialogRef = props.ref ?? useDialogRef(); const organizationId = useOrganizationId(); const task = useFragment(taskFragment, props.task); const [mutate] = task ? useMutationWithToasts(taskUpdateMutation, { successMessage: __("Task updated successfully."), errorMessage: __("Failed to update task. Please try again."), }) : useMutationWithToasts(taskCreateMutation, { successMessage: __("Task created successfully."), errorMessage: __("Failed to create task. Please try again."), }); const { control, handleSubmit, register, formState } = useFormWithSchema( schema, { defaultValues: { name: task?.name ?? "", description: task?.description ?? "", timeEstimate: task?.timeEstimate ?? "", assignedToId: task?.assignedTo?.id ?? "", measureId: task?.measure?.id ?? props.measureId ?? "", deadline: task?.deadline?.split("T")[0] ?? null, }, } ); const onSubmit = handleSubmit(async (data) => { if (task) { await mutate({ variables: { input: { taskId: task.id, name: data.name, description: data.description, timeEstimate: data.timeEstimate || null, deadline: data.deadline, }, }, }); } else { await mutate({ variables: { input: { organizationId, name: data.name, description: data.description, timeEstimate: data.timeEstimate || null, deadline: data.deadline || null, assignedToId: data.assignedToId, measureId: data.measureId, }, connections: [props.connection!], }, }); } dialogRef.current?.close(); }); const isUpdating = !!task; const showMeasure = !props.measureId && !isUpdating; const isCreating = !isUpdating; return ( } >
); }