Implement UI to add configure deployment step
This commit is contained in:
		
							parent
							
								
									f49c2af8e4
								
							
						
					
					
						commit
						ede9cd44b4
					
				| @ -222,13 +222,13 @@ type Mutation { | ||||
|   addProjectFromTemplate( | ||||
|     organizationSlug: String! | ||||
|     data: AddProjectFromTemplateInput | ||||
|     lrn: [String] | ||||
|     lrn: String | ||||
|     auctionData: AuctionData | ||||
|   ): Project! | ||||
|   addProject( | ||||
|     organizationSlug: String! | ||||
|     data: AddProjectInput | ||||
|     lrn: [String] | ||||
|     lrn: String | ||||
|     auctionData: AuctionData | ||||
|   ): Project! | ||||
|   updateProject(projectId: String!, data: UpdateProjectInput): Boolean! | ||||
|  | ||||
| @ -644,6 +644,14 @@ export class Service { | ||||
|       applicationDeploymentRequestData, | ||||
|     }); | ||||
| 
 | ||||
|     // Save deployer lrn only if present
 | ||||
|     let updateData: Partial<Project> = {}; | ||||
|     if (lrn) { | ||||
|       updateData.deployerLrn = [lrn]; | ||||
|     } | ||||
| 
 | ||||
|     await this.db.updateProjectById(data.project.id!, updateData); | ||||
| 
 | ||||
|     return newDeployment; | ||||
|   } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										165
									
								
								packages/frontend/src/components/projects/create/Configure.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								packages/frontend/src/components/projects/create/Configure.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,165 @@ | ||||
| import { useCallback, useState } from 'react'; | ||||
| import { useForm, Controller, SubmitHandler } from 'react-hook-form'; | ||||
| import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'; | ||||
| 
 | ||||
| import { Heading } from '../../shared/Heading'; | ||||
| import { Button } from '../../shared/Button'; | ||||
| import { Select, SelectOption } from 'components/shared/Select'; | ||||
| import { Input } from 'components/shared/Input'; | ||||
| import { useToast } from 'components/shared/Toast'; | ||||
| import { useGQLClient } from '../../../context/GQLClientContext'; | ||||
| 
 | ||||
| type ConfigureFormValues = { | ||||
|   option: string; | ||||
|   lrn?: string; | ||||
|   numProviders?: number; | ||||
|   maxPrice?: number; | ||||
| }; | ||||
| 
 | ||||
