vorteil/direktiv

View on GitHub
ui/src/pages/namespace/Explorer/Endpoint/EndpointEditor/Form/plugins/Auth/index.tsx

Summary

Maintainability
F
4 days
Test Coverage
import { Dialog, DialogTrigger } from "~/design/Dialog";
import { FC, useState } from "react";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "~/design/Select";
import { Table, TableBody, TableCell, TableRow } from "~/design/Table";
import { UseFormReturn, useFieldArray } from "react-hook-form";
import {
  WebhookAuthFormSchemaType,
  webhookAuthPluginNames,
} from "../../../schema/plugins/auth/webhookAuth";
import {
  authPluginTypes,
  availablePlugins,
} from "../../../schema/plugins/auth";
import {
  getBasicAuthConfigAtIndex,
  getKeyAuthConfigAtIndex,
  getWebhookAuthConfigAtIndex,
} from "../utils";

import { AuthPluginFormSchemaType } from "../../../schema/plugins/auth/schema";
import { BasicAuthForm } from "./BasicAuthForm";
import { BasicAuthFormSchemaType } from "../../../schema/plugins/auth/basicAuth";
import Button from "~/design/Button";
import { Card } from "~/design/Card";
import { EndpointFormSchemaType } from "../../../schema";
import { KeyAuthForm } from "./KeyAuthForm";
import { KeyAuthFormSchemaType } from "../../../schema/plugins/auth/keyAuth";
import { ListContextMenu } from "~/components/ListContextMenu";
import { ModalWrapper } from "~/components/ModalWrapper";
import { PluginSelector } from "../components/PluginSelector";
import { Plus } from "lucide-react";
import { TableHeader } from "../components/PluginsTable";
import { WebhookAuthForm } from "./WebhookAuthForm";
import { useTranslation } from "react-i18next";

type AuthPluginFormProps = {
  formControls: UseFormReturn<EndpointFormSchemaType>;
  onSave: (value: EndpointFormSchemaType) => void;
};

export const AuthPluginForm: FC<AuthPluginFormProps> = ({
  formControls,
  onSave,
}) => {
  const { t } = useTranslation();
  const { control, handleSubmit: handleParentSubmit } = formControls;
  const {
    append: addPlugin,
    remove: deletePlugin,
    move: movePlugin,
    update: editPlugin,
    fields,
  } = useFieldArray({
    control,
    name: "plugins.auth",
  });
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editIndex, setEditIndex] = useState<number>();

  const [selectedPlugin, setSelectedPlugin] =
    useState<AuthPluginFormSchemaType["type"]>();

  const pluginsCount = fields.length;
  const formId = "authPluginForm";

  type PluginConfigSchema =
    | BasicAuthFormSchemaType
    | KeyAuthFormSchemaType
    | WebhookAuthFormSchemaType;

  const handleSubmit = (configuration: PluginConfigSchema) => {
    setDialogOpen(false);
    if (editIndex === undefined) {
      addPlugin(configuration);
    } else {
      editPlugin(editIndex, configuration);
    }
    handleParentSubmit(onSave)();
    setEditIndex(undefined);
  };

  return (
    <Dialog
      open={dialogOpen}
      onOpenChange={(isOpen) => {
        if (isOpen === false) setEditIndex(undefined);
        setDialogOpen(isOpen);
      }}
    >
      <Card noShadow>
        <Table>
          <TableHeader
            title={t(
              "pages.explorer.endpoint.editor.form.plugins.auth.table.headline",
              {
                count: pluginsCount,
              }
            )}
          >
            <DialogTrigger asChild>
              <Button icon variant="outline" size="sm">
                <Plus />
                {t(
                  "pages.explorer.endpoint.editor.form.plugins.auth.table.addButton"
                )}
              </Button>
            </DialogTrigger>
          </TableHeader>
          <TableBody>
            {fields.map(({ id, type }, index, srcArray) => {
              const canMoveDown = index < srcArray.length - 1;
              const canMoveUp = index > 0;
              const onMoveUp = canMoveUp
                ? () => {
                    movePlugin(index, index - 1);
                  }
                : undefined;
              const onMoveDown = canMoveDown
                ? () => {
                    movePlugin(index, index + 1);
                  }
                : undefined;
              const onDelete = () => {
                deletePlugin(index);
              };

              return (
                <TableRow
                  key={id}
                  className="cursor-pointer"
                  onClick={() => {
                    setSelectedPlugin(type);
                    setDialogOpen(true);
                    setEditIndex(index);
                  }}
                >
                  <TableCell>
                    {t(
                      `pages.explorer.endpoint.editor.form.plugins.auth.types.${type}`
                    )}
                  </TableCell>
                  <TableCell className="text-right">
                    <ListContextMenu
                      onDelete={onDelete}
                      onMoveDown={onMoveDown}
                      onMoveUp={onMoveUp}
                    />
                  </TableCell>
                </TableRow>
              );
            })}
          </TableBody>
        </Table>
      </Card>

      <ModalWrapper
        formId={formId}
        showSaveBtn={!!selectedPlugin}
        title={
          editIndex === undefined
            ? t(
                "pages.explorer.endpoint.editor.form.plugins.auth.modal.headlineAdd"
              )
            : t(
                "pages.explorer.endpoint.editor.form.plugins.auth.modal.headlineEdit"
              )
        }
        onCancel={() => {
          setDialogOpen(false);
        }}
      >
        <PluginSelector
          title={t(
            "pages.explorer.endpoint.editor.form.plugins.auth.modal.label"
          )}
        >
          <Select
            onValueChange={(e) => {
              setSelectedPlugin(e as typeof selectedPlugin);
            }}
            value={selectedPlugin}
          >
            <SelectTrigger variant="outline" className="grow">
              <SelectValue
                placeholder={t(
                  "pages.explorer.endpoint.editor.form.plugins.auth.modal.placeholder"
                )}
              />
            </SelectTrigger>
            <SelectContent>
              {availablePlugins.map(({ name: pluginName }) => (
                <SelectItem key={pluginName} value={pluginName}>
                  {t(
                    `pages.explorer.endpoint.editor.form.plugins.auth.types.${pluginName}`
                  )}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </PluginSelector>
        {selectedPlugin === authPluginTypes.basicAuth.name && (
          <BasicAuthForm
            formId={formId}
            defaultConfig={getBasicAuthConfigAtIndex(fields, editIndex)}
            onSubmit={handleSubmit}
          />
        )}
        {selectedPlugin === authPluginTypes.keyAuth.name && (
          <KeyAuthForm
            formId={formId}
            defaultConfig={getKeyAuthConfigAtIndex(fields, editIndex)}
            onSubmit={handleSubmit}
          />
        )}
        {webhookAuthPluginNames.map(
          (name) =>
            selectedPlugin === name && (
              <WebhookAuthForm
                key={name}
                type={name}
                formId={formId}
                defaultConfig={getWebhookAuthConfigAtIndex(
                  name,
                  fields,
                  editIndex
                )}
                onSubmit={handleSubmit}
              />
            )
        )}
      </ModalWrapper>
    </Dialog>
  );
};