Create separate form for adding environment variables

This commit is contained in:
Isha Venikar 2024-10-16 23:00:07 +05:30 committed by IshaVenikar
parent 5aefda1248
commit 39db87633a
2 changed files with 105 additions and 112 deletions

View File

@ -1,22 +1,19 @@
import { useCallback, useEffect, useMemo, useState } from 'react'; import { useCallback, useEffect, useState } from 'react';
import { useFieldArray, useForm } from 'react-hook-form';
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import { Collapse, Checkbox } from '@snowballtools/material-tailwind-react-fork'; import { Collapse } from '@snowballtools/material-tailwind-react-fork';
import AddEnvironmentVariableRow from 'components/projects/project/settings/AddEnvironmentVariableRow';
import DisplayEnvironmentVariables from 'components/projects/project/settings/DisplayEnvironmentVariables'; import DisplayEnvironmentVariables from 'components/projects/project/settings/DisplayEnvironmentVariables';
import { useGQLClient } from 'context/GQLClientContext'; import { useGQLClient } from 'context/GQLClientContext';
import { EnvironmentVariablesFormValues } from '../../../../../types'; import { EnvironmentVariablesFormValues } from '../../../../../types';
import HorizontalLine from 'components/HorizontalLine'; import HorizontalLine from 'components/HorizontalLine';
import { Heading } from 'components/shared/Heading'; import { Heading } from 'components/shared/Heading';
import { Button } from 'components/shared/Button';
// import { Checkbox } from 'components/shared/Checkbox'; // import { Checkbox } from 'components/shared/Checkbox';
import { PlusIcon } from 'components/shared/CustomIcon'; import { PlusIcon } from 'components/shared/CustomIcon';
import { InlineNotification } from 'components/shared/InlineNotification';
import { ProjectSettingContainer } from 'components/projects/project/settings/ProjectSettingContainer'; import { ProjectSettingContainer } from 'components/projects/project/settings/ProjectSettingContainer';
import { useToast } from 'components/shared/Toast'; import { useToast } from 'components/shared/Toast';
import { Environment, EnvironmentVariable } from 'gql-client'; import { Environment, EnvironmentVariable } from 'gql-client';
import EnvironmentVariablesForm from './EnvironmentVariablesForm';
export const EnvironmentVariablesTabPanel = () => { export const EnvironmentVariablesTabPanel = () => {
const { id } = useParams(); const { id } = useParams();
@ -27,38 +24,8 @@ export const EnvironmentVariablesTabPanel = () => {
EnvironmentVariable[] EnvironmentVariable[]
>([]); >([]);
const {
handleSubmit,
register,
control,
reset,
formState: { isSubmitSuccessful, errors },
} = useForm<EnvironmentVariablesFormValues>({
defaultValues: {
variables: [{ key: '', value: '' }],
environment: {
development: false,
preview: false,
production: false,
},
},
});
const [createNewVariable, setCreateNewVariable] = useState(false); const [createNewVariable, setCreateNewVariable] = useState(false);
const { fields, append, remove } = useFieldArray({
name: 'variables',
control,
rules: {
required: 'Add at least 1 environment variables',
},
});
useEffect(() => {
if (isSubmitSuccessful) {
reset();
}
}, [isSubmitSuccessful, reset, id]);
const getEnvironmentVariables = useCallback( const getEnvironmentVariables = useCallback(
(environment: Environment) => { (environment: Environment) => {
return environmentVariables.filter( return environmentVariables.filter(
@ -68,21 +35,6 @@ export const EnvironmentVariablesTabPanel = () => {
[environmentVariables, id], [environmentVariables, id],
); );
const isFieldEmpty = useMemo(() => {
if (errors.variables) {
return fields.some((_, index) => {
if (
errors.variables![index]?.value?.type === 'required' ||
errors.variables![index]?.key?.type === 'required'
) {
return true;
}
});
}
return false;
}, [fields, errors.variables, id]);
const fetchEnvironmentVariables = useCallback( const fetchEnvironmentVariables = useCallback(
async (id: string | undefined) => { async (id: string | undefined) => {
if (id) { if (id) {
@ -99,7 +51,7 @@ export const EnvironmentVariablesTabPanel = () => {
}, [id]); }, [id]);
const createEnvironmentVariablesHandler = useCallback( const createEnvironmentVariablesHandler = useCallback(
async (createFormData: EnvironmentVariablesFormValues) => { async (createFormData: EnvironmentVariablesFormValues, reset: () => void) => {
const environmentVariables = createFormData.variables.map((variable) => { const environmentVariables = createFormData.variables.map((variable) => {
return { return {
key: variable.key, key: variable.key,
@ -160,66 +112,9 @@ export const EnvironmentVariablesTabPanel = () => {
</Heading> </Heading>
<Collapse open={createNewVariable}> <Collapse open={createNewVariable}>
<div className="p-4 bg-slate-100"> <div className="p-4 bg-slate-100">
<form onSubmit={handleSubmit(createEnvironmentVariablesHandler)}> <EnvironmentVariablesForm
{fields.map((field, index) => { onSubmit={(data, reset) => createEnvironmentVariablesHandler(data, reset)} />
return ( </div>
<AddEnvironmentVariableRow
key={field.id}
index={index}
register={register}
onDelete={() => remove(index)}
isDeleteDisabled={fields.length === 1}
/>
);
})}
<div className="flex gap-1 p-2">
<Button
size="md"
onClick={() =>
append({
key: '',
value: '',
})
}
>
+ Add variable
</Button>
{/* TODO: Implement import environment varible functionality */}
<Button size="md" disabled>
Import .env
</Button>
</div>
{isFieldEmpty && (
<InlineNotification
title="Please ensure no fields are empty before saving."
variant="danger"
size="md"
/>
)}
<div className="flex gap-2 p-2">
<Checkbox
label="Production"
{...register(`environment.production`)}
color="blue"
/>
<Checkbox
label="Preview"
{...register(`environment.preview`)}
color="blue"
/>
<Checkbox
label="Development"
{...register(`environment.development`)}
color="blue"
/>
</div>
<div className="p-2">
<Button size="md" type="submit">
Save changes
</Button>
</div>
</form>
</div>
</Collapse> </Collapse>
</div> </div>
<div className="p-2"> <div className="p-2">

View File

@ -0,0 +1,98 @@
import React, { useEffect, useMemo } from 'react';
import { useForm, useFieldArray } from 'react-hook-form';
import { Checkbox } from '@snowballtools/material-tailwind-react-fork';
import { Button } from 'components/shared/Button';
import { InlineNotification } from 'components/shared/InlineNotification';
import AddEnvironmentVariableRow from 'components/projects/project/settings/AddEnvironmentVariableRow';
import { EnvironmentVariablesFormValues } from 'types/types';
interface EnvironmentVariablesFormProps {
onSubmit: (data: EnvironmentVariablesFormValues, reset: () => void) => void;
}
const EnvironmentVariablesForm: React.FC<EnvironmentVariablesFormProps> = ({ onSubmit }) => {
const {
handleSubmit,
register,
control,
reset,
formState: { isSubmitSuccessful, errors },
} = useForm<EnvironmentVariablesFormValues>({
defaultValues: {
variables: [{ key: '', value: '' }],
environment: {
development: false,
preview: false,
production: false,
},
},
});
const { fields, append, remove } = useFieldArray({
name: 'variables',
control,
rules: {
required: 'Add at least 1 environment variables',
},
});
useEffect(() => {
if (isSubmitSuccessful) {
reset();
}
}, [isSubmitSuccessful, reset]);
const isFieldEmpty = useMemo(() => {
if (errors.variables) {
return fields.some((_, index) => {
if (
errors.variables![index]?.value?.type === 'required' ||
errors.variables![index]?.key?.type === 'required'
) {
return true;
}
});
}
return false;
}, [fields, errors.variables]);
return (
<form onSubmit={handleSubmit((data) => onSubmit(data, reset))}>
{fields.map((field, index) => (
<AddEnvironmentVariableRow
key={field.id}
index={index}
register={register}
onDelete={() => remove(index)}
isDeleteDisabled={fields.length === 1}
/>
))}
<div className="flex gap-1 p-2">
<Button size="md" onClick={() => append({ key: '', value: '' })}>
+ Add variable
</Button>
</div>
{isFieldEmpty && (
<InlineNotification
title="Please ensure no fields are empty before saving."
variant="danger"
/>
)}
<div className="flex gap-2 p-2">
<Checkbox label="Production" {...register('environment.production')} />
<Checkbox label="Preview" {...register('environment.preview')} />
<Checkbox label="Development" {...register('environment.development')} />
</div>
<div className="p-2">
<Button size="md" type="submit">
Save changes
</Button>
</div>
</form>
);
};
export default EnvironmentVariablesForm;