Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
FormControl,
FormErrorMessage,
ModalBody,
ModalCloseButton,
ModalFooter,
ModalHeader,
Text,
Expand All @@ -17,7 +18,14 @@ import { FormLabel, useIsMobile } from '@opengovsg/design-system-react'
import pairLogo from '@/assets/pair-logo.svg'
import { ImageBox } from '@/components/FlowStepConfigurationModal/ChooseAndAddConnection/ConfigureExcelConnection'
import { AI_FORM_SCHEMA, AiFormData } from '@/pages/AiBuilder/schema'
import { AI_FORM_FIELDS, AI_FORM_IDEAS } from '@/pages/Flows/constants'
import {
AI_FORM_FIELDS,
AI_FORM_IDEAS,
AiChatIdea,
AiFormIdea,
} from '@/pages/Flows/constants'

import IdeaButtons from './IdeaButtons'

export const AIFormModalContent = ({
flowName,
Expand Down Expand Up @@ -50,17 +58,20 @@ export const AIFormModalContent = ({
},
})

const handleIdeaClick = (idea: (typeof AI_FORM_IDEAS)[number]) => {
setValue('trigger', idea.trigger, { shouldValidate: true })
setValue('actions', idea.actions, { shouldValidate: true })
const handleIdeaClick = (idea: AiChatIdea | AiFormIdea) => {
setValue('trigger', (idea as AiFormIdea).trigger, { shouldValidate: true })
setValue('actions', (idea as AiFormIdea).actions, { shouldValidate: true })
}

const isCreate = type === 'create'

return (
<>
<Form onSubmit={handleSubmit(onSubmit)}>
<ModalHeader p="2.5rem 2rem 1.5rem">
<Text textStyle="h4">Build with AI</Text>
</ModalHeader>
{!isCreate && <ModalCloseButton onClick={onBack} />}
<ModalBody>
<Flex gap={4} flexDir="column">
{AI_FORM_FIELDS.map((field) => (
Expand All @@ -85,57 +96,43 @@ export const AIFormModalContent = ({
)}
</FormControl>
))}
<Flex flexDir="row" alignItems="center">
<FormLabel
isRequired
style={{ margin: 0, marginRight: '0.5rem' }}
>
{/* arbitrary isRequired to hide optional text */}
Try:
</FormLabel>
<Flex
flexDir="row"
gap={2}
justifyContent="space-between"
flexWrap="wrap"
>
{AI_FORM_IDEAS.map((idea) => (
<Button
key={idea.label}
size="sm"
bgColor="interaction.sub-subtle.default"
color="#5D6785"
variant="clear"
_hover={{
bgColor: 'interaction.sub-subtle.hover',
}}
onClick={() => handleIdeaClick(idea)}
px={3}
minH={4}
w={isMobile ? 'calc(50% - 4px)' : 'auto'}
flexShrink={0}
>
<Text textStyle="caption-1">{idea.label}</Text>
</Button>
))}
</Flex>
</Flex>
{isCreate && (
<IdeaButtons
ideas={AI_FORM_IDEAS}
onClick={(idea: AiChatIdea | AiFormIdea) =>
handleIdeaClick(idea)
}
builderType="form"
/>
)}
</Flex>
</ModalBody>
<ModalFooter>
<Flex justifyContent="space-between" alignItems="center" w="100%">
<Flex gap={1} alignItems="center">
<Text fontSize="xs" color="gray.500">
Powered by{' '}
</Text>
<ImageBox imageUrl={pairLogo} boxSize={6} />
</Flex>
<Flex
justifyContent={isMobile ? 'flex-end' : 'space-between'}
alignItems="center"
w="100%"
>
{!isMobile && (
<Flex gap={1} alignItems="center" justifyContent="center">
<Text fontSize="xs" color="gray.500">
Powered by{' '}
</Text>
<ImageBox imageUrl={pairLogo} boxSize={6} />
</Flex>
)}
<Flex gap={4}>
<Button variant="clear" colorScheme="secondary" onClick={onBack}>
Back
</Button>
{isCreate && (
<Button
variant="clear"
colorScheme="secondary"
onClick={onBack}
>
Back
</Button>
)}
<Button type="submit" isDisabled={!isValid}>
{type === 'update' ? 'Update workflow' : 'Create'}
{isCreate ? 'Create' : 'Update'}
</Button>
</Flex>
</Flex>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import { FaArrowCircleRight } from 'react-icons/fa'
import { FaCircleStop } from 'react-icons/fa6'
import { Box, Flex, Icon, Text, Textarea } from '@chakra-ui/react'
import { useIsMobile } from '@opengovsg/design-system-react'

import pairLogo from '@/assets/pair-logo.svg'
import { ImageBox } from '@/components/FlowStepConfigurationModal/ChooseAndAddConnection/ConfigureExcelConnection'
Expand All @@ -29,6 +30,7 @@ export default function PromptInput({
sendMessage,
cancelStream,
}: PromptInputProps) {
const isMobile = useIsMobile()
const [input, setInput] = useState<string>('')
const textareaRef = useRef<HTMLTextAreaElement>(null)

Expand Down Expand Up @@ -74,7 +76,7 @@ export default function PromptInput({
w="full"
minH={showIdeas ? '120px' : '50px'}
height="auto"
mb={6}
mb={isMobile ? 0 : 6}
>
<Textarea
ref={textareaRef}
Expand Down Expand Up @@ -153,15 +155,18 @@ export default function PromptInput({
// trigger resize after state update
setTimeout(() => handleResize(), 0)
}}
builderType="chat"
/>
)}

<Flex gap={1} alignItems="center" justify="center" mt={3}>
<Text fontSize="xs" color="gray.500">
Powered by{' '}
</Text>
<ImageBox imageUrl={pairLogo} boxSize={6} />
</Flex>
{!isMobile && (
<Flex gap={1} alignItems="center" justify="center" mt={3}>
<Text fontSize="xs" color="gray.500">
Powered by{' '}
</Text>
<ImageBox imageUrl={pairLogo} boxSize={6} />
</Flex>
)}
</Box>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@ import { AiChatIdea, AiFormIdea } from '@/pages/Flows/constants'
interface IdeaButtonsProps {
ideas: AiChatIdea[] | AiFormIdea[]
onClick: (idea: AiChatIdea | AiFormIdea) => void
builderType: 'chat' | 'form'
}

export default function IdeaButtons({ ideas, onClick }: IdeaButtonsProps) {
export default function IdeaButtons({
ideas,
onClick,
builderType,
}: IdeaButtonsProps) {
const isMobile = useIsMobile()
const isForm = builderType === 'form'

return (
<Flex flexDir="row" alignItems="center">
Expand All @@ -19,10 +25,11 @@ export default function IdeaButtons({ ideas, onClick }: IdeaButtonsProps) {
Try:
</FormLabel>
<Flex
flexDir="row"
flexDir={isMobile ? 'column' : 'row'}
gap={2}
justifyContent="space-between"
flexWrap="wrap"
w={isMobile ? 'full' : 'auto'}
>
{ideas.map((idea) => (
<Button
Expand All @@ -35,13 +42,13 @@ export default function IdeaButtons({ ideas, onClick }: IdeaButtonsProps) {
bgColor: 'interaction.sub-subtle.hover',
}}
onClick={() => onClick(idea)}
px={3}
px={isForm ? 2 : 3}
minH={4}
w={isMobile ? 'calc(50% - 4px)' : 'auto'}
w={isMobile ? 'full' : 'auto'}
flexShrink={0}
>
<TemplateIcon iconName={idea.icon} fontSize="1rem" />
<Text textStyle="caption-1" ml="0.25rem">
<Text textStyle="caption-1" ml={isForm ? 0 : '0.25rem'}>
{idea.label}
</Text>
</Button>
Expand Down
8 changes: 1 addition & 7 deletions packages/frontend/src/pages/Flows/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,8 @@ export const AI_CHAT_IDEAS = [
label: 'Attendance taking',
icon: 'BiCheckDouble',
input:
'I have a FormSG that I am using to track attendance. I need this workflow to track who has signed up and is present. It should also note down if this person is a new registrant.',
"When a new event attendance is received, find the attendee in Tiles. If the attendee is found, update the Attended? column to Yes. If the attendee is not found, create a new row in Tiles with the attendee's details.",
},
// {
// label: 'Send follow ups',
// icon: 'BiEnvelope',
// input:
// 'When a new form submission is received, send a follow up email to the customer.',
// },
]

export type AiChatIdea = {
Expand Down