Fix route for adding domain in settings page (#66)

* Use Namespace import instead of named import

* Fix route for add domain

* Fix settings tab routes on changing sub path

* Fix stepper for add domain and project

---------

Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
Nabarun Gogoi 2024-02-14 12:16:01 +05:30 committed by GitHub
parent 9144d42f70
commit adba64fd2b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 101 additions and 89 deletions

View File

@ -22,6 +22,7 @@ const AssignDomainDialog = ({ open, handleOpen }: AssignDomainProps) => {
<DialogBody> <DialogBody>
In order to assign a domain to your production deployments, configure it In order to assign a domain to your production deployments, configure it
in the{' '} in the{' '}
{/* TODO: Fix selection of project settings tab on navigation to domains */}
<Link to="../settings/domains" className="text-light-blue-800 inline"> <Link to="../settings/domains" className="text-light-blue-800 inline">
project settings{' '} project settings{' '}
</Link> </Link>

View File

@ -37,8 +37,9 @@ const Id = () => {
const currentTab = useMemo(() => { const currentTab = useMemo(() => {
if (id) { if (id) {
const [, tabPath] = location.pathname.split(id); const regex = /projects\/[^/]+\/([^/]+)/;
return tabPath; const match = location.pathname.match(regex);
return match ? match[1] : '';
} else { } else {
return ''; return '';
} }
@ -90,22 +91,22 @@ const Id = () => {
</Tab> </Tab>
</Link> </Link>
<Link to="deployments"> <Link to="deployments">
<Tab value="/deployments" className={'p-2 cursor-pointer'}> <Tab value="deployments" className={'p-2 cursor-pointer'}>
Deployments Deployments
</Tab> </Tab>
</Link> </Link>
<Link to="database"> <Link to="database">
<Tab value="/database" className={'p-2 cursor-pointer'}> <Tab value="database" className={'p-2 cursor-pointer'}>
Database Database
</Tab> </Tab>
</Link> </Link>
<Link to="integrations"> <Link to="integrations">
<Tab value="/integrations" className={'p-2 cursor-pointer'}> <Tab value="integrations" className={'p-2 cursor-pointer'}>
Integrations Integrations
</Tab> </Tab>
</Link> </Link>
<Link to="settings"> <Link to="settings">
<Tab value="/settings" className={'p-2 cursor-pointer'}> <Tab value="settings" className={'p-2 cursor-pointer'}>
Settings Settings
</Tab> </Tab>
</Link> </Link>

View File

@ -1,5 +1,10 @@
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { Outlet, useLocation, useSearchParams } from 'react-router-dom'; import {
Outlet,
useLocation,
useParams,
useSearchParams,
} from 'react-router-dom';
import { Avatar } from '@material-tailwind/react'; import { Avatar } from '@material-tailwind/react';
@ -7,13 +12,23 @@ import Stepper from '../../../../components/Stepper';
import templateDetails from '../../../../assets/templates.json'; import templateDetails from '../../../../assets/templates.json';
import { GIT_TEMPLATE_LINK } from '../../../../constants'; import { GIT_TEMPLATE_LINK } from '../../../../constants';
const STEPPER_VALUES = [
{ step: 1, route: '/projects/create/template', label: 'Create repository' },
{ step: 2, route: '/projects/create/template/deploy', label: 'Deploy' },
];
// TODO: Set dynamic route for template and load details from DB // TODO: Set dynamic route for template and load details from DB
const CreateWithTemplate = () => { const CreateWithTemplate = () => {
const { orgSlug } = useParams();
const stepperValues = [
{
step: 1,
route: `/${orgSlug}/projects/create/template`,
label: 'Create repository',
},
{
step: 2,
route: `/${orgSlug}/projects/create/template/deploy`,
label: 'Deploy',
},
];
const location = useLocation(); const location = useLocation();
const [searchParams] = useSearchParams(); const [searchParams] = useSearchParams();
@ -24,8 +39,7 @@ const CreateWithTemplate = () => {
const activeStep = useMemo( const activeStep = useMemo(
() => () =>
STEPPER_VALUES.find((data) => data.route === location.pathname)?.step ?? stepperValues.find((data) => data.route === location.pathname)?.step ?? 0,
0,
[location.pathname], [location.pathname],
); );
@ -42,7 +56,7 @@ const CreateWithTemplate = () => {
</div> </div>
<div className="grid grid-cols-3 w-5/6 p-6"> <div className="grid grid-cols-3 w-5/6 p-6">
<div> <div>
<Stepper activeStep={activeStep} stepperValues={STEPPER_VALUES} /> <Stepper activeStep={activeStep} stepperValues={stepperValues} />
</div> </div>
<div className="col-span-2"> <div className="col-span-2">
<Outlet /> <Outlet />

View File

@ -32,7 +32,7 @@ const Domains = () => {
<> <>
<div className="flex justify-between p-2"> <div className="flex justify-between p-2">
<Typography variant="h3">Domain</Typography> <Typography variant="h3">Domain</Typography>
<Link to="domain/add"> <Link to="add">
<Button color="blue" variant="outlined" className="rounded-full"> <Button color="blue" variant="outlined" className="rounded-full">
<i>^</i> Add domain <i>^</i> Add domain
</Button> </Button>

View File

@ -1,14 +1,15 @@
import React from 'react'; import React from 'react';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
import { Link, useParams, useSearchParams } from 'react-router-dom'; import { useNavigate, 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'; import { useGQLClient } from '../../../../../../../context/GQLClientContext';
const Config = () => { const Config = () => {
const { id, orgSlug } = useParams(); const { id, orgSlug } = useParams();
const client = useGQLClient(); const client = useGQLClient();
const navigate = useNavigate();
const [searchParams] = useSearchParams(); const [searchParams] = useSearchParams();
const primaryDomainName = searchParams.get('name'); const primaryDomainName = searchParams.get('name');
@ -29,6 +30,7 @@ const Config = () => {
if (isAdded) { if (isAdded) {
toast.success('Domain added successfully'); toast.success('Domain added successfully');
navigate(`/${orgSlug}/projects/${id}/settings/domains`);
} else { } else {
toast.error('Error adding domain'); toast.error('Error adding domain');
} }
@ -70,15 +72,9 @@ const Config = () => {
<i>^</i>It can take up to 48 hours for these updates to reflect <i>^</i>It can take up to 48 hours for these updates to reflect
globally. globally.
</Alert> </Alert>
<Link to={`/${orgSlug}/projects/${id}`}> <Button className="w-fit" color="blue" onClick={handleSubmitDomain}>
<Button Finish <i>{'>'}</i>
className="w-fit" </Button>
color="blue"
onClick={async () => await handleSubmitDomain()}
>
Finish <i>{'>'}</i>
</Button>
</Link>
</div> </div>
); );
}; };

View File

@ -2,7 +2,7 @@ import React, { useMemo } from 'react';
import { useParams, useLocation, Outlet, Link } from 'react-router-dom'; import { useParams, useLocation, Outlet, Link } from 'react-router-dom';
import { Typography, IconButton } from '@material-tailwind/react'; import { Typography, IconButton } from '@material-tailwind/react';
import Stepper from '../../../../../../components/Stepper'; import Stepper from '../../../../../../../components/Stepper';
const AddDomain = () => { const AddDomain = () => {
const { id, orgSlug } = useParams(); const { id, orgSlug } = useParams();
@ -11,12 +11,12 @@ const AddDomain = () => {
const stepperValues = [ const stepperValues = [
{ {
step: 1, step: 1,
route: `/projects/${id}/domain/add`, route: `/${orgSlug}/projects/${id}/settings/domains/add`,
label: 'Setup', label: 'Setup',
}, },
{ {
step: 2, step: 2,
route: `/projects/${id}/domain/add/config`, route: `/${orgSlug}/projects/${id}/settings/domains/add/config`,
label: 'Configure DNS', label: 'Configure DNS',
}, },
]; ];

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import Config from './Config'; import Config from './Config';
import SetupDomain from '../../../../../../components/projects/project/settings/SetupDomain'; import SetupDomain from '../../../../../../../components/projects/project/settings/SetupDomain';
export const addDomainRoutes = [ export const addDomainRoutes = [
{ {

View File

@ -2,10 +2,10 @@ import React from 'react';
import CreateProject from './Create'; import CreateProject from './Create';
import Id from './Id'; import Id from './Id';
import AddDomain from './id/domain/add'; import AddDomain from './id/settings/domains/add';
import { createProjectRoutes } from './create/routes'; import { createProjectRoutes } from './create/routes';
import { addDomainRoutes } from './id/domain/add/routes';
import { projectTabRoutes } from './id/routes'; import { projectTabRoutes } from './id/routes';
import { addDomainRoutes } from './id/settings/domains/add/routes';
export const projectsRoutesWithoutSearch = [ export const projectsRoutesWithoutSearch = [
{ {
@ -14,7 +14,7 @@ export const projectsRoutesWithoutSearch = [
children: createProjectRoutes, children: createProjectRoutes,
}, },
{ {
path: ':id/domain/add', path: ':id/settings/domains/add',
element: <AddDomain />, element: <AddDomain />,
children: addDomainRoutes, children: addDomainRoutes,
}, },

View File

@ -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 * as queries 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, DeleteDomainResponse, AddProjectMemberInput, AddProjectMemberResponse, AddProjectInput, AddProjectResponse, FilterDomainInput } from './types'; import * as types from './types';
import { removeProjectMember, addEnvironmentVariables, updateDeploymentToProd, updateProjectMutation, redeployToProd, deleteProject, addDomain, rollbackDeployment, updateDomainMutation, authenticateGitHub, unauthenticateGitHub, updateEnvironmentVariable, removeEnvironmentVariable, updateProjectMember, deleteDomain, addProjectMember, addProject } from './mutations'; import * as mutations from './mutations';
export interface GraphQLConfig { export interface GraphQLConfig {
gqlEndpoint: string; gqlEndpoint: string;
@ -31,17 +31,17 @@ export class GQLClient {
}); });
} }
async getUser () : Promise<GetUserResponse> { async getUser () : Promise<types.GetUserResponse> {
const { data } = await this.client.query({ const { data } = await this.client.query({
query: getUser query: queries.getUser
}); });
return data; return data;
} }
async getProject (projectId: string) : Promise<GetProjectResponse> { async getProject (projectId: string) : Promise<types.GetProjectResponse> {
const { data } = await this.client.query({ const { data } = await this.client.query({
query: getProject, query: queries.getProject,
variables: { variables: {
projectId projectId
} }
@ -50,9 +50,9 @@ export class GQLClient {
return data; return data;
} }
async getProjectsInOrganization (organizationSlug: string) : Promise<GetProjectsInOrganizationResponse> { async getProjectsInOrganization (organizationSlug: string) : Promise<types.GetProjectsInOrganizationResponse> {
const { data } = await this.client.query({ const { data } = await this.client.query({
query: getProjectsInOrganization, query: queries.getProjectsInOrganization,
variables: { variables: {
organizationSlug organizationSlug
} }
@ -61,17 +61,17 @@ export class GQLClient {
return data; return data;
} }
async getOrganizations () : Promise<GetOrganizationsResponse> { async getOrganizations () : Promise<types.GetOrganizationsResponse> {
const { data } = await this.client.query({ const { data } = await this.client.query({
query: getOrganizations query: queries.getOrganizations
}); });
return data; return data;
} }
async getDeployments (projectId: string) : Promise<GetDeploymentsResponse> { async getDeployments (projectId: string) : Promise<types.GetDeploymentsResponse> {
const { data } = await this.client.query({ const { data } = await this.client.query({
query: getDeployments, query: queries.getDeployments,
variables: { variables: {
projectId projectId
} }
@ -80,9 +80,9 @@ export class GQLClient {
return data; return data;
} }
async getEnvironmentVariables (projectId: string) : Promise<GetEnvironmentVariablesResponse> { async getEnvironmentVariables (projectId: string) : Promise<types.GetEnvironmentVariablesResponse> {
const { data } = await this.client.query({ const { data } = await this.client.query({
query: getEnvironmentVariables, query: queries.getEnvironmentVariables,
variables: { variables: {
projectId projectId
} }
@ -91,9 +91,9 @@ export class GQLClient {
return data; return data;
} }
async getProjectMembers (projectId: string) : Promise<GetProjectMembersResponse> { async getProjectMembers (projectId: string) : Promise<types.GetProjectMembersResponse> {
const result = await this.client.query({ const result = await this.client.query({
query: getProjectMembers, query: queries.getProjectMembers,
variables: { variables: {
projectId projectId
} }
@ -102,9 +102,9 @@ export class GQLClient {
return result.data; return result.data;
} }
async addProjectMember (projectId: string, data: AddProjectMemberInput) : Promise<AddProjectMemberResponse> { async addProjectMember (projectId: string, data: types.AddProjectMemberInput) : Promise<types.AddProjectMemberResponse> {
const result = await this.client.mutate({ const result = await this.client.mutate({
mutation: addProjectMember, mutation: mutations.addProjectMember,
variables: { variables: {
projectId, projectId,
data data
@ -114,9 +114,9 @@ export class GQLClient {
return result.data; return result.data;
} }
async updateProjectMember (projectMemberId: string, data: UpdateProjectMemberInput): Promise<UpdateProjectMemberResponse> { async updateProjectMember (projectMemberId: string, data: types.UpdateProjectMemberInput): Promise<types.UpdateProjectMemberResponse> {
const result = await this.client.mutate({ const result = await this.client.mutate({
mutation: updateProjectMember, mutation: mutations.updateProjectMember,
variables: { variables: {
projectMemberId, projectMemberId,
data data
@ -126,9 +126,9 @@ export class GQLClient {
return result.data; return result.data;
} }
async removeProjectMember (projectMemberId: string): Promise<RemoveProjectMemberResponse> { async removeProjectMember (projectMemberId: string): Promise<types.RemoveProjectMemberResponse> {
const result = await this.client.mutate({ const result = await this.client.mutate({
mutation: removeProjectMember, mutation: mutations.removeProjectMember,
variables: { variables: {
projectMemberId projectMemberId
} }
@ -137,9 +137,9 @@ export class GQLClient {
return result.data; return result.data;
} }
async searchProjects (searchText: string) : Promise<SearchProjectsResponse> { async searchProjects (searchText: string) : Promise<types.SearchProjectsResponse> {
const { data } = await this.client.query({ const { data } = await this.client.query({
query: searchProjects, query: queries.searchProjects,
variables: { variables: {
searchText searchText
} }
@ -148,9 +148,9 @@ export class GQLClient {
return data; return data;
} }
async addEnvironmentVariables (projectId: string, data: AddEnvironmentVariableInput[]): Promise<AddEnvironmentVariablesResponse> { async addEnvironmentVariables (projectId: string, data: types.AddEnvironmentVariableInput[]): Promise<types.AddEnvironmentVariablesResponse> {
const result = await this.client.mutate({ const result = await this.client.mutate({
mutation: addEnvironmentVariables, mutation: mutations.addEnvironmentVariables,
variables: { variables: {
projectId, projectId,
data data
@ -160,9 +160,9 @@ export class GQLClient {
return result.data; return result.data;
} }
async updateEnvironmentVariable (environmentVariableId: string, data: UpdateEnvironmentVariableInput): Promise<UpdateEnvironmentVariableResponse> { async updateEnvironmentVariable (environmentVariableId: string, data: types.UpdateEnvironmentVariableInput): Promise<types.UpdateEnvironmentVariableResponse> {
const result = await this.client.mutate({ const result = await this.client.mutate({
mutation: updateEnvironmentVariable, mutation: mutations.updateEnvironmentVariable,
variables: { variables: {
environmentVariableId, environmentVariableId,
data data
@ -172,9 +172,9 @@ export class GQLClient {
return result.data; return result.data;
} }
async removeEnvironmentVariable (environmentVariableId: string): Promise<RemoveEnvironmentVariableResponse> { async removeEnvironmentVariable (environmentVariableId: string): Promise<types.RemoveEnvironmentVariableResponse> {
const { data } = await this.client.mutate({ const { data } = await this.client.mutate({
mutation: removeEnvironmentVariable, mutation: mutations.removeEnvironmentVariable,
variables: { variables: {
environmentVariableId environmentVariableId
} }
@ -183,9 +183,9 @@ export class GQLClient {
return data; return data;
} }
async updateDeploymentToProd (deploymentId: string): Promise<UpdateDeploymentToProdResponse> { async updateDeploymentToProd (deploymentId: string): Promise<types.UpdateDeploymentToProdResponse> {
const { data } = await this.client.mutate({ const { data } = await this.client.mutate({
mutation: updateDeploymentToProd, mutation: mutations.updateDeploymentToProd,
variables: { variables: {
deploymentId deploymentId
} }
@ -194,9 +194,9 @@ export class GQLClient {
return data; return data;
} }
async addProject (organizationSlug: string, data: AddProjectInput): Promise<AddProjectResponse> { async addProject (organizationSlug: string, data: types.AddProjectInput): Promise<types.AddProjectResponse> {
const result = await this.client.mutate({ const result = await this.client.mutate({
mutation: addProject, mutation: mutations.addProject,
variables: { variables: {
organizationSlug, organizationSlug,
data data
@ -206,9 +206,9 @@ export class GQLClient {
return result.data; return result.data;
} }
async updateProject (projectId: string, projectDetails: UpdateProjectInput): Promise<UpdateProjectResponse> { async updateProject (projectId: string, projectDetails: types.UpdateProjectInput): Promise<types.UpdateProjectResponse> {
const { data } = await this.client.mutate({ const { data } = await this.client.mutate({
mutation: updateProjectMutation, mutation: mutations.updateProjectMutation,
variables: { variables: {
projectId, projectId,
projectDetails projectDetails
@ -218,9 +218,9 @@ export class GQLClient {
return data; return data;
} }
async updateDomain (domainId: string, domainDetails: UpdateDomainInput): Promise<UpdateDomainResponse> { async updateDomain (domainId: string, domainDetails: types.UpdateDomainInput): Promise<types.UpdateDomainResponse> {
const { data } = await this.client.mutate({ const { data } = await this.client.mutate({
mutation: updateDomainMutation, mutation: mutations.updateDomainMutation,
variables: { variables: {
domainId, domainId,
domainDetails domainDetails
@ -230,9 +230,9 @@ export class GQLClient {
return data; return data;
} }
async redeployToProd (deploymentId: string): Promise<RedeployToProdResponse> { async redeployToProd (deploymentId: string): Promise<types.RedeployToProdResponse> {
const { data } = await this.client.mutate({ const { data } = await this.client.mutate({
mutation: redeployToProd, mutation: mutations.redeployToProd,
variables: { variables: {
deploymentId deploymentId
} }
@ -241,9 +241,9 @@ export class GQLClient {
return data; return data;
} }
async deleteProject (projectId: string): Promise<DeleteProjectResponse> { async deleteProject (projectId: string): Promise<types.DeleteProjectResponse> {
const { data } = await this.client.mutate({ const { data } = await this.client.mutate({
mutation: deleteProject, mutation: mutations.deleteProject,
variables: { variables: {
projectId projectId
} }
@ -252,9 +252,9 @@ export class GQLClient {
return data; return data;
} }
async deleteDomain (domainId: string): Promise<DeleteDomainResponse> { async deleteDomain (domainId: string): Promise<types.DeleteDomainResponse> {
const { data } = await this.client.mutate({ const { data } = await this.client.mutate({
mutation: deleteDomain, mutation: mutations.deleteDomain,
variables: { variables: {
domainId domainId
} }
@ -263,9 +263,9 @@ export class GQLClient {
return data; return data;
} }
async rollbackDeployment (projectId: string, deploymentId: string): Promise<RollbackDeploymentResponse> { async rollbackDeployment (projectId: string, deploymentId: string): Promise<types.RollbackDeploymentResponse> {
const { data } = await this.client.mutate({ const { data } = await this.client.mutate({
mutation: rollbackDeployment, mutation: mutations.rollbackDeployment,
variables: { variables: {
projectId, projectId,
deploymentId deploymentId
@ -275,9 +275,9 @@ export class GQLClient {
return data; return data;
} }
async addDomain (projectId: string, domainDetails: AddDomainInput): Promise<AddDomainResponse> { async addDomain (projectId: string, domainDetails: types.AddDomainInput): Promise<types.AddDomainResponse> {
const { data } = await this.client.mutate({ const { data } = await this.client.mutate({
mutation: addDomain, mutation: mutations.addDomain,
variables: { variables: {
projectId, projectId,
domainDetails domainDetails
@ -287,9 +287,9 @@ export class GQLClient {
return data; return data;
} }
async getDomains (projectId: string, filter?: FilterDomainInput): Promise<GetDomainsResponse> { async getDomains (projectId: string, filter?: types.FilterDomainInput): Promise<types.GetDomainsResponse> {
const { data } = await this.client.query({ const { data } = await this.client.query({
query: getDomains, query: queries.getDomains,
variables: { variables: {
projectId, projectId,
filter filter
@ -299,9 +299,9 @@ export class GQLClient {
return data; return data;
} }
async authenticateGitHub (code: string): Promise<AuthenticateGitHubResponse> { async authenticateGitHub (code: string): Promise<types.AuthenticateGitHubResponse> {
const { data } = await this.client.mutate({ const { data } = await this.client.mutate({
mutation: authenticateGitHub, mutation: mutations.authenticateGitHub,
variables: { variables: {
code code
} }
@ -310,9 +310,9 @@ export class GQLClient {
return data; return data;
} }
async unauthenticateGithub (): Promise<UnauthenticateGitHubResponse> { async unauthenticateGithub (): Promise<types.UnauthenticateGitHubResponse> {
const { data } = await this.client.mutate({ const { data } = await this.client.mutate({
mutation: unauthenticateGitHub mutation: mutations.unauthenticateGitHub
}); });
return data; return data;