vorteil/direktiv

View on GitHub
ui/src/pages/namespace/Permissions/Tokens/Create/index.tsx

Summary

Maintainability
A
40 mins
Test Coverage
import {
  DialogClose,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "~/design/Dialog";
import { Diamond, PlusCircle } from "lucide-react";
import { SubmitHandler, useForm } from "react-hook-form";
import {
  TokenFormSchema,
  TokenFormSchemaType,
} from "~/api/enterprise/tokens/schema";

import Button from "~/design/Button";
import DurationHint from "../../components/DurationHint";
import FormErrors from "~/components/FormErrors";
import Input from "~/design/Input";
import { InputWithButton } from "~/design/InputWithButton";
import PermissionsSelector from "../../components/PermisionsSelector";
import ShowToken from "./ShowToken";
import { useCreateToken } from "~/api/enterprise/tokens/mutate/create";
import { usePermissionKeys } from "~/api/enterprise/permissions/query/get";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { zodResolver } from "@hookform/resolvers/zod";

const CreateToken = ({ close }: { close: () => void }) => {
  const { t } = useTranslation();
  const { data: availablePermissions } = usePermissionKeys();
  const { mutate: createToken, isPending } = useCreateToken({
    onSuccess: (data) => {
      setCreatedToken(data.token);
    },
  });

  const {
    register,
    setValue,
    handleSubmit,
    watch,
    formState: { isDirty, errors, isValid, isSubmitted },
  } = useForm<TokenFormSchemaType>({
    defaultValues: {
      description: "",
      duration: "",
      permissions: [],
    },
    resolver: zodResolver(TokenFormSchema),
  });

  const [createdToken, setCreatedToken] = useState<string>();

  const onSubmit: SubmitHandler<TokenFormSchemaType> = (params) => {
    createToken(params);
  };

  // you can not submit if the form has not changed or if there are any errors and
  // you have already submitted the form (errors will first show up after submit)
  const disableSubmit = !isDirty || (isSubmitted && !isValid);

  const formId = `new-token`;

  return (
    <>
      {createdToken ? (
        <ShowToken token={createdToken} onCloseClicked={close} />
      ) : (
        <>
          <DialogHeader>
            <DialogTitle>
              <Diamond /> {t("pages.permissions.tokens.create.title")}
            </DialogTitle>
          </DialogHeader>
          <div className="my-3">
            <FormErrors errors={errors} className="mb-5" />
            <form
              id={formId}
              onSubmit={handleSubmit(onSubmit)}
              className="flex flex-col space-y-5"
            >
              <fieldset className="flex items-center gap-5">
                <label
                  className="w-[90px] text-right text-[14px]"
                  htmlFor="description"
                >
                  {t("pages.permissions.tokens.create.description.label")}
                </label>
                <Input
                  id="description"
                  placeholder={t(
                    "pages.permissions.tokens.create.description.placeholder"
                  )}
                  autoComplete="off"
                  {...register("description")}
                />
              </fieldset>
              <fieldset className="flex items-center gap-5">
                <label
                  className="w-[90px] text-right text-[14px]"
                  htmlFor="duration"
                >
                  {t("pages.permissions.tokens.create.duration.label")}
                </label>

                <InputWithButton>
                  <Input
                    id="duration"
                    placeholder={t(
                      "pages.permissions.tokens.create.duration.placeholder"
                    )}
                    {...register("duration")}
                  />
                  <DurationHint
                    onDurationSelect={(duration) => {
                      setValue("duration", duration, {
                        shouldDirty: true,
                        shouldTouch: true,
                        shouldValidate: true,
                      });
                    }}
                  />
                </InputWithButton>
              </fieldset>
              <PermissionsSelector
                availablePermissions={availablePermissions ?? []}
                selectedPermissions={watch("permissions")}
                setPermissions={(permissions) =>
                  setValue("permissions", permissions, {
                    shouldDirty: true,
                    shouldTouch: true,
                    shouldValidate: true,
                  })
                }
              />
            </form>
          </div>
          <DialogFooter>
            <DialogClose asChild>
              <Button variant="ghost">
                {t("pages.permissions.tokens.create.cancelBtn")}
              </Button>
            </DialogClose>
            <Button
              type="submit"
              disabled={disableSubmit}
              loading={isPending}
              form={formId}
            >
              {!isPending && <PlusCircle />}
              {t("pages.permissions.tokens.create.createBtn")}
            </Button>
          </DialogFooter>
        </>
      )}
    </>
  );
};

export default CreateToken;