Skip to content

Commit

Permalink
Merge pull request #1354 from danskernesdigitalebibliotek/DDFLSBP-621…
Browse files Browse the repository at this point in the history
…-only-show-blocked-modal-when-reserving

DDFLSBP-621 - Make sure to only show blocked modal when logging in
  • Loading branch information
spaceo authored Aug 28, 2024
2 parents de95645 + 0fdcae9 commit f140c26
Show file tree
Hide file tree
Showing 18 changed files with 160 additions and 347 deletions.
9 changes: 0 additions & 9 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,11 @@ import {
} from "../src/core/token";
import "../src/core/mount";
import Store from "../src/components/store";
import { store } from "../src/core/store";

import React from "react";
import { updateStatus } from "../src/core/user.slice";
import { withErrorBoundary } from "react-error-boundary";
import ErrorBoundaryAlert from "../src/components/error-boundary-alert/ErrorBoundaryAlert";

if (process.env.NODE_ENV === "test") {
store.dispatch(
updateStatus({
hasToken: true
})
);
}

const getSessionStorage = (type) => window.sessionStorage.getItem(type);
const userToken =
Expand Down
10 changes: 0 additions & 10 deletions src/apps/adgangsplatformen/auth.dev.jsx

This file was deleted.

113 changes: 0 additions & 113 deletions src/apps/adgangsplatformen/auth.jsx

This file was deleted.

38 changes: 0 additions & 38 deletions src/apps/adgangsplatformen/auth.test.js

This file was deleted.

2 changes: 2 additions & 0 deletions src/apps/dashboard/dashboard.dev.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ import deleteReservationModalArgs from "../../core/storybook/deleteReservationMo
import reservationListArgs from "../../core/storybook/reservationListArgs";
import globalTextArgs from "../../core/storybook/globalTextArgs";
import globalConfigArgs from "../../core/storybook/globalConfigArgs";
import blockedArgs from "../../core/storybook/blockedArgs";

