From 93223f0ae1987e972c5fdf3e48c66a8e6d6e6636 Mon Sep 17 00:00:00 2001 From: Jeffrey Phillips Date: Tue, 13 Aug 2024 06:34:01 -0400 Subject: [PATCH] [RHOAIENG-10318] Add connection type field modal --- .../src/concepts/connectionTypes/types.ts | 12 +- .../dashboard/DashboardModalFooter.tsx | 8 +- .../AddConnectionTypeFieldModal.tsx | 261 ++++++++++++++++++ .../connectionTypeFields/TextForm.tsx | 37 +++ .../AddConnectionTypeFieldModal.spec.tsx | 93 +++++++ .../CreateConnectionTypeFieldsTable.tsx | 48 +++- .../create/CreateConnectionTypePage.tsx | 22 +- 7 files changed, 458 insertions(+), 23 deletions(-) create mode 100644 frontend/src/pages/connectionTypes/connectionTypeFields/AddConnectionTypeFieldModal.tsx create mode 100644 frontend/src/pages/connectionTypes/connectionTypeFields/TextForm.tsx create mode 100644 frontend/src/pages/connectionTypes/connectionTypeFields/__tests__/AddConnectionTypeFieldModal.spec.tsx diff --git a/frontend/src/concepts/connectionTypes/types.ts b/frontend/src/concepts/connectionTypes/types.ts index 4552db052e..28082af273 100644 --- a/frontend/src/concepts/connectionTypes/types.ts +++ b/frontend/src/concepts/connectionTypes/types.ts @@ -31,15 +31,17 @@ type Field = { description?: string; }; +export type ConnectionTypeCommonProperties = { + defaultValue?: V; + defaultReadOnly?: boolean; +}; + // P default to an empty set of properties // eslint-disable-next-line @typescript-eslint/ban-types -type DataField = Field & { +export type DataField = Field & { envVar: string; required?: boolean; - properties: P & { - defaultValue?: V; - defaultReadOnly?: boolean; - }; + properties: P & ConnectionTypeCommonProperties; }; export type SectionField = Field; diff --git a/frontend/src/concepts/dashboard/DashboardModalFooter.tsx b/frontend/src/concepts/dashboard/DashboardModalFooter.tsx index f11b2f1265..4b8d994471 100644 --- a/frontend/src/concepts/dashboard/DashboardModalFooter.tsx +++ b/frontend/src/concepts/dashboard/DashboardModalFooter.tsx @@ -56,7 +56,13 @@ const DashboardModalFooter: React.FC = ({ - diff --git a/frontend/src/pages/connectionTypes/connectionTypeFields/AddConnectionTypeFieldModal.tsx b/frontend/src/pages/connectionTypes/connectionTypeFields/AddConnectionTypeFieldModal.tsx new file mode 100644 index 0000000000..76c058695a --- /dev/null +++ b/frontend/src/pages/connectionTypes/connectionTypeFields/AddConnectionTypeFieldModal.tsx @@ -0,0 +1,261 @@ +import * as React from 'react'; +import { + Checkbox, + Form, + FormGroup, + FormHelperText, + HelperText, + HelperTextItem, + MenuToggle, + Modal, + Popover, + Select, + SelectList, + SelectOption, + TextArea, + TextInput, + ValidatedOptions, +} from '@patternfly/react-core'; +import { HelpIcon, ExclamationCircleIcon } from '@patternfly/react-icons'; +import DashboardModalFooter from '~/concepts/dashboard/DashboardModalFooter'; +import { + ConnectionTypeCommonProperties, + ConnectionTypeDataField, + ConnectionTypeFieldType, +} from '~/concepts/connectionTypes/types'; +import { TextForm } from '~/pages/connectionTypes/connectionTypeFields/TextForm'; +import { isEnumMember } from '~/utilities/utils'; + +const ENV_VAR_NAME_REGEX = new RegExp('^[-._a-zA-Z][-._a-zA-Z0-9]*$'); + +const isConnectionTypeFieldType = ( + fieldType: string | number | undefined, +): fieldType is ConnectionTypeFieldType => + isEnumMember(fieldType?.toString(), ConnectionTypeFieldType); + +interface AddConnectionTypeFieldModalProps { + onCancel: () => void; + onSubmit: (newField: ConnectionTypeDataField) => void; + // existingFields?: ConnectionTypeField[]; +} + +const fieldTypeLabels: { [key: string]: string } = { + [ConnectionTypeFieldType.Boolean]: 'Boolean', + [ConnectionTypeFieldType.Dropdown]: 'Short text', + [ConnectionTypeFieldType.File]: 'File', + [ConnectionTypeFieldType.Hidden]: 'Hidden', + [ConnectionTypeFieldType.Numeric]: 'Numeric', + [ConnectionTypeFieldType.ShortText]: 'Short text', + [ConnectionTypeFieldType.Text]: 'Text', + [ConnectionTypeFieldType.URI]: 'URI', +}; + +const validateForType = (value: string, fieldType: ConnectionTypeFieldType): ValidatedOptions => { + switch (fieldType) { + default: + return ValidatedOptions.default; + } +}; + +export const AddConnectionTypeFieldModal: React.FC = ({ + onCancel, + onSubmit, +}) => { + const [name, setName] = React.useState(''); + const [description, setDescription] = React.useState(); + const [envVar, setEnvVar] = React.useState(''); + const [fieldType, setFieldType] = React.useState( + ConnectionTypeFieldType.ShortText, + ); + const [required, setRequired] = React.useState(); + const [isOpen, setIsOpen] = React.useState(false); + const [textProperties, setTextProperties] = React.useState({}); + + const envVarValidation = + !envVar || ENV_VAR_NAME_REGEX.test(envVar) ? ValidatedOptions.default : ValidatedOptions.error; + const valid = React.useMemo( + () => !!name && !!envVar && envVarValidation === ValidatedOptions.default, + [envVar, envVarValidation, name], + ); + + const onAdd = () => { + switch (fieldType) { + case ConnectionTypeFieldType.Hidden: + case ConnectionTypeFieldType.File: + case ConnectionTypeFieldType.ShortText: + case ConnectionTypeFieldType.Text: + case ConnectionTypeFieldType.URI: + onSubmit({ + name, + description, + envVar, + type: fieldType, + properties: { + defaultValue: textProperties.defaultValue, + defaultReadOnly: textProperties.defaultValue + ? textProperties.defaultReadOnly + : undefined, + }, + required, + }); + } + }; + + const fieldTypeForm = React.useMemo(() => { + switch (fieldType) { + case ConnectionTypeFieldType.Hidden: + case ConnectionTypeFieldType.File: + case ConnectionTypeFieldType.ShortText: + case ConnectionTypeFieldType.Text: + return ( + setTextProperties(updatedProperties)} + validate={(value) => validateForType(value, fieldType)} + /> + ); + } + return null; + }, [fieldType, textProperties]); + + return ( + + } + data-testid="archive-model-version-modal" + > +
+ + setName(value)} + data-testid="field-name-input" + /> + + + + + } + > +