Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1520 multi project toolbar menu #1639

Merged
merged 23 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c738684
added ProjectCheckBoxMenu and set up where check boxes will be
agutiernc Dec 26, 2023
e0dc82b
added checkboxes and menu to project table - hide feature works
agutiernc Dec 27, 2023
4769fd8
added useHiddenStatus hook for checkbox button
agutiernc Dec 31, 2023
89e6e21
added code to disable hide button in ProjectCheckBoxMenu & adjust div…
agutiernc Dec 31, 2023
e05e3f6
header checkbox checks/unchecks all project rows
agutiernc Jan 3, 2024
8d20607
added filters to handleHeaderCheckbox & uncheck checkboxes when filte…
agutiernc Jan 5, 2024
1b5e4de
added permissions check in useHiddenStatus & ProjectCheckBoxMenu
agutiernc Jan 7, 2024
13369b8
fixed select all for current page only
agutiernc Jan 10, 2024
f50bd9b
multi-select delete feature working. added new multi-project data hook
agutiernc Feb 7, 2024
bd8ff3e
refactored handleHide
agutiernc Feb 7, 2024
267882b
delete and hidden buttons working. refactored ProjectCheckBoxMenu
agutiernc Feb 13, 2024
8701b22
added tooltips for toolbar menu - delete btn
agutiernc Feb 14, 2024
b3ef175
added tooltip to hide btn
agutiernc Feb 14, 2024
5465527
added tooltip & msg
agutiernc Feb 15, 2024
3bd13ce
added tooltip style and renamed ProjectCheckBoxMenu to MultiProjectTo…
agutiernc Feb 15, 2024
e85af39
added styles to tooltip. reset checked projects state on page change
agutiernc Feb 15, 2024
a3e21da
added message types for tooltip. added comments
agutiernc Feb 17, 2024
68a28ec
fixed tooltip message for delete button
agutiernc Feb 17, 2024
a32aff7
renamed toolbarmenu component
agutiernc Feb 17, 2024
7c931db
fixed bug on handleHide for context menu
agutiernc Mar 18, 2024
71381ad
added print btn
agutiernc Mar 20, 2024
7c7808b
added print pdf button and functionality
agutiernc Mar 20, 2024
8fd82c9
toolbar load on initial. tweaked tooltip for pdf btn
agutiernc Mar 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2018,
"ecmaVersion": 2020,
"sourceType": "module"
},
"plugins": ["react", "jest", "prettier", "eslint-plugin-react"],
Expand Down
5 changes: 2 additions & 3 deletions client/src/components/Projects/DeleteProjectModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,12 @@ const DeleteProjectModal = ({ mounted, onClose, project }) => {
className={classes.warningIcon}
alt="Warning"
/>
Are you sure you want to delete the project,
Are you sure you want to delete the following?
</div>
</>
)}

<div style={{ ...theme.typography.heading3, marginBottom: "1.5rem" }}>
{project.name}?
{Array.isArray(project.name) ? project.name.join(", ") : project.name}
</div>
<div className={classes.buttonFlexBox}>
<Button onClick={onClose} variant="text" id="cancelButton">
Expand Down
16 changes: 14 additions & 2 deletions client/src/components/Projects/FilterDrawer.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,13 @@ const useStyles = createUseStyles({
}
});

