forked from cerc-io/snowballtools-base
Add fixtures for remaining entities in database initialization script (#36)
* Create fixture data for remaining entities and load it in db * Rename currProject to currentProject in frontend package * Handle review changes * Update readme for loading fixtures --------- Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
parent
890603061f
commit
2d7e56c0e1
@ -15,7 +15,7 @@
|
|||||||
- Build packages
|
- Build packages
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn build
|
yarn build --ignore frontend
|
||||||
```
|
```
|
||||||
|
|
||||||
- Change directory to `packages/backend`
|
- Change directory to `packages/backend`
|
||||||
@ -24,6 +24,12 @@
|
|||||||
cd packages/backend
|
cd packages/backend
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- Load fixtures in database
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn db:load:fixtures
|
||||||
|
```
|
||||||
|
|
||||||
- Start the server
|
- Start the server
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"format": "prettier --write .",
|
"format": "prettier --write .",
|
||||||
"format:check": "prettier --check .",
|
"format:check": "prettier --check .",
|
||||||
"db:load:fixtures": "ts-node ./test/initialize-db.ts"
|
"db:load:fixtures": "DEBUG=snowball:* ts-node ./test/initialize-db.ts"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/fs-extra": "^11.0.4",
|
"@types/fs-extra": "^11.0.4",
|
||||||
|
92
packages/backend/test/fixtures/deployments.json
vendored
Normal file
92
packages/backend/test/fixtures/deployments.json
vendored
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"projectIndex": 0,
|
||||||
|
"domainIndex":0,
|
||||||
|
"title": "nextjs-boilerplate-1",
|
||||||
|
"status": "Building",
|
||||||
|
"environment": "Production",
|
||||||
|
"isCurrent": false,
|
||||||
|
"branch": "prod",
|
||||||
|
"commitHash": "testXyz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 0,
|
||||||
|
"domainIndex":1,
|
||||||
|
"title": "nextjs-boilerplate-2",
|
||||||
|
"status": "Ready",
|
||||||
|
"environment": "Preview",
|
||||||
|
"isCurrent": true,
|
||||||
|
"branch": "prod",
|
||||||
|
"commitHash": "testXyz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 0,
|
||||||
|
"domainIndex":2,
|
||||||
|
"title": "nextjs-boilerplate-3",
|
||||||
|
"status": "Error",
|
||||||
|
"environment": "Development",
|
||||||
|
"isCurrent": false,
|
||||||
|
"branch": "prod",
|
||||||
|
"commitHash": "testXyz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 1,
|
||||||
|
"domainIndex":3,
|
||||||
|
"title": "nextjs-boilerplate-1",
|
||||||
|
"status": "Building",
|
||||||
|
"environment": "Production",
|
||||||
|
"isCurrent": false,
|
||||||
|
"branch": "prod",
|
||||||
|
"commitHash": "testXyz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 1,
|
||||||
|
"domainIndex":4,
|
||||||
|
"title": "nextjs-boilerplate-2",
|
||||||
|
"status": "Ready",
|
||||||
|
"environment": "Preview",
|
||||||
|
"isCurrent": true,
|
||||||
|
"branch": "prod",
|
||||||
|
"commitHash": "testXyz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 1,
|
||||||
|
"domainIndex":5,
|
||||||
|
"title": "nextjs-boilerplate-3",
|
||||||
|
"status": "Error",
|
||||||
|
"environment": "Development",
|
||||||
|
"isCurrent": false,
|
||||||
|
"branch": "prod",
|
||||||
|
"commitHash": "testXyz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 2,
|
||||||
|
"domainIndex":6,
|
||||||
|
"title": "nextjs-boilerplate-1",
|
||||||
|
"status": "Building",
|
||||||
|
"environment": "Production",
|
||||||
|
"isCurrent": false,
|
||||||
|
"branch": "prod",
|
||||||
|
"commitHash": "testXyz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 2,
|
||||||
|
"domainIndex":7,
|
||||||
|
"title": "nextjs-boilerplate-2",
|
||||||
|
"status": "Ready",
|
||||||
|
"environment": "Preview",
|
||||||
|
"isCurrent": true,
|
||||||
|
"branch": "prod",
|
||||||
|
"commitHash": "testXyz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 2,
|
||||||
|
"domainIndex":8,
|
||||||
|
"title": "nextjs-boilerplate-3",
|
||||||
|
"status": "Error",
|
||||||
|
"environment": "Development",
|
||||||
|
"isCurrent": false,
|
||||||
|
"branch": "prod",
|
||||||
|
"commitHash": "testXyz"
|
||||||
|
}
|
||||||
|
]
|
56
packages/backend/test/fixtures/domains.json
vendored
Normal file
56
packages/backend/test/fixtures/domains.json
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "randomurl.snowballtools.xyz",
|
||||||
|
"status": "Live",
|
||||||
|
"isRedirected": false,
|
||||||
|
"branch": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "saugatt.com",
|
||||||
|
"status": "Pending",
|
||||||
|
"isRedirected": false,
|
||||||
|
"branch": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "www.saugatt.com",
|
||||||
|
"status": "Pending",
|
||||||
|
"isRedirected": true,
|
||||||
|
"branch": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "randomurl.snowballtools.xyz",
|
||||||
|
"status": "Live",
|
||||||
|
"isRedirected": false,
|
||||||
|
"branch": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "saugatt.com",
|
||||||
|
"status": "Pending",
|
||||||
|
"isRedirected": false,
|
||||||
|
"branch": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "www.saugatt.com",
|
||||||
|
"status": "Pending",
|
||||||
|
"isRedirected": true,
|
||||||
|
"branch": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "randomurl.snowballtools.xyz",
|
||||||
|
"status": "Live",
|
||||||
|
"isRedirected": false,
|
||||||
|
"branch": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "saugatt.com",
|
||||||
|
"status": "Pending",
|
||||||
|
"isRedirected": false,
|
||||||
|
"branch": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "www.saugatt.com",
|
||||||
|
"status": "Pending",
|
||||||
|
"isRedirected": true,
|
||||||
|
"branch": "test"
|
||||||
|
}
|
||||||
|
]
|
62
packages/backend/test/fixtures/environment-variables.json
vendored
Normal file
62
packages/backend/test/fixtures/environment-variables.json
vendored
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"projectIndex": 0,
|
||||||
|
"key": "ABC",
|
||||||
|
"value": "ABC",
|
||||||
|
"environments": ["Production", "Preview"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 0,
|
||||||
|
"key": "XYZ",
|
||||||
|
"value": "abc3",
|
||||||
|
"environments": ["Preview"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 1,
|
||||||
|
"key": "ABC",
|
||||||
|
"value": "ABC",
|
||||||
|
"environments": ["Production", "Preview"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 1,
|
||||||
|
"key": "XYZ",
|
||||||
|
"value": "abc3",
|
||||||
|
"environments": ["Preview"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 2,
|
||||||
|
"key": "ABC",
|
||||||
|
"value": "ABC",
|
||||||
|
"environments": ["Production", "Preview"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 2,
|
||||||
|
"key": "XYZ",
|
||||||
|
"value": "abc3",
|
||||||
|
"environments": ["Preview"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 3,
|
||||||
|
"key": "ABC",
|
||||||
|
"value": "ABC",
|
||||||
|
"environments": ["Production", "Preview"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 3,
|
||||||
|
"key": "XYZ",
|
||||||
|
"value": "abc3",
|
||||||
|
"environments": ["Preview"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 4,
|
||||||
|
"key": "ABC",
|
||||||
|
"value": "ABC",
|
||||||
|
"environments": ["Production", "Preview"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"projectIndex": 4,
|
||||||
|
"key": "XYZ",
|
||||||
|
"value": "abc3",
|
||||||
|
"environments": ["Preview"]
|
||||||
|
}
|
||||||
|
]
|
12
packages/backend/test/fixtures/project-members.json
vendored
Normal file
12
packages/backend/test/fixtures/project-members.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"memberIndex": 1,
|
||||||
|
"projectIndex": 0,
|
||||||
|
"permissions": ["View", "Edit"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"memberIndex": 2,
|
||||||
|
"projectIndex": 0,
|
||||||
|
"permissions": ["View", "Edit"]
|
||||||
|
}
|
||||||
|
]
|
@ -14,20 +14,37 @@ import { Deployment } from '../src/entity/Deployment';
|
|||||||
|
|
||||||
const log = debug('snowball:initialize-database');
|
const log = debug('snowball:initialize-database');
|
||||||
|
|
||||||
|
const DB_PATH = '../db/snowball';
|
||||||
|
|
||||||
const USER_DATA_PATH = './fixtures/users.json';
|
const USER_DATA_PATH = './fixtures/users.json';
|
||||||
const PROJECT_DATA_PATH = './fixtures/projects.json';
|
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 DOMAIN_DATA_PATH = './fixtures/domains.json';
|
||||||
|
const DEPLOYMENT_DATA_PATH = './fixtures/deployments.json';
|
||||||
|
const ENVIRONMENT_VARIABLE_DATA_PATH = './fixtures/environment-variables.json';
|
||||||
|
|
||||||
const loadAndSaveData = async <Entity extends ObjectLiteral>(entityType: EntityTarget<Entity>, dataSource: DataSource, filePath: string) => {
|
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');
|
||||||
const entities = JSON.parse(entitiesData) as DeepPartial<Entity>[];
|
const entities = JSON.parse(entitiesData);
|
||||||
const entityRepository = dataSource.getRepository(entityType);
|
const entityRepository = dataSource.getRepository(entityType);
|
||||||
|
|
||||||
const savedEntity:Entity[] = [];
|
const savedEntity:Entity[] = [];
|
||||||
|
|
||||||
for (const entityData of entities) {
|
for (const entityData of entities) {
|
||||||
const entity = entityRepository.create(entityData);
|
let entity = entityRepository.create(entityData as DeepPartial<Entity>);
|
||||||
|
|
||||||
|
if (relations) {
|
||||||
|
for (const field in relations) {
|
||||||
|
const valueIndex = String(field + 'Index');
|
||||||
|
|
||||||
|
entity = {
|
||||||
|
...entity,
|
||||||
|
[field]: relations[field][entityData[valueIndex]]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
const dbEntity = await entityRepository.save(entity);
|
const dbEntity = await entityRepository.save(entity);
|
||||||
savedEntity.push(dbEntity);
|
savedEntity.push(dbEntity);
|
||||||
}
|
}
|
||||||
@ -38,52 +55,69 @@ 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 projectsData = await fs.readFile(path.resolve(__dirname, PROJECT_DATA_PATH), 'utf-8');
|
const projectRelations = {
|
||||||
const projects = JSON.parse(projectsData);
|
owner: savedUsers,
|
||||||
const projectRepository = dataSource.getRepository(Project);
|
organization: savedOrgs
|
||||||
|
};
|
||||||
|
|
||||||
for (const projectData of projects) {
|
const savedProjects = await loadAndSaveData(Project, dataSource, path.resolve(__dirname, PROJECT_DATA_PATH), projectRelations);
|
||||||
const project = projectRepository.create(projectData as DeepPartial<Project>);
|
|
||||||
project.owner = savedUsers[projectData.ownerIndex];
|
|
||||||
project.organization = savedOrgs[projectData.organizationIndex];
|
|
||||||
await projectRepository.save(project);
|
|
||||||
}
|
|
||||||
|
|
||||||
const userOrgData = await fs.readFile(path.resolve(__dirname, USER_ORGANIZATION_DATA_PATH), 'utf-8');
|
const userOrganizationRelations = {
|
||||||
const userOrgs = JSON.parse(userOrgData);
|
member: savedUsers,
|
||||||
const userOrgRepository = dataSource.getRepository(UserOrganization);
|
organization: savedOrgs
|
||||||
|
};
|
||||||
|
|
||||||
for (const userOrgData of userOrgs) {
|
await loadAndSaveData(UserOrganization, dataSource, path.resolve(__dirname, USER_ORGANIZATION_DATA_PATH), userOrganizationRelations);
|
||||||
const userOrg = userOrgRepository.create(userOrgData as DeepPartial<UserOrganization>);
|
|
||||||
userOrg.member = savedUsers[userOrgData.memberIndex];
|
|
||||||
userOrg.organization = savedOrgs[userOrgData.organizationIndex];
|
|
||||||
|
|
||||||
await userOrgRepository.save(userOrg);
|
const projectMemberRelations = {
|
||||||
|
member: savedUsers,
|
||||||
|
project: savedProjects
|
||||||
|
};
|
||||||
|
|
||||||
|
await loadAndSaveData(ProjectMember, dataSource, path.resolve(__dirname, PROJECT_MEMBER_DATA_PATH), projectMemberRelations);
|
||||||
|
|
||||||
|
const deploymentRelations = {
|
||||||
|
project: savedProjects,
|
||||||
|
domain: savedDomains
|
||||||
|
};
|
||||||
|
|
||||||
|
await loadAndSaveData(Deployment, dataSource, path.resolve(__dirname, DEPLOYMENT_DATA_PATH), deploymentRelations);
|
||||||
|
|
||||||
|
const environmentVariableRelations = {
|
||||||
|
project: savedProjects
|
||||||
|
};
|
||||||
|
|
||||||
|
await loadAndSaveData(EnvironmentVariable, dataSource, path.resolve(__dirname, ENVIRONMENT_VARIABLE_DATA_PATH), environmentVariableRelations);
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkFileExists = async (filePath: string) => {
|
||||||
|
try {
|
||||||
|
await fs.access(filePath, fs.constants.F_OK);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
log(err);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const main = async () => {
|
const main = async () => {
|
||||||
const dataSource = new DataSource({
|
const isDbPresent = await checkFileExists(path.resolve(__dirname, DB_PATH));
|
||||||
type: 'better-sqlite3',
|
|
||||||
database: 'db/snowball',
|
|
||||||
synchronize: true,
|
|
||||||
logging: true,
|
|
||||||
entities: [
|
|
||||||
User,
|
|
||||||
Organization,
|
|
||||||
Project,
|
|
||||||
UserOrganization,
|
|
||||||
EnvironmentVariable,
|
|
||||||
Domain,
|
|
||||||
ProjectMember,
|
|
||||||
Deployment
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
await dataSource.initialize();
|
if (!isDbPresent) {
|
||||||
|
const dataSource = new DataSource({
|
||||||
|
type: 'better-sqlite3',
|
||||||
|
database: 'db/snowball',
|
||||||
|
synchronize: true,
|
||||||
|
logging: true,
|
||||||
|
entities: [path.join(__dirname, '../src/entity/*')]
|
||||||
|
});
|
||||||
|
|
||||||
await generateTestData(dataSource);
|
await dataSource.initialize();
|
||||||
|
|
||||||
|
await generateTestData(dataSource);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
main().then(() => {
|
main().then(() => {
|
||||||
|
@ -14,19 +14,19 @@ const Domains = () => {
|
|||||||
|
|
||||||
const { projects } = useOutletContext<ProjectsOutletContext>();
|
const { projects } = useOutletContext<ProjectsOutletContext>();
|
||||||
|
|
||||||
const currProject = useMemo(() => {
|
const currentProject = useMemo(() => {
|
||||||
return projects.find((project) => {
|
return projects.find((project) => {
|
||||||
return project.id === id;
|
return project.id === id;
|
||||||
});
|
});
|
||||||
}, [id, projects]);
|
}, [id, projects]);
|
||||||
|
|
||||||
const linkedRepo = useMemo(() => {
|
const linkedRepo = useMemo(() => {
|
||||||
return currProject?.repositories.find(
|
return currentProject?.repositories.find(
|
||||||
(repo: any) => repo.id === Number(currProject?.repositoryId),
|
(repo: any) => repo.id === Number(currentProject?.repositoryId),
|
||||||
);
|
);
|
||||||
}, [currProject]);
|
}, [currentProject]);
|
||||||
|
|
||||||
const domains = currProject?.deployments
|
const domains = currentProject?.deployments
|
||||||
.filter((deployment) => {
|
.filter((deployment) => {
|
||||||
return deployment.domain != null;
|
return deployment.domain != null;
|
||||||
})
|
})
|
||||||
@ -49,7 +49,7 @@ const Domains = () => {
|
|||||||
domain={domain}
|
domain={domain}
|
||||||
key={domain.id}
|
key={domain.id}
|
||||||
repo={linkedRepo!}
|
repo={linkedRepo!}
|
||||||
project={currProject!}
|
project={currentProject!}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@ -38,7 +38,7 @@ export const EnvironmentVariablesTabPanel = () => {
|
|||||||
|
|
||||||
const { projects } = useOutletContext<ProjectsOutletContext>();
|
const { projects } = useOutletContext<ProjectsOutletContext>();
|
||||||
|
|
||||||
const currProject = useMemo(() => {
|
const currentProject = useMemo(() => {
|
||||||
return projects.find((project) => {
|
return projects.find((project) => {
|
||||||
return project.id === id;
|
return project.id === id;
|
||||||
});
|
});
|
||||||
@ -77,9 +77,9 @@ export const EnvironmentVariablesTabPanel = () => {
|
|||||||
}, [isSubmitSuccessful, reset]);
|
}, [isSubmitSuccessful, reset]);
|
||||||
|
|
||||||
const getEnvironmentVariable = useCallback((environment: Environments) => {
|
const getEnvironmentVariable = useCallback((environment: Environments) => {
|
||||||
return (currProject?.environmentVariables as EnvironmentVariable[]).filter(
|
return (
|
||||||
(item) => item.environments.includes(environment),
|
currentProject?.environmentVariables as EnvironmentVariable[]
|
||||||
);
|
).filter((item) => item.environments.includes(environment));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const isFieldEmpty = useMemo(() => {
|
const isFieldEmpty = useMemo(() => {
|
||||||
|
@ -15,7 +15,6 @@ import DeleteProjectDialog from './DeleteProjectDialog';
|
|||||||
import ConfirmDialog from '../../../shared/ConfirmDialog';
|
import ConfirmDialog from '../../../shared/ConfirmDialog';
|
||||||
import { ProjectsOutletContext } from '../../../../types/project';
|
import { ProjectsOutletContext } from '../../../../types/project';
|
||||||
|
|
||||||
const PROJECT_ID = '62f87575-7a2b-4951-8156-9f9821j380d';
|
|
||||||
const TEAMS = ['Airfoil'];
|
const TEAMS = ['Airfoil'];
|
||||||
const DEFAULT_SELECT_TEAM = undefined;
|
const DEFAULT_SELECT_TEAM = undefined;
|
||||||
|
|
||||||
@ -37,7 +36,7 @@ const GeneralTabPanel = () => {
|
|||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const { projects } = useOutletContext<ProjectsOutletContext>();
|
const { projects } = useOutletContext<ProjectsOutletContext>();
|
||||||
|
|
||||||
const currProject = useMemo(() => {
|
const currentProject = useMemo(() => {
|
||||||
return projects.find((project: any) => project.id === id);
|
return projects.find((project: any) => project.id === id);
|
||||||
}, [id]);
|
}, [id]);
|
||||||
|
|
||||||
@ -61,128 +60,132 @@ const GeneralTabPanel = () => {
|
|||||||
|
|
||||||
const { handleSubmit, register } = useForm({
|
const { handleSubmit, register } = useForm({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
appName: currProject?.name,
|
appName: currentProject?.name,
|
||||||
description: currProject?.description,
|
description: currentProject?.description,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<form onSubmit={handleSubmit(() => {})}>
|
{currentProject && (
|
||||||
<Typography variant="h6">Project info</Typography>
|
<>
|
||||||
<Typography variant="small" className="font-medium text-gray-800">
|
<form onSubmit={handleSubmit(() => {})}>
|
||||||
App name
|
<Typography variant="h6">Project info</Typography>
|
||||||
</Typography>
|
<Typography variant="small" className="font-medium text-gray-800">
|
||||||
<Input
|
App name
|
||||||
variant="outlined"
|
</Typography>
|
||||||
// TODO: Debug issue: https://github.com/creativetimofficial/material-tailwind/issues/427
|
<Input
|
||||||
crossOrigin={undefined}
|
variant="outlined"
|
||||||
size="md"
|
// TODO: Debug issue: https://github.com/creativetimofficial/material-tailwind/issues/427
|
||||||
{...register('appName')}
|
crossOrigin={undefined}
|
||||||
/>
|
size="md"
|
||||||
<Typography variant="small" className="font-medium text-gray-800">
|
{...register('appName')}
|
||||||
Description (Optional)
|
/>
|
||||||
</Typography>
|
<Typography variant="small" className="font-medium text-gray-800">
|
||||||
<Input
|
Description (Optional)
|
||||||
variant="outlined"
|
</Typography>
|
||||||
crossOrigin={undefined}
|
<Input
|
||||||
size="md"
|
variant="outlined"
|
||||||
{...register('description')}
|
crossOrigin={undefined}
|
||||||
/>
|
size="md"
|
||||||
<Typography variant="small" className="font-medium text-gray-800">
|
{...register('description')}
|
||||||
Project ID
|
/>
|
||||||
</Typography>
|
<Typography variant="small" className="font-medium text-gray-800">
|
||||||
<Input
|
Project ID
|
||||||
crossOrigin={undefined}
|
</Typography>
|
||||||
variant="outlined"
|
<Input
|
||||||
value={PROJECT_ID}
|
crossOrigin={undefined}
|
||||||
size="md"
|
variant="outlined"
|
||||||
disabled
|
value={currentProject.id}
|
||||||
icon={<CopyIcon value={PROJECT_ID} />}
|
size="md"
|
||||||
/>
|
disabled
|
||||||
<Button type="submit" variant="gradient" size="sm" className="mt-1">
|
icon={<CopyIcon value={currentProject.id} />}
|
||||||
Save
|
/>
|
||||||
</Button>
|
<Button type="submit" variant="gradient" size="sm" className="mt-1">
|
||||||
</form>
|
Save
|
||||||
<div className="mb-1">
|
</Button>
|
||||||
<Typography variant="h6">Transfer project</Typography>
|
</form>
|
||||||
<Typography variant="small">
|
<div className="mb-1">
|
||||||
Transfer this app to your personal account or a team you are a member
|
<Typography variant="h6">Transfer project</Typography>
|
||||||
of.
|
<Typography variant="small">
|
||||||
<Link to="" className="text-blue-500">
|
Transfer this app to your personal account or a team you are a
|
||||||
Learn more
|
member of.
|
||||||
</Link>
|
<Link to="" className="text-blue-500">
|
||||||
</Typography>
|
Learn more
|
||||||
<form
|
</Link>
|
||||||
onSubmit={handleTransfer(() => {
|
</Typography>
|
||||||
handleTransferProjectDialog();
|
<form
|
||||||
})}
|
onSubmit={handleTransfer(() => {
|
||||||
>
|
handleTransferProjectDialog();
|
||||||
<Typography variant="small" className="font-medium text-gray-800">
|
})}
|
||||||
Choose team
|
>
|
||||||
</Typography>
|
<Typography variant="small" className="font-medium text-gray-800">
|
||||||
<Controller
|
Choose team
|
||||||
name="team"
|
</Typography>
|
||||||
rules={{ required: 'This field is required' }}
|
<Controller
|
||||||
control={control}
|
name="team"
|
||||||
render={({ field }) => (
|
rules={{ required: 'This field is required' }}
|
||||||
<Select
|
control={control}
|
||||||
{...field}
|
render={({ field }) => (
|
||||||
// TODO: Implement placeholder for select
|
<Select
|
||||||
label={!field.value ? 'Select an account / team' : ''}
|
{...field}
|
||||||
|
// TODO: Implement placeholder for select
|
||||||
|
label={!field.value ? 'Select an account / team' : ''}
|
||||||
|
>
|
||||||
|
{TEAMS.map((team, key) => (
|
||||||
|
<Option key={key} value={team}>
|
||||||
|
^ {team}
|
||||||
|
</Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
variant="gradient"
|
||||||
|
size="sm"
|
||||||
|
className="mt-1"
|
||||||
|
disabled={!formState.isValid}
|
||||||
|
type="submit"
|
||||||
>
|
>
|
||||||
{TEAMS.map((team, key) => (
|
Transfer
|
||||||
<Option key={key} value={team}>
|
</Button>
|
||||||
^ {team}
|
</form>
|
||||||
</Option>
|
<ConfirmDialog
|
||||||
))}
|
dialogTitle="Transfer project"
|
||||||
</Select>
|
handleOpen={handleTransferProjectDialog}
|
||||||
)}
|
open={openTransferDialog}
|
||||||
/>
|
confirmButtonTitle="Yes, Confirm transfer"
|
||||||
<Button
|
handleConfirm={handleTransferProjectDialog}
|
||||||
variant="gradient"
|
color="blue"
|
||||||
size="sm"
|
>
|
||||||
className="mt-1"
|
<Typography variant="small">
|
||||||
disabled={!formState.isValid}
|
Upon confirmation, your project nextjs-boilerplate will be
|
||||||
type="submit"
|
transferred from saugat to Airfoil.
|
||||||
>
|
</Typography>
|
||||||
Transfer
|
</ConfirmDialog>
|
||||||
</Button>
|
</div>
|
||||||
</form>
|
<div className="mb-1">
|
||||||
<ConfirmDialog
|
<Typography variant="h6">Delete project</Typography>
|
||||||
dialogTitle="Transfer project"
|
<Typography variant="small">
|
||||||
handleOpen={handleTransferProjectDialog}
|
The project will be permanently deleted, including its deployments
|
||||||
open={openTransferDialog}
|
and domains. This action is irreversible and can not be undone.
|
||||||
confirmButtonTitle="Yes, Confirm transfer"
|
</Typography>
|
||||||
handleConfirm={handleTransferProjectDialog}
|
<Button
|
||||||
color="blue"
|
variant="gradient"
|
||||||
>
|
size="sm"
|
||||||
<Typography variant="small">
|
color="red"
|
||||||
Upon confirmation, your project nextjs-boilerplate will be
|
onClick={handleDeleteProjectDialog}
|
||||||
transferred from saugat to Airfoil.
|
>
|
||||||
</Typography>
|
^ Delete project
|
||||||
</ConfirmDialog>
|
</Button>
|
||||||
</div>
|
<DeleteProjectDialog
|
||||||
<div className="mb-1">
|
handleOpen={handleDeleteProjectDialog}
|
||||||
<Typography variant="h6">Delete project</Typography>
|
open={openDeleteDialog}
|
||||||
<Typography variant="small">
|
project={{ name: 'Iglootools' }}
|
||||||
The project will be permanently deleted, including its deployments and
|
/>
|
||||||
domains. This action is irreversible and can not be undone.
|
</div>
|
||||||
</Typography>
|
</>
|
||||||
<Button
|
)}
|
||||||
variant="gradient"
|
|
||||||
size="sm"
|
|
||||||
color="red"
|
|
||||||
onClick={handleDeleteProjectDialog}
|
|
||||||
>
|
|
||||||
^ Delete project
|
|
||||||
</Button>
|
|
||||||
<DeleteProjectDialog
|
|
||||||
handleOpen={handleDeleteProjectDialog}
|
|
||||||
open={openDeleteDialog}
|
|
||||||
project={{ name: 'Iglootools' }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -18,12 +18,12 @@ const MembersTabPanel = () => {
|
|||||||
// @ts-expect-error create context type for projects
|
// @ts-expect-error create context type for projects
|
||||||
const { projects } = useOutletContext();
|
const { projects } = useOutletContext();
|
||||||
|
|
||||||
const currProject = useMemo(() => {
|
const currentProject = useMemo(() => {
|
||||||
return projects.find((project: any) => project.id === id);
|
return projects.find((project: any) => project.id === id);
|
||||||
}, [id]);
|
}, [id]);
|
||||||
|
|
||||||
const [updatedMembers, setUpdatedMembers] = useState([
|
const [updatedMembers, setUpdatedMembers] = useState([
|
||||||
...currProject?.members,
|
...currentProject?.members,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const addMemberHandler = useCallback((member: Member) => {
|
const addMemberHandler = useCallback((member: Member) => {
|
||||||
@ -59,7 +59,7 @@ const MembersTabPanel = () => {
|
|||||||
member={member.member}
|
member={member.member}
|
||||||
key={member.id}
|
key={member.id}
|
||||||
isFirstCard={index === FIRST_MEMBER_CARD}
|
isFirstCard={index === FIRST_MEMBER_CARD}
|
||||||
isOwner={member.member.id === currProject?.owner.id}
|
isOwner={member.member.id === currentProject?.owner.id}
|
||||||
isPending={member.name === ''}
|
isPending={member.name === ''}
|
||||||
permissions={member.permissions}
|
permissions={member.permissions}
|
||||||
handleDeletePendingMember={(id: number) => {
|
handleDeletePendingMember={(id: number) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user