diff --git a/client/src/components/InputsModal/Auth/InputAccess.tsx b/client/src/components/InputsModal/Auth/InputAccess.tsx deleted file mode 100644 index 9616bfc4d..000000000 --- a/client/src/components/InputsModal/Auth/InputAccess.tsx +++ /dev/null @@ -1,153 +0,0 @@ -import React, { FC, useEffect } from 'react'; -import { Card, CardContent, InputLabel, List, ListItem } from '@mui/material'; -import Markdown from 'react-markdown'; -import remarkGfm from 'remark-gfm'; -import { Auth, TestInput } from '~/models/testSuiteModels'; -import { AuthType, getAccessFields } from '~/components/InputsModal/Auth/AuthSettings'; -import AuthTypeSelector from '~/components/InputsModal/Auth/AuthTypeSelector'; -import FieldLabel from '~/components/InputsModal/FieldLabel'; -import InputFields from '~/components/InputsModal/InputFields'; -import useStyles from '../styles'; - -export interface InputAccessProps { - input: TestInput; - index: number; - inputsMap: Map; - setInputsMap: (map: Map, edited?: boolean) => void; -} - -const InputAccess: FC = ({ input, index, inputsMap, setInputsMap }) => { - const { classes } = useStyles(); - const [accessValues, setAccessValues] = React.useState>(new Map()); - const [accessValuesPopulated, setAccessValuesPopulated] = React.useState(false); - - // Default auth type settings - const authComponent = input.options?.components?.find( - (component) => component.name === 'auth_type', - ); - - const firstListOption = - authComponent?.options?.list_options && authComponent?.options?.list_options?.length > 0 - ? authComponent?.options?.list_options[0].value - : undefined; - - const [authType, setAuthType] = React.useState( - (authComponent?.default || firstListOption || 'public') as string, - ); - - const [accessFields, setAccessFields] = React.useState( - getAccessFields(authType as AuthType, accessValues, input.options?.components || []), - ); - - useEffect(() => { - // Set defaults on radio buttons - // This is necessary because radio buttons with no preset defaults will still cause - // missing input errors - setAccessFields( - accessFields.map((field) => { - if ( - field.type === 'radio' && - !field.default && - !field.value && - field.options?.list_options - ) { - field.default = field.options?.list_options[0].value; - } - return field; - }), - ); - - const combinedStartingValues = getStartingValues(); - - // Populate accessValues on mount - accessValues.set('auth_type', authType); - accessFields.forEach((field: TestInput) => { - accessValues.set(field.name, combinedStartingValues[field.name as keyof Auth] || ''); - }); - setAccessValuesPopulated(true); - - // Trigger change on mount for default values - const accessValuesCopy = new Map(accessValues); - setAccessValues(accessValuesCopy); - }, []); - - useEffect(() => { - // Recalculate hidden fields - setAccessFields( - getAccessFields(authType as AuthType, accessValues, input.options?.components || []), - ); - - // Update inputsMap while maintaining hidden values - if (accessValuesPopulated) { - const combinedStartingValues = getStartingValues(); - const accessValuesObject = Object.fromEntries(accessValues) as Auth; - const combinedValues = { ...combinedStartingValues, ...accessValuesObject }; - const stringifiedAccessValues = JSON.stringify(combinedValues); - inputsMap.set(input.name, stringifiedAccessValues); - setInputsMap(new Map(inputsMap)); - } - }, [accessValues]); - - const getStartingValues = () => { - // Pre-populate values from AuthFields, input, and inputsMap in order of precedence - const fieldDefaultValues = accessFields.reduce( - (acc, field) => ({ ...acc, [field.name]: field.default }), - {}, - ) as Auth; - const inputDefaultValues = - input.default && typeof input.default === 'string' ? (JSON.parse(input.default) as Auth) : {}; - const inputStartingValues = - input.value && typeof input.value === 'string' ? (JSON.parse(input.value) as Auth) : {}; - const inputsMapValues = inputsMap.get(input.name) - ? (JSON.parse(inputsMap.get(input.name) as string) as Auth) - : {}; - return { - ...fieldDefaultValues, - ...inputDefaultValues, - ...inputStartingValues, - ...inputsMapValues, - } as Auth; - }; - - const updateAuthType = (map: Map) => { - setAuthType(map.get('auth_type') as string); - setAccessValues(map); - }; - - return ( - - - - - - - {input.description && ( - - {input.description} - - )} - - - - - - - - ); -}; - -export default InputAccess; diff --git a/client/src/components/InputsModal/Auth/InputAuth.tsx b/client/src/components/InputsModal/Auth/InputAuth.tsx index 272225191..916ebfa91 100644 --- a/client/src/components/InputsModal/Auth/InputAuth.tsx +++ b/client/src/components/InputsModal/Auth/InputAuth.tsx @@ -3,20 +3,25 @@ import { Card, CardContent, InputLabel, List, ListItem } from '@mui/material'; import Markdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import { Auth, TestInput } from '~/models/testSuiteModels'; -import { AuthType, getAuthFields } from '~/components/InputsModal/Auth/AuthSettings'; +import { + AuthType, + getAccessFields, + getAuthFields, +} from '~/components/InputsModal/Auth/AuthSettings'; import AuthTypeSelector from '~/components/InputsModal/Auth/AuthTypeSelector'; import FieldLabel from '~/components/InputsModal/FieldLabel'; import InputFields from '~/components/InputsModal/InputFields'; import useStyles from '../styles'; export interface InputAuthProps { + mode: 'access' | 'auth'; input: TestInput; index: number; inputsMap: Map; setInputsMap: (map: Map, edited?: boolean) => void; } -const InputAuth: FC = ({ input, index, inputsMap, setInputsMap }) => { +const InputAuth: FC = ({ mode, input, index, inputsMap, setInputsMap }) => { const { classes } = useStyles(); const [authValues, setAuthValues] = React.useState>(new Map()); const [authValuesPopulated, setAuthValuesPopulated] = React.useState(false); @@ -35,9 +40,14 @@ const InputAuth: FC = ({ input, index, inputsMap, setInputsMap } (authComponent?.default || firstListOption || 'public') as string, ); - const [authFields, setAuthFields] = React.useState( - getAuthFields(authType as AuthType, authValues, input.options?.components || []), - ); + // Set fields depending on mode + let fields: TestInput[] = []; + if (mode === 'access') { + fields = getAccessFields(authType as AuthType, authValues, input.options?.components || []); + } else if (mode === 'auth') { + fields = getAuthFields(authType as AuthType, authValues, input.options?.components || []); + } + const [authFields, setAuthFields] = React.useState(fields); useEffect(() => { // Set defaults on radio buttons @@ -64,7 +74,6 @@ const InputAuth: FC = ({ input, index, inputsMap, setInputsMap } authFields.forEach((field: TestInput) => { authValues.set(field.name, combinedStartingValues[field.name as keyof Auth] || ''); }); - setAuthValuesPopulated(true); // Trigger change on mount for default values @@ -74,12 +83,26 @@ const InputAuth: FC = ({ input, index, inputsMap, setInputsMap } useEffect(() => { // Recalculate hidden fields - setAuthFields(getAuthFields(authType as AuthType, authValues, input.options?.components || [])); + if (mode === 'access') { + setAuthFields( + getAccessFields(authType as AuthType, authValues, input.options?.components || []), + ); + } else if (mode === 'auth') { + setAuthFields( + getAuthFields(authType as AuthType, authValues, input.options?.components || []), + ); + } - // Update inputsMap + // Update inputsMap while maintaining hidden values if (authValuesPopulated) { - const stringifiedAuthValues = JSON.stringify(Object.fromEntries(authValues)); - inputsMap.set(input.name, stringifiedAuthValues); + let stringifiedValues = JSON.stringify(Object.fromEntries(authValues)); + if (mode === 'access') { + const combinedStartingValues = getStartingValues(); + const accessValuesObject = Object.fromEntries(authValues) as Auth; + const combinedValues = { ...combinedStartingValues, ...accessValuesObject }; + stringifiedValues = JSON.stringify(combinedValues); + } + inputsMap.set(input.name, stringifiedValues); setInputsMap(new Map(inputsMap)); } }, [authValues]); diff --git a/client/src/components/InputsModal/InputFields.tsx b/client/src/components/InputsModal/InputFields.tsx index 15aecd0fc..78f3d914d 100644 --- a/client/src/components/InputsModal/InputFields.tsx +++ b/client/src/components/InputsModal/InputFields.tsx @@ -1,14 +1,13 @@ import React, { FC } from 'react'; import { List } from '@mui/material'; import { TestInput } from '~/models/testSuiteModels'; -import InputOAuthCredentials from '~/components/InputsModal/InputOAuthCredentials'; +import InputAuth from '~/components/InputsModal/Auth/InputAuth'; import InputCheckboxGroup from '~/components/InputsModal/InputCheckboxGroup'; +import InputCombobox from '~/components/InputsModal/InputCombobox'; +import InputOAuthCredentials from '~/components/InputsModal/InputOAuthCredentials'; import InputRadioGroup from '~/components/InputsModal/InputRadioGroup'; -import InputTextField from '~/components/InputsModal/InputTextField'; -import InputAuth from '~/components/InputsModal/Auth/InputAuth'; import InputSingleCheckbox from '~/components/InputsModal/InputSingleCheckbox'; -import InputCombobox from '~/components/InputsModal/InputCombobox'; -import InputAccess from '~/components/InputsModal/Auth/InputAccess'; +import InputTextField from '~/components/InputsModal/InputTextField'; export interface InputFieldsProps { inputs: TestInput[]; @@ -26,6 +25,7 @@ const InputFields: FC = ({ inputs, inputsMap, setInputsMap }) if (input.options?.mode === 'auth') { return ( = ({ inputs, inputsMap, setInputsMap }) ); } return ( - { it('renders InputCheckboxGroup', () => { @@ -176,6 +175,7 @@ describe('Input Components', () => { ()} @@ -208,7 +208,8 @@ describe('Input Components', () => { render( - ()}