Fix people deletion
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
ActionDropdown,
|
||||
DropdownItem,
|
||||
IconTrashCan,
|
||||
IconCalendar2,
|
||||
} from "@probo/ui";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import type { PeopleGraphPaginatedQuery } from "/hooks/graph/__generated__/PeopleGraphPaginatedQuery.graphql";
|
||||
@@ -22,9 +23,10 @@ import type { NodeOf } from "/types";
|
||||
import { usePageTitle } from "@probo/hooks";
|
||||
import { getRole } from "@probo/helpers";
|
||||
import { CreatePeopleDialog } from "./dialogs/CreatePeopleDialog";
|
||||
import { SetEndOfContractDialog, type SetEndOfContractDialogRef } from "./dialogs/SetEndOfContractDialog";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||
import { PermissionsContext } from "/providers/PermissionsContext";
|
||||
import { use } from "react";
|
||||
import { use, useRef } from "react";
|
||||
|
||||
type People = NodeOf<PeopleGraphPaginatedFragment$data["peoples"]>;
|
||||
|
||||
@@ -108,40 +110,56 @@ function PeopleRow({
|
||||
const deletePeople = useDeletePeople(people, connectionId);
|
||||
const contractEnded = isContractEnded(people);
|
||||
const { isAuthorized } = use(PermissionsContext);
|
||||
const dialogRef = useRef<SetEndOfContractDialogRef>(null);
|
||||
|
||||
return (
|
||||
<Tr
|
||||
to={`/organizations/${organizationId}/people/${people.id}/tasks`}
|
||||
className={contractEnded ? "opacity-50" : ""}
|
||||
>
|
||||
<Td>
|
||||
<div className="flex gap-3 items-center">
|
||||
<Avatar name={people.fullName} />
|
||||
<div>
|
||||
<div className="text-sm">{people.fullName}</div>
|
||||
<div className="text-xs text-txt-tertiary">
|
||||
{people.primaryEmailAddress}
|
||||
<>
|
||||
<SetEndOfContractDialog
|
||||
peopleId={people.id}
|
||||
currentContractEndDate={people.contractEndDate}
|
||||
ref={dialogRef}
|
||||
/>
|
||||
<Tr
|
||||
to={`/organizations/${organizationId}/people/${people.id}/profile`}
|
||||
className={contractEnded ? "opacity-50" : ""}
|
||||
>
|
||||
<Td>
|
||||
<div className="flex gap-3 items-center">
|
||||
<Avatar name={people.fullName} />
|
||||
<div>
|
||||
<div className="text-sm">{people.fullName}</div>
|
||||
<div className="text-xs text-txt-tertiary">
|
||||
{people.primaryEmailAddress}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Td>
|
||||
<Td className="text-sm">{getRole(__, people.kind)}</Td>
|
||||
<Td className="text-sm">{people.position}</Td>
|
||||
{hasAnyAction && (
|
||||
<Td noLink width={50} className="text-end">
|
||||
<ActionDropdown>
|
||||
{isAuthorized("People", "deletePeople") && (
|
||||
<DropdownItem
|
||||
icon={IconTrashCan}
|
||||
variant="danger"
|
||||
onClick={deletePeople}
|
||||
>
|
||||
{__("Delete")}
|
||||
</DropdownItem>
|
||||
)}
|
||||
</ActionDropdown>
|
||||
</Td>
|
||||
)}
|
||||
</Tr>
|
||||
<Td className="text-sm">{getRole(__, people.kind)}</Td>
|
||||
<Td className="text-sm">{people.position}</Td>
|
||||
{hasAnyAction && (
|
||||
<Td noLink width={50} className="text-end">
|
||||
<ActionDropdown>
|
||||
{isAuthorized("People", "updatePeople") && (
|
||||
<DropdownItem
|
||||
icon={IconCalendar2}
|
||||
onClick={() => dialogRef.current?.open()}
|
||||
>
|
||||
{__("Set end of contract")}
|
||||
</DropdownItem>
|
||||
)}
|
||||
{isAuthorized("People", "deletePeople") && (
|
||||
<DropdownItem
|
||||
icon={IconTrashCan}
|
||||
variant="danger"
|
||||
onClick={deletePeople}
|
||||
>
|
||||
{__("Delete")}
|
||||
</DropdownItem>
|
||||
)}
|
||||
</ActionDropdown>
|
||||
</Td>
|
||||
)}
|
||||
</Tr>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogFooter,
|
||||
Field,
|
||||
Input,
|
||||
Spinner,
|
||||
useDialogRef,
|
||||
} from "@probo/ui";
|
||||
import { forwardRef, useImperativeHandle } from "react";
|
||||
import { z } from "zod";
|
||||
import { formatDatetime, toDateInput } from "@probo/helpers";
|
||||
import { useFormWithSchema } from "/hooks/useFormWithSchema";
|
||||
import { useMutationWithToasts } from "/hooks/useMutationWithToasts";
|
||||
import { updatePeopleMutation } from "/hooks/graph/PeopleGraph";
|
||||
|
||||
const schema = z.object({
|
||||
contractEndDate: z.string().optional(),
|
||||
});
|
||||
|
||||
export type SetEndOfContractDialogRef = {
|
||||
open: () => void;
|
||||
close: () => void;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
peopleId: string;
|
||||
currentContractEndDate?: string | null;
|
||||
};
|
||||
|
||||
export const SetEndOfContractDialog = forwardRef<SetEndOfContractDialogRef, Props>(function SetEndOfContractDialog(
|
||||
{
|
||||
peopleId,
|
||||
currentContractEndDate,
|
||||
},
|
||||
ref
|
||||
) {
|
||||
const { __ } = useTranslate();
|
||||
const dialogRef = useDialogRef();
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
open: () => dialogRef.current?.open(),
|
||||
close: () => dialogRef.current?.close(),
|
||||
}));
|
||||
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { isSubmitting },
|
||||
reset,
|
||||
} = useFormWithSchema(schema, {
|
||||
defaultValues: {
|
||||
contractEndDate: toDateInput(currentContractEndDate),
|
||||
},
|
||||
});
|
||||
|
||||
const [mutate] = useMutationWithToasts(updatePeopleMutation, {
|
||||
successMessage: __("End of contract updated successfully"),
|
||||
errorMessage: __("Failed to update end of contract"),
|
||||
});
|
||||
|
||||
const onSubmit = handleSubmit(async (data) => {
|
||||
await mutate({
|
||||
variables: {
|
||||
input: {
|
||||
id: peopleId,
|
||||
contractEndDate: formatDatetime(data.contractEndDate),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
dialogRef.current?.close();
|
||||
});
|
||||
|
||||
const handleClose = () => {
|
||||
reset();
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
title={__("Set End of Contract")}
|
||||
ref={dialogRef}
|
||||
className="max-w-lg"
|
||||
onClose={handleClose}
|
||||
>
|
||||
<form onSubmit={onSubmit}>
|
||||
<DialogContent padded className="space-y-4">
|
||||
<Field label={__("End of contract")}>
|
||||
<Input {...register("contractEndDate")} type="date" />
|
||||
</Field>
|
||||
</DialogContent>
|
||||
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="submit"
|
||||
disabled={isSubmitting}
|
||||
icon={isSubmitting ? Spinner : undefined}
|
||||
>
|
||||
{__("Update")}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</Dialog>
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user