Skip to content

Commit

Permalink
Merge pull request #540 from AI4Bharat/clone-project
Browse files Browse the repository at this point in the history
Bulk Project Creation
  • Loading branch information
harsh12-99 authored Jan 23, 2024
2 parents 371487f + 27ef383 commit a8d4f82
Show file tree
Hide file tree
Showing 7 changed files with 338 additions and 5 deletions.
13 changes: 11 additions & 2 deletions src/containers/Organization/MyOrganization.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,6 @@ const MyOrganization = () => {
organization: { organization_owner },
} = userData;

console.log(organization_owner,'organization_owner tetete');

setOrgOwnerId(organization_owner.id);
}
// eslint-disable-next-line
Expand Down Expand Up @@ -228,6 +226,17 @@ const MyOrganization = () => {
Add New Project
</Button>

<Button
style={{ marginRight: "10px" }}
className={classes.projectButton}
onClick={() =>
navigate(`/my-organization/${id}/create-bulk-projects`)
}
variant="contained"
>
Create Bulk Projects from Template
</Button>

{organizationDetails.enable_upload && (
<Button
style={{ marginLeft: "10px" }}
Expand Down
247 changes: 247 additions & 0 deletions src/containers/Organization/Project/CreateBulkProjects.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
import React, { useState, useEffect } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";

//Styles
import { DatasetStyle } from "styles";

//Components
import {
Card,
Grid,
Typography,
FormControl,
MenuItem,
Select,
Button,
Divider,
Tooltip,
IconButton,
} from "@mui/material";
import { Box } from "@mui/system";
import { OutlinedTextField } from "common";

//APIs
import {
APITransport,
CreateBulkProjectsAPI,
ProjectListAPI,
} from "redux/actions";

import AddIcon from "@mui/icons-material/Add";
import DeleteIcon from "@mui/icons-material/Delete";

const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250,
},
},
};

const CreateBulkProjects = () => {
const { orgId } = useParams();
const classes = DatasetStyle();
const navigate = useNavigate();
const dispatch = useDispatch();

const [template, setTemplate] = useState("");
const [numberOfProjects, setNumberOfProjects] = useState(1);
const [projectNames, setProjectNames] = useState([""]);

const projectList = useSelector((state) => state.getProjectList.data);
const apiStatus = useSelector((state) => state.apiStatus);

useEffect(() => {
const { progress, success, apiType } = apiStatus;

if (!progress) {
if (success) {
if (apiType === "CREATE_BULK_PROJECTS") {
navigate(`/my-organization/${orgId}`, {
replace: true,
});
}
}
}

// eslint-disable-next-line
}, [apiStatus]);

const getProjectList = () => {
const userObj = new ProjectListAPI(orgId);
dispatch(APITransport(userObj));
};

useEffect(() => {
getProjectList();
}, []);

const handleNumProjectsChange = (e) => {
const newNumProjects = parseInt(e.target.value, 10) || 1;
const clampedNumProjects = Math.min(Math.max(newNumProjects, 1), 20);

setNumberOfProjects(clampedNumProjects);

setProjectNames((prevProjectNames) =>
prevProjectNames.slice(0, clampedNumProjects)
);
};

const handleProjectNameChange = (e, index) => {
const newProjectNames = [...projectNames];
newProjectNames[index] = e.target.value;
setProjectNames(newProjectNames);
};

const handleAddProject = () => {
setNumberOfProjects((prevNumProjects) => prevNumProjects + 1);
setProjectNames((prevProjectNames) => [...prevProjectNames, ""]);
};

const handleRemoveProject = (index) => {
setNumberOfProjects((prevNumProjects) => prevNumProjects - 1);
setProjectNames((prevProjectNames) =>
prevProjectNames.filter((_, i) => i !== index)
);
};

const handleCreateProject = () => {
const apiObj = new CreateBulkProjectsAPI(template, projectNames);
dispatch(APITransport(apiObj));
};

const disableBtn = () => {
if (numberOfProjects !== projectNames.length) {
return true;
}

if (template.length <= 0) {
return true;
}

return false;
};

return (
<Grid container className={classes.bulkProjectContainer}>
<Card className={classes.workspaceCard}>
<Typography variant="h2" sx={{ mb: 5 }}>
Create Bulk Project from a Template
</Typography>

<Grid container>
<Grid item xs={12} md={3}>
<Typography gutterBottom>Number Of Projects</Typography>
<OutlinedTextField
fullWidth
value={numberOfProjects}
onChange={handleNumProjectsChange}
sx={{ width: "95%" }}
/>
</Grid>

<Grid item xs={12} md={9}>
<Typography gutterBottom>Project Template</Typography>
<FormControl fullWidth>
<Select
id="template-name"
value={template}
onChange={(event) => setTemplate(event.target.value)}
MenuProps={MenuProps}
>
{projectList.map((element, index) => (
<MenuItem key={index} value={element.id}>
{element.title}
</MenuItem>
))}
</Select>
</FormControl>
</Grid>
</Grid>

<Divider sx={{ my: 2 }} />

<Grid container>
{[...Array(numberOfProjects)].map((_, index) => {
return (
<>
<Grid item xs={12} md={3} className={classes.newProjectWrapper}>
<Typography>Project {index + 1} Title</Typography>
</Grid>

<Grid item xs={12} md={7} sx={{ my: 1 }}>
<OutlinedTextField
fullWidth
value={projectNames[index]}
onChange={(e) => handleProjectNameChange(e, index)}
/>
</Grid>

<Grid item xs={12} md={2} className={classes.newProjectWrapper}>
<Tooltip title="Add Project">
<IconButton
color="primary"
onClick={() => handleAddProject(index)}
sx={{
visibility: `${
index + 1 === numberOfProjects &&
numberOfProjects < 20
? "visible"
: "hidden"
}`,
}}
>
<AddIcon />
</IconButton>
</Tooltip>

<Tooltip title="Remove Project">
<IconButton
color="error"
onClick={() => handleRemoveProject(index)}
sx={{
visibility: `${
numberOfProjects !== 1 ? "visible" : "hidden"
}`,
}}
>
<DeleteIcon />
</IconButton>
</Tooltip>
</Grid>
</>
);
})}
</Grid>

<Divider sx={{ my: 2 }} />

<Box sx={{ mt: 3 }}>
<Button
color="primary"
variant="contained"
className={classes.bulkProjectButton}
onClick={() => handleCreateProject()}
disabled={disableBtn()}
>
Create Projects
</Button>

<Button
variant="text"
className={classes.bulkProjectButton}
onClick={() => navigate(`/my-organization/${orgId}`)}
>
Cancel
</Button>
</Box>
</Card>
</Grid>
);
};

