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

Add section for hidden rows #490

Merged
merged 5 commits into from
May 24, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
26 changes: 21 additions & 5 deletions frontend/src/components/Row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import fillStar from "../icons/star-fill.svg";
import star from "../icons/star.svg";
import grip from "../icons/grip-vertical.svg";
import x from "../icons/x.svg";
import doubleUp from "../icons/chevron-double-up.svg";
import { dateFormat } from "../utils";
import { SNOWPACK_PUBLIC_REDMINE_URL } from "../utils";

Expand All @@ -17,9 +18,10 @@ export const Row = ({
rowEntries,
onCellUpdate,
onToggleFav,
onHide,
onToggleHide,
getRowSum,
isFav,
isHidden,
}: {
topic: IssueActivityPair;
days: Date[];
Expand All @@ -28,9 +30,9 @@ export const Row = ({
onCellUpdate: (timeEntry: TimeEntry) => void;
onToggleFav: (topic: IssueActivityPair) => void;
getRowSum: (pair: IssueActivityPair) => number;
onHide?: (topic: IssueActivityPair) => void;

isFav: boolean;
onToggleHide?: (topic: IssueActivityPair) => void;
isFav?: boolean;
isHidden?: boolean;
}) => {
// State var for setting the className of the row depending on focus
const [rowClass, setRowClass] = React.useState("row");
Expand All @@ -49,11 +51,25 @@ export const Row = ({
<div className="col-1 cell-container grip-container">
{isFav ? (
<img src={grip} className="grip" alt="grip to change row sorting" />
) : isHidden ? (
<button
type="button"
className="star-button"
onClick={() => onToggleHide(topic)}
>
<img
src={doubleUp}
className="unhide-icon"
role="button"
alt={"Stop hiding"}
title={"Stop hiding"}
/>
</button>
) : (
<button
type="button"
className="star-button"
onClick={() => onHide(topic)}
onClick={() => onToggleHide(topic)}
>
<img
src={x}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/icons/caret-down-fill.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion frontend/src/icons/caret-up-fill.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions frontend/src/icons/chevron-double-up.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 23 additions & 3 deletions frontend/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,8 @@ Other button classes are defined further down together with other classes for th

.recent-container {
background-color: hsl(0deg 0% 97%);
padding: 0.5rem 1.5rem 2.5rem;
padding: 1rem 1.5rem;
margin-top: 0.2rem;
}

.footer-container {
Expand All @@ -318,8 +319,7 @@ Other button classes are defined further down together with other classes for th

.favorites-container {
background-color: hsl(0deg 0% 97%);
padding: 2.5rem 1.5rem 0.5rem;
margin-bottom: 0.2rem;
padding: 2.5rem 1.5rem 1rem;
}

.issue-label {
Expand Down Expand Up @@ -384,6 +384,11 @@ Other button classes are defined further down together with other classes for th
margin-top: 0.5rem;
}

.unhide-icon {
width: 1.5rem;
margin-top: 0.2rem;
}

.star-button {
background-color: transparent;
border: none;
Expand Down Expand Up @@ -639,3 +644,18 @@ Other button classes are defined further down together with other classes for th
.row-focused {
background-color: hsl(186deg 30% 94%);
}

.hide-button {
color: hsl(288deg 46% 22%);
background-color: hsl(291deg 13% 90%);
padding: 0.2rem 0.5rem;
margin: 1rem;
}

.hide-button:hover {
background-color: hsl(291deg 13% 81%);
}

.hide-button > img {
margin-left: 0.5rem;
}
106 changes: 92 additions & 14 deletions frontend/src/pages/Report.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import ClimbingBoxLoader from "react-spinners/ClimbingBoxLoader";
import LoadingOverlay from "react-loading-overlay-ts";
import warning from "../icons/exclamation-triangle.svg";
import check from "../icons/check.svg";
import up from "../icons/caret-up-fill.svg";
import down from "../icons/caret-down-fill.svg";

const beforeUnloadHandler = (event) => {
event.preventDefault();
Expand All @@ -55,6 +57,7 @@ export const Report = () => {
getFullWeek(new Date())
);
const [showUnsavedWarning, setShowUnsavedWarning] = useState(false);
const [showHidden, setShowHidden] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const context = React.useContext(AuthContext);
const urlparams = useParams();
Expand Down Expand Up @@ -273,10 +276,30 @@ export const Report = () => {

// Toggle favorite status for an issue-activity pair
const handleToggleFav = async (topic: IssueActivityPair) => {
// Check if topic is hidden. If yes, make it a favorite.
const existingHidden = hidden.find(
(hidden) =>
hidden.activity.id === topic.activity.id &&
hidden.issue.id === topic.issue.id
);
if (!!existingHidden) {
const shortenedHidden = removeIssueActivityPair([...hidden], topic);
topic.is_hidden = false;
const saved = await saveFavorites([...favorites, ...hidden, topic]);
if (!saved) {
console.log("Something went wrong with adding a favorite!");
return;
}
setFavorites([...favorites, topic]);
setHidden(shortenedHidden);
return;
}
// Topic was not hidden. Check if it is a favorite.
const existingFav = favorites.find(
(fav) =>
fav.activity.id === topic.activity.id && fav.issue.id === topic.issue.id
);
// If it is not a favorite, make it one and remove it from recents.
if (!existingFav) {
topic.custom_name = `${topic.issue.subject} - ${topic.activity.name}`;
const saved = await saveFavorites([...favorites, topic, ...hidden]);
Expand All @@ -290,7 +313,9 @@ export const Report = () => {
topic
);
setFilteredRecents(shortenedRecents);
} else {
}
// Topic was a favorite. Remove it from favorites and make it a recent.
else {
const shortenedFavs = removeIssueActivityPair([...favorites], topic);
const saved = await saveFavorites([...shortenedFavs, ...hidden]);
if (!saved) {
Expand All @@ -303,17 +328,39 @@ export const Report = () => {
};

// Enable hiding an issue-activity pair from the list of recent issues
const handleHide = async (topic: IssueActivityPair) => {
topic.is_hidden = true;
topic.custom_name = `${topic.issue.subject} - ${topic.activity.name}`;
const saved = await saveFavorites([...favorites, ...hidden, topic]);
if (!saved) {
console.log("Something went wrong with hiding the row");
return;
} else {
const newRecents = removeIssueActivityPair([...filteredRecents], topic);
setFilteredRecents(newRecents);
setHidden([...hidden, topic]);
const toggleHide = async (topic: IssueActivityPair) => {
// Check if topic is hidden.
const existingHidden = hidden.find(
(hidden) =>
hidden.activity.id === topic.activity.id &&
hidden.issue.id === topic.issue.id
);
// If not, make it a hidden and remove from recent.
if (!existingHidden) {
topic.is_hidden = true;
topic.custom_name = `${topic.issue.subject} - ${topic.activity.name}`;
const saved = await saveFavorites([...favorites, topic, ...hidden]);
if (!saved) {
console.log("Something went wrong with hiding the row");
return;
} else {
const newRecents = removeIssueActivityPair([...filteredRecents], topic);
setFilteredRecents(newRecents);
setHidden([topic, ...hidden]);
}
}
// If yes, remove it from hidden and add to recent.
else {
const shortenedHidden = removeIssueActivityPair([...hidden], topic);
const saved = await saveFavorites([...favorites, ...shortenedHidden]);
if (!saved) {
console.log("Something went wrong with unhiding the row");
return;
} else {
topic.is_hidden = false;
setFilteredRecents([...filteredRecents, topic]);
setHidden(shortenedHidden);
}
}
};

Expand Down Expand Up @@ -645,16 +692,47 @@ export const Report = () => {
topic={recentIssue}
onCellUpdate={handleCellUpdate}
onToggleFav={handleToggleFav}
onHide={handleHide}
onToggleHide={toggleHide}
days={currentWeekArray}
rowHours={findRowHours(recentIssue)}
rowEntries={rowEntries}
getRowSum={getRowSum}
isFav={false}
/>
);
})}
<button
onClick={() => setShowHidden(!showHidden)}
className="basic-button hide-button"
>
{showHidden ? "Collapse hidden rows" : "Show hidden rows"}
<img src={showHidden ? up : down} alt="" />
</button>
</section>
{showHidden && (
<section className="recent-container">
{hidden &&
hidden.map((hiddenIssue) => {
const rowEntries = findRowEntries(
hiddenIssue,
currentWeekArray
);
return (
<Row
key={`${hiddenIssue.issue.id}${hiddenIssue.activity.id}`}
topic={hiddenIssue}
onCellUpdate={handleCellUpdate}
onToggleFav={handleToggleFav}
onToggleHide={toggleHide}
days={currentWeekArray}
rowHours={findRowHours(hiddenIssue)}
rowEntries={rowEntries}
getRowSum={getRowSum}
isHidden={true}
/>
);
})}
</section>
)}
<section className="recent-container ">
<div className="row">
<div className="col-6">
Expand Down