const FilterPopup = ({ criteria, setCriteria, setCollapsed }) => {
const FilterPopup = ({
criteria,
setCriteria,
setCollapsed,
setCheckedProjects,
setSelectAllChecked
}) => {
const userContext = useContext(UserContext);
const account = userContext.account;
const classes = useStyles();
Expand All @@ -62,6 +68,10 @@ const FilterPopup = ({ criteria, setCriteria, setCollapsed }) => {

const handleChange = (e, propertyName) => {
setCriteria({ ...criteria, [propertyName]: e.target.value });

// reset any checked project rows when filter is applied
setCheckedProjects([]);
setSelectAllChecked(false);
};

const handleChangeDate = (property, date) => {
Expand Down Expand Up @@ -178,7 +188,9 @@ FilterPopup.propTypes = {
criteria: PropTypes.any,
setCriteria: PropTypes.func,
collapsed: PropTypes.bool,
setCollapsed: PropTypes.func
setCollapsed: PropTypes.func,
setCheckedProjects: PropTypes.func,
setSelectAllChecked: PropTypes.func
};

export default FilterPopup;
209 changes: 209 additions & 0 deletions client/src/components/Projects/MultiProjectToolbarMenu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import React, { useContext, useRef } from "react";
import UserContext from "../../contexts/UserContext";
import PropTypes from "prop-types";
import { createUseStyles } from "react-jss";
import {
faEyeSlash,
faEye,
faTrashCan,
faPrint
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Tooltip } from "react-tooltip";
import PdfPrint from "../PdfPrint/PdfPrint";
import moment from "moment";
import { useReactToPrint } from "react-to-print";

const useStyles = createUseStyles({
container: {
display: "flex",
flexDirection: "row",
alignItems: "center",
marginLeft: "0.5em",
marginBottom: "-1em"
},
list: {
display: "flex",
flexDirection: "row",
listStyleType: "none",
justifyContent: "space-between",
alignItems: "center",
width: "6.5em"
},
button: {
border: "none",
padding: 0,
background: "none"
},
multiStatus: {
color: "#002E6D"
}
});

const MultiProjectToolbarMenu = ({
handleHideBoxes,
handleDeleteModalOpen,
checkedProjects,
criteria,
projects,
pdfProjectData
}) => {
const momentModified = moment(projects.dateModified);
const printRef = useRef(null);
const classes = useStyles();
const userContext = useContext(UserContext);
const account = userContext.account;
const isProjectOwner = account.id === projects.loginId;

const isBtnDisabled = (projProp, criteriaProp) => {
const sameDateVals = projects[projProp] !== false;
const criteriaFilter = criteria[criteriaProp] === "all";

// disable button if current user is not the owner
// or if criteria is "all" and the date values are different
return !isProjectOwner || (criteriaFilter && !sameDateVals);
};

const isHideBtnDisabled = isBtnDisabled("dateHidden", "visibility");
const isDelBtnDisabled = isBtnDisabled("dateTrashed", "status");

const tooltipMsg = (criteriaProp, msg, dateProp) => {
if (checkedProjects.length === 0) return;

if (!isProjectOwner) {
return "You have selected a project that does not belong to you";
}

// show recover message if project is deleted
if (projects.dateTrashed && criteriaProp === "status") {
return "Restore from Trash";
}

// show message when selecting mixed types (e.g. hide & unhide)
if (checkedProjects.length > 1 && projects[dateProp] === false) {
return criteria[criteriaProp] === "all" ? msg : "";
}
};

const hasPdfData = () => {
return pdfProjectData && pdfProjectData.pdf !== null;
};

const handlePrintPdf = useReactToPrint({
content: () => printRef.current,
bodyClass: "printContainer",
pageStyle: ".printContainer {overflow: hidden;}"
});

return (
<div className={classes.container}>
<div className={classes.multiStatus}>
{checkedProjects.length} Projects Selected
</div>
<ul className={classes.list}>
<li>
<button
id="print-btn"
className={classes.button}
onClick={handlePrintPdf}
disabled={checkedProjects.length !== 1}
>
<FontAwesomeIcon icon={faPrint} />
</button>
{checkedProjects.length !== 1 ? (
<Tooltip
style={{
backgroundColor: "#e6e3e3",
color: "#000",
width: "11%",
borderRadius: "10px",
fontWeight: "bold",
textAlign: "center"
}}
anchorSelect="#print-btn"
content="Please select one project"
/>
) : (
""
)}
{hasPdfData() && (
<div style={{ display: "none" }}>
<PdfPrint
ref={printRef}
rules={pdfProjectData.pdf}
dateModified={momentModified.format("MM/DD/YYYY")}
/>
</div>
)}
</li>
<li>
<button
id="hide-btn"
className={classes.button}
disabled={isHideBtnDisabled}
onClick={handleHideBoxes}
>
{!projects.dateHidden ? (
<FontAwesomeIcon icon={faEyeSlash} />
) : (
<FontAwesomeIcon icon={faEye} />
)}

<Tooltip
style={{
backgroundColor: "#e6e3e3",
color: "#000",
width: "10%",
borderRadius: "10px"
}}
anchorSelect="#hide-btn"
content={tooltipMsg(
"visibility",
"Your selection includes both hidden and visible items",
"dateHidden"
)}
/>
</button>
</li>
<li>
<button
id="delete-btn"
className={classes.button}
disabled={isDelBtnDisabled}
onClick={handleDeleteModalOpen}
>
<FontAwesomeIcon
icon={faTrashCan}
color={isDelBtnDisabled ? "#1010104d" : "red"}
/>
<Tooltip
style={{
backgroundColor: "#e6e3e3",
color: "#000",
width: "10%",
borderRadius: "10px"
}}
anchorSelect="#delete-btn"
content={tooltipMsg(
"status",
"Your selection includes both deleted and active items",
"dateTrashed"
)}
/>
</button>
</li>
</ul>
</div>
);
};

MultiProjectToolbarMenu.propTypes = {
handleHideBoxes: PropTypes.func.isRequired,
handleDeleteModalOpen: PropTypes.func.isRequired,
checkedProjects: PropTypes.array.isRequired,
criteria: PropTypes.object.isRequired,
projects: PropTypes.object.isRequired,
pdfProjectData: PropTypes.object
};

export default MultiProjectToolbarMenu;
16 changes: 14 additions & 2 deletions client/src/components/Projects/ProjectTableRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,9 @@ const ProjectTableRow = ({
handleDeleteModalOpen,
handleSnapshotModalOpen,
handleRenameSnapshotModalOpen,
handleHide
handleHide,
handleCheckboxChange,
checkedProjects
}) => {
const classes = useStyles();
const momentModified = moment(project.dateModified);
Expand Down Expand Up @@ -297,6 +299,14 @@ const ProjectTableRow = ({

return (
<tr key={project.id}>
<td className={classes.tdCenterAlign}>
<input
style={{ height: "15px" }}
type="checkbox"
checked={checkedProjects.includes(project.id)}
onChange={() => handleCheckboxChange(project.id)}
/>
</td>
<td className={classes.tdCenterAlign}>
{project.dateHidden ? (
<FontAwesomeIcon
Expand Down Expand Up @@ -388,7 +398,9 @@ ProjectTableRow.propTypes = {
handleDeleteModalOpen: PropTypes.func.isRequired,
handleSnapshotModalOpen: PropTypes.func.isRequired,
handleRenameSnapshotModalOpen: PropTypes.func.isRequired,
handleHide: PropTypes.func.isRequired
handleHide: PropTypes.func.isRequired,
handleCheckboxChange: PropTypes.func.isRequired,
checkedProjects: PropTypes.array.isRequired
};

export default ProjectTableRow;
Loading
Loading