diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 962dea062..247f984c7 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -803,7 +803,6 @@ "__PLAN_PAGE_EXPERT_REVIEW_TOOLTIP_CONTENT": "An expert will contact you within 3-5 business days with a custom quote", "__PLAN_PAGE_EXPERT_REVIEW_WARNING": "Requires expert review", "__PLAN_PAGE_GROUP_TITLE_ACTIVITY_SCOPE": "Activity Scope", - "__PLAN_PAGE_GROUP_TITLE_ADDITIONAL_DETAILS": "Additional Details", "__PLAN_PAGE_GROUP_TITLE_ADVANCED_CRITERIA": "Other", "__PLAN_PAGE_GROUP_TITLE_BEFORE_STARTING": " ", "__PLAN_PAGE_GROUP_TITLE_BEHAVIOURAL_DATA": "Behavioural Data", diff --git a/src/locales/it/translation.json b/src/locales/it/translation.json index f3dbda73c..bc2913b6d 100644 --- a/src/locales/it/translation.json +++ b/src/locales/it/translation.json @@ -833,7 +833,6 @@ "__PLAN_PAGE_EXPERT_REVIEW_TOOLTIP_CONTENT": "", "__PLAN_PAGE_EXPERT_REVIEW_WARNING": "", "__PLAN_PAGE_GROUP_TITLE_ACTIVITY_SCOPE": "", - "__PLAN_PAGE_GROUP_TITLE_ADDITIONAL_DETAILS": "", "__PLAN_PAGE_GROUP_TITLE_ADVANCED_CRITERIA": "", "__PLAN_PAGE_GROUP_TITLE_BEFORE_STARTING": "", "__PLAN_PAGE_GROUP_TITLE_BEHAVIOURAL_DATA": "", diff --git a/src/pages/Plan/common/constants.ts b/src/pages/Plan/common/constants.ts index ec1f8ebb4..131200246 100644 --- a/src/pages/Plan/common/constants.ts +++ b/src/pages/Plan/common/constants.ts @@ -15,7 +15,7 @@ export const MODULE_GROUPS: Record = { { id: 'essentials', title: '__PLAN_PAGE_GROUP_TITLE_ESSENTIALS', - modules: ['goal'], + modules: ['goal', 'out_of_scope'], }, { id: 'technicalRequirements', @@ -75,11 +75,6 @@ export const MODULE_GROUPS: Record = { title: '__PLAN_PAGE_GROUP_TITLE_ACTIVITY_SCOPE', modules: ['tasks'], }, - { - id: 'additionalDetails', - title: '__PLAN_PAGE_GROUP_TITLE_ADDITIONAL_DETAILS', - modules: ['out_of_scope'], - }, ], summary: [], }; @@ -99,7 +94,6 @@ const i18nPlanTitles = () => { t('__PLAN_PAGE_GROUP_TITLE_BEHAVIOURAL_DATA'); t('__PLAN_PAGE_GROUP_TITLE_ADVANCED_CRITERIA'); t('__PLAN_PAGE_GROUP_TITLE_ACTIVITY_SCOPE'); - t('__PLAN_PAGE_GROUP_TITLE_ADDITIONAL_DETAILS'); // Tab titles t('__PLAN_PAGE_TAB_SETUP_TAB_TITLE'); t('__PLAN_PAGE_TAB_TARGET_TAB_TITLE'); diff --git a/src/pages/Plan/modules/Factory/modules/Tasks/Component/parts/CreateTaskListsWithAI.tsx b/src/pages/Plan/modules/Factory/modules/Tasks/Component/parts/CreateTaskListsWithAI.tsx index 83d80347a..53ed73e09 100644 --- a/src/pages/Plan/modules/Factory/modules/Tasks/Component/parts/CreateTaskListsWithAI.tsx +++ b/src/pages/Plan/modules/Factory/modules/Tasks/Component/parts/CreateTaskListsWithAI.tsx @@ -1,20 +1,33 @@ import { + AccordionNew, Button, - Textarea, FormField, - Label, - Message, Input, - AccordionNew, + Label, LG, + Message, + Textarea, } from '@appquality/unguess-design-system'; import { useEffect, useMemo, useState } from 'react'; import { useParams } from 'react-router-dom'; +import { useAppSelector } from 'src/app/hooks'; import { appTheme } from 'src/app/theme'; import { useGetServicesApiKJobsByJobIdQuery, usePostServicesApiKUsecasesMutation, } from 'src/features/api'; +import { processItemOutput } from './processItemOutput'; + +// constants +const MODULES_TO_PROMPT = [ + 'title', + 'goal', + 'out_of_scope', + 'tasks', + 'language', + 'touchpoints', +]; +const MAX_PROMPT_LENGTH = 102300; export const CreateTaskListsWithAI = () => { const { planId } = useParams(); @@ -23,9 +36,12 @@ export const CreateTaskListsWithAI = () => { const [taskCount, setTaskCount] = useState(3); const [isCreating, setIsCreating] = useState(false); const [pollingInterval, setPollingInterval] = useState(0); + + const { records } = useAppSelector((state) => state.planModules); + + // API hooks const [postServicesApiKUsecases, { data: jobData, error: postError }] = usePostServicesApiKUsecasesMutation(); - const { data: useCasesData, error: useCasesError } = useGetServicesApiKJobsByJobIdQuery( { jobId: jobData?.jobId || '' }, @@ -35,11 +51,13 @@ export const CreateTaskListsWithAI = () => { } ); + // Form inputs and button are disabled while creating the task lists or while polling for results const isFormDisabled = useMemo( () => isCreating || pollingInterval > 0, [isCreating, pollingInterval] ); + // Button is disabled if form is disabled or if user prompt is too short const isButtonDisabled = useMemo( () => userPrompt.length < MIN_LENGTH || isFormDisabled, [userPrompt, isFormDisabled] @@ -47,12 +65,21 @@ export const CreateTaskListsWithAI = () => { const handleClick = async () => { setIsCreating(true); - console.log('Button clicked', userPrompt); + // gather modules info to prepend to the user prompt + const modulesInfo = Object.entries(records) + .filter(([key]) => MODULES_TO_PROMPT.includes(key)) + .map( + ([key, item]) => + `Module: ${key}, Config: ${JSON.stringify(processItemOutput(item))}` + ) + .join('\n'); + const fullPrompt = `User prompt:\n${userPrompt}\nModules info:\n${modulesInfo}`; + await postServicesApiKUsecases({ body: { planId: planId || '', count: taskCount, - requirements: userPrompt, + requirements: fullPrompt.slice(0, MAX_PROMPT_LENGTH), }, }); setIsCreating(false); @@ -61,7 +88,6 @@ export const CreateTaskListsWithAI = () => { // Polling for job status every 5 seconds when jobId becomes available or changes useEffect(() => { if (jobData?.jobId) { - console.log('Job ID received:', jobData.jobId); setPollingInterval(5000); } }, [jobData?.jobId]); @@ -69,7 +95,6 @@ export const CreateTaskListsWithAI = () => { // Stop polling when job is completed useEffect(() => { if (useCasesData?.status === 'completed' && useCasesData?.result) { - console.log('Use cases data received:', useCasesData); setPollingInterval(0); } }, [useCasesData]); @@ -127,7 +152,7 @@ export const CreateTaskListsWithAI = () => { Generated Task Lists: - {useCasesData.result.useCases.map((useCase: any, index: number) => ( + {useCasesData.result.useCases.map((useCase: any) => ( diff --git a/src/pages/Plan/modules/Factory/modules/Tasks/Component/parts/processItemOutput.ts b/src/pages/Plan/modules/Factory/modules/Tasks/Component/parts/processItemOutput.ts new file mode 100644 index 000000000..1a3596fd0 --- /dev/null +++ b/src/pages/Plan/modules/Factory/modules/Tasks/Component/parts/processItemOutput.ts @@ -0,0 +1,17 @@ +// Helper function to process module item output for better readability in the AI prompt +export const processItemOutput = (item: any): any => { + if (Array.isArray(item)) { + // If it's an array, process each item in the array + return item.map((subItem) => processItemOutput(subItem)); + } + if (typeof item === 'object' && item !== null) { + // recursively process nested values + return Object.fromEntries( + Object.entries(item) + // here we can filter out any keys we don't want to include in the prompt, for example 'id' + .filter(([key]) => key !== 'id') + .map(([key, value]) => [key, processItemOutput(value)]) + ); + } + return item; +};