export default CreateBulkProjects;
47 changes: 47 additions & 0 deletions src/redux/actions/api/Project/CreateBulkProjects.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import API from "../../../api";
import ENDPOINTS from "../../../../config/apiendpoint";
import C from "../../../constants";

export default class CreateBulkProjectsAPI extends API {
constructor(projectId, projectTitles, timeout = 2000) {
super("POST", timeout, false);
this.type = C.CREATE_BULK_PROJECTS;
this.projectId = projectId;
this.projectTitles = projectTitles;
this.endpoint = `${super.apiEndPointAuto()}${
ENDPOINTS.project
}create_bulk_projects/`;
}

processResponse(res) {
super.processResponse(res);
if (res) {
this.report = res;
}
}

apiEndPoint() {
return this.endpoint;
}

getBody() {
return {
titles: this.projectTitles,
project_id: this.projectId,
};
}

getHeaders() {
this.headers = {
headers: {
"Content-Type": "application/json",
Authorization: `JWT ${localStorage.getItem("token")}`,
},
};
return this.headers;
}

getPayload() {
return this.report;
}
}
2 changes: 2 additions & 0 deletions src/redux/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ import UploadToYoutubeAPI from "./api/Project/UploadToYoutube";
import FetchSupportedBulkTaskTypeAPI from "./api/Project/FetchSupportedBulkTaskTypes";
import FetchTaskFailInfoAPI from "./api/Project/FetchTaskFailInfo";
import ReopenTaskAPI from "./api/Project/ReopenTask";
import CreateBulkProjectsAPI from "./api/Project/CreateBulkProjects";

//User APIs
import ChangePasswordAPI from "./api/User/ChangePassword";
Expand Down Expand Up @@ -267,5 +268,6 @@ export {
updateOrgSearchValues,
updateCurrentOrgSearchedColumn,
UnSubscribeNewletterFromEmailAPI,
CreateBulkProjectsAPI,
RegenerateResponseAPI,
};
1 change: 1 addition & 0 deletions src/redux/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const constants = {
CLEAR_PROJECT_VIDEOS: "CLEAR_PROJECT_VIDEOS",
GET_TRANSCRIPT_EXPORT_TYPE: "GET_TRANSCRIPT_EXPORT_TYPE",
GET_TRANSLATION_EXPORT_TYPE: "GET_TRANSLATION_EXPORT_TYPE",
CREATE_BULK_PROJECTS: "CREATE_BULK_PROJECTS",
REGENERATE_RESPONSE: "REGENERATE_RESPONSE",

//User
Expand Down
18 changes: 18 additions & 0 deletions src/styles/datasetStyle.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,24 @@ const DatasetStyle = makeStyles({
fontSize: 16,
fontWeight: "700"
},

bulkProjectContainer: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center"
},

newProjectWrapper: {
my: 1,
display: "flex",
justifyContent: "center",
alignItems: "center",
},

bulkProjectButton: {
borderRadius: "8px",
margin: "0px 10px 0px 0px"
},
});

export default DatasetStyle;
Loading

0 comments on commit a8d4f82

Please sign in to comment.