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

Give custom names to favorite rows #526

Merged
merged 14 commits into from
Aug 2, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
37 changes: 32 additions & 5 deletions frontend/src/components/Row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const Row = ({
rowEntries,
onCellUpdate,
onToggleFav,
onFavNameUpdate,
onToggleHide,
getRowSum,
isFav,
Expand All @@ -29,6 +30,7 @@ export const Row = ({
rowEntries: FetchedTimeEntry[];
onCellUpdate: (timeEntry: TimeEntry) => void;
onToggleFav: (topic: IssueActivityPair) => void;
onFavNameUpdate: (topic: IssueActivityPair, custom_name: string) => void;
getRowSum: (pair: IssueActivityPair) => number;
onToggleHide?: (topic: IssueActivityPair) => void;
isFav?: boolean;
Expand Down Expand Up @@ -101,11 +103,36 @@ export const Row = ({
href={`${PUBLIC_REDMINE_URL}` + `/issues/${topic.issue.id}`}
>{`# ${topic.issue.id}`}</a>
</p>
<p className="issue-label-text">
{topic.custom_name
? `${topic.custom_name}`
: `${topic.issue.subject} - ${topic.activity.name}`}
</p>
{isFav ? (
<div className="issuetooltip">
<textarea
aria-label={`Custom name for the issue ${topic.issue.id}, ${topic.issue.subject}, on the activity ${topic.activity.name}`}
className="issue-textarea"
defaultValue={
topic.custom_name
? `${topic.custom_name}`
: `${topic.issue.subject} - ${topic.activity.name}`
}
onFocus={onFocusRow}
onBlur={() => {
onBlurRow();
}}
onChange={(ev) => {
onFavNameUpdate(topic, ev.target.value);
}}
maxLength={100}
/>
<span className="tooltiptext">
{topic.issue.subject} - {topic.activity.name}
</span>
</div>
) : (
<p className="issue-label-text">
{topic.custom_name
? `${topic.custom_name}`
: `${topic.issue.subject} - ${topic.activity.name}`}
</p>
)}
</div>
</div>
{days.map((day, i) => {
Expand Down
45 changes: 45 additions & 0 deletions frontend/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,51 @@ Other button classes are defined further down together with other classes for th
min-width: 4rem;
}

.issue-textarea {
width: 100%;
height: 2em;
border: 1px solid hsl(0deg 0% 83%);
border-radius: 3px;
opacity: 1;
}

.issuetooltip {
width: 100%;
position: relative;
display: inline-block;
opacity: 1;
z-index: 1;
}

.tooltiptext {
visibility: hidden;
width: auto;
height: auto;
background-color: hsl(0deg 0% 90%);
text-align: center;
border-radius: 6px;
padding: 0.5em;
position: absolute;
bottom: 125%;
left: 50%;
margin-left: -60px;
}

.tooltiptext::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: hsl(0deg 0% 0%) transparent transparent transparent;
}

.issuetooltip:hover .tooltiptext {
visibility: visible;
}

.dropdown-button {
margin-right: 1rem;
background-color: hsl(186deg 30% 94%);
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/pages/Help.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ export const Help = () => {
rows can be changed by drag and dropping the row using the
drag–and–drop handle icon at the left-most position of the row.
</p>
<p className="help-info">
Favourite rows can be given a custom name by editing the text area
next to the issue number. The custom name is only saved after clicking
on the <b>"Save Changes"</b> button. The original names of the rows
can be seen after hovering over the text area. When unfavouriting a
row, the custom name is reset to the original name.
</p>
<Row
key={1}
topic={exampleIAP}
Expand All @@ -94,6 +101,7 @@ export const Help = () => {
onToggleHide={() => {}}
isFav={true}
onToggleFav={() => {}}
onFavNameUpdate={() => {}}
onCellUpdate={() => {}}
></Row>
<p className="help-info">
Expand All @@ -113,6 +121,7 @@ export const Help = () => {
onToggleHide={() => {}}
isFav={false}
onToggleFav={() => {}}
onFavNameUpdate={() => {}}
onCellUpdate={() => {}}
></Row>
<h2 className="help-subtitle">Hidden rows</h2>
Expand All @@ -136,6 +145,7 @@ export const Help = () => {
onToggleHide={() => {}}
isHidden={true}
onToggleFav={() => {}}
onFavNameUpdate={() => {}}
onCellUpdate={() => {}}
></Row>
<h2 className="help-subtitle">Adding new rows</h2>
Expand Down
46 changes: 43 additions & 3 deletions frontend/src/pages/Report.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ export const Report = () => {
}
// Topic was a favorite. Remove it from favorites and make it a recent.
else {
topic.custom_name = `${topic.issue.subject} - ${topic.activity.name}`;
const shortenedFavs = removeIssueActivityPair([...favorites], topic);
const saved = await saveFavorites([...shortenedFavs, ...hidden]);
if (!saved) {
Expand All @@ -314,6 +315,29 @@ export const Report = () => {
}
setFavorites(shortenedFavs);
setFilteredRecents([topic, ...filteredRecents]);
// Make sure that the warning is gone when we un-favorite an issue
if (newTimeEntries.length === 0) {
setShowUnsavedWarning(false);
}
}
};

// Makes sure that the custom name of the favorite is updated in the local state
const handleFavNameUpdate = (
topic: IssueActivityPair,
custom_name: string
) => {
let favs = favorites.slice();
let existingFav = favs.find(
(fav) =>
fav.activity.id === topic.activity.id && fav.issue.id === topic.issue.id
);

if (existingFav) {
setShowUnsavedWarning(true);
let newFav = { ...existingFav, custom_name };
favs.splice(favs.indexOf(existingFav), 1, newFav);
setFavorites(favs);
}
};

Expand Down Expand Up @@ -383,13 +407,28 @@ export const Report = () => {
return saved;
};

// Make sure that the custom issue name is saved in the database.
const handleCustomNamesSave = async () => {
const saved = await saveFavorites([...favorites, ...hidden]);
if (!saved) {
alert("Favourite rows could not be saved. Please try again later.");
return;
}
setToastList([
...toastList,
{
type: "success",
timeout: 3000,
message: "Custom names were saved!",
},
]);
};

// Check for ...
const handleSave = async () => {
setShowUnsavedWarning(false);
handleCustomNamesSave();
if (newTimeEntries.length === 0) {
alert(
"You haven't added, edited or deleted any time entries yet, so nothing could be saved."
);
return;
}
toggleLoadingPage(true);
Expand Down Expand Up @@ -648,6 +687,7 @@ export const Report = () => {
topic={fav}
onCellUpdate={handleCellUpdate}
onToggleFav={handleToggleFav}
onFavNameUpdate={handleFavNameUpdate}
days={currentWeekArray}
rowHours={findRowHours(fav)}
rowEntries={rowEntries}
Expand Down