瀏覽代碼

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

Nicolas Meienberger 2 年之前
父節點
當前提交
ea7ad75e18

+ 1 - 0
src/client/mocks/fixtures/app.fixtures.ts

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

+ 19 - 6
src/client/modules/Apps/components/InstallForm/InstallForm.test.tsx

@@ -1,12 +1,13 @@
 import React from 'react';
 import React from 'react';
 import { faker } from '@faker-js/faker';
 import { faker } from '@faker-js/faker';
+import { fromPartial } from '@total-typescript/shoehorn';
 import { fireEvent, render, screen, waitFor } from '../../../../../../tests/test-utils';
 import { fireEvent, render, screen, waitFor } from '../../../../../../tests/test-utils';
 import { FormField } from '../../../../core/types';
 import { FormField } from '../../../../core/types';
 import { InstallForm } from './InstallForm';
 import { InstallForm } from './InstallForm';
 
 
 describe('Test: InstallForm', () => {
 describe('Test: InstallForm', () => {
   it('should render the form', () => {
   it('should render the form', () => {
-    render(<InstallForm formFields={[]} onSubmit={jest.fn} />);
+    render(<InstallForm formFields={[]} onSubmit={jest.fn} info={fromPartial({})} />);
 
 
     expect(screen.getByText('Install')).toBeInTheDocument();
     expect(screen.getByText('Install')).toBeInTheDocument();
   });
   });
@@ -20,7 +21,7 @@ describe('Test: InstallForm', () => {
       { env_variable: 'test5', label: 'test5', type: 'number', required: false },
       { 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('test')).toBeInTheDocument();
     expect(screen.getByLabelText('test2')).toBeInTheDocument();
     expect(screen.getByLabelText('test2')).toBeInTheDocument();
@@ -34,7 +35,7 @@ describe('Test: InstallForm', () => {
 
 
     const onSubmit = jest.fn();
     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' } });
     fireEvent.change(screen.getByLabelText('test-field'), { target: { value: 'test' } });
     screen.getByText('Install').click();
     screen.getByText('Install').click();
@@ -63,7 +64,7 @@ describe('Test: InstallForm', () => {
 
 
     const onSubmit = jest.fn();
     const onSubmit = jest.fn();
 
 
-    render(<InstallForm formFields={formFields} onSubmit={onSubmit} />);
+    render(<InstallForm info={fromPartial({})} formFields={formFields} onSubmit={onSubmit} />);
 
 
     screen.getByText('Install').click();
     screen.getByText('Install').click();
 
 
@@ -93,7 +94,7 @@ describe('Test: InstallForm', () => {
 
 
     const onSubmit = jest.fn();
     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('textbox', { name: 'test-env' })).toHaveValue('test');
     expect(screen.getByRole('combobox', { name: 'test-select' })).toHaveTextContent('Should appear');
     expect(screen.getByRole('combobox', { name: 'test-select' })).toHaveTextContent('Should appear');
@@ -105,8 +106,20 @@ describe('Test: InstallForm', () => {
 
 
     const onSubmit = jest.fn();
     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();
     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();
+  });
 });
 });

+ 13 - 5
src/client/modules/Apps/components/InstallForm/InstallForm.tsx

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

+ 1 - 1
src/client/modules/Apps/components/InstallModal/InstallModal.tsx

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

+ 1 - 1
src/client/modules/Apps/components/UpdateSettingsModal.tsx

@@ -21,7 +21,7 @@ export const UpdateSettingsModal: React.FC<IProps> = ({ info, config, isOpen, on
         <h5 className="modal-title">Update {info.name} config</h5>
         <h5 className="modal-title">Update {info.name} config</h5>
       </DialogHeader>
       </DialogHeader>
       <DialogDescription>
       <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>
       </DialogDescription>
     </DialogContent>
     </DialogContent>
   </Dialog>
   </Dialog>