Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,21 @@ All notable changes to this project will be documented in this file. Dates are d

Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).

#### [v6.272.0](https://github.com/opengovsg/FormSG/compare/v6.271.0...v6.272.0)

- feat: respondent copy v3 (phase2) [`#8869`](https://github.com/opengovsg/FormSG/pull/8869)
- build: merge release-al2 v6.271.0 back to develop [`#8908`](https://github.com/opengovsg/FormSG/pull/8908)
- build: release v6.271.0 [`#8905`](https://github.com/opengovsg/FormSG/pull/8905)

#### [v6.271.0](https://github.com/opengovsg/FormSG/compare/v6.270.0...v6.271.0)

> 17 November 2025

- feat: respondent copy v3 (phase 1) [`#8854`](https://github.com/opengovsg/FormSG/pull/8854)
- fix: remove noisy chromatic diffs due to dynamic dates and form link [`#8903`](https://github.com/opengovsg/FormSG/pull/8903)
- build: release al2 6.270.0 back to develop [`#8904`](https://github.com/opengovsg/FormSG/pull/8904)
- build: release v6.270.0 [`#8902`](https://github.com/opengovsg/FormSG/pull/8902)
- chore: bump version to v6.271.0 [`43fb858`](https://github.com/opengovsg/FormSG/commit/43fb858a0c8537cddaf2fa362f89899a22785021)

#### [v6.270.0](https://github.com/opengovsg/FormSG/compare/v6.269.0...v6.270.0)

Expand Down
1 change: 1 addition & 0 deletions __tests__/e2e/helpers/createForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import {
getMyInfoAttribute,
getTitleWithQuestionNumber,
} from '../utils'

import { closeModals } from './closeModals';

type CreateFormReturn = {
Expand Down
4 changes: 2 additions & 2 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "form-frontend",
"version": "6.271.0",
"version": "6.272.0",
"homepage": ".",
"type": "module",
"private": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import Input from '~components/Input'
import Textarea from '~components/Textarea'
import Toggle from '~components/Toggle'

import { useUser } from '~features/user/queries'

import { CreatePageDrawerContentContainer } from '../../../../../common'
import { useCreateTabForm } from '../../../../useCreateTabForm'
import { SPLIT_TEXTAREA_TRANSFORM } from '../common/constants'
Expand Down Expand Up @@ -87,6 +89,8 @@ export const EditEmail = ({ field }: EditEmailProps): JSX.Element => {
const watchedHasAllowedEmailDomains = watch('hasAllowedEmailDomains')
const watchedHasAutoReply = watch('autoReplyOptions.hasAutoReply')

const { user } = useUser()

const requiredValidationRule = useMemo(
() =>
createBaseValidationRules<EditEmailInputs, 'title'>({
Expand Down Expand Up @@ -139,23 +143,21 @@ export const EditEmail = ({ field }: EditEmailProps): JSX.Element => {
const isEncryptMode = form?.responseMode === FormResponseMode.Encrypt
const isPaymentDisabledForm =
isEncryptMode &&
form.payments_channel.channel === PaymentChannel.Unconnected
form.payments_channel.channel !== PaymentChannel.Unconnected

const isPdfResponseEnabled =
form?.responseMode === FormResponseMode.Email || isPaymentDisabledForm

const pdfResponseToggleDescription = isPdfResponseEnabled
// For payment forms inclusion of PDF responses are disallowed
const pdfResponseToggleDescription = isPaymentDisabledForm
? t(
'features.adminForm.sidebar.fields.email.emailConfirmation.includeResponseDescription',
'features.adminForm.sidebar.fields.email.emailConfirmation.includePdfResponseWarning',
)
: t(
'features.adminForm.sidebar.fields.email.emailConfirmation.includePdfResponseWarning',
'features.adminForm.sidebar.fields.email.emailConfirmation.includeResponseDescription',
)

// email confirmation is not supported on MRF
// TODO: FRM-2172 Remove when respondent copy is out of beta
const isToggleEmailConfirmationDisabled =
form?.responseMode === FormResponseMode.Multirespondent &&
!field.autoReplyOptions.hasAutoReply
!user?.betaFlags?.respondentCopy

return (
<CreatePageDrawerContentContainer>
Expand Down Expand Up @@ -211,7 +213,7 @@ export const EditEmail = ({ field }: EditEmailProps): JSX.Element => {
'features.adminForm.sidebar.fields.email.emailConfirmation.includeResponse',
)}
description={pdfResponseToggleDescription}
isDisabled={!isPdfResponseEnabled}
isDisabled={isPaymentDisabledForm}
/>
</FormControl>
<FormControl isRequired isReadOnly={isLoading} mt="1.5rem">
Expand All @@ -222,7 +224,6 @@ export const EditEmail = ({ field }: EditEmailProps): JSX.Element => {
'features.adminForm.sidebar.fields.email.emailConfirmation.subject.placeholder',
{ formTitle: form?.title },
)}
_placeholder={{ color: 'secondary.700' }}
{...register('autoReplyOptions.autoReplySubject')}
/>
</FormControl>
Expand All @@ -234,7 +235,6 @@ export const EditEmail = ({ field }: EditEmailProps): JSX.Element => {
</FormLabel>
<Input
placeholder={form?.admin.agency.fullName}
_placeholder={{ color: 'secondary.700' }}
{...register('autoReplyOptions.autoReplySender')}
/>
</FormControl>
Expand All @@ -249,12 +249,6 @@ export const EditEmail = ({ field }: EditEmailProps): JSX.Element => {
'features.adminForm.sidebar.fields.email.emailConfirmation.content.placeholder',
{ agencyName: form?.admin.agency.fullName },
)}
sx={{
'::placeholder': {
color: 'secondary.700',
opacity: 1,
},
}}
{...register('autoReplyOptions.autoReplyMessage')}
/>
</FormControl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ export const getLogicFieldLabel = (field: FormFieldWithQuestionNo) => {
case BasicField.Image:
title = field.name
break
case BasicField.Email:
// Inform admins if email confirmation will be sent
if (field.autoReplyOptions.hasAutoReply) {
title = title + ' (confirmation will be sent)'
}
break
default:
break
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ export const StepNameBlock = ({
<Input
{...field}
placeholder={displayStepName}
_placeholder={{ color: 'secondary.700' }}
_focus={{
_placeholder: { color: 'transparent' },
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,6 @@ export const FormEmailSection = ({
settings,
isHighContrast = true,
}: EmailFormSectionProps): JSX.Element => {
//TODO: (Respondent Copy): Remove isTest and user when respondent copy is out of beta
const { user } = useUser()
const isTest = import.meta.env.STORYBOOK_NODE_ENV === 'test'

const { t } = useTranslation()
const initialEmailSet = useMemo(
() => new Set(settings.emails),
Expand Down Expand Up @@ -169,13 +165,6 @@ export const FormEmailSection = ({
</FormLabel.Description>
) : null}
</FormControl>
{isTest || user?.betaFlags?.respondentCopy ? (
<FormControl isDisabled={isDisabled}>
<Box mt={'1.5rem'}>
<RespondentCopyToggle />
</Box>
</FormControl>
) : null}
</FormProvider>
</>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { Flex, Skeleton, Stack, Text, useDisclosure } from '@chakra-ui/react'
import { BasicField } from '~shared/types'
import {
EmailFormDto,
FormAuthType,
FormResponseMode,
FormStatus,
} from '~shared/types/form/form'
Expand All @@ -14,6 +13,7 @@ import InlineMessage from '~components/InlineMessage'
import { Switch } from '~components/Toggle/Switch'

import { useAdminForm } from '~features/admin-form/common/queries'
import { useUser } from '~features/user/queries'

import { useMutateFormSettings } from '../mutations'
import { useAdminFormSettings } from '../queries'
Expand All @@ -30,7 +30,7 @@ export const FormStatusToggle = (): JSX.Element => {
} = useAdminForm()
const { data: formSettings, isLoading: isLoadingFormSettings } =
useAdminFormSettings()

const { user } = useUser()
const { status, responseMode, authType, esrvcId } = formSettings ?? {}

const secretKeyActivationModalProps = useDisclosure()
Expand All @@ -54,7 +54,8 @@ export const FormStatusToggle = (): JSX.Element => {
form_fields?.some(
(ff) =>
ff.fieldType === BasicField.Email && ff.autoReplyOptions.hasAutoReply,
)
) &&
!user?.betaFlags?.respondentCopy
) {
return t('features.adminForm.settings.general.status.noEmailsInMRF')
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,13 +285,6 @@ const MrfEmailNotificationsForm = ({
</FormErrorMessage>
)}
</FormControl>
{isTest || user?.betaFlags?.respondentCopy ? (
<FormControl isDisabled={isDisabled}>
<Box mt={'1.5rem'}>
<RespondentCopyToggle />
</Box>
</FormControl>
) : null}
</Box>
</form>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import { PaymentPreview } from '../../../../templates/Field/PaymentPreview/Payme
import { PublicFormPaymentResumeModal } from '../FormPaymentPage/FormPaymentResumeModal'

import { PublicFormSubmitButton } from './PublicFormSubmitButton'
import { PublicRespondentEmailField } from './PublicRespondentEmailField'
import { VisibleFormFields } from './VisibleFormFields'

export interface FormFieldsProps {
Expand Down Expand Up @@ -119,12 +118,6 @@ export const FormFields = ({
/>
</Box>
)}
{/* TODO: (respondent copy): Remove when respondent copy is out of beta */}
{form?.hasRespondentCopy && isRespondentCopyEnabled ? (
<Box mt="2.5rem" px={{ base: '1rem', md: 0 }}>
<PublicRespondentEmailField />
</Box>
) : null}
<PublicFormPaymentResumeModal />
<PublicFormSubmitButton
onSubmit={onSubmit ? handleSubmit(onSubmit) : undefined}
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "FormSG",
"description": "Form Manager for Government",
"version": "6.271.0",
"version": "6.272.0",
"homepage": "https://form.gov.sg",
"authors": [
"FormSG <[email protected]>"
Expand Down
4 changes: 2 additions & 2 deletions src/app/models/field/__tests__/emailField.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ describe('models.fields.emailField', () => {
expect(actual.field.toObject()).toEqual(expected)
})

it('should set includeFormSummary to false on ResponseMode.Multirespondent forms', async () => {
it('should set includeFormSummary to given on ResponseMode.Multirespondent forms', async () => {
// Arrange
const mockEmailField = {
autoReplyOptions: {
Expand All @@ -125,7 +125,7 @@ describe('models.fields.emailField', () => {
_id: expect.anything(),
autoReplyOptions: {
// Should be always set to false for MRF forms
includeFormSummary: false,
includeFormSummary: true,
},
})
expect(actual.field.toObject()).toEqual(expected)
Expand Down
7 changes: 0 additions & 7 deletions src/app/models/field/emailField.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Schema } from 'mongoose'

import { FormResponseMode } from '../../../../shared/types'
import { validateEmailDomains } from '../../../../shared/utils/email-domain-validation'
import { IEmailFieldSchema } from '../../../types'

Expand Down Expand Up @@ -30,12 +29,6 @@ const createEmailFieldSchema = (): Schema<IEmailFieldSchema> => {
includeFormSummary: {
type: Boolean,
default: false,
set: function (this: IEmailFieldSchema, v: boolean) {
// Set to false if mrf mode regardless of initial value.
return this.parent().responseMode === FormResponseMode.Multirespondent
? false
: v
},
},
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,12 @@ describe('Multirespondent Submission Middleware', () => {
stepsToNotify: [new ObjectId().toHexString()],
}),
// Add other required properties to satisfy IPopulatedForm interface
admin: { _id: new ObjectId() },
admin: {
_id: new ObjectId(),
agency: {
fullName: 'Government Technology Agency',
},
},
permissionList: [],
startPage: { title: 'Start', paragraph: 'Start page' },
endPage: { title: 'End', paragraph: 'End page' },
Expand Down Expand Up @@ -212,7 +217,7 @@ describe('Multirespondent Submission Middleware', () => {
form_logics: MOCK_MRF_SUBMISSION.form_logics, // Should use snapshot from submission
webhook: MOCK_FORM.webhook, // Should use current form data
workflow: MOCK_MRF_SUBMISSION.workflow, // Should use snapshot from submission
hasRespondentCopy: MOCK_FORM.hasRespondentCopy, // Should use current form data
admin: MOCK_FORM.admin, // Should use current form data
emails: MOCK_FORM.emails, // Should use current form data
stepOneEmailNotificationFieldId:
MOCK_FORM.stepOneEmailNotificationFieldId, // Should use current form data
Expand Down
Loading
Loading