Skip to content

Commit

Permalink
feat(form-v2/react-to-angular/1): add switch to angular option (#4263)
Browse files Browse the repository at this point in the history
* feat: add switch env endpoint for respondents

* feat: add switchEnvMessage for respondents

* feat: add AdminSwitchEnvMessage

* fix: adjust styling

* fix: adjust PublicSwitchEnvMessage margin

* ref: hardcode angular in params

* feat: add react-query env mutations

* fix: amend cookie expiry date

* fix: update cookie expiry

* fix: navigate to old workspace page

* fix: add window reload

* fix: mutations

* chore: add removal TODOs

* fix: underline inline links
  • Loading branch information
wanlingt authored Jul 25, 2022
1 parent e85d47c commit 81da65b
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 6 deletions.
28 changes: 28 additions & 0 deletions frontend/src/features/env/mutations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// TODO #4279: Remove after React rollout is complete
import { useMutation } from 'react-query'
import { useNavigate } from 'react-router-dom'

import {
adminChooseEnvironment,
publicChooseEnvironment,
} from '~services/EnvService'

export const useEnvMutations = () => {
const navigate = useNavigate()

const publicSwitchEnvMutation = useMutation(() => publicChooseEnvironment(), {
onSuccess: () => window.location.reload(),
})

const adminSwitchEnvMutation = useMutation(() => adminChooseEnvironment(), {
onSuccess: () => {
navigate('/#!/forms')
window.location.reload()
},
})

return {
publicSwitchEnvMutation,
adminSwitchEnvMutation,
}
}
2 changes: 1 addition & 1 deletion frontend/src/features/public-form/PublicFormService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
createEncryptedSubmissionData,
} from './utils/createSubmission'

const PUBLIC_FORMS_ENDPOINT = '/forms'
export const PUBLIC_FORMS_ENDPOINT = '/forms'

