Skip to content

Commit

Permalink
fix: add option to have switch field for connection form
Browse files Browse the repository at this point in the history
  • Loading branch information
mainawycliffe committed Oct 31, 2023
1 parent 39b0224 commit 651391b
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 81 deletions.
69 changes: 7 additions & 62 deletions src/components/Connections/ConnectionForm.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
import clsx from "clsx";
import { Form, Formik } from "formik";
import FormikTextInput from "../Forms/Formik/FormikTextInput";
import FormikCheckbox from "../Forms/Formik/FormikCheckbox";
import { mapValues, method } from "lodash";
import React, { useEffect, useState } from "react";
import { FaTrash } from "react-icons/fa";
import { Button } from "../Button";
import { Icon } from "../Icon";
import { Modal } from "../Modal";
import { useEffect, useState } from "react";
import RenderConnectionFormFields from "./RenderConnectionFormFields";
import {
ConnectionType,
ConnectionValueType,
Field,
connectionTypes
} from "./connectionTypes";
import { FormikEnvVarSource } from "../Forms/Formik/FormikEnvVarSource";
import { Icon } from "../Icon";
import React from "react";
import { FaTrash } from "react-icons/fa";
import { Button } from "../Button";
import { mapValues, method } from "lodash";

export type Connection = {
altID?: string;
Expand Down Expand Up @@ -119,55 +115,6 @@ export default function ConnectionForm({
} as Connection;
};

const getFieldView = (field: Field) => {
const type = field.type ?? "input";
switch (type) {
case "input":
return (
<FormikTextInput
name={field.key}
label={field.label}
required={field.required}
hint={field.hint}
defaultValue={field.default?.toString()}
/>
);
case "numberInput":
return (
<FormikTextInput
type="number"
name={field.key}
label={field.label}
required={field.required}
hint={field.hint}
defaultValue={field.default?.toString()}
/>
);
case "checkbox":
return (
<FormikCheckbox
name={field.key}
label={field.label}
labelClassName="text-sm font-semibold text-gray-700"
required={field.required}
hint={field.hint}
/>
);
case "EnvVarSource":
return (
<FormikEnvVarSource
name={field.key}
label={field.label}
variant={field.variant}
hint={field.hint}
required={field.required}
/>
);
default:
return null;
}
};

const getFormView = (connectionType: ConnectionType) => {
return (
<Formik
Expand Down Expand Up @@ -204,9 +151,7 @@ export default function ConnectionForm({
<div className="flex flex-col space-y-4 overflow-y-auto p-4">
{connectionType.fields.map((field, index) => {
return (
<React.Fragment key={index}>
{getFieldView(field)}
</React.Fragment>
<RenderConnectionFormFields field={field} key={field.key} />
);
})}
</div>
Expand Down
55 changes: 55 additions & 0 deletions src/components/Connections/FormikConnectionOptionsSwitchField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { useState } from "react";
import RenderConnectionFormFields from "./RenderConnectionFormFields";
import { ConnectionFormFields } from "./connectionTypes";
import { Switch } from "../Switch";
import { useFormikContext } from "formik";

type Props = {
field: ConnectionFormFields;
};

export default function FormikConnectionOptionsSwitchField({ field }: Props) {
const [selectedGroup, setSelectedGroup] = useState(field.default);

const { setFieldValue } = useFormikContext<Record<string, any>>();

if (!field.options) {
return null;
}

const selectedField = field.options.find(
(option) => option.key === selectedGroup
);

return (
<div className="flex flex-col gap-4 overflow-y-auto">
<label className="font-semibold text-sm">{field.label}</label>
<div className="flex flex-row">
<Switch
options={[...field.options?.map((option) => option.label)]}
defaultValue="None"
value={
field.options?.find((option) => option.key === selectedGroup)?.label
}
onChange={(v) => {
// reset all other fields that are not selected
field.options?.forEach((option) => {
if (option.key === v) {
return;
}
setFieldValue(option.key, undefined);
});
setSelectedGroup(
field.options?.find((option) => option.label === v)?.key
);
}}
/>
</div>
<div className="flex flex-col gap-4 overflow-y-auto px-4">
{selectedField?.fields?.map((field) => (
<RenderConnectionFormFields field={field} key={field.key} />
))}
</div>
</div>
);
}
60 changes: 60 additions & 0 deletions src/components/Connections/RenderConnectionFormFields.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import FormikConnectionOptionsSwitchField from "./FormikConnectionOptionsSwitchField";
import FormikCheckbox from "../Forms/Formik/FormikCheckbox";
import { FormikEnvVarSource } from "../Forms/Formik/FormikEnvVarSource";
import FormikTextInput from "../Forms/Formik/FormikTextInput";
import { ConnectionFormFields } from "./connectionTypes";

interface FieldViewProps {
field: ConnectionFormFields;
}

export default function RenderConnectionFormFields({ field }: FieldViewProps) {
const type = field.type ?? "input";
switch (type) {
case "input":
return (
<FormikTextInput
name={field.key}
label={field.label}
required={field.required}
hint={field.hint}
defaultValue={field.default?.toString()}
/>
);
case "numberInput":
return (
<FormikTextInput
type="number"
name={field.key}
label={field.label}
required={field.required}
hint={field.hint}
defaultValue={field.default?.toString()}
/>
);
case "checkbox":
return (
<FormikCheckbox
name={field.key}
label={field.label}
labelClassName="text-sm font-semibold text-gray-700"
required={field.required}
hint={field.hint}
/>
);
case "EnvVarSource":
return (
<FormikEnvVarSource
name={field.key}
label={field.label}
variant={field.variant}
hint={field.hint}
required={field.required}
/>
);
case "switch":
return <FormikConnectionOptionsSwitchField field={field} />;
default:
return null;
}
}
62 changes: 43 additions & 19 deletions src/components/Connections/connectionTypes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ const enum ConnectionsFieldTypes {
checkbox = "checkbox",
input = "input",
numberInput = "numberInput",
EnvVarSource = "EnvVarSource"
EnvVarSource = "EnvVarSource",
switch = "switch"
}

type Variant = "small" | "large";
Expand All @@ -17,14 +18,19 @@ const variants: { [key: string]: Variant } = {
large: "large"
};

export type Field = {
export type ConnectionFormFields = {
label: string;
key: string;
type: ConnectionsFieldTypes;
variant?: Variant;
required?: boolean;
hint?: string;
default?: boolean | number | string;
options?: {
label: string;
key: string;
fields: Omit<ConnectionFormFields, "options">[];
}[];
};

export const enum ConnectionValueType {
Expand Down Expand Up @@ -74,7 +80,7 @@ export type ConnectionType = {
title: string;
value: ConnectionValueType;
icon?: React.ReactNode | string | null;
fields: Field[];
fields: ConnectionFormFields[];
convertToFormSpecificValue?: (data: Record<string, string>) => Connection;
preSubmitConverter?: (data: Record<string, string>) => object;
hide?: boolean;
Expand Down Expand Up @@ -1826,22 +1832,40 @@ export const connectionTypes: ConnectionType[] = [
required: true
},
{
label: "Username",
key: "username",
type: ConnectionsFieldTypes.EnvVarSource,
variant: variants.large
},
{
label: "Password",
key: "password",
type: ConnectionsFieldTypes.EnvVarSource,
variant: variants.large
},
{
label: "SSH Key",
key: "certificate",
type: ConnectionsFieldTypes.EnvVarSource,
variant: variants.large
label: "Authentication",
key: "authentication",
type: ConnectionsFieldTypes.switch,
default: "certificate",
options: [
{
label: "SSH Key",
key: "certificate",
fields: [
{
label: "SSH Key",
key: "certificate",
type: ConnectionsFieldTypes.EnvVarSource,
variant: variants.large
}
]
},
{
label: "Password",
key: "password",
fields: [
{
label: "Username",
key: "username",
type: ConnectionsFieldTypes.EnvVarSource
},
{
label: "Password",
key: "password",
type: ConnectionsFieldTypes.EnvVarSource
}
]
}
]
},
{
label: "Ref",
Expand Down

0 comments on commit 651391b

Please sign in to comment.