Skip to content

Commit

Permalink
feat: add custom header to track user selected form language
Browse files Browse the repository at this point in the history
  • Loading branch information
siddarth2824 committed Dec 20, 2024
1 parent 5209b21 commit d407a10
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 17 deletions.
5 changes: 4 additions & 1 deletion frontend/src/features/public-form/PublicFormProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { ErrorCode } from '~shared/types/errorCodes'
import {
FormAuthType,
FormResponseMode,
Language,
ProductItem,
PublicFormDto,
} from '~shared/types/form'
Expand Down Expand Up @@ -187,7 +188,8 @@ export const PublicFormProvider = ({
children,
startTime,
}: PublicFormProviderProps): JSX.Element => {
const { t } = useTranslation()
const { t, i18n } = useTranslation()
const selectedLanguage = i18n.language as Language

// Once form has been submitted, submission data will be set here.
const [submissionData, setSubmissionData] = useState<SubmissionData>()
Expand Down Expand Up @@ -590,6 +592,7 @@ export const PublicFormProvider = ({
? numVisibleFields + 1
: numVisibleFields,
},
selectedFormLanguage: selectedLanguage,
}

const logMeta = {
Expand Down
16 changes: 16 additions & 0 deletions frontend/src/features/public-form/PublicFormService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
import {
FormAuthType,
FormDto,
Language,
PublicFormViewDto,
} from '~shared/types/form/form'
import {
Expand Down Expand Up @@ -49,6 +50,8 @@ import { MultirespondentSubmissionDtoWithAttachments } from './types'

export const PUBLIC_FORMS_ENDPOINT = '/forms'

export const X_FORMSG_SELECTED_FORM_LANGUAGE = 'X-Formsg-Selected-Form-Language'

/**
* Gets public view of form, along with any
* identify information obtained from Singpass/Corppass/MyInfo.
Expand Down Expand Up @@ -136,6 +139,7 @@ export type SubmitEmailFormArgs = {
formLogics: FormDto['form_logics']
formInputs: FormFieldValues
responseMetadata?: ResponseMetadata
selectedFormLanguage?: Language
}

export type SubmitStorageFormArgs = SubmitEmailFormArgs & {
Expand Down Expand Up @@ -175,6 +179,7 @@ export const submitEmailModeForm = async ({
captchaResponse = null,
captchaType = '',
responseMetadata,
selectedFormLanguage = Language.ENGLISH,
}: SubmitEmailFormArgs): Promise<SubmissionResponseDto> => {
const filteredInputs = filterHiddenInputs({
formFields,
Expand All @@ -195,6 +200,9 @@ export const submitEmailModeForm = async ({
captchaResponse: String(captchaResponse),
captchaType: captchaType,
},
headers: {
[X_FORMSG_SELECTED_FORM_LANGUAGE]: selectedFormLanguage,
},
},
).then(({ data }) => data)
}
Expand Down Expand Up @@ -266,6 +274,7 @@ export const submitStorageModeForm = async ({
paymentProducts,
payments,
fieldIdToQuarantineKeyMap,
selectedFormLanguage = Language.ENGLISH,
}: SubmitStorageFormWithVirusScanningArgs) => {
const filteredInputs = filterHiddenInputs({
formFields,
Expand Down Expand Up @@ -294,6 +303,9 @@ export const submitStorageModeForm = async ({
captchaResponse: String(captchaResponse),
captchaType: captchaType,
},
headers: {
[X_FORMSG_SELECTED_FORM_LANGUAGE]: selectedFormLanguage,
},
},
).then(({ data }) => data)
}
Expand Down Expand Up @@ -349,6 +361,7 @@ export const submitMultirespondentForm = async ({
captchaType = '',
responseMetadata,
fieldIdToQuarantineKeyMap,
selectedFormLanguage = Language.ENGLISH,
}: SubmitMultirespondentFormWithVirusScanningArgs) => {
const filteredInputs = filterHiddenInputs({
formFields,
Expand All @@ -374,6 +387,9 @@ export const submitMultirespondentForm = async ({
captchaResponse: String(captchaResponse),
captchaType: captchaType,
},
headers: {
[X_FORMSG_SELECTED_FORM_LANGUAGE]: selectedFormLanguage,
},
},
).then(({ data }) => data)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,13 @@ export const LanguageControl = (): JSX.Element | null => {
px={{ base: '1.5rem', md: 0 }}
justifyContent={{ base: 'start', md: 'center' }}
>
<HStack mt="-2rem" bg="white" borderRadius="0.25rem" shadow="md">
<HStack
mt={{ base: '-1rem', md: '-2rem' }}
mb={{ base: '1rem', md: 0 }}
bg="white"
borderRadius="0.25rem"
shadow="md"
>
<Menu variant="clear">
<MenuButton
as={Button}
Expand Down
11 changes: 4 additions & 7 deletions frontend/src/templates/Field/Dropdown/DropdownField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export const DropdownField = ({

const selectedLanguage = i18n.language as Language

// This has to be done because of how the SingleSelect function
// extracts the value attribute from the fieldOption to set
// as the selected option which will then be used to validate
// against the schema fieldOptions which are the defaultFieldOptions.
const fieldOptions: ComboboxItem[] = useMemo(() => {
const englishFieldOptions = schema.fieldOptions
const fieldOptionsTranslations = schema?.fieldOptionsTranslations ?? []
Expand All @@ -42,9 +46,6 @@ export const DropdownField = ({
return translation.language === selectedLanguage
})

// Check if translations for field options exist and whether
// each field option has its own respective translation. If not
// render the default field options in English.
if (
translationIdx !== -1 &&
fieldOptionsTranslations[translationIdx].translation.length ===
Expand All @@ -53,10 +54,6 @@ export const DropdownField = ({
const translatedFieldOptions =
fieldOptionsTranslations[translationIdx].translation

// The label will be the translated option while the value is the
// default English option so that upon form submission, the value recorded
// will be the default english option. The indexes of the translated options
// and the default English options are corresponding with each other.
return translatedFieldOptions.map((translatedFieldOption, index) => {
return {
value: englishFieldOptions[index],
Expand Down
13 changes: 5 additions & 8 deletions frontend/src/templates/Field/Table/ColumnCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,18 @@ const DropdownColumnCell = ({
)

const selectedLanguage = i18n.language as Language

// This has to be done because of how the SingleSelect function
// extracts the value attribute from the fieldOption to set
// as the selected option which will then be used to validate
// against the schema fieldOptions which are the defaultFieldOptions.
const fieldOptions: ComboboxItem[] = useMemo(() => {
const defaultEnglishFieldOptions = schema.fieldOptions ?? []
const fieldOptionsTranslations = schema?.fieldOptionsTranslations ?? []
const translationIdx = fieldOptionsTranslations.findIndex(
(translation) => translation.language === selectedLanguage,
)

// Check if translations for field options exist and whether
// each field option has its own respective translation. If not
// render the default field options in English.
if (
translationIdx !== -1 &&
fieldOptionsTranslations[translationIdx].translation.length ===
Expand All @@ -110,11 +112,6 @@ const DropdownColumnCell = ({
const translatedFieldOptions =
fieldOptionsTranslations[translationIdx].translation

// The label will be the translated option while the value is the
// default English option so that upon form submission, the value recorded
// and collected will be the default english option. The indexes of the
// translated options and the default English options are corresponding
// with each other.
return translatedFieldOptions.map((translatedFieldOption, index) => {
return {
value: defaultEnglishFieldOptions[index],
Expand Down

0 comments on commit d407a10

Please sign in to comment.