Integrate SP auctions for app deployment #2
@ -222,13 +222,13 @@ type Mutation {
|
|||||||
addProjectFromTemplate(
|
addProjectFromTemplate(
|
||||||
organizationSlug: String!
|
organizationSlug: String!
|
||||||
data: AddProjectFromTemplateInput
|
data: AddProjectFromTemplateInput
|
||||||
lrn: [String]
|
lrn: String
|
||||||
auctionData: AuctionData
|
auctionData: AuctionData
|
||||||
): Project!
|
): Project!
|
||||||
addProject(
|
addProject(
|
||||||
organizationSlug: String!
|
organizationSlug: String!
|
||||||
data: AddProjectInput
|
data: AddProjectInput
|
||||||
lrn: [String]
|
lrn: String
|
||||||
auctionData: AuctionData
|
auctionData: AuctionData
|
||||||
): Project!
|
): Project!
|
||||||
updateProject(projectId: String!, data: UpdateProjectInput): Boolean!
|
updateProject(projectId: String!, data: UpdateProjectInput): Boolean!
|
||||||
|
@ -644,6 +644,14 @@ export class Service {
|
|||||||
applicationDeploymentRequestData,
|
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;
|
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,
|
step: 2,
|
||||||
|
route: `/${orgSlug}/projects/create/template/configure`,
|
||||||
|
label: 'Configure',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
step: 3,
|
||||||
route: `/${orgSlug}/projects/create/template/deploy`,
|
route: `/${orgSlug}/projects/create/template/deploy`,
|
||||||
label: '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 { RequestError } from 'octokit';
|
||||||
|
|
||||||
import { useOctokit } from '../../../../../context/OctokitContext';
|
import { useOctokit } from '../../../../../context/OctokitContext';
|
||||||
import { useGQLClient } from '../../../../../context/GQLClientContext';
|
|
||||||
import { Template } from '../../../../../types/types';
|
import { Template } from '../../../../../types/types';
|
||||||
import { Heading } from 'components/shared/Heading';
|
import { Heading } from 'components/shared/Heading';
|
||||||
import { Input } from 'components/shared/Input';
|
import { Input } from 'components/shared/Input';
|
||||||
@ -31,7 +30,6 @@ type SubmitRepoValues = {
|
|||||||
const CreateRepo = () => {
|
const CreateRepo = () => {
|
||||||
const { octokit, isAuth } = useOctokit();
|
const { octokit, isAuth } = useOctokit();
|
||||||
const { template } = useOutletContext<{ template: Template }>();
|
const { template } = useOutletContext<{ template: Template }>();
|
||||||
const client = useGQLClient();
|
|
||||||
|
|
||||||
const { orgSlug } = useParams();
|
const { orgSlug } = useParams();
|
||||||
const { toast, dismiss } = useToast();
|
const { toast, dismiss } = useToast();
|
||||||
@ -55,19 +53,18 @@ const CreateRepo = () => {
|
|||||||
|
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
const { addProjectFromTemplate } = await client.addProjectFromTemplate(
|
|
||||||
orgSlug!,
|
|
||||||
{
|
|
||||||
templateOwner: owner,
|
|
||||||
templateRepo: repo,
|
|
||||||
owner: data.account,
|
|
||||||
name: data.repoName,
|
|
||||||
isPrivate: false,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
navigate(
|
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) {
|
} catch (err) {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@ -203,7 +200,7 @@ const CreateRepo = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Deploy
|
Next
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import CreateRepo from './index';
|
import CreateRepo from './index';
|
||||||
|
import Configure from './Configure';
|
||||||
import Deploy from './Deploy';
|
import Deploy from './Deploy';
|
||||||
|
|
||||||
export const templateRoutes = [
|
export const templateRoutes = [
|
||||||
@ -6,6 +7,10 @@ export const templateRoutes = [
|
|||||||
index: true,
|
index: true,
|
||||||
element: <CreateRepo />,
|
element: <CreateRepo />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'configure',
|
||||||
|
element: <Configure />,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'deploy',
|
path: 'deploy',
|
||||||
element: <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`
|
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) {
|
addProjectFromTemplate(organizationSlug: $organizationSlug, data: $data, lrn: $lrn, auctionData: $auctionData) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
var addProject = import_client2.gql`
|
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) {
|
addProject(organizationSlug: $organizationSlug, data: $data, lrn: $lrn, auctionData: $auctionData) {
|
||||||
id
|
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`
|
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) {
|
addProjectFromTemplate(organizationSlug: $organizationSlug, data: $data, lrn: $lrn, auctionData: $auctionData) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
var addProject = gql2`
|
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) {
|
addProject(organizationSlug: $organizationSlug, data: $data, lrn: $lrn, auctionData: $auctionData) {
|
||||||
id
|
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`
|
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) {
|
addProjectFromTemplate(organizationSlug: $organizationSlug, data: $data, lrn: $lrn, auctionData: $auctionData) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
@ -57,7 +57,7 @@ export const addProjectFromTemplate = gql`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const addProject = 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) {
|
addProject(organizationSlug: $organizationSlug, data: $data, lrn: $lrn, auctionData: $auctionData) {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user