mirror of
https://github.com/snowball-tools/snowballtools-base.git
synced 2024-11-17 16:29:19 +00:00
Implement functionality for adding new domain in project settings (#48)
* Add mutation to create new domain * Update mutation to create two domains for www and non-www variant * Add gql-client method and frontend to create domain * Display fetched domains in domains tab panel using project id * Fix graphql type for fetching domains --------- Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
parent
8c38d4788e
commit
a34e2286a6
@ -11,6 +11,7 @@ import { Project } from './entity/Project';
|
|||||||
import { Deployment, Environment } from './entity/Deployment';
|
import { Deployment, Environment } from './entity/Deployment';
|
||||||
import { ProjectMember } from './entity/ProjectMember';
|
import { ProjectMember } from './entity/ProjectMember';
|
||||||
import { EnvironmentVariable } from './entity/EnvironmentVariable';
|
import { EnvironmentVariable } from './entity/EnvironmentVariable';
|
||||||
|
import { Domain } from './entity/Domain';
|
||||||
|
|
||||||
const log = debug('snowball:database');
|
const log = debug('snowball:database');
|
||||||
|
|
||||||
@ -261,7 +262,7 @@ export class Database {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async redeployToProdById (deploymentId: string): Promise<boolean> {
|
async redeployToProdById (deploymentId: string): Promise<Deployment> {
|
||||||
const deploymentRepository = this.dataSource.getRepository(Deployment);
|
const deploymentRepository = this.dataSource.getRepository(Deployment);
|
||||||
const deployment = await deploymentRepository.findOne({
|
const deployment = await deploymentRepository.findOne({
|
||||||
relations: {
|
relations: {
|
||||||
@ -284,13 +285,8 @@ export class Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await deploymentRepository.update({ id: Number(deploymentId) }, { domain: null, isCurrent: false });
|
await deploymentRepository.update({ id: Number(deploymentId) }, { domain: null, isCurrent: false });
|
||||||
const savedUpdatedDeployment = await deploymentRepository.save(updatedDeployment);
|
|
||||||
|
|
||||||
if (savedUpdatedDeployment) {
|
return deploymentRepository.save(updatedDeployment);
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteProjectById (projectId: string): Promise<boolean> {
|
async deleteProjectById (projectId: string): Promise<boolean> {
|
||||||
@ -317,4 +313,56 @@ export class Database {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async addDomainByProjectId (projectId: string, domainDetails: { name: string }): Promise<Domain[]> {
|
||||||
|
const domainRepository = this.dataSource.getRepository(Domain);
|
||||||
|
const projectRepository = this.dataSource.getRepository(Project);
|
||||||
|
|
||||||
|
const currentProject = await projectRepository.findOneBy({
|
||||||
|
id: projectId
|
||||||
|
});
|
||||||
|
|
||||||
|
if (currentProject === null) {
|
||||||
|
throw new Error(`Project with ${projectId} not found`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const primaryDomainDetails = {
|
||||||
|
...domainDetails,
|
||||||
|
isRedirected: false,
|
||||||
|
branch: currentProject.prodBranch,
|
||||||
|
project: currentProject
|
||||||
|
};
|
||||||
|
|
||||||
|
const primaryDomain = domainRepository.create(primaryDomainDetails as DeepPartial<Domain>);
|
||||||
|
|
||||||
|
const domainArr = domainDetails.name.split('www.');
|
||||||
|
|
||||||
|
const redirectedDomainDetails = {
|
||||||
|
name: domainArr.length > 1 ? domainArr[1] : `www.${domainArr[0]}`,
|
||||||
|
isRedirected: true,
|
||||||
|
branch: currentProject.prodBranch,
|
||||||
|
project: currentProject
|
||||||
|
};
|
||||||
|
|
||||||
|
const savedPrimaryDomain = await domainRepository.save(primaryDomain);
|
||||||
|
|
||||||
|
const redirectedDomain = domainRepository.create(redirectedDomainDetails as DeepPartial<Domain>);
|
||||||
|
const savedRedirectedDomain = await domainRepository.save(redirectedDomain);
|
||||||
|
|
||||||
|
return [savedPrimaryDomain, savedRedirectedDomain];
|
||||||
|
}
|
||||||
|
|
||||||
|
async getDomainsByProjectId (projectId: string): Promise<Domain[]> {
|
||||||
|
const domainRepository = this.dataSource.getRepository(Domain);
|
||||||
|
|
||||||
|
const domains = await domainRepository.find({
|
||||||
|
where: {
|
||||||
|
project: {
|
||||||
|
id: projectId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return domains;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,14 @@ import {
|
|||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
Column,
|
Column,
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
UpdateDateColumn
|
UpdateDateColumn,
|
||||||
|
ManyToOne,
|
||||||
|
JoinColumn
|
||||||
} from 'typeorm';
|
} from 'typeorm';
|
||||||
|
|
||||||
enum Status {
|
import { Project } from './Project';
|
||||||
|
|
||||||
|
export enum Status {
|
||||||
Live = 'Live',
|
Live = 'Live',
|
||||||
Pending = 'Pending',
|
Pending = 'Pending',
|
||||||
}
|
}
|
||||||
@ -16,6 +20,10 @@ export class Domain {
|
|||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id!: number;
|
id!: number;
|
||||||
|
|
||||||
|
@ManyToOne(() => Project, { onDelete: 'CASCADE' })
|
||||||
|
@JoinColumn({ name: 'projectId' })
|
||||||
|
project!: Project;
|
||||||
|
|
||||||
@Column('varchar', { length: 255, default: 'main' })
|
@Column('varchar', { length: 255, default: 'main' })
|
||||||
branch!: string;
|
branch!: string;
|
||||||
|
|
||||||
@ -26,7 +34,8 @@ export class Domain {
|
|||||||
isRedirected!: boolean;
|
isRedirected!: boolean;
|
||||||
|
|
||||||
@Column({
|
@Column({
|
||||||
enum: Status
|
enum: Status,
|
||||||
|
default: Status.Pending
|
||||||
})
|
})
|
||||||
status!: Status;
|
status!: Status;
|
||||||
|
|
||||||
|
@ -98,6 +98,15 @@ export const createResolvers = async (db: Database): Promise<any> => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return projects;
|
return projects;
|
||||||
|
},
|
||||||
|
|
||||||
|
domains: async (_:any, { projectId }: { projectId: string }) => {
|
||||||
|
try {
|
||||||
|
return db.getDomainsByProjectId(projectId);
|
||||||
|
} catch (err) {
|
||||||
|
log(err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -155,7 +164,8 @@ export const createResolvers = async (db: Database): Promise<any> => {
|
|||||||
|
|
||||||
redeployToProd: async (_: any, { deploymentId }: { deploymentId: string }) => {
|
redeployToProd: async (_: any, { deploymentId }: { deploymentId: string }) => {
|
||||||
try {
|
try {
|
||||||
return db.redeployToProdById(deploymentId);
|
await db.redeployToProdById(deploymentId);
|
||||||
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log(err);
|
log(err);
|
||||||
return false;
|
return false;
|
||||||
@ -178,6 +188,16 @@ export const createResolvers = async (db: Database): Promise<any> => {
|
|||||||
log(err);
|
log(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addDomain: async (_: any, { projectId, domainDetails }: { projectId: string, domainDetails: { name: string } }) => {
|
||||||
|
try {
|
||||||
|
await db.addDomainByProjectId(projectId, domainDetails);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
log(err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -122,6 +122,7 @@ type Query {
|
|||||||
environmentVariables(projectId: String!): [EnvironmentVariable!]
|
environmentVariables(projectId: String!): [EnvironmentVariable!]
|
||||||
projectMembers(projectId: String!): [ProjectMember!]
|
projectMembers(projectId: String!): [ProjectMember!]
|
||||||
searchProjects(searchText: String!): [Project!]
|
searchProjects(searchText: String!): [Project!]
|
||||||
|
domains(projectId: String!): [Domain!]
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
@ -132,6 +133,7 @@ type Mutation {
|
|||||||
redeployToProd(deploymentId: String!): Boolean!
|
redeployToProd(deploymentId: String!): Boolean!
|
||||||
deleteProject(projectId: String!): Boolean!
|
deleteProject(projectId: String!): Boolean!
|
||||||
rollbackDeployment(projectId: String!, deploymentId: String!): Boolean!
|
rollbackDeployment(projectId: String!, deploymentId: String!): Boolean!
|
||||||
|
addDomain(projectId: String!, domainDetails: AddDomainInput!): Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
input AddEnvironmentVariableInput {
|
input AddEnvironmentVariableInput {
|
||||||
@ -144,3 +146,7 @@ input UpdateProjectInput {
|
|||||||
name: String
|
name: String
|
||||||
description: String
|
description: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input AddDomainInput {
|
||||||
|
name: String!
|
||||||
|
}
|
||||||
|
18
packages/backend/test/fixtures/deployments.json
vendored
18
packages/backend/test/fixtures/deployments.json
vendored
@ -6,7 +6,7 @@
|
|||||||
"status": "Building",
|
"status": "Building",
|
||||||
"environment": "Production",
|
"environment": "Production",
|
||||||
"isCurrent": true,
|
"isCurrent": true,
|
||||||
"branch": "prod",
|
"branch": "main",
|
||||||
"commitHash": "testXyz"
|
"commitHash": "testXyz"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -16,7 +16,7 @@
|
|||||||
"status": "Ready",
|
"status": "Ready",
|
||||||
"environment": "Preview",
|
"environment": "Preview",
|
||||||
"isCurrent": false,
|
"isCurrent": false,
|
||||||
"branch": "prod",
|
"branch": "test",
|
||||||
"commitHash": "testXyz"
|
"commitHash": "testXyz"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -26,7 +26,7 @@
|
|||||||
"status": "Error",
|
"status": "Error",
|
||||||
"environment": "Development",
|
"environment": "Development",
|
||||||
"isCurrent": false,
|
"isCurrent": false,
|
||||||
"branch": "prod",
|
"branch": "test",
|
||||||
"commitHash": "testXyz"
|
"commitHash": "testXyz"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -46,7 +46,7 @@
|
|||||||
"status": "Building",
|
"status": "Building",
|
||||||
"environment": "Production",
|
"environment": "Production",
|
||||||
"isCurrent": true,
|
"isCurrent": true,
|
||||||
"branch": "prod",
|
"branch": "main",
|
||||||
"commitHash": "testXyz"
|
"commitHash": "testXyz"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -56,7 +56,7 @@
|
|||||||
"status": "Ready",
|
"status": "Ready",
|
||||||
"environment": "Preview",
|
"environment": "Preview",
|
||||||
"isCurrent": false,
|
"isCurrent": false,
|
||||||
"branch": "prod",
|
"branch": "test",
|
||||||
"commitHash": "testXyz"
|
"commitHash": "testXyz"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -66,7 +66,7 @@
|
|||||||
"status": "Error",
|
"status": "Error",
|
||||||
"environment": "Development",
|
"environment": "Development",
|
||||||
"isCurrent": false,
|
"isCurrent": false,
|
||||||
"branch": "prod",
|
"branch": "test",
|
||||||
"commitHash": "testXyz"
|
"commitHash": "testXyz"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -76,7 +76,7 @@
|
|||||||
"status": "Building",
|
"status": "Building",
|
||||||
"environment": "Production",
|
"environment": "Production",
|
||||||
"isCurrent": true,
|
"isCurrent": true,
|
||||||
"branch": "prod",
|
"branch": "main",
|
||||||
"commitHash": "testXyz"
|
"commitHash": "testXyz"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -86,7 +86,7 @@
|
|||||||
"status": "Ready",
|
"status": "Ready",
|
||||||
"environment": "Preview",
|
"environment": "Preview",
|
||||||
"isCurrent": false,
|
"isCurrent": false,
|
||||||
"branch": "prod",
|
"branch": "test",
|
||||||
"commitHash": "testXyz"
|
"commitHash": "testXyz"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -96,7 +96,7 @@
|
|||||||
"status": "Error",
|
"status": "Error",
|
||||||
"environment": "Development",
|
"environment": "Development",
|
||||||
"isCurrent": false,
|
"isCurrent": false,
|
||||||
"branch": "prod",
|
"branch": "test",
|
||||||
"commitHash": "testXyz"
|
"commitHash": "testXyz"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
15
packages/backend/test/fixtures/domains.json
vendored
15
packages/backend/test/fixtures/domains.json
vendored
@ -1,53 +1,62 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
"projectIndex": 0,
|
||||||
"name": "randomurl.snowballtools.xyz",
|
"name": "randomurl.snowballtools.xyz",
|
||||||
"status": "Live",
|
"status": "Live",
|
||||||
"isRedirected": false,
|
"isRedirected": false,
|
||||||
"branch": "test"
|
"branch": "main"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"projectIndex": 0,
|
||||||
"name": "saugatt.com",
|
"name": "saugatt.com",
|
||||||
"status": "Pending",
|
"status": "Pending",
|
||||||
"isRedirected": false,
|
"isRedirected": false,
|
||||||
"branch": "test"
|
"branch": "test"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"projectIndex": 0,
|
||||||
"name": "www.saugatt.com",
|
"name": "www.saugatt.com",
|
||||||
"status": "Pending",
|
"status": "Pending",
|
||||||
"isRedirected": true,
|
"isRedirected": true,
|
||||||
"branch": "test"
|
"branch": "test"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"projectIndex": 1,
|
||||||
"name": "randomurl.snowballtools.xyz",
|
"name": "randomurl.snowballtools.xyz",
|
||||||
"status": "Live",
|
"status": "Live",
|
||||||
"isRedirected": false,
|
"isRedirected": false,
|
||||||
"branch": "test"
|
"branch": "main"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"projectIndex": 1,
|
||||||
"name": "saugatt.com",
|
"name": "saugatt.com",
|
||||||
"status": "Pending",
|
"status": "Pending",
|
||||||
"isRedirected": false,
|
"isRedirected": false,
|
||||||
"branch": "test"
|
"branch": "test"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"projectIndex": 1,
|
||||||
"name": "www.saugatt.com",
|
"name": "www.saugatt.com",
|
||||||
"status": "Pending",
|
"status": "Pending",
|
||||||
"isRedirected": true,
|
"isRedirected": true,
|
||||||
"branch": "test"
|
"branch": "test"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"projectIndex": 2,
|
||||||
"name": "randomurl.snowballtools.xyz",
|
"name": "randomurl.snowballtools.xyz",
|
||||||
"status": "Live",
|
"status": "Live",
|
||||||
"isRedirected": false,
|
"isRedirected": false,
|
||||||
"branch": "test"
|
"branch": "main"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"projectIndex": 2,
|
||||||
"name": "saugatt.com",
|
"name": "saugatt.com",
|
||||||
"status": "Pending",
|
"status": "Pending",
|
||||||
"isRedirected": false,
|
"isRedirected": false,
|
||||||
"branch": "test"
|
"branch": "test"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"projectIndex": 2,
|
||||||
"name": "www.saugatt.com",
|
"name": "www.saugatt.com",
|
||||||
"status": "Pending",
|
"status": "Pending",
|
||||||
"isRedirected": true,
|
"isRedirected": true,
|
||||||
|
@ -56,7 +56,6 @@ const loadAndSaveData = async <Entity extends ObjectLiteral>(entityType: EntityT
|
|||||||
const generateTestData = async (dataSource: DataSource) => {
|
const generateTestData = async (dataSource: DataSource) => {
|
||||||
const savedUsers = await loadAndSaveData(User, dataSource, path.resolve(__dirname, USER_DATA_PATH));
|
const savedUsers = await loadAndSaveData(User, dataSource, path.resolve(__dirname, USER_DATA_PATH));
|
||||||
const savedOrgs = await loadAndSaveData(Organization, dataSource, path.resolve(__dirname, ORGANIZATION_DATA_PATH));
|
const savedOrgs = await loadAndSaveData(Organization, dataSource, path.resolve(__dirname, ORGANIZATION_DATA_PATH));
|
||||||
const savedDomains = await loadAndSaveData(Domain, dataSource, path.resolve(__dirname, DOMAIN_DATA_PATH));
|
|
||||||
|
|
||||||
const projectRelations = {
|
const projectRelations = {
|
||||||
owner: savedUsers,
|
owner: savedUsers,
|
||||||
@ -65,6 +64,12 @@ const generateTestData = async (dataSource: DataSource) => {
|
|||||||
|
|
||||||
const savedProjects = await loadAndSaveData(Project, dataSource, path.resolve(__dirname, PROJECT_DATA_PATH), projectRelations);
|
const savedProjects = await loadAndSaveData(Project, dataSource, path.resolve(__dirname, PROJECT_DATA_PATH), projectRelations);
|
||||||
|
|
||||||
|
const domainRelations = {
|
||||||
|
project: savedProjects
|
||||||
|
};
|
||||||
|
|
||||||
|
const savedDomains = await loadAndSaveData(Domain, dataSource, path.resolve(__dirname, DOMAIN_DATA_PATH), domainRelations);
|
||||||
|
|
||||||
const userOrganizationRelations = {
|
const userOrganizationRelations = {
|
||||||
member: savedUsers,
|
member: savedUsers,
|
||||||
organization: savedOrgs
|
organization: savedOrgs
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
|
import { Domain, DomainStatus } from 'gql-client';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Chip,
|
Chip,
|
||||||
@ -14,7 +15,6 @@ import {
|
|||||||
import { ProjectDetails, RepositoryDetails } from '../../../../types/project';
|
import { ProjectDetails, RepositoryDetails } from '../../../../types/project';
|
||||||
import ConfirmDialog from '../../../shared/ConfirmDialog';
|
import ConfirmDialog from '../../../shared/ConfirmDialog';
|
||||||
import EditDomainDialog from './EditDomainDialog';
|
import EditDomainDialog from './EditDomainDialog';
|
||||||
import { Domain, DomainStatus } from 'gql-client';
|
|
||||||
|
|
||||||
enum RefreshStatus {
|
enum RefreshStatus {
|
||||||
IDLE,
|
IDLE,
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import { useParams, Link, useOutletContext } from 'react-router-dom';
|
import { useParams, Link, useOutletContext } from 'react-router-dom';
|
||||||
|
|
||||||
import { Button, Typography } from '@material-tailwind/react';
|
import { Button, Typography } from '@material-tailwind/react';
|
||||||
|
|
||||||
import DomainCard from './DomainCard';
|
import DomainCard from './DomainCard';
|
||||||
import { ProjectSearchOutletContext } from '../../../../types/project';
|
import { ProjectSearchOutletContext } from '../../../../types/project';
|
||||||
|
import { useGQLClient } from '../../../../context/GQLClientContext';
|
||||||
|
import { Domain } from 'gql-client';
|
||||||
|
|
||||||
const Domains = () => {
|
const Domains = () => {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
|
const client = useGQLClient();
|
||||||
|
|
||||||
|
const [domains, setDomains] = useState<Domain[]>([]);
|
||||||
|
|
||||||
const { projects } = useOutletContext<ProjectSearchOutletContext>();
|
const { projects } = useOutletContext<ProjectSearchOutletContext>();
|
||||||
|
|
||||||
@ -23,11 +28,18 @@ const Domains = () => {
|
|||||||
);
|
);
|
||||||
}, [currentProject]);
|
}, [currentProject]);
|
||||||
|
|
||||||
const domains = currentProject?.deployments
|
const fetchDomains = async () => {
|
||||||
.filter((deployment) => {
|
if (currentProject === undefined) {
|
||||||
return deployment.domain != null;
|
return;
|
||||||
})
|
}
|
||||||
.map((deployment) => deployment.domain);
|
|
||||||
|
const fetchedDomains = await client.getDomains(currentProject.id);
|
||||||
|
setDomains(fetchedDomains.domains);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchDomains();
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -40,7 +52,7 @@ const Domains = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{domains?.map((domain) => {
|
{domains.map((domain) => {
|
||||||
return (
|
return (
|
||||||
<DomainCard
|
<DomainCard
|
||||||
domain={domain}
|
domain={domain}
|
||||||
|
@ -47,7 +47,9 @@ const SetupDomain = () => {
|
|||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
onSubmit={handleSubmit(() => {
|
onSubmit={handleSubmit(() => {
|
||||||
navigate('config');
|
watch('isWWW') === 'true'
|
||||||
|
? navigate(`config?name=www.${domainStr}`)
|
||||||
|
: navigate(`config?name=${domainStr}`);
|
||||||
})}
|
})}
|
||||||
className="flex flex-col gap-6 w-full"
|
className="flex flex-col gap-6 w-full"
|
||||||
>
|
>
|
||||||
|
@ -1,9 +1,38 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link, useParams } from 'react-router-dom';
|
|
||||||
|
import toast from 'react-hot-toast';
|
||||||
|
import { Link, useParams, useSearchParams } from 'react-router-dom';
|
||||||
import { Typography, Alert, Button } from '@material-tailwind/react';
|
import { Typography, Alert, Button } from '@material-tailwind/react';
|
||||||
|
|
||||||
|
import { useGQLClient } from '../../../../../context/GQLClientContext';
|
||||||
|
|
||||||
const Config = () => {
|
const Config = () => {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
|
const client = useGQLClient();
|
||||||
|
const [searchParams] = useSearchParams();
|
||||||
|
const primaryDomainName = searchParams.get('name');
|
||||||
|
|
||||||
|
const handleSubmitDomain = async () => {
|
||||||
|
if (primaryDomainName === null) {
|
||||||
|
toast.error('Cannot resolve domain name');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id === undefined) {
|
||||||
|
toast.error('Cannot find project');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isAdded = await client.addDomain(id, {
|
||||||
|
name: primaryDomainName,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isAdded) {
|
||||||
|
toast.success('Domain added successfully');
|
||||||
|
} else {
|
||||||
|
toast.error('Error adding domain');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-6 w-full">
|
<div className="flex flex-col gap-6 w-full">
|
||||||
@ -43,7 +72,11 @@ const Config = () => {
|
|||||||
</Alert>
|
</Alert>
|
||||||
|
|
||||||
<Link to={`/projects/${id}`}>
|
<Link to={`/projects/${id}`}>
|
||||||
<Button className="w-fit" color="blue">
|
<Button
|
||||||
|
className="w-fit"
|
||||||
|
color="blue"
|
||||||
|
onClick={async () => await handleSubmitDomain()}
|
||||||
|
>
|
||||||
Finish <i>{'>'}</i>
|
Finish <i>{'>'}</i>
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { ApolloClient, DefaultOptions, InMemoryCache, NormalizedCacheObject } from '@apollo/client';
|
import { ApolloClient, DefaultOptions, InMemoryCache, NormalizedCacheObject } from '@apollo/client';
|
||||||
|
|
||||||
import { getUser, getOrganizations, getDeployments, getProjectMembers, searchProjects, getEnvironmentVariables, getProject, getProjectsInOrganization } from './queries';
|
import { getUser, getOrganizations, getDeployments, getProjectMembers, searchProjects, getEnvironmentVariables, getProject, getDomains, getProjectsInOrganization } from './queries';
|
||||||
import { AddEnvironmentVariableInput, AddEnvironmentVariablesResponse, GetDeploymentsResponse, GetEnvironmentVariablesResponse, GetOrganizationsResponse, GetProjectMembersResponse, SearchProjectsResponse, GetUserResponse, RemoveMemberResponse, UpdateDeploymentToProdResponse, GetProjectResponse, UpdateProjectResponse, UpdateProjectInput, RedeployToProdResponse, DeleteProjectResponse, GetProjectsInOrganizationResponse, RollbackDeploymentResponse } from './types';
|
import { AddEnvironmentVariableInput, AddEnvironmentVariablesResponse, GetDeploymentsResponse, GetEnvironmentVariablesResponse, GetOrganizationsResponse, GetProjectMembersResponse, SearchProjectsResponse, GetUserResponse, RemoveMemberResponse, UpdateDeploymentToProdResponse, GetProjectResponse, UpdateProjectResponse, UpdateProjectInput, RedeployToProdResponse, DeleteProjectResponse, GetProjectsInOrganizationResponse, RollbackDeploymentResponse, AddDomainInput, AddDomainResponse, GetDomainsResponse } from './types';
|
||||||
import { removeMember, addEnvironmentVariables, updateDeploymentToProd, updateProjectMutation, redeployToProd, deleteProject, rollbackDeployment } from './mutations';
|
import { removeMember, addEnvironmentVariables, updateDeploymentToProd, updateProjectMutation, redeployToProd, deleteProject, addDomain, rollbackDeployment } from './mutations';
|
||||||
|
|
||||||
export interface GraphQLConfig {
|
export interface GraphQLConfig {
|
||||||
gqlEndpoint: string;
|
gqlEndpoint: string;
|
||||||
@ -192,4 +192,27 @@ export class GQLClient {
|
|||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async addDomain (projectId: string, domainDetails: AddDomainInput): Promise<AddDomainResponse> {
|
||||||
|
const { data } = await this.client.mutate({
|
||||||
|
mutation: addDomain,
|
||||||
|
variables: {
|
||||||
|
projectId,
|
||||||
|
domainDetails
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getDomains (projectId: string): Promise<GetDomainsResponse> {
|
||||||
|
const { data } = await this.client.query({
|
||||||
|
query: getDomains,
|
||||||
|
variables: {
|
||||||
|
projectId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,3 +40,9 @@ mutation ($projectId: String! ,$deploymentId: String!) {
|
|||||||
rollbackDeployment(proejctId: $projectId, deploymentId: $deploymentId)
|
rollbackDeployment(proejctId: $projectId, deploymentId: $deploymentId)
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const addDomain = gql`
|
||||||
|
mutation ($projectId: String!, $domainDetails: AddDomainInput!) {
|
||||||
|
addDomain(projectId: $projectId, domainDetails: $domainDetails)
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
@ -215,3 +215,17 @@ query ($searchText: String!) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const getDomains = gql`
|
||||||
|
query ($projectId: String!) {
|
||||||
|
domains(projectId: $projectId) {
|
||||||
|
branch
|
||||||
|
createdAt
|
||||||
|
isRedirected
|
||||||
|
id
|
||||||
|
name
|
||||||
|
status
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
@ -161,6 +161,10 @@ export type GetProjectsInOrganizationResponse = {
|
|||||||
projectsInOrganization: Project[]
|
projectsInOrganization: Project[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type GetDomainsResponse = {
|
||||||
|
domains: Domain[]
|
||||||
|
}
|
||||||
|
|
||||||
export type SearchProjectsResponse = {
|
export type SearchProjectsResponse = {
|
||||||
searchProjects: Project[]
|
searchProjects: Project[]
|
||||||
}
|
}
|
||||||
@ -199,3 +203,11 @@ export type RedeployToProdResponse = {
|
|||||||
export type RollbackDeploymentResponse = {
|
export type RollbackDeploymentResponse = {
|
||||||
rollbackDeployment: boolean
|
rollbackDeployment: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type AddDomainInput = {
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AddDomainResponse = {
|
||||||
|
addDomain: true
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user