export default {
title: "Apps / Dashboard",
argTypes: {
...blockedArgs,
...serviceUrlArgs,
...groupModalArgs,
...loanGroupModalArgs,
Expand Down
2 changes: 2 additions & 0 deletions src/apps/menu/menu-logged-in/MenuLoggedInContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import DashboardNotificationList from "../../dashboard/dashboard-notification-li
import useReservations from "../../../core/utils/useReservations";
import useLoans from "../../../core/utils/useLoans";
import { usePatronData } from "../../../core/utils/helpers/usePatronData";
import { resetPersistedData } from "../../../core/store";

interface MenuLoggedInContentProps {
pageSize: number;
Expand Down Expand Up @@ -111,6 +112,7 @@ const MenuLoggedInContent: FC<MenuLoggedInContentProps> = ({ pageSize }) => {
<div className="modal-profile__btn-logout mx-32">
<Link
className="btn-primary btn-filled btn-large arrow__hover--right-small"
onClick={() => resetPersistedData()}
href={logoutUrl}
>
{t("menuLogOutText")}
Expand Down
12 changes: 11 additions & 1 deletion src/components/atoms/links/Link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { getLinkHandler } from "./getLinkHandler";

export interface LinkProps {
href: URL;
onClick?: () => Promise<void>;
children: React.ReactNode;
isNewTab?: boolean;
className?: string;
Expand All @@ -16,6 +17,7 @@ export interface LinkProps {

const Link: React.FC<LinkProps> = ({
href,
onClick,
children,
isNewTab = false,
className,
Expand All @@ -42,6 +44,14 @@ const Link: React.FC<LinkProps> = ({
trackClick
});

const onclickHandler = onClick
? (
e:
| React.MouseEvent<HTMLAnchorElement>
| React.KeyboardEvent<HTMLAnchorElement>
) => onClick().then(() => handleClick(e))
: handleClick;

return (
<a
id={id}
Expand All @@ -50,7 +60,7 @@ const Link: React.FC<LinkProps> = ({
target={isNewTab ? "_blank" : undefined}
rel="noreferrer"
className={className}
onClick={handleClick}
onClick={onclickHandler}
onKeyUp={handleKeyUp}
aria-labelledby={ariaLabelledBy}
tabIndex={isHiddenFromScreenReaders ? -1 : 0}
Expand Down
41 changes: 40 additions & 1 deletion src/components/blocked-patron/BlockedPatron.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
import { resetPersistedData } from "../../core/store";

describe("Patron page", () => {
before(() => {
// Make sure we have a clean slate before we start testing.
resetPersistedData();
cy.createFakeAuthenticatedSession();
cy.createFakeLibrarySession();
});

beforeEach(() => {
cy.intercept("GET", "**/external/agencyid/patrons/patronid/loans/v2**", {
statusCode: 200,
body: []
});
cy.intercept("GET", "**/v1/user/**", {
statusCode: 200,
body: {
loans: []
}
});
});

it("Patron not blocked", () => {
cy.intercept("GET", "**/external/agencyid/patrons/patronid/v2**", {
patron: {
Expand All @@ -14,6 +31,7 @@ describe("Patron page", () => {
cy.get(".modal").should("not.exist");
});

// TYPE: E (fee)
// Blocked types:
// https://github.com/itk-dev/dpl-react/blob/develop/src/core/utils/types/BlockedTypes.ts
it("Patron blocked E", () => {
Expand All @@ -30,15 +48,33 @@ describe("Patron page", () => {
});
cy.visit("/iframe.html?path=/story/apps-loan-list--loan-list-entry");
cy.getBySel("modal").should("exist");
cy.getBySel("modal").should("exist");
cy.getBySel("modal").get("h1").should("exist");
cy.getBySel("modal").get("p").should("exist");
cy.getBySel("modal").get("a").should("exist");
});

it("Does NOT show the blocked modal again once it has been shown", () => {
cy.intercept("GET", "**/external/agencyid/patrons/patronid/v2**", {
patron: {
blockStatus: [
{
blockedReason: "E",
blockedSince: "",
message: ""
}
]
}
});
cy.visit("/iframe.html?path=/story/apps-loan-list--loan-list-entry");
cy.getBySel("modal").should("not.exist");
});

// TYPE: U (exclusion)
// Blocked types:
// https://github.com/itk-dev/dpl-react/blob/develop/src/core/utils/types/BlockedTypes.ts
it("Patron blocked U", () => {
// To make sure that the modal is shown, we need to reset the persisted data.
resetPersistedData();
cy.intercept("GET", "**/external/agencyid/patrons/patronid/v2**", {
patron: {
blockStatus: [
Expand All @@ -57,9 +93,12 @@ describe("Patron page", () => {
cy.getBySel("modal").get("a").should("not.exist");
});

// TYPE: W (selfcreated)
// Blocked types:
// https://github.com/itk-dev/dpl-react/blob/develop/src/core/utils/types/BlockedTypes.ts
it("Patron blocked W", () => {
// To make sure that the modal is shown, we need to reset the persisted data.
resetPersistedData();
cy.intercept("GET", "**/external/agencyid/patrons/patronid/v2**", {
patron: {
blockStatus: [
Expand Down
26 changes: 17 additions & 9 deletions src/components/blocked-patron/blocked-modal/BlockedModal.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,37 @@
import React, { FC } from "react";
import React, { FC, useEffect } from "react";
import Modal from "../../../core/utils/modal";
import { useText } from "../../../core/utils/text";
import BlockedTypes from "../../../core/utils/types/BlockedTypes";
import { useUrls } from "../../../core/utils/url";
import Link from "../../atoms/links/Link";
import { getModalIds } from "../../../core/utils/helpers/modal-helpers";
import { useSetHasBeenVisible } from "../../../core/blockedModal.slice";
import { useBlockedModalHasBeenVisible } from "../helper";

interface BlockedModalProps {
blockedStatus: string;
blockedStatus: BlockedTypes;
}

export const getBlockedModalId = () => "blocked-patron";

const BlockedModal: FC<BlockedModalProps> = ({ blockedStatus }) => {
const t = useText();
const u = useUrls();
const blockedPatronELinkUrl = u("blockedPatronELinkUrl", true);
const { blockedModal } = getModalIds();
const modalId = getBlockedModalId();
const setHasBeenVisible = useSetHasBeenVisible();
// Used to check whether the modal has been opened by another component,
// the modal should really only be showed once.
const hasBeenVisible = useBlockedModalHasBeenVisible();

// If the user isn't actually blocked, don't render the modal.
if (!blockedStatus || blockedStatus === "") {
return null;
}
useEffect(() => {
if (!hasBeenVisible) {
setHasBeenVisible();
}
}, [blockedStatus, hasBeenVisible, setHasBeenVisible]);

return (
<Modal
modalId={blockedModal as string}
modalId={modalId}
classNames="modal-cta modal-padding"
closeModalAriaLabelText={t(`blockedPatronCloseModalAriaLabelText`)}
screenReaderModalDescriptionText={t(
Expand Down
12 changes: 12 additions & 0 deletions src/components/blocked-patron/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useSelector } from "react-redux";
import { RootState } from "../../core/store";

export const useBlockedModalHasBeenVisible = () => {
const {
data: { hasBeenVisible }
} = useSelector((state: RootState) => state.blockedModal);

return Boolean(hasBeenVisible);
};

export default {};
Loading

0 comments on commit f140c26

Please sign in to comment.