/**
* Gets public view of form, along with any
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { FormAuthType } from '~shared/types/form/form'
import { usePublicFormContext } from '~features/public-form/PublicFormContext'

import { FormAuth } from '../FormAuth'
// TODO #4279: Remove after React rollout is complete
import { PublicSwitchEnvMessage } from '../PublicSwitchEnvMessage'

import { FormFields } from './FormFields'
import { FormFieldsSkeleton } from './FormFieldsSkeleton'
Expand Down Expand Up @@ -47,6 +49,7 @@ export const FormFieldsContainer = (): JSX.Element | null => {
<Flex justify="center">
{isAuthRequired ? null : <SectionSidebar />}
<Box w="100%" minW={0} h="fit-content" maxW="57rem">
<PublicSwitchEnvMessage />
{renderFields}
</Box>
{isAuthRequired ? null : <Spacer />}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// TODO #4279: Remove after React rollout is complete
import { Text } from '@chakra-ui/react'

import Button from '~components/Button'
import InlineMessage from '~components/InlineMessage'

import { useEnvMutations } from '~features/env/mutations'

export const PublicSwitchEnvMessage = (): JSX.Element => {
const { publicSwitchEnvMutation } = useEnvMutations()

return (
<InlineMessage variant="warning" mb="1.5rem" mt={{ base: '2rem', md: '0' }}>
<Text>
You’re filling this form on the new FormSG. If you have trouble
submitting,{' '}
<Button variant="link" onClick={() => publicSwitchEnvMutation.mutate}>
<Text as="u">switch to the original one here.</Text>
</Button>
</Text>
</InlineMessage>
)
}
9 changes: 7 additions & 2 deletions frontend/src/features/workspace/WorkspacePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { RolloutAnnouncementModal } from '~features/rollout-announcement/Rollout
import { EmergencyContactModal } from '~features/user/emergency-contact/EmergencyContactModal'
import { useUser } from '~features/user/queries'

// TODO #4279: Remove after React rollout is complete
import { AdminSwitchEnvMessage } from './components/AdminSwitchEnvMessage'
import CreateFormModal from './components/CreateFormModal'
import { EmptyWorkspace } from './components/EmptyWorkspace'
import { WorkspaceFormRows } from './components/WorkspaceFormRow'
Expand Down Expand Up @@ -159,10 +161,13 @@ export const WorkspacePage = (): JSX.Element => {
<Grid
bg="neutral.100"
templateColumns="1fr"
templateRows="auto 1fr auto"
templateRows="auto auto 1fr auto"
minH="100vh"
templateAreas="'header' 'main' 'footer'"
templateAreas="'banner' 'header' 'main' 'footer'"
>
<Container gridArea="banner" maxW={CONTAINER_MAXW} pt="1.5rem">
<AdminSwitchEnvMessage />
</Container>
<Container
gridArea="header"
maxW={CONTAINER_MAXW}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// TODO #4279: Remove after React rollout is complete
import { Text } from '@chakra-ui/react'

import Button from '~components/Button'
import InlineMessage from '~components/InlineMessage'

import { useEnvMutations } from '~features/env/mutations'

export const AdminSwitchEnvMessage = (): JSX.Element => {
const { adminSwitchEnvMutation } = useEnvMutations()

return (
<InlineMessage>
<Text>
Welcome to the new FormSG! You can still{' '}
<Button variant="link" onClick={() => adminSwitchEnvMutation.mutate}>
<Text as="u">switch to the original one,</Text>
</Button>{' '}
which is available until 28 May 2022.
</Text>
</InlineMessage>
)
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { BiPlus } from 'react-icons/bi'
import { Flex, Text } from '@chakra-ui/react'
import { Box, Flex, Text } from '@chakra-ui/react'

import { useIsMobile } from '~hooks/useIsMobile'
import Button from '~components/Button'

// TODO #4279: Remove after React rollout is complete
import { AdminSwitchEnvMessage } from '../AdminSwitchEnvMessage'

import { EmptyWorkspaceSvgr } from './EmptyWorkspaceSvgr'

export interface EmptyWorkspacePage {
Expand All @@ -26,6 +29,9 @@ export const EmptyWorkspace = ({
py="1rem"
bg="neutral.100"
>
<Box pb="1.5rem">
<AdminSwitchEnvMessage />
</Box>
<Text as="h2" textStyle="h2" color="primary.500" mb="1rem">
You don't have any forms yet
</Text>
Expand Down
21 changes: 21 additions & 0 deletions frontend/src/services/EnvService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// TODO #4279: Remove after React rollout is complete
import { UiCookieValues } from '~shared/types'

import { PUBLIC_FORMS_ENDPOINT } from '~features/public-form/PublicFormService'

import { ApiService } from './ApiService'

const ENV_ENDPOINT = '/environment'
const ADMIN_ENDPOINT = '/admin'

export const publicChooseEnvironment = async (): Promise<UiCookieValues> => {
return ApiService.get(
`${PUBLIC_FORMS_ENDPOINT}/${ENV_ENDPOINT}/${UiCookieValues.Angular}`,
).then(({ data }) => data)
}

export const adminChooseEnvironment = async (): Promise<UiCookieValues> => {
return ApiService.get(
`${ADMIN_ENDPOINT}/${ENV_ENDPOINT}/${UiCookieValues.Angular}`,
).then(({ data }) => data)
}
41 changes: 39 additions & 2 deletions src/app/modules/react-migration/react-migration.controller.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// TODO #4279: Remove after React rollout is complete
import path from 'path'

import { FormAuthType, UiCookieValues } from '../../../../shared/types'
Expand All @@ -19,13 +20,22 @@ export const RESPONDENT_COOKIE_OPTIONS = {
secure: !config.isDev,
}

export const RESPONDENT_COOKIE_OPTIONS_WITH_EXPIRY = {
...RESPONDENT_COOKIE_OPTIONS,
maxAge: 31 * 2 * 24 * 60 * 60, // 2 months
}

export const ADMIN_COOKIE_OPTIONS = {
httpOnly: false,
maxAge: 31 * 2 * 24 * 60 * 60, // 2 months
sameSite: 'strict' as const,
secure: !config.isDev,
}

export const ADMIN_COOKIE_OPTIONS_WITH_EXPIRY = {
...ADMIN_COOKIE_OPTIONS,
maxAge: 31 * 2 * 24 * 60 * 60, // 2 months
}

const logger = createLoggerWithLabel(module)

const serveFormReact: ControllerHandler = (_req, res) => {
Expand Down Expand Up @@ -163,6 +173,33 @@ export const adminChooseEnvironment: ControllerHandler<
req.params.ui === UiCookieValues.React
? UiCookieValues.React
: UiCookieValues.Angular
res.cookie(config.reactMigration.adminCookieName, ui, ADMIN_COOKIE_OPTIONS)
res.cookie(
config.reactMigration.adminCookieName,
ui,
// When admin chooses to switch environments, we want them to stay on their
// chosen environment until the alternative is stable.
ADMIN_COOKIE_OPTIONS_WITH_EXPIRY,
)
return res.json({ ui })
}

// Note: frontend is expected to refresh after executing this
export const publicChooseEnvironment: ControllerHandler<
SetEnvironmentParams,
unknown,
unknown,
Record<string, string>
> = (req, res) => {
const ui =
req.params.ui === UiCookieValues.React
? UiCookieValues.React
: UiCookieValues.Angular
res.cookie(
config.reactMigration.respondentCookieName,
ui,
// When public responded chooses to switch environments, we want them to stay on
// their chosen environment until the alternative is stable.
RESPONDENT_COOKIE_OPTIONS_WITH_EXPIRY,
)
return res.json({ ui })
}
1 change: 1 addition & 0 deletions src/app/routes/api/v3/admin/admin.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const AdminRouter = Router()

AdminRouter.use('/forms', AdminFormsRouter)

// TODO #4279: Remove after React rollout is complete
// This endpoint doesn't reaaaallly need to be a verified admin to be used
AdminRouter.get(
'/environment/:ui(react|angular)',
Expand Down
10 changes: 10 additions & 0 deletions src/app/routes/api/v3/forms/public-forms.form.routes.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Router } from 'express'

import * as PublicFormController from '../../../../modules/form/public-form/public-form.controller'
import * as ReactMigrationController from '../../../../modules/react-migration/react-migration.controller'

export const PublicFormsFormRouter = Router()

Expand All @@ -21,3 +22,12 @@ export const PublicFormsFormRouter = Router()
PublicFormsFormRouter.route('/:formId([a-fA-F0-9]{24})').get(
PublicFormController.handleGetPublicForm,
)

// TODO #4279: Remove after React rollout is complete
/**
* Switches the environment cookie for a public form
* @route GET /environment/:ui
*/
PublicFormsFormRouter.route('/environment/:ui(react|angular)').get(
ReactMigrationController.publicChooseEnvironment,
)

0 comments on commit 81da65b

Please sign in to comment.