forked from cerc-io/snowballtools-base
Implement functionality for editing domain (#57)
* Make use of domain id for redirecting domains * Add checks in backend to prevent chain redirecting and editing redirected domain * Add self relation to domain entity and use it to create and edit domains * Add self referencing relation to initialize db script * Add redirectToId column in domain entity * Remove isRedirected flag from domain entity * Refactor edit domain dialog box * Use dummy data for repository --------- Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
parent
ace27c7eae
commit
0dd6c7702a
@ -378,24 +378,22 @@ export class Database {
|
|||||||
|
|
||||||
const primaryDomainDetails = {
|
const primaryDomainDetails = {
|
||||||
...domainDetails,
|
...domainDetails,
|
||||||
isRedirected: false,
|
|
||||||
branch: currentProject.prodBranch,
|
branch: currentProject.prodBranch,
|
||||||
project: currentProject
|
project: currentProject
|
||||||
};
|
};
|
||||||
|
|
||||||
const primaryDomain = domainRepository.create(primaryDomainDetails as DeepPartial<Domain>);
|
const primaryDomain = domainRepository.create(primaryDomainDetails as DeepPartial<Domain>);
|
||||||
|
const savedPrimaryDomain = await domainRepository.save(primaryDomain);
|
||||||
|
|
||||||
const domainArr = domainDetails.name.split('www.');
|
const domainArr = domainDetails.name.split('www.');
|
||||||
|
|
||||||
const redirectedDomainDetails = {
|
const redirectedDomainDetails = {
|
||||||
name: domainArr.length > 1 ? domainArr[1] : `www.${domainArr[0]}`,
|
name: domainArr.length > 1 ? domainArr[1] : `www.${domainArr[0]}`,
|
||||||
isRedirected: true,
|
|
||||||
branch: currentProject.prodBranch,
|
branch: currentProject.prodBranch,
|
||||||
project: currentProject
|
project: currentProject,
|
||||||
|
redirectTo: savedPrimaryDomain
|
||||||
};
|
};
|
||||||
|
|
||||||
const savedPrimaryDomain = await domainRepository.save(primaryDomain);
|
|
||||||
|
|
||||||
const redirectedDomain = domainRepository.create(redirectedDomainDetails as DeepPartial<Domain>);
|
const redirectedDomain = domainRepository.create(redirectedDomainDetails as DeepPartial<Domain>);
|
||||||
const savedRedirectedDomain = await domainRepository.save(redirectedDomain);
|
const savedRedirectedDomain = await domainRepository.save(redirectedDomain);
|
||||||
|
|
||||||
@ -406,6 +404,9 @@ export class Database {
|
|||||||
const domainRepository = this.dataSource.getRepository(Domain);
|
const domainRepository = this.dataSource.getRepository(Domain);
|
||||||
|
|
||||||
const domains = await domainRepository.find({
|
const domains = await domainRepository.find({
|
||||||
|
relations: {
|
||||||
|
redirectTo: true
|
||||||
|
},
|
||||||
where: {
|
where: {
|
||||||
project: {
|
project: {
|
||||||
id: projectId
|
id: projectId
|
||||||
@ -416,10 +417,56 @@ export class Database {
|
|||||||
return domains;
|
return domains;
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateDomainById (domainId: string, updates: DeepPartial<Domain>): Promise<boolean> {
|
async updateDomainById (domainId: string, data: DeepPartial<Domain>): Promise<boolean> {
|
||||||
const domainRepository = this.dataSource.getRepository(Domain);
|
const domainRepository = this.dataSource.getRepository(Domain);
|
||||||
|
|
||||||
const updateResult = await domainRepository.update({ id: Number(domainId) }, updates);
|
const domain = await domainRepository.findOne({
|
||||||
|
where: {
|
||||||
|
id: Number(domainId)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const newDomain: DeepPartial<Domain> = {
|
||||||
|
...data
|
||||||
|
};
|
||||||
|
|
||||||
|
if (domain === null) {
|
||||||
|
throw new Error(`Error finding domain with id ${domainId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const domainsRedirectedFrom = await domainRepository.find({
|
||||||
|
where: {
|
||||||
|
project: {
|
||||||
|
id: domain.projectId
|
||||||
|
},
|
||||||
|
redirectToId: domain.id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// If there are domains redirecting to current domain, only branch of current domain can be updated
|
||||||
|
if (domainsRedirectedFrom.length > 0 && data.branch === domain.branch) {
|
||||||
|
throw new Error('Remove all redirects to this domain before updating');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.redirectToId) {
|
||||||
|
const redirectedDomain = await domainRepository.findOne({
|
||||||
|
where: {
|
||||||
|
id: Number(data.redirectToId)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (redirectedDomain === null) {
|
||||||
|
throw new Error('Could not find Domain to redirect to');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (redirectedDomain.redirectToId) {
|
||||||
|
throw new Error('Unable to redirect to the domain because it is already redirecting elsewhere. Redirects cannot be chained.');
|
||||||
|
}
|
||||||
|
|
||||||
|
newDomain.redirectTo = redirectedDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateResult = await domainRepository.update({ id: Number(domainId) }, newDomain);
|
||||||
|
|
||||||
if (updateResult.affected) {
|
if (updateResult.affected) {
|
||||||
return updateResult.affected > 0;
|
return updateResult.affected > 0;
|
||||||
|
@ -20,6 +20,9 @@ export class Domain {
|
|||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id!: number;
|
id!: number;
|
||||||
|
|
||||||
|
@Column('varchar')
|
||||||
|
projectId!: string;
|
||||||
|
|
||||||
@ManyToOne(() => Project, { onDelete: 'CASCADE' })
|
@ManyToOne(() => Project, { onDelete: 'CASCADE' })
|
||||||
@JoinColumn({ name: 'projectId' })
|
@JoinColumn({ name: 'projectId' })
|
||||||
project!: Project;
|
project!: Project;
|
||||||
@ -30,8 +33,13 @@ export class Domain {
|
|||||||
@Column('varchar', { length: 255 })
|
@Column('varchar', { length: 255 })
|
||||||
name!: string;
|
name!: string;
|
||||||
|
|
||||||
@Column('boolean', { default: false })
|
@Column('int', { nullable: true })
|
||||||
isRedirected!: boolean;
|
redirectToId!: number;
|
||||||
|
|
||||||
|
@ManyToOne(() => Domain)
|
||||||
|
@JoinColumn({ name: 'redirectToId' })
|
||||||
|
// eslint-disable-next-line no-use-before-define
|
||||||
|
redirectTo!: Domain | null;
|
||||||
|
|
||||||
@Column({
|
@Column({
|
||||||
enum: Status,
|
enum: Status,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import debug from 'debug';
|
import debug from 'debug';
|
||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
|
import { DeepPartial } from 'typeorm';
|
||||||
|
|
||||||
import { OAuthApp } from '@octokit/oauth-app';
|
import { OAuthApp } from '@octokit/oauth-app';
|
||||||
|
|
||||||
@ -7,6 +8,7 @@ import { Database } from './database';
|
|||||||
import { deploymentToGqlType, projectMemberToGqlType, projectToGqlType, environmentVariableToGqlType, isUserOwner } from './utils';
|
import { deploymentToGqlType, projectMemberToGqlType, projectToGqlType, environmentVariableToGqlType, isUserOwner } from './utils';
|
||||||
import { Environment } from './entity/Deployment';
|
import { Environment } from './entity/Deployment';
|
||||||
import { Permission } from './entity/ProjectMember';
|
import { Permission } from './entity/ProjectMember';
|
||||||
|
import { Domain } from './entity/Domain';
|
||||||
|
|
||||||
const log = debug('snowball:database');
|
const log = debug('snowball:database');
|
||||||
|
|
||||||
@ -233,7 +235,7 @@ export const createResolvers = async (db: Database, app: OAuthApp): Promise<any>
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
updateDomain: async (_: any, { domainId, domainDetails }: { domainId: string, domainDetails: {name?: string, isRedirected?: boolean, branch?: string }}) => {
|
updateDomain: async (_: any, { domainId, domainDetails }: { domainId: string, domainDetails: DeepPartial<Domain>}) => {
|
||||||
try {
|
try {
|
||||||
await db.updateDomainById(domainId, domainDetails);
|
await db.updateDomainById(domainId, domainDetails);
|
||||||
return true;
|
return true;
|
||||||
|
@ -98,7 +98,7 @@ type Domain {
|
|||||||
id: String!
|
id: String!
|
||||||
branch: String!
|
branch: String!
|
||||||
name: String!
|
name: String!
|
||||||
isRedirected: Boolean!
|
redirectTo: Domain
|
||||||
status: DomainStatus!
|
status: DomainStatus!
|
||||||
createdAt: String!
|
createdAt: String!
|
||||||
updatedAt: String!
|
updatedAt: String!
|
||||||
@ -163,8 +163,8 @@ input AddDomainInput {
|
|||||||
|
|
||||||
input UpdateDomainInput {
|
input UpdateDomainInput {
|
||||||
name: String
|
name: String
|
||||||
isRedirected: Boolean
|
|
||||||
branch: String
|
branch: String
|
||||||
|
redirectToId: String
|
||||||
}
|
}
|
||||||
|
|
||||||
input UpdateEnvironmentVariableInput {
|
input UpdateEnvironmentVariableInput {
|
||||||
|
@ -3,63 +3,36 @@
|
|||||||
"projectIndex": 0,
|
"projectIndex": 0,
|
||||||
"name": "randomurl.snowballtools.xyz",
|
"name": "randomurl.snowballtools.xyz",
|
||||||
"status": "Live",
|
"status": "Live",
|
||||||
"isRedirected": false,
|
|
||||||
"branch": "main"
|
"branch": "main"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"projectIndex": 0,
|
"projectIndex": 0,
|
||||||
"name": "saugatt.com",
|
"name": "saugatt.com",
|
||||||
"status": "Pending",
|
"status": "Pending",
|
||||||
"isRedirected": false,
|
|
||||||
"branch": "test"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"projectIndex": 0,
|
|
||||||
"name": "www.saugatt.com",
|
|
||||||
"status": "Pending",
|
|
||||||
"isRedirected": true,
|
|
||||||
"branch": "test"
|
"branch": "test"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"projectIndex": 1,
|
"projectIndex": 1,
|
||||||
"name": "randomurl.snowballtools.xyz",
|
"name": "randomurl.snowballtools.xyz",
|
||||||
"status": "Live",
|
"status": "Live",
|
||||||
"isRedirected": false,
|
|
||||||
"branch": "main"
|
"branch": "main"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"projectIndex": 1,
|
"projectIndex": 1,
|
||||||
"name": "saugatt.com",
|
"name": "saugatt.com",
|
||||||
"status": "Pending",
|
"status": "Pending",
|
||||||
"isRedirected": false,
|
|
||||||
"branch": "test"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"projectIndex": 1,
|
|
||||||
"name": "www.saugatt.com",
|
|
||||||
"status": "Pending",
|
|
||||||
"isRedirected": true,
|
|
||||||
"branch": "test"
|
"branch": "test"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"projectIndex": 2,
|
"projectIndex": 2,
|
||||||
"name": "randomurl.snowballtools.xyz",
|
"name": "randomurl.snowballtools.xyz",
|
||||||
"status": "Live",
|
"status": "Live",
|
||||||
"isRedirected": false,
|
|
||||||
"branch": "main"
|
"branch": "main"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"projectIndex": 2,
|
"projectIndex": 2,
|
||||||
"name": "saugatt.com",
|
"name": "saugatt.com",
|
||||||
"status": "Pending",
|
"status": "Pending",
|
||||||
"isRedirected": false,
|
|
||||||
"branch": "test"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"projectIndex": 2,
|
|
||||||
"name": "www.saugatt.com",
|
|
||||||
"status": "Pending",
|
|
||||||
"isRedirected": true,
|
|
||||||
"branch": "test"
|
"branch": "test"
|
||||||
}
|
}
|
||||||
]
|
]
|
23
packages/backend/test/fixtures/redirected-domains.json
vendored
Normal file
23
packages/backend/test/fixtures/redirected-domains.json
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"projectIndex": 0,
|
||||||
|
"name": "www.saugatt.com",
|
||||||
|
"status": "Pending",
|
||||||
|
"redirectToIndex": 1,
|
||||||
|
"branch": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 1,
|
||||||
|
"name": "www.saugatt.com",
|
||||||
|
"status": "Pending",
|
||||||
|
"redirectToIndex": 3,
|
||||||
|
"branch": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 2,
|
||||||
|
"name": "www.saugatt.com",
|
||||||
|
"status": "Pending",
|
||||||
|
"redirectToIndex": 5,
|
||||||
|
"branch": "test"
|
||||||
|
}
|
||||||
|
]
|
@ -22,9 +22,10 @@ const PROJECT_DATA_PATH = './fixtures/projects.json';
|
|||||||
const ORGANIZATION_DATA_PATH = './fixtures/organizations.json';
|
const ORGANIZATION_DATA_PATH = './fixtures/organizations.json';
|
||||||
const USER_ORGANIZATION_DATA_PATH = './fixtures/user-orgnizations.json';
|
const USER_ORGANIZATION_DATA_PATH = './fixtures/user-orgnizations.json';
|
||||||
const PROJECT_MEMBER_DATA_PATH = './fixtures/project-members.json';
|
const PROJECT_MEMBER_DATA_PATH = './fixtures/project-members.json';
|
||||||
const DOMAIN_DATA_PATH = './fixtures/domains.json';
|
const PRIMARY_DOMAIN_DATA_PATH = './fixtures/primary-domains.json';
|
||||||
const DEPLOYMENT_DATA_PATH = './fixtures/deployments.json';
|
const DEPLOYMENT_DATA_PATH = './fixtures/deployments.json';
|
||||||
const ENVIRONMENT_VARIABLE_DATA_PATH = './fixtures/environment-variables.json';
|
const ENVIRONMENT_VARIABLE_DATA_PATH = './fixtures/environment-variables.json';
|
||||||
|
const REDIRECTED_DOMAIN_DATA_PATH = './fixtures/redirected-domains.json';
|
||||||
|
|
||||||
const loadAndSaveData = async <Entity extends ObjectLiteral>(entityType: EntityTarget<Entity>, dataSource: DataSource, filePath: string, relations?: any | undefined) => {
|
const loadAndSaveData = async <Entity extends ObjectLiteral>(entityType: EntityTarget<Entity>, dataSource: DataSource, filePath: string, relations?: any | undefined) => {
|
||||||
const entitiesData = await fs.readFile(filePath, 'utf-8');
|
const entitiesData = await fs.readFile(filePath, 'utf-8');
|
||||||
@ -54,6 +55,8 @@ const loadAndSaveData = async <Entity extends ObjectLiteral>(entityType: EntityT
|
|||||||
};
|
};
|
||||||
|
|
||||||
const generateTestData = async (dataSource: DataSource) => {
|
const generateTestData = async (dataSource: DataSource) => {
|
||||||
|
const domainRepository = await dataSource.getRepository(Domain);
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
@ -64,11 +67,20 @@ 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 = {
|
const domainPrimaryRelations = {
|
||||||
project: savedProjects
|
project: savedProjects
|
||||||
};
|
};
|
||||||
|
|
||||||
const savedDomains = await loadAndSaveData(Domain, dataSource, path.resolve(__dirname, DOMAIN_DATA_PATH), domainRelations);
|
const savedPrimaryDomains = await loadAndSaveData(Domain, dataSource, path.resolve(__dirname, PRIMARY_DOMAIN_DATA_PATH), domainPrimaryRelations);
|
||||||
|
|
||||||
|
const domainRedirectedRelations = {
|
||||||
|
project: savedProjects,
|
||||||
|
redirectTo: savedPrimaryDomains
|
||||||
|
};
|
||||||
|
|
||||||
|
await loadAndSaveData(Domain, dataSource, path.resolve(__dirname, REDIRECTED_DOMAIN_DATA_PATH), domainRedirectedRelations);
|
||||||
|
|
||||||
|
const savedDomains = await domainRepository.find();
|
||||||
|
|
||||||
const userOrganizationRelations = {
|
const userOrganizationRelations = {
|
||||||
member: savedUsers,
|
member: savedUsers,
|
||||||
|
@ -22,11 +22,15 @@ const Domains = () => {
|
|||||||
});
|
});
|
||||||
}, [id, projects]);
|
}, [id, projects]);
|
||||||
|
|
||||||
const linkedRepo = useMemo(() => {
|
// TODO: Use github API for getting linked repository
|
||||||
return currentProject?.repositories?.find(
|
const linkedRepo = {
|
||||||
(repo: any) => repo.id === Number(currentProject?.repositoryId),
|
id: 3,
|
||||||
);
|
title: 'project-103',
|
||||||
}, [currentProject]);
|
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) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useCallback, useMemo } from 'react';
|
import React, { useCallback, useEffect, useMemo } from 'react';
|
||||||
import { Controller, useForm } from 'react-hook-form';
|
import { Controller, useForm } from 'react-hook-form';
|
||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
import { Domain } from 'gql-client';
|
import { Domain } from 'gql-client';
|
||||||
@ -40,37 +40,57 @@ const EditDomainDialog = ({
|
|||||||
const client = useGQLClient();
|
const client = useGQLClient();
|
||||||
|
|
||||||
const getRedirectUrl = (domain: Domain) => {
|
const getRedirectUrl = (domain: Domain) => {
|
||||||
const domainArr = domain.name.split('www.');
|
const redirectDomain = domain.redirectTo;
|
||||||
let redirectUrl = '';
|
|
||||||
if (domain.name.startsWith('www.')) {
|
if (redirectDomain !== null) {
|
||||||
redirectUrl = domainArr[1];
|
return redirectDomain?.name;
|
||||||
} else {
|
} else {
|
||||||
redirectUrl = `www.${domainArr[0]}`;
|
return 'none';
|
||||||
}
|
}
|
||||||
return redirectUrl;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const redirectOptions = useMemo(() => {
|
const redirectOptions = useMemo(() => {
|
||||||
const redirectUrl = getRedirectUrl(domain);
|
const domainNames = domains
|
||||||
return [...DEFAULT_REDIRECT_OPTIONS, redirectUrl];
|
.filter((domainData) => domainData.id !== domain.id)
|
||||||
}, [domain]);
|
.map((domain) => domain.name);
|
||||||
|
return ['none', ...domainNames];
|
||||||
|
}, [domain, domains]);
|
||||||
|
|
||||||
|
const domainRedirectedFrom = useMemo(() => {
|
||||||
|
return domains.find(
|
||||||
|
(domainData) => domainData.redirectTo?.id === domain.id,
|
||||||
|
);
|
||||||
|
}, [domains, domain]);
|
||||||
|
|
||||||
const isDisableDropdown = useMemo(() => {
|
const isDisableDropdown = useMemo(() => {
|
||||||
const redirectUrl = getRedirectUrl(domain);
|
return domainRedirectedFrom?.redirectTo?.id !== undefined;
|
||||||
|
}, [domain, domains]);
|
||||||
|
|
||||||
const domainRedirected = domains.find(
|
const {
|
||||||
(domain) => domain.name === redirectUrl,
|
handleSubmit,
|
||||||
|
register,
|
||||||
|
control,
|
||||||
|
watch,
|
||||||
|
reset,
|
||||||
|
formState: { isValid, isDirty },
|
||||||
|
} = useForm({
|
||||||
|
defaultValues: {
|
||||||
|
name: domain.name,
|
||||||
|
branch: domain.branch,
|
||||||
|
redirectedTo: getRedirectUrl(domain),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const updateDomainHandler = useCallback(
|
||||||
|
async (data: any) => {
|
||||||
|
const domainRedirectTo = domains.find(
|
||||||
|
(domainData) => data.redirectedTo === domainData.name,
|
||||||
);
|
);
|
||||||
|
|
||||||
return domainRedirected?.isRedirected;
|
|
||||||
}, [domain]);
|
|
||||||
|
|
||||||
const onSubmit = useCallback(
|
|
||||||
async (data: any) => {
|
|
||||||
const updates = {
|
const updates = {
|
||||||
name: data.name,
|
name: data.name ? data.name : domain.name,
|
||||||
branch: data.branch,
|
branch: data.branch ? data.branch : domain.branch,
|
||||||
isRedirected: data.redirectedTo !== 'none',
|
redirectToId: domainRedirectTo ? domainRedirectTo.id : null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const { updateDomain } = await client.updateDomain(domain.id, updates);
|
const { updateDomain } = await client.updateDomain(domain.id, updates);
|
||||||
@ -79,29 +99,22 @@ const EditDomainDialog = ({
|
|||||||
await onUpdate();
|
await onUpdate();
|
||||||
toast.success(`Domain ${domain.name} has been updated`);
|
toast.success(`Domain ${domain.name} has been updated`);
|
||||||
} else {
|
} else {
|
||||||
|
reset();
|
||||||
toast.error(`Error updating domain ${domain.name}`);
|
toast.error(`Error updating domain ${domain.name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleOpen();
|
handleOpen();
|
||||||
},
|
},
|
||||||
[client],
|
[client, domains, domain],
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
useEffect(() => {
|
||||||
handleSubmit,
|
reset({
|
||||||
register,
|
|
||||||
control,
|
|
||||||
watch,
|
|
||||||
formState: { isValid, isDirty },
|
|
||||||
} = useForm({
|
|
||||||
defaultValues: {
|
|
||||||
name: domain.name,
|
name: domain.name,
|
||||||
branch: repo.branch[0],
|
branch: domain.branch,
|
||||||
redirectedTo: !domain.isRedirected
|
redirectedTo: getRedirectUrl(domain),
|
||||||
? redirectOptions[0]
|
|
||||||
: redirectOptions[1],
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
}, [domain, repo]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} handler={handleOpen}>
|
<Dialog open={open} handler={handleOpen}>
|
||||||
@ -115,7 +128,7 @@ const EditDomainDialog = ({
|
|||||||
X
|
X
|
||||||
</Button>
|
</Button>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(updateDomainHandler)}>
|
||||||
<DialogBody className="flex flex-col gap-2 p-4">
|
<DialogBody className="flex flex-col gap-2 p-4">
|
||||||
<Typography variant="small">Domain name</Typography>
|
<Typography variant="small">Domain name</Typography>
|
||||||
<Input crossOrigin={undefined} {...register('name')} />
|
<Input crossOrigin={undefined} {...register('name')} />
|
||||||
@ -137,8 +150,9 @@ const EditDomainDialog = ({
|
|||||||
<div className="flex p-2 gap-2 text-black bg-gray-300 rounded-lg">
|
<div className="flex p-2 gap-2 text-black bg-gray-300 rounded-lg">
|
||||||
<div>^</div>
|
<div>^</div>
|
||||||
<Typography variant="small">
|
<Typography variant="small">
|
||||||
Domain “{redirectOptions[1]}” redirects to this domain so you
|
Domain “{domainRedirectedFrom ? domainRedirectedFrom.name : ''}”
|
||||||
can not redirect this doman further.
|
redirects to this domain so you can not redirect this doman
|
||||||
|
further.
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -41,7 +41,6 @@ const ProjectSearch = () => {
|
|||||||
name: '',
|
name: '',
|
||||||
value: '',
|
value: '',
|
||||||
},
|
},
|
||||||
isRedirectedto: deployment.domain.isRedirected,
|
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
};
|
};
|
||||||
|
@ -70,7 +70,6 @@ export interface DomainDetails {
|
|||||||
name: string;
|
name: string;
|
||||||
value: string;
|
value: string;
|
||||||
};
|
};
|
||||||
isRedirectedto: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum Permission {
|
export enum Permission {
|
||||||
|
@ -48,7 +48,6 @@ query ($projectId: String!) {
|
|||||||
updatedAt
|
updatedAt
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
isRedirected
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,7 +84,6 @@ query ($organizationId: String!) {
|
|||||||
updatedAt
|
updatedAt
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
isRedirected
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,7 +134,6 @@ query ($projectId: String!) {
|
|||||||
domain{
|
domain{
|
||||||
branch
|
branch
|
||||||
createdAt
|
createdAt
|
||||||
isRedirected
|
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
status
|
status
|
||||||
@ -218,7 +215,12 @@ query ($projectId: String!) {
|
|||||||
domains(projectId: $projectId) {
|
domains(projectId: $projectId) {
|
||||||
branch
|
branch
|
||||||
createdAt
|
createdAt
|
||||||
isRedirected
|
redirectTo {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
branch
|
||||||
|
status
|
||||||
|
}
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
status
|
status
|
||||||
|
@ -41,8 +41,8 @@ export type Domain = {
|
|||||||
id: string
|
id: string
|
||||||
branch: string
|
branch: string
|
||||||
name: string
|
name: string
|
||||||
isRedirected: boolean
|
|
||||||
status: DomainStatus
|
status: DomainStatus
|
||||||
|
redirectTo?: Domain
|
||||||
createdAt: string
|
createdAt: string
|
||||||
updatedAt: string
|
updatedAt: string
|
||||||
}
|
}
|
||||||
@ -224,8 +224,8 @@ export type UpdateProjectInput = {
|
|||||||
|
|
||||||
export type UpdateDomainInput = {
|
export type UpdateDomainInput = {
|
||||||
name?: string;
|
name?: string;
|
||||||
isRedirected?: boolean;
|
|
||||||
branch?: string;
|
branch?: string;
|
||||||
|
redirectToId?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RedeployToProdResponse = {
|
export type RedeployToProdResponse = {
|
||||||
|
Loading…
Reference in New Issue
Block a user