diff --git a/src-ts/lib/contact-support-form/contact-support-form.config.ts b/src-ts/lib/contact-support-form/contact-support-form.config.ts index 4b1ce5c25..e8b75e7be 100644 --- a/src-ts/lib/contact-support-form/contact-support-form.config.ts +++ b/src-ts/lib/contact-support-form/contact-support-form.config.ts @@ -12,7 +12,7 @@ export const contactSupportFormDef: FormDefinition = { primaryGroup: [ { buttonStyle: 'secondary', - isSave: true, + isSubmit: true, label: 'Submit', size: 'lg', type: 'submit', diff --git a/src-ts/lib/form/Form.tsx b/src-ts/lib/form/Form.tsx index fcdf0c7f1..ce6141ec4 100644 --- a/src-ts/lib/form/Form.tsx +++ b/src-ts/lib/form/Form.tsx @@ -15,7 +15,7 @@ import { Button } from '../button' import '../styles/index.scss' import { IconOutline } from '../svgs' -import { FormButton, FormDefinition, FormInputModel } from '.' +import { FormAction, FormButton, FormDefinition, FormInputModel } from '.' import { formGetInputFields, formInitializeValues, @@ -29,6 +29,7 @@ import { FormGroups } from './form-groups' import styles from './Form.module.scss' interface FormProps { + readonly action?: FormAction // only type submit will perform validation readonly formDef: FormDefinition readonly formValues?: ValueType readonly onChange?: (inputs: ReadonlyArray) => void, @@ -96,7 +97,7 @@ const Form: (props: FormProps): Promise { const values: RequestType = props.requestGenerator(inputs) - formOnSubmitAsync(event, formDef, values, props.save, props.onSuccess) + formOnSubmitAsync(props.action || 'submit', event, formDef, values, props.save, props.onSuccess) .then(() => { setFormKey(Date.now()) formOnReset(inputs, props.formValues) @@ -126,7 +127,7 @@ const Form: (props: FormProps ) diff --git a/src-ts/lib/form/form-button.model.ts b/src-ts/lib/form/form-button.model.ts index cd3684ecc..7eb1d836b 100644 --- a/src-ts/lib/form/form-button.model.ts +++ b/src-ts/lib/form/form-button.model.ts @@ -6,7 +6,7 @@ export interface FormButton { readonly buttonStyle?: ButtonStyle readonly icon?: FC> readonly isReset?: boolean - readonly isSave?: boolean + readonly isSubmit?: boolean readonly label?: string readonly notTabble?: boolean onClick?: (event?: any) => void diff --git a/src-ts/lib/form/form-definition.model.ts b/src-ts/lib/form/form-definition.model.ts index 5924f38c3..fef7d8c58 100644 --- a/src-ts/lib/form/form-definition.model.ts +++ b/src-ts/lib/form/form-definition.model.ts @@ -1,5 +1,7 @@ import { FormButton, FormGroup } from '.' +export type FormAction = 'save' | 'submit' | undefined + export interface FormButtons { primaryGroup: ReadonlyArray secondaryGroup?: ReadonlyArray diff --git a/src-ts/lib/form/form-functions/form.functions.ts b/src-ts/lib/form/form-functions/form.functions.ts index 0cec530e6..5f5e72246 100644 --- a/src-ts/lib/form/form-functions/form.functions.ts +++ b/src-ts/lib/form/form-functions/form.functions.ts @@ -1,7 +1,7 @@ import { ChangeEvent, FormEvent } from 'react' import { toast } from 'react-toastify' -import { FormDefinition } from '../form-definition.model' +import { FormAction, FormDefinition } from '../form-definition.model' import { FormGroup } from '../form-group.model' import { FormInputModel } from '../form-input.model' @@ -31,11 +31,11 @@ export function getInputModel(inputs: ReadonlyArray, fieldName: export function initializeValues(inputs: Array, formValues?: T): void { inputs - .filter(input => !input.dirty && !input.touched) + .filter(input => !input.dirty && !input.touched) .forEach(input => { input.value = !!(formValues as any)?.hasOwnProperty(input.name) - ? (formValues as any)[input.name] - : undefined + ? (formValues as any)[input.name] + : undefined }) } @@ -58,6 +58,7 @@ export function onReset(inputs: ReadonlyArray, formValue?: any): } export async function onSubmitAsync( + action: FormAction, event: FormEvent, formDef: FormDefinition, formValue: T, @@ -78,9 +79,11 @@ export async function onSubmitAsync( // could have a form that's not dirty but has errors and you wouldn't // want to have it look like the submit succeeded const formValues: HTMLFormControlsCollection = (event.target as HTMLFormElement).elements - const isValid: boolean = validateForm(formValues, 'submit', inputs) - if (!isValid) { - return Promise.reject() + if (action === 'submit') { + const isValid: boolean = validateForm(formValues, action, inputs) + if (!isValid) { + return Promise.reject() + } } // set the properties for the updated T value @@ -170,9 +173,9 @@ function validateField(formInputDef: FormInputModel, formElements: HTMLFormContr export function validateForm(formElements: HTMLFormControlsCollection, event: 'blur' | 'change' | 'submit' | 'initial', inputs: ReadonlyArray): boolean { const errors: ReadonlyArray = inputs?.filter(formInputDef => { - formInputDef.dirty = formInputDef.dirty || event === 'submit' - validateField(formInputDef, formElements, event) - return !!formInputDef.error - }) + formInputDef.dirty = formInputDef.dirty || event === 'submit' + validateField(formInputDef, formElements, event) + return !!formInputDef.error + }) return !errors.length } diff --git a/src-ts/lib/styles/_buttons.scss b/src-ts/lib/styles/_buttons.scss index 3eeb63daf..9256346a6 100644 --- a/src-ts/lib/styles/_buttons.scss +++ b/src-ts/lib/styles/_buttons.scss @@ -23,7 +23,7 @@ border: solid $border; white-space: nowrap; cursor: pointer; - font-family: $font-roboto; + font-family: $font-roboto; font-weight: $font-weight-bold; font-size: 11px; line-height: 24px; @@ -32,7 +32,7 @@ &.primary, &.secondary { - &:focus { + &:not(.disabled):focus { outline: $border solid $turq-140; } } @@ -47,7 +47,7 @@ padding: $border $pad-xl; font-size: 13px; } - + &.button-md { padding: 3*$border $pad-xl; font-size: 13px; @@ -57,7 +57,7 @@ padding: $pad-sm $pad-xxl; font-size: 14px; } - + &.button-xl { padding: $pad-md $pad-xxl; font-size: 16px; @@ -85,6 +85,7 @@ color: $black-60; background-color: $black-5; border-color: $black-5; + cursor: default; } } @@ -105,6 +106,7 @@ color: $black-60; background-color: $black-5; border-color: $black-5; + cursor: default; } } @@ -125,6 +127,7 @@ color: $black-60; background-color: $tc-white; border-color: $black-5; + cursor: default; } } @@ -156,6 +159,7 @@ color: $black-60; background-color: $tc-white; border-color: $black-5; + cursor: default; } svg { diff --git a/src-ts/tools/work/work-detail-header/WorkFeedback/work-feedback-form.config.ts b/src-ts/tools/work/work-detail-header/WorkFeedback/work-feedback-form.config.ts index 6a9185bdc..d1b8a612f 100644 --- a/src-ts/tools/work/work-detail-header/WorkFeedback/work-feedback-form.config.ts +++ b/src-ts/tools/work/work-detail-header/WorkFeedback/work-feedback-form.config.ts @@ -5,7 +5,7 @@ export const workFeedbackFormDef: FormDefinition = { primaryGroup: [ { buttonStyle: 'primary', - isSave: true, + isSubmit: true, label: 'Mark as done', size: 'xl', type: 'submit', diff --git a/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/BugHuntIntakeForm.tsx b/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/BugHuntIntakeForm.tsx index b5a965de6..52adb72ca 100644 --- a/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/BugHuntIntakeForm.tsx +++ b/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/BugHuntIntakeForm.tsx @@ -3,6 +3,7 @@ import { NavigateFunction, useNavigate, useParams } from 'react-router-dom' import { Form, + FormAction, FormDefinition, formGetInputModel, FormInputModel, @@ -45,9 +46,13 @@ const BugHuntIntakeForm: React.FC = () => { const isMobile: boolean = useCheckIsMobile() const { isLoggedIn }: ProfileContextData = useContext(profileContext) - let action: string = '' - BugHuntFormConfig.buttons.primaryGroup[0].onClick = () => { action = 'save' } - BugHuntFormConfig.buttons.primaryGroup[1].onClick = () => { action = 'submit' } + const [action, setAction]: [FormAction, Dispatch>] = useState() + + BugHuntFormConfig.buttons.primaryGroup[0].onClick = () => { setAction('save') } + BugHuntFormConfig.buttons.primaryGroup[1].onClick = () => { setAction('submit') } + if (BugHuntFormConfig.buttons.secondaryGroup) { + BugHuntFormConfig.buttons.secondaryGroup[0].onClick = () => { navigate(-1) } + } const [challenge, setChallenge]: [Challenge | undefined, Dispatch>] = useState() const [formDef, setFormDef]: [FormDefinition, Dispatch>] @@ -187,6 +192,7 @@ const BugHuntIntakeForm: React.FC = () => { onSuccess={onSaveSuccess} requestGenerator={requestGenerator} save={onSave} + action={action} /> diff --git a/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/bug-hunt.form.config.tsx b/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/bug-hunt.form.config.tsx index 284bca9b0..03619cb40 100644 --- a/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/bug-hunt.form.config.tsx +++ b/src-ts/tools/work/work-self-service/intake-forms/bug-hunt/bug-hunt.form.config.tsx @@ -15,6 +15,7 @@ export const BugHuntFormConfig: FormDefinition = { }, { buttonStyle: 'primary', + isSubmit: true, label: 'Complete and pay', onClick: () => { }, type: 'submit', @@ -92,7 +93,7 @@ export const BugHuntFormConfig: FormDefinition = { { label: 'Features to test (optional)', name: ChallengeMetadataName.featuresToTest, - placeholder: 'List the sepcific features', + placeholder: 'List the specific features', type: 'textarea', }, ], diff --git a/src-ts/utils/settings/account/change-password/change-password-form.config.ts b/src-ts/utils/settings/account/change-password/change-password-form.config.ts index 3a8626121..32f71e31c 100644 --- a/src-ts/utils/settings/account/change-password/change-password-form.config.ts +++ b/src-ts/utils/settings/account/change-password/change-password-form.config.ts @@ -21,7 +21,7 @@ export const changePasswordFormDef: FormDefinition = { primaryGroup: [ { buttonStyle: 'secondary', - isSave: true, + isSubmit: true, label: 'Change password', size: 'xl', type: 'submit', @@ -80,7 +80,7 @@ export const changePasswordFormDef: FormDefinition = { { autocomplete: FormInputAutocompleteOption.off, dependentFields: [ - ChangePasswordFieldName.newPassword, + ChangePasswordFieldName.newPassword, ], label: 'Confirm Password', name: ChangePasswordFieldName.confirmPassword, diff --git a/src-ts/utils/settings/account/edit-name/edit-name-form.config.ts b/src-ts/utils/settings/account/edit-name/edit-name-form.config.ts index 93ab59d45..4a3167cbf 100644 --- a/src-ts/utils/settings/account/edit-name/edit-name-form.config.ts +++ b/src-ts/utils/settings/account/edit-name/edit-name-form.config.ts @@ -12,7 +12,7 @@ export const editNameFormDef: FormDefinition = { primaryGroup: [ { buttonStyle: 'secondary', - isSave: true, + isSubmit: true, label: 'Save', size: 'lg', type: 'submit',