Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: mfb v1.1 accept-deny re-prompt #7959

Open
wants to merge 22 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
6cc6789
feat: implement search functionality
kevin9foong Nov 29, 2024
768f9df
feat: add mfb button beside search bar
kevin9foong Nov 29, 2024
8a68323
fix: disable support for mfb for mobile
kevin9foong Nov 29, 2024
d65f838
feat: popover modal for input
kevin9foong Dec 23, 2024
23f0581
feat: add accept deny modal and created field ids from mfb
kevin9foong Dec 24, 2024
9af405a
feat: add delete functionality for deny
kevin9foong Dec 24, 2024
6d8b9f9
feat: support field addition during revert
kevin9foong Dec 24, 2024
c4ebcdb
feat: remove old button
kevin9foong Dec 24, 2024
66521d8
feat: move isAcceptDenyOpen away from store
kevin9foong Dec 24, 2024
8c0847b
feat: add text prompt selector to popover
kevin9foong Dec 24, 2024
eeac69f
fix: remove deleted prop
kevin9foong Dec 30, 2024
70e9630
feat: remove unused text prompt selector
kevin9foong Dec 30, 2024
7441e9a
fix: improve styling and add timeout to clearing field ids
kevin9foong Dec 30, 2024
a965f83
fix: popover posiitoning
kevin9foong Dec 30, 2024
6ea7103
feat: add beta flag
kevin9foong Dec 30, 2024
8edf2cc
feat: make active state for button
kevin9foong Dec 30, 2024
a726584
fix: update failing tc
kevin9foong Dec 30, 2024
89a3f1c
feat: add tc for delete fields by id
kevin9foong Dec 30, 2024
37e0940
feat: add tc for delete form fields controller and service
kevin9foong Dec 30, 2024
b368fd0
feat: add stories for mfb popover
kevin9foong Dec 30, 2024
718385d
fix: bug where recently created field ids are shared across forms
kevin9foong Dec 30, 2024
7ca49d6
fix: remove unused import
kevin9foong Dec 30, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const makeTextPrompt = ({
formId: string
prompt: string
}) => {
return ApiService.post<undefined>(
return ApiService.post<{ message: string; createdFieldIds?: string[] }>(
`${ADMIN_FORM_ENDPOINT}/${formId}/assistance/text-prompt`,
{ prompt },
).then(({ data }) => data)
Expand Down
12 changes: 11 additions & 1 deletion frontend/src/features/admin-form/assistance/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { makeTextPrompt } from '~features/admin-form/assistance/AssistanceServic

import { useToast } from '../../../hooks/useToast'
import { adminFormKeys } from '../common/queries'
import { useMagicFormBuilderStore } from '../create/builder-and-design/useMagicFormBuilderStore'

export const useAssistanceMutations = () => {
const { formId } = useParams()
Expand All @@ -19,7 +20,16 @@ export const useAssistanceMutations = () => {
const useMakeTextPromptMutation = useMutation(
(prompt: string) => makeTextPrompt({ formId, prompt }),
{
onSuccess: () => {
onSuccess: (data) => {
const { createdFieldIds } = data
useMagicFormBuilderStore.setState((state) => {
return {
recentlyCreatedFieldIds: {
...state.recentlyCreatedFieldIds,
[formId]: new Set(createdFieldIds),
},
}
})
queryClient.invalidateQueries(adminFormKeys.id(formId))
toast.closeAll()
toast({ description: 'Form generated successfully', status: 'success' })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const Template: StoryFn = (args) => {
{...args}
isDraggingOver={false}
onClick={() => {}}
onMagicFormButtonClick={() => {}}
/>
</Box>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,132 +4,70 @@ import {
ButtonProps,
Center,
chakra,
Flex,
forwardRef,
Icon,
Text,
} from '@chakra-ui/react'

import { FormResponseMode } from '~shared/types'

import { BxsWidget } from '~assets/icons/BxsWidget'
import { useIsMobile } from '~hooks/useIsMobile'

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

import { MagicFormButton } from './MagicFormButton'

const OrDivider = ({ isMobile }: { isMobile: boolean }) => (
<Flex
width="100%"
maxW={isMobile ? '12rem' : '18rem'}
flexDir="row"
alignItems="center"
justifyContent="space-around"
verticalAlign="middle"
>
<Box flexGrow={1} height="1px" bgColor="black" />
<Text
textStyle="subhead-2"
color="secondary.500"
px="1.5rem"
textAlign={'center'}
>
OR
</Text>
<Box flexGrow={1} height="1px" bgColor="black" />
</Flex>
)

interface EmptyFormPlaceholderProps extends ButtonProps {
isDraggingOver: boolean
onClick: () => void
onMagicFormButtonClick: () => void
}

export const EmptyFormPlaceholder = forwardRef<
EmptyFormPlaceholderProps,
'button'
>(
(
{ isDraggingOver, onClick, onMagicFormButtonClick, ...props },
ref,
): JSX.Element => {
// TODO: (MFB) Remove isTest check when MFB is out of beta
const isTest = import.meta.env.STORYBOOK_NODE_ENV === 'test'
const isMobile = useIsMobile()
const { user } = useUser()
const { data: form } = useAdminForm()
const isStorageMode = form?.responseMode === FormResponseMode.Encrypt
// TODO: (MFB) Remove isTest check when MFB is out of beta
const isMagicFormBuilderEnabled =
isStorageMode && (isTest || user?.betaFlags?.mfb)
>(({ isDraggingOver, onClick, ...props }, ref): JSX.Element => {
const isMobile = useIsMobile()

const placeholderText = useMemo(() => {
if (isDraggingOver) {
return 'Drop your field here'
}
return isMobile
? 'Tap here to add a field'
: 'Drag a field from the Builder on the left to start'
}, [isDraggingOver, isMobile])
const placeholderText = useMemo(() => {
if (isDraggingOver) {
return 'Drop your field here'
}
return isMobile
? 'Tap here to add a field'
: 'Drag a field from the Builder on the left to start'
}, [isDraggingOver, isMobile])

return (
<Box position="relative" h="13.75rem" m={{ base: 0, lg: '1.625rem' }}>
<chakra.button
_hover={{
bg: 'primary.200',
}}
_focus={{
boxShadow: '0 0 0 2px var(--chakra-colors-neutral-500)',
}}
h="100%"
w="100%"
border="1px dashed"
borderColor={isDraggingOver ? 'primary.700' : 'secondary.300'}
borderRadius="4px"
bg="neutral.100"
transitionProperty="common"
transitionDuration="normal"
onClick={onClick}
{...props}
ref={ref}
>
<Center flexDir="column" gap={'0.75rem'}>
<Icon
as={BxsWidget}
__css={{ color: 'secondary.500', fontSize: '1.5rem' }}
/>
<Text
textStyle="subhead-2"
color="secondary.500"
px="1.5rem"
textAlign={'center'}
>
{placeholderText}
</Text>
{isMagicFormBuilderEnabled ? (
<>
<OrDivider isMobile={isMobile} />
<Box h="2.75rem">Box</Box>
</>
) : null}
</Center>
</chakra.button>
{isMagicFormBuilderEnabled ? (
<Box
bottom="2.375rem"
w="100%"
px="2rem"
position="absolute"
display="flex"
justifyContent="center"
return (
<Box position="relative" h="13.75rem" m={{ base: 0, lg: '1.625rem' }}>
<chakra.button
_hover={{
bg: 'primary.200',
}}
_focus={{
boxShadow: '0 0 0 2px var(--chakra-colors-neutral-500)',
}}
h="100%"
w="100%"
border="1px dashed"
borderColor={isDraggingOver ? 'primary.700' : 'secondary.300'}
borderRadius="4px"
bg="neutral.100"
transitionProperty="common"
transitionDuration="normal"
onClick={onClick}
{...props}
ref={ref}
>
<Center flexDir="column" gap={'0.75rem'}>
<Icon
as={BxsWidget}
__css={{ color: 'secondary.500', fontSize: '1.5rem' }}
/>
<Text
textStyle="subhead-2"
color="secondary.500"
px="1.5rem"
textAlign={'center'}
>
<MagicFormButton onClick={onMagicFormButtonClick} />
</Box>
) : null}
</Box>
)
},
)
{placeholderText}
</Text>
</Center>
</chakra.button>
</Box>
)
})

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ interface BuilderFieldsProps {
responseMode: AdminFormDto['responseMode']
fields: AdminFormDto['form_fields']
visibleFieldIds: FieldIdSet
highlightFieldIds: FieldIdSet
isDraggingOver: boolean
}

export const BuilderFields = ({
responseMode,
fields,
visibleFieldIds,
highlightFieldIds,
isDraggingOver,
}: BuilderFieldsProps) => {
const fieldsWithQuestionNos = augmentWithQuestionNo(fields)
Expand Down Expand Up @@ -64,6 +66,7 @@ export const BuilderFields = ({
handleBuilderClick={handleBuilderClick}
isDirty={isDirty}
colorTheme={colorTheme}
isHighlighted={highlightFieldIds.has(f._id)}
{...activeFieldExtraProps}
/>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { BiCog, BiDuplicate, BiGridHorizontal, BiTrash } from 'react-icons/bi'
import { useIsMutating } from 'react-query'
import {
Box,
BoxProps,
ButtonGroup,
chakra,
Collapse,
Expand Down Expand Up @@ -94,6 +95,30 @@ export interface FieldRowContainerProps {
colorTheme?: FormColorTheme
// handleBuilderClick is passed down to prevent unnecessary re-renders from useContext
handleBuilderClick: CreatePageSidebarContextProps['handleBuilderClick']
isHighlighted?: boolean
}

/**
* Used for highlighting fields that were created by Magic Form Builder.
*/
const HighlightableBox = ({
children,
isHighlighted,
...props
}: {
children: React.ReactNode
isHighlighted?: boolean
} & BoxProps) => {
return (
<Box
borderColor="danger.300"
borderRadius="0.25rem"
borderWidth={isHighlighted ? '0.125rem' : '0'}
{...props}
>
{children}
</Box>
)
}

const FieldRowContainer = ({
Expand All @@ -106,6 +131,7 @@ const FieldRowContainer = ({
isDirty,
colorTheme,
handleBuilderClick,
isHighlighted,
}: FieldRowContainerProps): JSX.Element => {
const isMobile = useIsMobile()
const numFormFieldMutations = useIsMutating(adminFormKeys.base)
Expand Down Expand Up @@ -285,7 +311,8 @@ const FieldRowContainer = ({
)}
</chakra.button>
</Fade>
<Box
<HighlightableBox
isHighlighted={isHighlighted}
px={{ base: '0.75rem', md: '1.5rem' }}
pb={{ base: '0.75rem', md: '1.5rem' }}
w="100%"
Expand All @@ -300,7 +327,7 @@ const FieldRowContainer = ({
showMyInfoBadge={isMyInfoField}
/>
</FormProvider>
</Box>
</HighlightableBox>
<Collapse in={isActive} style={{ width: '100%' }}>
{isActive && (
<FieldButtonGroup
Expand Down
Loading
Loading