Repository: inovex/scrumlr.io
Pull request #3980 (2024-03-18 08:53:57)

fix: add missing title to voting buttons 
## Description
I've noticed that my accessibility tool has complained that the add- and remove-vote buttons are missing a label. Therefore I've added the translated labels as title to the dot buttons.

## Changelog
- Add missing translated labels
- Refactor remove vote button to retrieve number of votes via props instead of children
- Update snapshots



github-actions[bot]: The deployment to the dev cluster was successful. You can find the deployment here: https://3980.development.scrumlr.fra.ics.inovex.io
This deployment is only for testing purposes and will be deleted after 1 week.
To redeploy rerun the workflow.
<strong>DO NOT STORE IMPORTANT DATA ON THIS DEPLOYMENT</strong>

<details>
<summary>Deployed Images</summary>

- ghcr.io/inovex/scrumlr.io/scrumlr-frontend:sha-4baac8c

- ghcr.io/inovex/scrumlr.io/scrumlr-server:sha-4baac8c

</details>
<!-- thollander/actions-comment-pull-request "dev-deployment" -->
octomind-dev[bot]: 
# 🐙 Octomind

[Test Report](https://app.octomind.dev/testreports/673b7a4e-4993-403d-95ab-5d778505fa9c): 0/13 successful.


| description | status | details |
|--|--|--|
|change avatar|Waiting ⏳||
|check Privacy Policy|Waiting ⏳||
|check terms & conditions|Waiting ⏳||
|close cookie banner - front page|Waiting ⏳||
|close cookie banner - sign-in|Waiting ⏳||
|create and delete board columns|Waiting ⏳||
|create_and_delete_notes_and_actions_v2|Waiting ⏳||
|create lean coffee board|Waiting ⏳||
|edit_notes_and_actions_v5|Waiting ⏳||
|get started|Waiting ⏳||
|share_session|Waiting ⏳||
|sign-in|Waiting ⏳||
|test all ways to open the setup flow|Waiting ⏳||

commit sha: [4baac8c](https://github.com/inovex/scrumlr.io/commit/4baac8cb7268e89bfd72755437d4b9ad6954c37b)


Patch:
diff --git a/src/components/Votes/VoteButtons/AddVoteButton.tsx b/src/components/Votes/VoteButtons/AddVoteButton.tsx
index c52c9b9e..503056ed 100644
--- a/src/components/Votes/VoteButtons/AddVoteButton.tsx
+++ b/src/components/Votes/VoteButtons/AddVoteButton.tsx
@@ -1,5 +1,6 @@
 import {FC} from "react";
 import {useDispatch} from "react-redux";
+import {useTranslation} from "react-i18next";
 import {Actions} from "store/action";
 import {DotButton} from "components/DotButton";
 import {ReactComponent as PlusIcon} from "assets/icon-add.svg";
@@ -12,13 +13,14 @@ type AddVoteProps = {
 
 export const AddVoteButton: FC<AddVoteProps> = ({noteId, disabled}) => {
   const dispatch = useDispatch();
+  const {t} = useTranslation();
 
   const addVote = () => {
     dispatch(Actions.addVote(noteId));
   };
 
   return (
-    <DotButton className="vote-button-add" onClick={addVote} disabled={disabled}>
+    <DotButton title={t("Votes.AddVote")} className="vote-button-add" onClick={addVote} disabled={disabled}>
       <PlusIcon className="vote-button-add__icon" />
     </DotButton>
   );
diff --git a/src/components/Votes/VoteButtons/RemoveVoteButton.tsx b/src/components/Votes/VoteButtons/RemoveVoteButton.tsx
index 48589c1b..96e48492 100644
--- a/src/components/Votes/VoteButtons/RemoveVoteButton.tsx
+++ b/src/components/Votes/VoteButtons/RemoveVoteButton.tsx
@@ -1,18 +1,21 @@
-import {FC, PropsWithChildren, useEffect, useRef, useState} from "react";
+import {FC, useEffect, useRef, useState} from "react";
 import {useDispatch} from "react-redux";
+import {useTranslation} from "react-i18next";
+import classNames from "classnames";
 import {Actions} from "store/action";
 import {DotButton} from "components/DotButton";
-import "./RemoveVoteButton.scss";
-import classNames from "classnames";
 import {ReactComponent as RemoveIcon} from "assets/icon-remove.svg";
+import "./RemoveVoteButton.scss";
 
 type RemoveVoteProps = {
   noteId: string;
   disabled?: boolean;
+  numberOfVotes: number;
 };
 
-export const RemoveVoteButton: FC<PropsWithChildren<RemoveVoteProps>> = ({noteId, disabled, children}) => {
+export const RemoveVoteButton: FC<RemoveVoteProps> = ({noteId, disabled, numberOfVotes}) => {
   const dispatch = useDispatch();
+  const {t} = useTranslation();
 
   const deleteVote = () => {
     dispatch(Actions.deleteVote(noteId));
@@ -27,10 +30,11 @@ export const RemoveVoteButton: FC<PropsWithChildren<RemoveVoteProps>> = ({noteId
       return;
     }
     setDoBump(true);
-  }, [children]);
+  }, [numberOfVotes]);
 
   return (
     <DotButton
+      title={disabled ? t("Votes.VotesOnNote", {votes: numberOfVotes}) : t("Votes.RemoveVote")}
       className={classNames("vote-button-remove", {bump: doBump})}
       disabled={disabled}
       onClick={deleteVote}
@@ -40,7 +44,7 @@ export const RemoveVoteButton: FC<PropsWithChildren<RemoveVoteProps>> = ({noteId
     >
       <span className="vote-button-remove__folded-corner" />
       <RemoveIcon className="vote-button-remove__icon" />
-      <span className="vote-button-remove__count">{children}</span>
+      <span className="vote-button-remove__count">{numberOfVotes}</span>
     </DotButton>
   );
 };
diff --git a/src/components/Votes/Votes.tsx b/src/components/Votes/Votes.tsx
index 9422804a..03b06508 100644
--- a/src/components/Votes/Votes.tsx
+++ b/src/components/Votes/Votes.tsx
@@ -39,12 +39,8 @@ export const Votes: FC<VotesProps> = (props) => {
 
   return voting || allPastVotes > 0 ? (
     <div role="none" className={classNames("votes", props.className)} onClick={(e) => e.stopPropagation()}>
-      {!voting && allPastVotes > 0 && (
-        <VoteButtons.Remove noteId={props.noteId} disabled>
-          {allPastVotes}
-        </VoteButtons.Remove>
-      )}
-      {voting && ongoingVotes.note > 0 && <VoteButtons.Remove noteId={props.noteId}>{ongoingVotes.note}</VoteButtons.Remove>}
+      {!voting && allPastVotes > 0 && <VoteButtons.Remove noteId={props.noteId} numberOfVotes={allPastVotes} disabled />}
+      {voting && ongoingVotes.note > 0 && <VoteButtons.Remove noteId={props.noteId} numberOfVotes={ongoingVotes.note} />}
       {voting && <VoteButtons.Add noteId={props.noteId} disabled={ongoingVotes.total === voting.voteLimit || (ongoingVotes.note > 0 && !voting.allowMultipleVotes)} />}
     </div>
   ) : null;
diff --git a/src/i18n/de/translation.json b/src/i18n/de/translation.json
index 9c8d01ab..a893c6ac 100644
--- a/src/i18n/de/translation.json
+++ b/src/i18n/de/translation.json
@@ -647,5 +647,10 @@
     "description": "Es sieht so aus, als ob die Türen zu dieser Sitzung vorerst geschlossen bleiben. Wir freuen uns über dein Interesse, aber leider wurde dein Antrag auf Teilnahme abgelehnt.",
     "banned": "Es tut uns Leid, aber es sieht so aus, als ob du von dieser Sitzung ausgeschlossen wurdest.",
     "button": "Zurück zur Startseite"
+  },
+  "Votes": {
+    "AddVote": "Stimme hinzufügen",
+    "RemoveVote": "Stimme entfernen",
+    "VotesOnNote": "{{votes}} Stimme(n)"
   }
 }
diff --git a/src/i18n/en/translation.json b/src/i18n/en/translation.json
index 5b4e641d..d41fd960 100644
--- a/src/i18n/en/translation.json
+++ b/src/i18n/en/translation.json
@@ -647,5 +647,10 @@
     "description": "It looks like the doors to this session remain closed for now. We appreciate your interest, but unfortunately, your request to join has been declined.",
     "banned": "We're sorry, but it looks like you have been excluded from this session.",
     "button": "Back to Homepage"
+  },
+  "Votes": {
+    "AddVote": "Add vote",
+    "RemoveVote": "Remove vote",
+    "VotesOnNote": "{{votes}} vote(s)"
   }
 }


Test patch:
diff --git a/src/components/Column/__tests__/__snapshots__/Column.test.tsx.snap b/src/components/Column/__tests__/__snapshots__/Column.test.tsx.snap
index 1b34a172..5af50a33 100644
--- a/src/components/Column/__tests__/__snapshots__/Column.test.tsx.snap
+++ b/src/components/Column/__tests__/__snapshots__/Column.test.tsx.snap
@@ -560,6 +560,7 @@ exports[`Column should have correct style show column with correct style 1`] = `
                 >
                   <button
                     class="dot-button vote-button-remove"
+                    title="Remove vote"
                   >
                     <span
                       class="vote-button-remove__folded-corner"
@@ -578,6 +579,7 @@ exports[`Column should have correct style show column with correct style 1`] = `
                   <button
                     class="dot-button vote-button-add"
                     disabled=""
+                    title="Add vote"
                   >
                     <svg
                       class="vote-button-add__icon"
@@ -1126,6 +1128,7 @@ exports[`Column should have correct style show column with correct style 1`] = `
                 >
                   <button
                     class="dot-button vote-button-add"
+                    title="Add vote"
                   >
                     <svg
                       class="vote-button-add__icon"
diff --git a/src/components/Votes/__tests__/__snapshots__/Votes.test.tsx.snap b/src/components/Votes/__tests__/__snapshots__/Votes.test.tsx.snap
index 69221037..fdead566 100644
--- a/src/components/Votes/__tests__/__snapshots__/Votes.test.tsx.snap
+++ b/src/components/Votes/__tests__/__snapshots__/Votes.test.tsx.snap
@@ -8,6 +8,7 @@ exports[`Votes should render correctly with no votes and active voting 1`] = `
   >
     <button
       class="dot-button vote-button-add"
+      title="Add vote"
     >
       <svg
         class="vote-button-add__icon"
@@ -29,6 +30,7 @@ exports[`Votes should render correctly with votes and active voting 1`] = `
   >
     <button
       class="dot-button vote-button-remove"
+      title="Remove vote"
     >
       <span
         class="vote-button-remove__folded-corner"
@@ -47,6 +49,7 @@ exports[`Votes should render correctly with votes and active voting 1`] = `
     <button
       class="dot-button vote-button-add"
       disabled=""
+      title="Add vote"
     >
       <svg
         class="vote-button-add__icon"
@@ -67,6 +70,7 @@ exports[`Votes should render correctly with votes and disabled voting 1`] = `
     <button
       class="dot-button vote-button-remove"
       disabled=""
+      title="1 vote(s)"
     >
       <span
         class="vote-button-remove__folded-corner"