Skip to content

Commit

Permalink
1437 snapshot modal (#1514)
Browse files Browse the repository at this point in the history
* New branch

* Ready for review

---------

Co-authored-by: John Darragh <[email protected]>
  • Loading branch information
Jonathanko52 and entrotech authored Nov 16, 2023
1 parent 4c16478 commit 8346c1b
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 7 deletions.
7 changes: 6 additions & 1 deletion client/src/components/Projects/ProjectContextMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const ProjectContextMenu = ({
project,
handleCopyModalOpen,
handleDeleteModalOpen,
handleSnapshotModalOpen,
handleDownloadCsv,
handlePrintPdf
}) => {
Expand All @@ -50,7 +51,10 @@ const ProjectContextMenu = ({
return (
<ul className={classes.list}>
{project.dateSnapshotted ? null : (
<li className={classes.listItem}>
<li
className={classes.listItem}
onClick={() => handleSnapshotModalOpen(project)}
>
<FontAwesomeIcon
icon={faCamera}
className={classes.listItemIcon}
Expand Down Expand Up @@ -147,6 +151,7 @@ ProjectContextMenu.propTypes = {
project: PropTypes.object,
handleCopyModalOpen: PropTypes.func,
handleDeleteModalOpen: PropTypes.func,
handleSnapshotModalOpen: PropTypes.func,
handleDownloadCsv: PropTypes.func,
handlePrintPdf: PropTypes.func
};
Expand Down
7 changes: 5 additions & 2 deletions client/src/components/Projects/ProjectTableRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ const mapCsvRules = rules => {
const ProjectTableRow = ({
project,
handleCopyModalOpen,
handleDeleteModalOpen
handleDeleteModalOpen,
handleSnapshotModalOpen
}) => {
const classes = useStyles();
const momentModified = moment(project.dateModified);
Expand Down Expand Up @@ -195,6 +196,7 @@ const ProjectTableRow = ({
handleDeleteModalOpen={handleDeleteModalOpen}
handleDownloadCsv={handleDownloadCsv}
handlePrintPdf={handlePrintPdf}
handleSnapshotModalOpen={handleSnapshotModalOpen}
/>
</Popup>
<div style={{ display: "none" }}>
Expand All @@ -220,7 +222,8 @@ const ProjectTableRow = ({
ProjectTableRow.propTypes = {
project: PropTypes.object.isRequired,
handleCopyModalOpen: PropTypes.func.isRequired,
handleDeleteModalOpen: PropTypes.func.isRequired
handleDeleteModalOpen: PropTypes.func.isRequired,
handleSnapshotModalOpen: PropTypes.func.isRequired
};

export default ProjectTableRow;
30 changes: 29 additions & 1 deletion client/src/components/Projects/ProjectsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import ContentContainerNoSidebar from "../Layout/ContentContainerNoSidebar";
import useErrorHandler from "../../hooks/useErrorHandler";
import useProjects from "../../hooks/useGetProjects";
import * as projectService from "../../services/project.service";

import SnapshotProjectModal from "./SnapshotProjectModal";
import DeleteProjectModal from "./DeleteProjectModal";
import CopyProjectModal from "./CopyProjectModal";
import ProjectTableRow from "./ProjectTableRow";
Expand Down Expand Up @@ -102,6 +102,7 @@ const ProjectsPage = ({ account, contentContainerRef }) => {
const projects = useProjects(handleError);
const [orderBy, setOrderBy] = useState("dateCreated");
const [copyModalOpen, setCopyModalOpen] = useState(false);
const [snapshotModalOpen, setSnapshotModalOpen] = useState(false);
const [deleteModalOpen, setDeleteModalOpen] = useState(false);
const [selectedProject, setSelectedProject] = useState(null);
const classes = useStyles();
Expand Down Expand Up @@ -170,6 +171,26 @@ const ProjectsPage = ({ account, contentContainerRef }) => {
setDeleteModalOpen(false);
};

const handleSnapshotModalOpen = project => {
setSelectedProject(project);
setSnapshotModalOpen(true);
};

const handleSnapshotModalClose = async (action, newProjectName) => {
if (action === "ok") {
try {
await projectService.snapshot({
id: selectedProject.id,
name: newProjectName
});
setSelectedProject(null);
} catch (err) {
handleError(err);
}
}
setSnapshotModalOpen(false);
};

const descCompareBy = (a, b, orderBy) => {
let projectA, projectB;

Expand Down Expand Up @@ -375,6 +396,7 @@ const ProjectsPage = ({ account, contentContainerRef }) => {
project={project}
handleCopyModalOpen={handleCopyModalOpen}
handleDeleteModalOpen={handleDeleteModalOpen}
handleSnapshotModalOpen={handleSnapshotModalOpen}
/>
))
) : (
Expand Down Expand Up @@ -406,6 +428,12 @@ const ProjectsPage = ({ account, contentContainerRef }) => {
onClose={handleDeleteModalClose}
selectedProjectName={selectedProjectName}
/>

<SnapshotProjectModal
mounted={snapshotModalOpen}
onClose={handleSnapshotModalClose}
selectedProjectName={selectedProjectName}
/>
</>
)}
</ContentContainerNoSidebar>
Expand Down
83 changes: 83 additions & 0 deletions client/src/components/Projects/SnapshotProjectModal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import { createUseStyles, useTheme } from "react-jss";

import Button from "../Button/Button";
import { faCopy } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

import ModalDialog from "../UI/AriaModal/ModalDialog";

const useStyles = createUseStyles(theme => ({
buttonFlexBox: {
display: "flex",
flexDirection: "row",
justifyContent: "center",
margin: 0
},
heading1: theme.typography.heading1,
buttonColor: {
backgroundColor: "#eaeff2"
}
}));

export default function SnapshotProjectModal({
mounted,
onClose,
selectedProjectName
}) {
const theme = useTheme();
const classes = useStyles({ theme });
const [snapshotProjectName, setSnapshotProjectName] = useState(
`${selectedProjectName}`
);

return (
<ModalDialog
mounted={mounted}
onClose={onClose}
initialFocus="#duplicateName"
>
<div className={classes.heading1} style={{ marginBottom: "1.5rem" }}>
<FontAwesomeIcon icon={faCopy} /> Convert &quot;
{`${selectedProjectName}`}&quot; Into a Snapshot?
</div>
<div style={theme.typography.subHeading}>
Once converted, this project draft will no longer be in an editable
state.
</div>
<div style={{ margin: "1.5rem 2.5rem 1.5rem 0.75rem" }}>
<input
placeholder="Name of Duplicated Project"
type="text"
id="duplicateName"
name="duplicateName"
value={snapshotProjectName}
onChange={e => setSnapshotProjectName(e.target.value)}
/>
</div>
<div className={classes.buttonFlexBox}>
<Button
className={classes.buttonColor}
onClick={onClose}
variant="contained"
>
Cancel
</Button>
<Button
className={classes.buttonColor}
onClick={() => onClose("ok", snapshotProjectName)}
variant="contained"
>
Done
</Button>
</div>
</ModalDialog>
);
}

SnapshotProjectModal.propTypes = {
mounted: PropTypes.bool,
onClose: PropTypes.func,
selectedProjectName: PropTypes.string
};
4 changes: 4 additions & 0 deletions client/src/services/project.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ export function del(id) {
return axios.delete(baseUrl + "/" + id);
}

export function snapshot(id) {
return axios.put(baseUrl + "/snapshot", id);
}

export function getAllArchivedProjects() {
try {
return axios.get(`${baseUrl}/archivedprojects`);
Expand Down
4 changes: 2 additions & 2 deletions server/app/controllers/project.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ const trash = async (req, res) => {

const snapshot = async (req, res) => {
try {
const { id } = req.body;
const { id, name } = req.body;

const result = await projectService.snapshot(id, req.user.id);
const result = await projectService.snapshot(id, req.user.id, name);
if (result === 1) {
res.sendStatus(403);
} else {
Expand Down
4 changes: 3 additions & 1 deletion server/app/services/project.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,15 @@ const trash = async (ids, trash, loginId) => {
}
};

const snapshot = async (id, loginId) => {
const snapshot = async (id, loginId, name) => {
try {
await poolConnect;
const request = pool.request();

request.input("id", id);
request.input("loginId", loginId);
request.input("name", name);

const response = await request.execute("Project_Snapshot");
return response.returnValue;
} catch (err) {
Expand Down

0 comments on commit 8346c1b

Please sign in to comment.