feat(client): make force_exposed react accordingly in install form

This commit is contained in:
Nicolas Meienberger 2023-04-17 09:53:03 +02:00 committed by Nicolas Meienberger
parent 0e81ced999
commit ea7ad75e18
5 changed files with 35 additions and 13 deletions

View file

@ -27,6 +27,7 @@ export const createApp = (overrides?: Partial<AppInfo>): AppInfo => {
no_gui: false,
exposable: true,
url_suffix: '',
force_expose: false,
...overrides,
};
};

View file

@ -1,12 +1,13 @@
import React from 'react';
import { faker } from '@faker-js/faker';
import { fromPartial } from '@total-typescript/shoehorn';
import { fireEvent, render, screen, waitFor } from '../../../../../../tests/test-utils';
import { FormField } from '../../../../core/types';
import { InstallForm } from './InstallForm';
describe('Test: InstallForm', () => {
it('should render the form', () => {
render(<InstallForm formFields={[]} onSubmit={jest.fn} />);
render(<InstallForm formFields={[]} onSubmit={jest.fn} info={fromPartial({})} />);
expect(screen.getByText('Install')).toBeInTheDocument();
});
@ -20,7 +21,7 @@ describe('Test: InstallForm', () => {
{ env_variable: 'test5', label: 'test5', type: 'number', required: false },
];
render(<InstallForm formFields={formFields} onSubmit={jest.fn} />);
render(<InstallForm info={fromPartial({})} formFields={formFields} onSubmit={jest.fn} />);
expect(screen.getByLabelText('test')).toBeInTheDocument();
expect(screen.getByLabelText('test2')).toBeInTheDocument();
@ -34,7 +35,7 @@ describe('Test: InstallForm', () => {
const onSubmit = jest.fn();
render(<InstallForm formFields={formFields} onSubmit={onSubmit} />);
render(<InstallForm info={fromPartial({})} formFields={formFields} onSubmit={onSubmit} />);
fireEvent.change(screen.getByLabelText('test-field'), { target: { value: 'test' } });
screen.getByText('Install').click();
@ -63,7 +64,7 @@ describe('Test: InstallForm', () => {
const onSubmit = jest.fn();
render(<InstallForm formFields={formFields} onSubmit={onSubmit} />);
render(<InstallForm info={fromPartial({})} formFields={formFields} onSubmit={onSubmit} />);
screen.getByText('Install').click();
@ -93,7 +94,7 @@ describe('Test: InstallForm', () => {
const onSubmit = jest.fn();
render(<InstallForm formFields={formFields} onSubmit={onSubmit} initalValues={{ 'test-env': 'test', 'test-select': selectValue, 'test-boolean': true }} />);
render(<InstallForm info={fromPartial({})} formFields={formFields} onSubmit={onSubmit} initalValues={{ 'test-env': 'test', 'test-select': selectValue, 'test-boolean': true }} />);
expect(screen.getByRole('textbox', { name: 'test-env' })).toHaveValue('test');
expect(screen.getByRole('combobox', { name: 'test-select' })).toHaveTextContent('Should appear');
@ -105,8 +106,20 @@ describe('Test: InstallForm', () => {
const onSubmit = jest.fn();
render(<InstallForm formFields={formFields} onSubmit={onSubmit} exposable />);
render(<InstallForm formFields={formFields} onSubmit={onSubmit} info={fromPartial({ exposable: true })} />);
expect(screen.getByLabelText('Expose app')).toBeInTheDocument();
});
it('should render the domain form and disable the expose switch when info has force_expose set to true', () => {
const formFields: FormField[] = [{ env_variable: 'test-env', label: 'test-field', type: 'text', required: true }];
const onSubmit = jest.fn();
render(<InstallForm formFields={formFields} onSubmit={onSubmit} info={fromPartial({ force_expose: true, exposable: true })} />);
expect(screen.getByRole('switch')).toBeDisabled();
expect(screen.getByRole('switch')).toBeChecked();
expect(screen.getByRole('textbox', { name: 'domain' })).toBeInTheDocument();
});
});

View file

@ -8,14 +8,14 @@ import { Button } from '../../../../components/ui/Button';
import { Switch } from '../../../../components/ui/Switch';
import { Input } from '../../../../components/ui/Input';
import { validateAppConfig } from '../../utils/validators';
import { type FormField } from '../../../../core/types';
import { type FormField, type AppInfo } from '../../../../core/types';
interface IProps {
formFields: FormField[];
onSubmit: (values: FormValues) => void;
initalValues?: { exposed?: boolean; domain?: string } & { [key: string]: string | boolean | undefined };
info: AppInfo;
loading?: boolean;
exposable?: boolean | null;
}
export type FormValues = {
@ -27,7 +27,7 @@ export type FormValues = {
const hiddenTypes = ['random'];
const typeFilter = (field: FormField) => !hiddenTypes.includes(field.type);
export const InstallForm: React.FC<IProps> = ({ formFields, onSubmit, initalValues, exposable, loading }) => {
export const InstallForm: React.FC<IProps> = ({ formFields, info, onSubmit, initalValues, loading }) => {
const {
register,
handleSubmit,
@ -39,6 +39,12 @@ export const InstallForm: React.FC<IProps> = ({ formFields, onSubmit, initalValu
} = useForm<FormValues>({});
const watchExposed = watch('exposed', false);
useEffect(() => {
if (info.force_expose) {
setValue('exposed', true);
}
}, [info.force_expose, setValue]);
useEffect(() => {
if (initalValues && !isDirty) {
Object.entries(initalValues).forEach(([key, value]) => {
@ -105,7 +111,9 @@ export const InstallForm: React.FC<IProps> = ({ formFields, onSubmit, initalValu
control={control}
name="exposed"
defaultValue={false}
render={({ field: { onChange, value, ref, ...props } }) => <Switch className="mb-3" ref={ref} checked={value} onCheckedChange={onChange} {...props} label="Expose app" />}
render={({ field: { onChange, value, ref, ...props } }) => (
<Switch className="mb-3" disabled={info.force_expose} ref={ref} checked={value} onCheckedChange={onChange} {...props} label="Expose app" />
)}
/>
{watchExposed && (
<div className="mb-3">
@ -135,7 +143,7 @@ export const InstallForm: React.FC<IProps> = ({ formFields, onSubmit, initalValu
return (
<form className="flex flex-col" onSubmit={handleSubmit(validate)}>
{formFields.filter(typeFilter).map(renderField)}
{exposable && renderExposeForm()}
{info.exposable && renderExposeForm()}
<Button loading={loading} type="submit" className="btn-success">
{initalValues ? 'Update' : 'Install'}
</Button>

View file

@ -18,7 +18,7 @@ export const InstallModal: React.FC<IProps> = ({ info, isOpen, onClose, onSubmit
<h5 className="modal-title">Install {info.name}</h5>
</DialogHeader>
<DialogDescription>
<InstallForm onSubmit={onSubmit} formFields={info.form_fields} exposable={info.exposable} />
<InstallForm onSubmit={onSubmit} formFields={info.form_fields} info={info} />
</DialogDescription>
</DialogContent>
</Dialog>

View file

@ -21,7 +21,7 @@ export const UpdateSettingsModal: React.FC<IProps> = ({ info, config, isOpen, on
<h5 className="modal-title">Update {info.name} config</h5>
</DialogHeader>
<DialogDescription>
<InstallForm onSubmit={onSubmit} formFields={info.form_fields} exposable={info.exposable} initalValues={{ ...config, exposed, domain }} />
<InstallForm onSubmit={onSubmit} formFields={info.form_fields} info={info} initalValues={{ ...config, exposed, domain }} />
</DialogDescription>
</DialogContent>
</Dialog>