| const Configure = () => { | ||||
|   const [searchParams] = useSearchParams(); | ||||
|   const templateId = searchParams.get('templateId'); | ||||
|   const location = useLocation(); | ||||
|   const { templateOwner, templateRepo, owner, name, isPrivate, orgSlug } = location.state || {}; | ||||
| 
 | ||||
|   const navigate = useNavigate(); | ||||
|   const { toast, dismiss } = useToast(); | ||||
|   const client = useGQLClient(); | ||||
| 
 | ||||
|   const [isLoading, setIsLoading] = useState(false); | ||||
|   const { handleSubmit, control, watch } = useForm<ConfigureFormValues>({ | ||||
|     defaultValues: { option: 'LRN' }, | ||||
|   }); | ||||
| 
 | ||||
|   const selectedOption = watch('option'); | ||||
| 
 | ||||
|   const onSubmit: SubmitHandler<ConfigureFormValues> = useCallback( | ||||
|     async (data) => { | ||||
|       setIsLoading(true); | ||||
| 
 | ||||
|       try { | ||||
|         const projectData: any = { | ||||
|           templateOwner, | ||||
|           templateRepo, | ||||
|           owner, | ||||
|           name, | ||||
|           isPrivate | ||||
|         }; | ||||
| 
 | ||||
|         let configData: any; | ||||
|         if (data.option === 'LRN') { | ||||
|           configData = data.lrn; | ||||
|         } else if (data.option === 'Auction') { | ||||
|           configData = { | ||||
|             numProviders: data.numProviders, | ||||
|             maxPrice: data.maxPrice | ||||
|           } | ||||
|         } | ||||
| 
 | ||||
|         const { addProjectFromTemplate } = await client.addProjectFromTemplate( | ||||
|           orgSlug, | ||||
|           projectData, | ||||
|           configData | ||||
|         ); | ||||
| 
 | ||||
|         navigate(`/${orgSlug}/projects/create/template/deploy?projectId=${addProjectFromTemplate.id}&templateId=${templateId}`); | ||||
|       } catch (error) { | ||||
|         console.error('Error creating project:', error); | ||||
|         toast({ | ||||
|           id: 'error-creating-project', | ||||
|           title: 'Error creating project', | ||||
|           variant: 'error', | ||||
|           onDismiss: dismiss, | ||||
|         }); | ||||
|       } finally { | ||||
|         setIsLoading(false); | ||||
|       } | ||||
|     }, | ||||
|     [client, isPrivate, templateId, navigate, dismiss, toast] | ||||
|   ); | ||||
| 
 | ||||
|   return ( | ||||
|     <div className="space-y-7"> | ||||
|       <div className="flex justify-between"> | ||||
|         <div className="space-y-1.5"> | ||||
|           <Heading as="h4" className="md:text-lg font-medium"> | ||||
|             Configure deployment | ||||
|           </Heading> | ||||
|         </div> | ||||
|       </div> | ||||
| 
 | ||||
|       <form onSubmit={handleSubmit(onSubmit)}> | ||||
|       <div className="flex flex-col gap-4 lg:gap-7 w-full"> | ||||
|         <div className="flex flex-col justify-start gap-3"> | ||||
|           <span className="text-sm text-elements-high-em">Choose an option</span> | ||||
|           <Controller | ||||
|             name="option" | ||||
|             control={control} | ||||
|             render={({ field: { value, onChange } }) => ( | ||||
|               <Select | ||||
|                 value={{ value } as SelectOption} | ||||
|                 onChange={(value) => | ||||
|                   onChange((value as SelectOption).value) | ||||
|                 } | ||||
|                 options={[ | ||||
|                   { value: 'LRN', label: 'Set LRN' }, | ||||
|                   { value: 'Auction', label: 'Create Auction' }, | ||||
|                 ]} | ||||
|               /> | ||||
|             )} | ||||
|           /> | ||||
|         </div> | ||||
| 
 | ||||
|         {selectedOption === 'LRN' && ( | ||||
|           <div className="flex flex-col justify-start gap-3"> | ||||
|             <span className="text-sm text-elements-high-em">Enter LRN</span> | ||||
|             <Controller | ||||
|               name="lrn" | ||||
|               control={control} | ||||
|               render={({ field: { value, onChange } }) => ( | ||||
|                 <Input value={value} onChange={onChange} /> | ||||
|               )} | ||||
|             /> | ||||
|           </div> | ||||
|         )} | ||||
| 
 | ||||
|         {selectedOption === 'Auction' && ( | ||||
|           <> | ||||
|             <div className="flex flex-col justify-start gap-3"> | ||||
|               <span className="text-sm text-elements-high-em">Num Providers</span> | ||||
|               <Controller | ||||
|                 name="numProviders" | ||||
|                 control={control} | ||||
|                 render={({ field: { value, onChange } }) => ( | ||||
|                   <Input type="number" value={value} onChange={onChange} /> | ||||
|                 )} | ||||
|               /> | ||||
|             </div> | ||||
|             <div className="flex flex-col justify-start gap-3"> | ||||
|               <span className="text-sm text-elements-high-em">Max Price</span> | ||||
|               <Controller | ||||
|                 name="maxPrice" | ||||
|                 control={control} | ||||
|                 render={({ field: { value, onChange } }) => ( | ||||
|                   <Input type="number" value={value} onChange={onChange} /> | ||||
|                 )} | ||||
|               /> | ||||
|             </div> | ||||
|           </> | ||||
|         )} | ||||
| 
 | ||||
|         <div> | ||||
|           <Button | ||||
|             type="submit" | ||||
|             disabled={isLoading} | ||||
|           > | ||||
|             {isLoading? 'Deploying' : 'Deploy' } | ||||
|           </Button> | ||||
|         </div> | ||||
|       </div> | ||||
|     </form> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default Configure; | ||||
| @ -31,6 +31,11 @@ const CreateWithTemplate = () => { | ||||
|     }, | ||||
|     { | ||||
|       step: 2, | ||||
|       route: `/${orgSlug}/projects/create/template/configure`, | ||||
|       label: 'Configure', | ||||
|     }, | ||||
|     { | ||||
|       step: 3, | ||||
|       route: `/${orgSlug}/projects/create/template/deploy`, | ||||
|       label: 'Deploy', | ||||
|     }, | ||||
|  | ||||
| @ -0,0 +1,7 @@ | ||||
| import ConfigureComponent from '../../../../../components/projects/create/Configure'; | ||||
| 
 | ||||
| const Configure = () => { | ||||
|   return <ConfigureComponent />; | ||||
| }; | ||||
| 
 | ||||
| export default Configure; | ||||
| @ -6,7 +6,6 @@ import { useMediaQuery } from 'usehooks-ts'; | ||||
| import { RequestError } from 'octokit'; | ||||
| 
 | ||||
| import { useOctokit } from '../../../../../context/OctokitContext'; | ||||
| import { useGQLClient } from '../../../../../context/GQLClientContext'; | ||||
| import { Template } from '../../../../../types/types'; | ||||
| import { Heading } from 'components/shared/Heading'; | ||||
| import { Input } from 'components/shared/Input'; | ||||
| @ -31,7 +30,6 @@ type SubmitRepoValues = { | ||||
| const CreateRepo = () => { | ||||
|   const { octokit, isAuth } = useOctokit(); | ||||
|   const { template } = useOutletContext<{ template: Template }>(); | ||||
|   const client = useGQLClient(); | ||||
| 
 | ||||
|   const { orgSlug } = useParams(); | ||||
|   const { toast, dismiss } = useToast(); | ||||
| @ -55,19 +53,18 @@ const CreateRepo = () => { | ||||
| 
 | ||||
|         setIsLoading(true); | ||||
| 
 | ||||
|         const { addProjectFromTemplate } = await client.addProjectFromTemplate( | ||||
|           orgSlug!, | ||||
|           { | ||||
|             templateOwner: owner, | ||||
|             templateRepo: repo, | ||||
|             owner: data.account, | ||||
|             name: data.repoName, | ||||
|             isPrivate: false, | ||||
|           }, | ||||
|         ); | ||||
| 
 | ||||
|         navigate( | ||||
|           `deploy?projectId=${addProjectFromTemplate.id}&templateId=${template.id}`, | ||||
|           `configure?templateId=${template.id}`, | ||||
|           { | ||||
|             state: { | ||||
|               templateOwner: owner, | ||||
|               templateRepo: repo, | ||||
|               owner: data.account, | ||||
|               name: data.repoName, | ||||
|               isPrivate: false, | ||||
|               orgSlug | ||||
|             }, | ||||
|           } | ||||
|         ); | ||||
|       } catch (err) { | ||||
|         setIsLoading(false); | ||||
| @ -203,7 +200,7 @@ const CreateRepo = () => { | ||||
|               ) | ||||
|             } | ||||
|           > | ||||
|             Deploy | ||||
|             Next | ||||
|           </Button> | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| import CreateRepo from './index'; | ||||
| import Configure from './Configure'; | ||||
| import Deploy from './Deploy'; | ||||
| 
 | ||||
| export const templateRoutes = [ | ||||
| @ -6,6 +7,10 @@ export const templateRoutes = [ | ||||
|     index: true, | ||||
|     element: <CreateRepo />, | ||||
|   }, | ||||
|   { | ||||
|     path: 'configure', | ||||
|     element: <Configure />, | ||||
|   }, | ||||
|   { | ||||
|     path: 'deploy', | ||||
|     element: <Deploy />, | ||||
|  | ||||
							
								
								
									
										4
									
								
								packages/gql-client/dist/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								packages/gql-client/dist/index.js
									
									
									
									
										vendored
									
									
								
							| @ -314,14 +314,14 @@ var updateDeploymentToProd = import_client2.gql` | ||||
|   } | ||||
| `;
 | ||||
| var addProjectFromTemplate = import_client2.gql` | ||||
|   mutation ($organizationSlug: String!, $data: AddProjectFromTemplateInput, $lrn: string, $auctionData: Auctiondata) { | ||||
|   mutation ($organizationSlug: String!, $data: AddProjectFromTemplateInput, $lrn: String, $auctionData: AuctionData) { | ||||
|     addProjectFromTemplate(organizationSlug: $organizationSlug, data: $data, lrn: $lrn, auctionData: $auctionData) { | ||||
|       id | ||||
|     } | ||||
|   } | ||||
| `;
 | ||||
| var addProject = import_client2.gql` | ||||
|   mutation ($organizationSlug: String!, $data: AddProjectInput, $lrn: string, $auctionData: Auctiondata) { | ||||
|   mutation ($organizationSlug: String!, $data: AddProjectInput, $lrn: String, $auctionData: AuctionData) { | ||||
|     addProject(organizationSlug: $organizationSlug, data: $data, lrn: $lrn, auctionData: $auctionData) { | ||||
|       id | ||||
|     } | ||||
|  | ||||
							
								
								
									
										2
									
								
								packages/gql-client/dist/index.js.map
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								packages/gql-client/dist/index.js.map
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										4
									
								
								packages/gql-client/dist/index.mjs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								packages/gql-client/dist/index.mjs
									
									
									
									
										vendored
									
									
								
							| @ -287,14 +287,14 @@ var updateDeploymentToProd = gql2` | ||||
|   } | ||||
| `;
 | ||||
| var addProjectFromTemplate = gql2` | ||||
|   mutation ($organizationSlug: String!, $data: AddProjectFromTemplateInput, $lrn: string, $auctionData: Auctiondata) { | ||||
|   mutation ($organizationSlug: String!, $data: AddProjectFromTemplateInput, $lrn: String, $auctionData: AuctionData) { | ||||
|     addProjectFromTemplate(organizationSlug: $organizationSlug, data: $data, lrn: $lrn, auctionData: $auctionData) { | ||||
|       id | ||||
|     } | ||||
|   } | ||||
| `;
 | ||||
| var addProject = gql2` | ||||
|   mutation ($organizationSlug: String!, $data: AddProjectInput, $lrn: string, $auctionData: Auctiondata) { | ||||
|   mutation ($organizationSlug: String!, $data: AddProjectInput, $lrn: String, $auctionData: AuctionData) { | ||||
|     addProject(organizationSlug: $organizationSlug, data: $data, lrn: $lrn, auctionData: $auctionData) { | ||||
|       id | ||||
|     } | ||||
|  | ||||
							
								
								
									
										2
									
								
								packages/gql-client/dist/index.mjs.map
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								packages/gql-client/dist/index.mjs.map
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -49,7 +49,7 @@ export const updateDeploymentToProd = gql` | ||||
| `;
 | ||||
| 
 | ||||
| export const addProjectFromTemplate = gql` | ||||
|   mutation ($organizationSlug: String!, $data: AddProjectFromTemplateInput, $lrn: string, $auctionData: Auctiondata) { | ||||
|   mutation ($organizationSlug: String!, $data: AddProjectFromTemplateInput, $lrn: String, $auctionData: AuctionData) { | ||||
|     addProjectFromTemplate(organizationSlug: $organizationSlug, data: $data, lrn: $lrn, auctionData: $auctionData) { | ||||
|       id | ||||
|     } | ||||
| @ -57,7 +57,7 @@ export const addProjectFromTemplate = gql` | ||||
| `;
 | ||||
| 
 | ||||
| export const addProject = gql` | ||||
|   mutation ($organizationSlug: String!, $data: AddProjectInput, $lrn: string, $auctionData: Auctiondata) { | ||||
|   mutation ($organizationSlug: String!, $data: AddProjectInput, $lrn: String, $auctionData: AuctionData) { | ||||
|     addProject(organizationSlug: $organizationSlug, data: $data, lrn: $lrn, auctionData: $auctionData) { | ||||
|       id | ||||
|     } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user