Skip to content

feat(PM-1365): Populate project field in copilot request form when query param presents #1173

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

Merged
merged 2 commits into from
Aug 1, 2025
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
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ workflows:
- LVT-256
- CORE-635
- feat/system-admin
- pm-1506_1
- pm-1365_1

- deployQa:
context: org-global
Expand Down
42 changes: 36 additions & 6 deletions src/apps/copilots/src/pages/copilot-request-form/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { FC, useContext, useEffect, useMemo, useState } from 'react'
import { bind, debounce, isEmpty } from 'lodash'
import { toast } from 'react-toastify'
import { Params, useNavigate, useParams } from 'react-router-dom'
import { Params, useNavigate, useParams, useSearchParams } from 'react-router-dom'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The useSearchParams hook is imported but not used in the code. Please ensure that it is utilized if needed, or remove the import to keep the code clean.

import classNames from 'classnames'

import { profileContext, ProfileContextData } from '~/libs/core'
import { Button, IconSolid, InputDatePicker, InputMultiselectOption,
InputRadio, InputSelect, InputSelectReact, InputText, InputTextarea } from '~/libs/ui'
import { InputSkillSelector } from '~/libs/shared'

import { getProjects, ProjectsResponse, useProjects } from '../../services/projects'
import { getProject, getProjects, ProjectsResponse, useProjects } from '../../services/projects'
import { ProjectTypes, ProjectTypeValues } from '../../constants'
import { CopilotRequestResponse, saveCopilotRequest, useCopilotRequest } from '../../services/copilot-requests'
import { Project } from '../../models/Project'

import styles from './styles.module.scss'

Expand All @@ -37,11 +38,13 @@ const CopilotRequestForm: FC<{}> = () => {
const { profile }: ProfileContextData = useContext(profileContext)
const navigate = useNavigate()
const routeParams: Params<string> = useParams()
const [params] = useSearchParams()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a more descriptive name for the params variable to clarify its purpose, such as searchParams.


const [formValues, setFormValues] = useState<any>({})
const [isFormChanged, setIsFormChanged] = useState(false)
const [formErrors, setFormErrors] = useState<any>({})
const [paymentType, setPaymentType] = useState<string>('')
const [projectFromQuery, setProjectFromQuery] = useState<Project>()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The projectFromQuery state is initialized but not used in the provided diff. Ensure that it is utilized appropriately in the component logic or remove it if unnecessary.


const { data: copilotRequestData }: CopilotRequestResponse = useCopilotRequest(routeParams.requestId)

Expand All @@ -51,15 +54,42 @@ const CopilotRequestForm: FC<{}> = () => {
}
}, [copilotRequestData])

const fetchProject = async (): Promise<void> => {
const projectId = params.get('projectId')

if (!projectId) {
return
}

const project = await getProject(projectId as string)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding error handling for the getProject function to manage cases where the project might not be found or the request fails.


setFormValues((prevValues: any) => ({
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid using any type for prevValues. Consider defining a specific type for form values to improve type safety.

...prevValues,
projectId: project.id,
}))
setIsFormChanged(true)
setProjectFromQuery(project)
}

useEffect(() => {
fetchProject()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that fetchProject is only called when necessary. Currently, it will be called on every change to params, which might not be efficient if params changes frequently.

}, [params])

const { data: projects = [] }: ProjectsResponse = useProjects(undefined, {
filter: { id: copilotRequestData?.projectId },
isPaused: () => !copilotRequestData?.projectId,
})

const projectOptions = useMemo(() => projects.map(p => ({
label: p.name,
value: p.id,
})), [projects])
const projectOptions = useMemo(() => {
const projectsFromResponse = projects.map(p => ({
label: p.name,
value: p.id,
}))

return projectFromQuery
? [...projectsFromResponse, { label: projectFromQuery.name, value: projectFromQuery.id }]
: projectsFromResponse
}, [projects, projectFromQuery])

const projectTypes = ProjectTypes ? ProjectTypes.map(project => ({
label: project,
Expand Down
5 changes: 5 additions & 0 deletions src/apps/copilots/src/services/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ export const useProjects = (search?: string, config?: {isPaused?: () => boolean,
})
}

export const getProject = (projectId: string): Promise<Project> => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding error handling to the getProject function to manage cases where the request might fail or return an unexpected response. This will improve the robustness of the function.

const url = `${baseUrl}/${projectId}`
return xhrGetAsync<Project>(url)
}

export const getProjects = (search?: string, filter?: any): Promise<Project[]> => {
const params = { name: `"${search}"`, ...filter }
const url = buildUrl(baseUrl, params)
Expand Down