Implement functionality to delete domain (#59)
* Implement functionality to delete domain * Remove redirectToId from frontend --------- Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
parent
3a7f16467e
commit
1d58beb2ec
@ -347,6 +347,28 @@ export class Database {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteDomainById (domainId: string): Promise<boolean> {
|
||||||
|
const domainRepository = this.dataSource.getRepository(Domain);
|
||||||
|
|
||||||
|
const domainsRedirectedFrom = await domainRepository.find({
|
||||||
|
where: {
|
||||||
|
redirectToId: Number(domainId)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (domainsRedirectedFrom.length > 0) {
|
||||||
|
throw new Error('Cannot delete domain since it has redirects from other domains');
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteResult = await domainRepository.softDelete({ id: Number(domainId) });
|
||||||
|
|
||||||
|
if (deleteResult.affected) {
|
||||||
|
return deleteResult.affected > 0;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async rollbackDeploymentById (projectId: string, deploymentId: string): Promise<boolean> {
|
async rollbackDeploymentById (projectId: string, deploymentId: string): Promise<boolean> {
|
||||||
const deploymentRepository = this.dataSource.getRepository(Deployment);
|
const deploymentRepository = this.dataSource.getRepository(Deployment);
|
||||||
|
|
||||||
|
@ -5,7 +5,8 @@ import {
|
|||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
ManyToOne,
|
ManyToOne,
|
||||||
JoinColumn
|
JoinColumn,
|
||||||
|
DeleteDateColumn
|
||||||
} from 'typeorm';
|
} from 'typeorm';
|
||||||
|
|
||||||
import { Project } from './Project';
|
import { Project } from './Project';
|
||||||
@ -52,4 +53,7 @@ export class Domain {
|
|||||||
|
|
||||||
@UpdateDateColumn()
|
@UpdateDateColumn()
|
||||||
updatedAt!: Date;
|
updatedAt!: Date;
|
||||||
|
|
||||||
|
@DeleteDateColumn()
|
||||||
|
deletedAt?: Date;
|
||||||
}
|
}
|
||||||
|
@ -216,6 +216,16 @@ export const createResolvers = async (db: Database, app: OAuthApp): Promise<any>
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
deleteDomain: async (_: any, { domainId }: { domainId: string }) => {
|
||||||
|
try {
|
||||||
|
await db.deleteDomainById(domainId);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
log(err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
rollbackDeployment: async (_: any, { projectId, deploymentId }: {deploymentId: string, projectId: string }) => {
|
rollbackDeployment: async (_: any, { projectId, deploymentId }: {deploymentId: string, projectId: string }) => {
|
||||||
try {
|
try {
|
||||||
return db.rollbackDeploymentById(projectId, deploymentId);
|
return db.rollbackDeploymentById(projectId, deploymentId);
|
||||||
|
@ -141,6 +141,7 @@ type Mutation {
|
|||||||
updateProject(projectId: String!, projectDetails: UpdateProjectInput): Boolean!
|
updateProject(projectId: String!, projectDetails: UpdateProjectInput): Boolean!
|
||||||
redeployToProd(deploymentId: String!): Boolean!
|
redeployToProd(deploymentId: String!): Boolean!
|
||||||
deleteProject(projectId: String!): Boolean!
|
deleteProject(projectId: String!): Boolean!
|
||||||
|
deleteDomain(domainId: String!): Boolean!
|
||||||
rollbackDeployment(projectId: String!, deploymentId: String!): Boolean!
|
rollbackDeployment(projectId: String!, deploymentId: String!): Boolean!
|
||||||
addDomain(projectId: String!, domainDetails: AddDomainInput!): Boolean!
|
addDomain(projectId: String!, domainDetails: AddDomainInput!): Boolean!
|
||||||
updateDomain(domainId: String!, domainDetails: UpdateDomainInput!): Boolean!
|
updateDomain(domainId: String!, domainDetails: UpdateDomainInput!): Boolean!
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
"updatedAt": "2023-12-21T08:30:00",
|
"updatedAt": "2023-12-21T08:30:00",
|
||||||
"user": "bob",
|
"user": "bob",
|
||||||
"private": false,
|
"private": false,
|
||||||
"branch": ["main", "prod", "dev"]
|
"branch": ["main", "prod", "test"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 2,
|
"id": 2,
|
||||||
@ -13,7 +13,7 @@
|
|||||||
"updatedAt": "2023-12-21T08:30:00",
|
"updatedAt": "2023-12-21T08:30:00",
|
||||||
"user": "alice",
|
"user": "alice",
|
||||||
"private": true,
|
"private": true,
|
||||||
"branch": ["main", "prod", "dev"]
|
"branch": ["main", "prod", "test"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
@ -21,7 +21,7 @@
|
|||||||
"updatedAt": "2023-12-21T04:20:00",
|
"updatedAt": "2023-12-21T04:20:00",
|
||||||
"user": "charlie",
|
"user": "charlie",
|
||||||
"private": false,
|
"private": false,
|
||||||
"branch": ["main", "prod", "dev"]
|
"branch": ["main", "prod", "test"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 4,
|
"id": 4,
|
||||||
@ -29,7 +29,7 @@
|
|||||||
"updatedAt": "2023-12-21T04:27:00",
|
"updatedAt": "2023-12-21T04:27:00",
|
||||||
"user": "alice",
|
"user": "alice",
|
||||||
"private": false,
|
"private": false,
|
||||||
"branch": ["main", "prod", "dev"]
|
"branch": ["main", "prod", "test"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 5,
|
"id": 5,
|
||||||
@ -37,6 +37,6 @@
|
|||||||
"updatedAt": "2023-12-21T04:41:00",
|
"updatedAt": "2023-12-21T04:41:00",
|
||||||
"user": "ivan",
|
"user": "ivan",
|
||||||
"private": false,
|
"private": false,
|
||||||
"branch": ["main", "prod", "dev"]
|
"branch": ["main", "prod", "test"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -15,6 +15,7 @@ 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 { useGQLClient } from '../../../../context/GQLClientContext';
|
||||||
|
|
||||||
enum RefreshStatus {
|
enum RefreshStatus {
|
||||||
IDLE,
|
IDLE,
|
||||||
@ -51,6 +52,19 @@ const DomainCard = ({
|
|||||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||||
const [editDialogOpen, setEditDialogOpen] = useState(false);
|
const [editDialogOpen, setEditDialogOpen] = useState(false);
|
||||||
|
|
||||||
|
const client = useGQLClient();
|
||||||
|
|
||||||
|
const deleteDomain = async () => {
|
||||||
|
const { deleteDomain } = await client.deleteDomain(domain.id);
|
||||||
|
|
||||||
|
if (deleteDomain) {
|
||||||
|
onUpdate();
|
||||||
|
toast.success(`Domain ${domain.name} deleted successfully`);
|
||||||
|
} else {
|
||||||
|
toast.error(`Error deleting domain ${domain.name}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex justify-between py-3">
|
<div className="flex justify-between py-3">
|
||||||
@ -109,8 +123,8 @@ const DomainCard = ({
|
|||||||
open={deleteDialogOpen}
|
open={deleteDialogOpen}
|
||||||
confirmButtonTitle="Yes, Delete domain"
|
confirmButtonTitle="Yes, Delete domain"
|
||||||
handleConfirm={() => {
|
handleConfirm={() => {
|
||||||
|
deleteDomain();
|
||||||
setDeleteDialogOpen((preVal) => !preVal);
|
setDeleteDialogOpen((preVal) => !preVal);
|
||||||
toast.success(`Domain "${domain.name}" has been deleted`);
|
|
||||||
}}
|
}}
|
||||||
color="red"
|
color="red"
|
||||||
>
|
>
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import React, { useEffect, useMemo, useState } 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 { Domain } from 'gql-client';
|
||||||
|
|
||||||
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 { useGQLClient } from '../../../../context/GQLClientContext';
|
||||||
import { Domain } from 'gql-client';
|
import repositories from '../../../../assets/repositories.json';
|
||||||
|
|
||||||
const Domains = () => {
|
const Domains = () => {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
@ -22,16 +23,6 @@ const Domains = () => {
|
|||||||
});
|
});
|
||||||
}, [id, projects]);
|
}, [id, projects]);
|
||||||
|
|
||||||
// TODO: Use github API for getting linked repository
|
|
||||||
const linkedRepo = {
|
|
||||||
id: 3,
|
|
||||||
title: 'project-103',
|
|
||||||
updatedAt: '2023-12-21T04:20:00',
|
|
||||||
user: 'charlie',
|
|
||||||
private: false,
|
|
||||||
branch: ['main', 'prod', 'test'],
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchDomains = async () => {
|
const fetchDomains = async () => {
|
||||||
if (currentProject === undefined) {
|
if (currentProject === undefined) {
|
||||||
return;
|
return;
|
||||||
@ -62,7 +53,8 @@ const Domains = () => {
|
|||||||
domains={domains}
|
domains={domains}
|
||||||
domain={domain}
|
domain={domain}
|
||||||
key={domain.id}
|
key={domain.id}
|
||||||
repo={linkedRepo!}
|
// TODO: Use github API for getting linked repository
|
||||||
|
repo={repositories[0]!}
|
||||||
project={currentProject!}
|
project={currentProject!}
|
||||||
onUpdate={fetchDomains}
|
onUpdate={fetchDomains}
|
||||||
/>
|
/>
|
||||||
|
@ -63,7 +63,7 @@ const EditDomainDialog = ({
|
|||||||
}, [domains, domain]);
|
}, [domains, domain]);
|
||||||
|
|
||||||
const isDisableDropdown = useMemo(() => {
|
const isDisableDropdown = useMemo(() => {
|
||||||
return domainRedirectedFrom?.redirectTo?.id !== undefined;
|
return domainRedirectedFrom !== undefined;
|
||||||
}, [domain, domains]);
|
}, [domain, domains]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -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, getDomains, getProjectsInOrganization } from './queries';
|
import { getUser, getOrganizations, getDeployments, getProjectMembers, searchProjects, getEnvironmentVariables, getProject, getDomains, getProjectsInOrganization } from './queries';
|
||||||
import { AddEnvironmentVariableInput, AddEnvironmentVariablesResponse, GetDeploymentsResponse, GetEnvironmentVariablesResponse, GetOrganizationsResponse, GetProjectMembersResponse, SearchProjectsResponse, GetUserResponse, UpdateDeploymentToProdResponse, GetProjectResponse, UpdateProjectResponse, UpdateProjectInput, RedeployToProdResponse, DeleteProjectResponse, GetProjectsInOrganizationResponse, RollbackDeploymentResponse, AddDomainInput, AddDomainResponse, GetDomainsResponse, UpdateDomainInput, UpdateDomainResponse, AuthenticateGitHubResponse, UnauthenticateGitHubResponse, UpdateEnvironmentVariableResponse, UpdateEnvironmentVariableInput, RemoveEnvironmentVariableResponse, UpdateProjectMemberInput, RemoveProjectMemberResponse, UpdateProjectMemberResponse } from './types';
|
import { AddEnvironmentVariableInput, AddEnvironmentVariablesResponse, GetDeploymentsResponse, GetEnvironmentVariablesResponse, GetOrganizationsResponse, GetProjectMembersResponse, SearchProjectsResponse, GetUserResponse, UpdateDeploymentToProdResponse, GetProjectResponse, UpdateProjectResponse, UpdateProjectInput, RedeployToProdResponse, DeleteProjectResponse, GetProjectsInOrganizationResponse, RollbackDeploymentResponse, AddDomainInput, AddDomainResponse, GetDomainsResponse, UpdateDomainInput, UpdateDomainResponse, AuthenticateGitHubResponse, UnauthenticateGitHubResponse, UpdateEnvironmentVariableResponse, UpdateEnvironmentVariableInput, RemoveEnvironmentVariableResponse, UpdateProjectMemberInput, RemoveProjectMemberResponse, UpdateProjectMemberResponse, DeleteDomainResponse } from './types';
|
||||||
import { removeProjectMember, addEnvironmentVariables, updateDeploymentToProd, updateProjectMutation, redeployToProd, deleteProject, addDomain, rollbackDeployment, updateDomainMutation, authenticateGitHub, unauthenticateGitHub, updateEnvironmentVariable, removeEnvironmentVariable, updateProjectMember } from './mutations';
|
import { removeProjectMember, addEnvironmentVariables, updateDeploymentToProd, updateProjectMutation, redeployToProd, deleteProject, addDomain, rollbackDeployment, updateDomainMutation, authenticateGitHub, unauthenticateGitHub, updateEnvironmentVariable, removeEnvironmentVariable, updateProjectMember, deleteDomain } from './mutations';
|
||||||
|
|
||||||
export interface GraphQLConfig {
|
export interface GraphQLConfig {
|
||||||
gqlEndpoint: string;
|
gqlEndpoint: string;
|
||||||
@ -228,6 +228,17 @@ export class GQLClient {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteDomain (domainId: string): Promise<DeleteDomainResponse> {
|
||||||
|
const { data } = await this.client.mutate({
|
||||||
|
mutation: deleteDomain,
|
||||||
|
variables: {
|
||||||
|
domainId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
async rollbackDeployment (projectId: string, deploymentId: string): Promise<RollbackDeploymentResponse> {
|
async rollbackDeployment (projectId: string, deploymentId: string): Promise<RollbackDeploymentResponse> {
|
||||||
const { data } = await this.client.mutate({
|
const { data } = await this.client.mutate({
|
||||||
mutation: rollbackDeployment,
|
mutation: rollbackDeployment,
|
||||||
|
@ -58,6 +58,11 @@ mutation ($projectId: String!) {
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const deleteDomain = gql`
|
||||||
|
mutation ($domainId: String!) {
|
||||||
|
deleteDomain(domainId: $domainId)
|
||||||
|
}`;
|
||||||
|
|
||||||
export const rollbackDeployment = gql`
|
export const rollbackDeployment = gql`
|
||||||
mutation ($projectId: String! ,$deploymentId: String!) {
|
mutation ($projectId: String! ,$deploymentId: String!) {
|
||||||
rollbackDeployment(projectId: $projectId, deploymentId: $deploymentId)
|
rollbackDeployment(projectId: $projectId, deploymentId: $deploymentId)
|
||||||
|
@ -218,6 +218,10 @@ export type DeleteProjectResponse = {
|
|||||||
deleteProject: boolean;
|
deleteProject: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type DeleteDomainResponse = {
|
||||||
|
deleteDomain: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export type UpdateProjectInput = {
|
export type UpdateProjectInput = {
|
||||||
name: string
|
name: string
|
||||||
description: string
|
description: string
|
||||||
|
Loading…
Reference in New Issue
Block a user