diff --git a/frontend/playwright/ui/specs/dashboard-teams.spec.js b/frontend/playwright/ui/specs/dashboard-teams.spec.js new file mode 100644 index 0000000000..8a95cf8e12 --- /dev/null +++ b/frontend/playwright/ui/specs/dashboard-teams.spec.js @@ -0,0 +1,31 @@ +import { test, expect } from "@playwright/test"; +import DashboardPage from "../pages/DashboardPage"; + +test.beforeEach(async ({ page }) => { + await DashboardPage.init(page); + await DashboardPage.mockRPC( + page, + "get-profile", + "logged-in-user/get-profile-logged-in-no-onboarding.json", + ); +}); + +test("BUG 12359 - Selected invitations count is not pluralized", async ({ + page, +}) => { + const dashboardPage = new DashboardPage(page); + await dashboardPage.setupDashboardFull(); + await dashboardPage.setupTeamInvitations(); + + await dashboardPage.goToSecondTeamInvitationsSection(); + + await expect(page.getByText("test1@mail.com")).toBeVisible(); + + // NOTE: we cannot use check() or getByLabel() because the checkbox + // is hidden inside the label. + await page.getByText("test1@mail.com").click(); + await expect(page.getByText("1 invitation selected")).toBeVisible(); + + await page.getByText("test2@mail.com").check(); + await expect(page.getByText("2 invitations selected")).toBeVisible(); +}); diff --git a/frontend/src/app/main/ui/dashboard/team.cljs b/frontend/src/app/main/ui/dashboard/team.cljs index 718b5b33d4..96afda2563 100644 --- a/frontend/src/app/main/ui/dashboard/team.cljs +++ b/frontend/src/app/main/ui/dashboard/team.cljs @@ -690,18 +690,18 @@ [:div {:class (stl/css :table-row :table-row-invitations)} [:div {:class (stl/css :table-field :field-email)} [:div {:class (stl/css :input-wrapper)} - [:label {:for (str "email-" email)} + [:label [:span {:class (stl/css-case :input-checkbox true :global/checked (is-selected? email))} deprecated-icon/status-tick] [:input {:type "checkbox" - :id (str "email-" email) + :id (dm/str "email-" email) :data-attr email :value email :checked (is-selected? email) - :on-change on-change}]]] - email] + :on-change on-change}] + email]]] [:div {:class (stl/css :table-field :field-roles)} [:> invitation-role-selector* @@ -930,7 +930,7 @@ [:* [:div {:class (stl/css :invitations-actions)} [:div - (str (count @selected) " invitations selected")] + (tr "team.invitations-selected" (i18n/c (count @selected)))] [:div [:> button* {:variant "secondary" :type "button" diff --git a/frontend/src/app/main/ui/dashboard/team.scss b/frontend/src/app/main/ui/dashboard/team.scss index f7918faa32..90e33f5cca 100644 --- a/frontend/src/app/main/ui/dashboard/team.scss +++ b/frontend/src/app/main/ui/dashboard/team.scss @@ -780,28 +780,19 @@ @extend .input-base; height: auto; } -// TODO: Fix this nested classes. +// FIXME: This does not conform to our CSS Guidelines. Need to unnest and to use +// custom properties to handle state changes. .input-wrapper { display: flex; align-items: center; + @include t.use-typography("body-large"); + label { - @include t.use-typography("body-small"); display: flex; align-items: center; gap: px2rem(6); cursor: pointer; - color: var(--color-foreground-secondary); - span { - @extend .checkbox-icon; - } - input { - margin: 0; - } - &:hover { - span { - border-color: var(--color-accent-primary-muted); - } - } + color: var(--color-foreground-primary); &:focus, &:focus-within { @@ -809,6 +800,22 @@ border-color: var(--color-accent-primary); } } + &:hover { + span { + border-color: var(--color-accent-primary-muted); + } + } + } + + span { + @extend .checkbox-icon; + @include t.use-typography("body-small"); + color: var(--color-foreground-secondary); + } + input { + margin: 0; + @include t.use-typography("body-small"); + color: var(--color-foreground-secondary); } } diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 00bb995959..2edc233718 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -766,6 +766,12 @@ msgstr "Resend invitations" msgid "dashboard.invite-profile" msgstr "Invite people" +#: src/app/main/ui/dashboard/team.cljs:933 +msgid "team.invitations-selected" +msgid_plural "team.invitations-selected" +msgstr[0] "1 invitation selected" +msgstr[1] "%s invitations selected" + #: src/app/main/ui/dashboard/sidebar.cljs:459, src/app/main/ui/dashboard/sidebar.cljs:466, src/app/main/ui/dashboard/sidebar.cljs:471, src/app/main/ui/dashboard/team.cljs:351 msgid "dashboard.leave-team" msgstr "Leave team" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index ccdfe35dc0..1df1b8300e 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -780,6 +780,12 @@ msgstr "Reenviar invitaciones" msgid "dashboard.invite-profile" msgstr "Invitar a la gente" +#: src/app/main/ui/dashboard/team.cljs:933 +msgid "team.invitations-selected" +msgid_plural "team.invitations-selected" +msgstr[0] "1 invitación seleccionada" +msgstr[1] "%s invitaciones seleccionadas" + #: src/app/main/ui/dashboard/sidebar.cljs:459, src/app/main/ui/dashboard/sidebar.cljs:466, src/app/main/ui/dashboard/sidebar.cljs:471, src/app/main/ui/dashboard/team.cljs:351 msgid "dashboard.leave-team" msgstr "Abandonar equipo"