Skip to content
This repository was archived by the owner on Jun 25, 2025. It is now read-only.

Commit 41f6022

Browse files
authored
Merge pull request #129 from reload/4801-button-list-state
4801: Material button list state
2 parents ff4d757 + 77853fe commit 41f6022

18 files changed

+294
-62
lines changed

.storybook/preview.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ tokenConfigs.forEach(function(tokenConfig) {
3232
// We do not want to keep prompting people if they have already cancelled the prompt once.
3333
const seenKey = `ddb-token-${type}-prompt-seen`;
3434
const promptHasBeenCancelled = localStorage.getItem(seenKey);
35-
if (!promptHasBeenCancelled && ENV != "test") {
35+
if (!promptHasBeenCancelled && process.env.NODE_ENV !== "test") {
3636
token = window.prompt(
3737
`Do you have a ${type} token for Adgangsplatformen? Input it here.`
3838
);

.storybook/webpack.config.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ module.exports = async ({ config }) => {
4646
: null,
4747
DDB_TOKEN_LIBRARY: tokens.hasOwnProperty("library")
4848
? JSON.stringify(tokens.library)
49-
: null,
50-
ENV: JSON.stringify(process.env.NODE_ENV)
49+
: null
5150
})
5251
];
5352
return { ...config, plugins, module: { ...config.module, rules } };

src/apps/add-to-checklist/add-to-checklist.dev.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from "react";
22
import AddToChecklist from "./add-to-checklist.entry";
33

44
export default {
5-
title: "Apps/Add to Checklist"
5+
title: "Apps/Checklist/Add (Deprecated)"
66
};
77

88
const Template = args => <AddToChecklist {...args} />;

src/apps/add-to-checklist/add-to-checklist.entry.jsx

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
import React, { useState } from "react";
1+
import React from "react";
22
import PropTypes from "prop-types";
33
import urlPropType from "url-prop-type";
4-
5-
import AddToChecklist from "./add-to-checklist";
6-
import MaterialList from "../../core/MaterialList";
4+
import ChecklistMaterialButtonEntry from "../checklist-button/checklist-material-button.entry";
75

86
function AddToChecklistEntry({
97
materialListUrl,
@@ -13,33 +11,23 @@ function AddToChecklistEntry({
1311
id,
1412
loginUrl
1513
}) {
16-
const [status, setStatus] = useState("ready");
17-
18-
function setRestoreStatus() {
19-
setStatus("ready");
20-
}
21-
22-
function setListErrorStatus() {
23-
setStatus("failed");
24-
setTimeout(setRestoreStatus, 4000);
25-
}
26-
27-
function addToList() {
28-
setStatus("processing");
29-
30-
const client = new MaterialList({ baseUrl: materialListUrl });
31-
client.addListMaterial({ materialId: id }).catch(setListErrorStatus);
14+
if (process.env.NODE_ENV !== "production") {
15+
// eslint-disable-next-line no-console
16+
console.warn(
17+
"AddToChecklist is deprecated. Please use ChecklistMaterialButton instead."
18+
);
3219
}
3320

3421
return (
35-
<AddToChecklist
36-
text={text}
37-
errorText={errorText}
38-
successText={successText}
39-
status={status}
40-
onClick={addToList}
22+
<ChecklistMaterialButtonEntry
23+
addText={text}
24+
addErrorText={errorText}
25+
addSuccessText={successText}
4126
loginUrl={loginUrl}
42-
materialId={id}
27+
id={id}
28+
materialListUrl={materialListUrl}
29+
initialOnList="off"
30+
containerClass="ddb-add-to-checklist__container"
4331
/>
4432
);
4533
}

src/apps/add-to-checklist/add-to-checklist.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ describe("Add to Checklist", () => {
77
status: 201,
88
response: {}
99
});
10-
cy.visit("/iframe.html?id=apps-add-to-checklist--entry");
10+
cy.visit("/iframe.html?id=apps-checklist-add-deprecated--entry");
1111
cy.contains("Tilføj til din huskeliste").click();
1212
cy.contains("Tilføjet");
1313
});
@@ -19,7 +19,7 @@ describe("Add to Checklist", () => {
1919
status: 500,
2020
response: {}
2121
});
22-
cy.visit("/iframe.html?id=apps-add-to-checklist--entry");
22+
cy.visit("/iframe.html?id=apps-checklist-add-deprecated--entry");
2323
cy.contains("Tilføj til din huskeliste").click();
2424
cy.contains("Der opstod en fejl");
2525
cy.contains("Tilføj til din huskeliste");

src/apps/add-to-searchlist/add-to-searchlist.dev.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import AddToSearchlist from "./add-to-searchlist.entry";
33
import "./add-to-searchlist.scss";
44

55
export default {
6-
title: "Apps/Add to Searchlist"
6+
title: "Apps/Searchlist/Add"
77
};
88

99
const Template = args => <AddToSearchlist {...args} />;

src/apps/add-to-searchlist/add-to-searchlist.test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ describe("Add to Searchlist", () => {
99
});
1010
});
1111
it("Submit", () => {
12-
cy.visit("/iframe.html?id=apps-add-to-searchlist--entry");
12+
cy.visit("/iframe.html?id=apps-searchlist-add--entry");
1313
cy.contains("Tilføj til mine søgninger").click();
1414
cy.get('input[placeholder*="Søgetitel"]').type("Min søgning");
1515
cy.contains("button", "Gem").click();
@@ -19,7 +19,7 @@ describe("Add to Searchlist", () => {
1919
});
2020

2121
it("Submit and wait for auto close", () => {
22-
cy.visit("/iframe.html?id=apps-add-to-searchlist--entry");
22+
cy.visit("/iframe.html?id=apps-searchlist-add--entry");
2323
cy.clock();
2424
cy.contains("Tilføj til mine søgninger").click();
2525
cy.get('input[placeholder*="Søgetitel"]').type("Min søgning");
@@ -30,7 +30,7 @@ describe("Add to Searchlist", () => {
3030
});
3131

3232
it("Submit with errors", () => {
33-
cy.visit("/iframe.html?id=apps-add-to-searchlist--entry");
33+
cy.visit("/iframe.html?id=apps-searchlist-add--entry");
3434
cy.contains("Tilføj til mine søgninger").click();
3535
cy.contains("button", "Gem").click();
3636
cy.contains("En titel er påkrævet.");
@@ -52,7 +52,7 @@ describe("Add to Searchlist", () => {
5252
status: 500,
5353
response: {}
5454
});
55-
cy.visit("/iframe.html?id=apps-add-to-searchlist--entry");
55+
cy.visit("/iframe.html?id=apps-searchlist-add--entry");
5656
cy.clock();
5757
cy.contains("Tilføj til mine søgninger").click();
5858
cy.get("form")
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React from "react";
2+
import ChecklistMaterialButton from "./checklist-material-button.entry";
3+
4+
export default {
5+
title: "Apps/Checklist/Material button"
6+
};
7+
8+
const Template = args => <ChecklistMaterialButton {...args} />;
9+
10+
export const Entry = Template.bind({});
11+
Entry.args = {
12+
materialListUrl: "https://test.materiallist.dandigbib.org",
13+
addText: "Tilføj til din huskeliste",
14+
addErrorText: "Der opstod en fejl",
15+
addSuccessText: "Tilføjet",
16+
removeText: "Fjern fra din huskeliste",
17+
removeErrorText: "Der opstod en fejl",
18+
removeSuccessText: "Fjernet",
19+
id: "870970-basis:54172613",
20+
loginUrl:
21+
"https://lollandbib.dk/adgangsplatformen/login?destination=ting/object/:id",
22+
initialOnList: "unknown"
23+
};
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import React, { useState } from "react";
2+
import PropTypes from "prop-types";
3+
import urlPropType from "url-prop-type";
4+
5+
import ChecklistMaterialButton from "./checklist-material-button";
6+
import MaterialList from "../../core/MaterialList";
7+
8+
function ChecklistMaterialButtonEntry({
9+
materialListUrl,
10+
addText,
11+
addSuccessText,
12+
addErrorText,
13+
removeText,
14+
removeSuccessText,
15+
removeErrorText,
16+
id,
17+
loginUrl,
18+
initialOnList,
19+
containerClass
20+
}) {
21+
const [status, setStatus] = useState("ready");
22+
const [onList, setOnList] = useState(initialOnList);
23+
24+
function setRestoreStatus(newOnList) {
25+
setOnList(newOnList);
26+
setStatus("ready");
27+
}
28+
29+
function setListErrorStatus() {
30+
setStatus("failed");
31+
setTimeout(() => {
32+
setRestoreStatus("unknown");
33+
}, 4000);
34+
}
35+
36+
function addToList() {
37+
setStatus("processing");
38+
39+
const client = new MaterialList({ baseUrl: materialListUrl });
40+
client
41+
.addListMaterial({ materialId: id })
42+
.then(() => {
43+
setTimeout(() => {
44+
setRestoreStatus("on");
45+
}, 4000);
46+
})
47+
.catch(setListErrorStatus);
48+
}
49+
50+
function removeFromList() {
51+
setStatus("processing");
52+
53+
const client = new MaterialList({ baseUrl: materialListUrl });
54+
client
55+
.deleteListMaterial({ materialId: id })
56+
.then(() => {
57+
setTimeout(() => {
58+
setRestoreStatus("off");
59+
}, 4000);
60+
})
61+
.catch(setListErrorStatus);
62+
}
63+
64+
let onClick = addToList;
65+
let text = addText;
66+
let errorText = addErrorText;
67+
let successText = addSuccessText;
68+
if (onList === "on") {
69+
onClick = removeFromList;
70+
text = removeText;
71+
errorText = removeErrorText;
72+
successText = removeSuccessText;
73+
}
74+
75+
if (status === "ready" && onList === "unknown") {
76+
const client = new MaterialList({ baseUrl: materialListUrl });
77+
client
78+
.checkListMaterial({ materialId: id })
79+
.then(listMaterial => {
80+
setOnList(listMaterial ? "on" : "off");
81+
})
82+
// eslint-disable-next-line no-unused-vars
83+
.catch(err => {
84+
// Do nothing. If the call fails then we show the add button by default.
85+
// If this is a permanent error then clicking the button will trigger an
86+
// error. If this is a temporary error and the user clicks the button
87+
// then the material will not be added multiple times and thus cause
88+
// further problems.
89+
});
90+
}
91+
92+
return (
93+
<ChecklistMaterialButton
94+
text={text}
95+
errorText={errorText}
96+
successText={successText}
97+
status={status}
98+
onClick={onClick}
99+
loginUrl={loginUrl}
100+
materialId={id}
101+
containerClass={containerClass}
102+
/>
103+
);
104+
}
105+
106+
ChecklistMaterialButtonEntry.propTypes = {
107+
materialListUrl: urlPropType,
108+
addText: PropTypes.string,
109+
addErrorText: PropTypes.string,
110+
addSuccessText: PropTypes.string,
111+
removeText: PropTypes.string,
112+
removeErrorText: PropTypes.string,
113+
removeSuccessText: PropTypes.string,
114+
id: PropTypes.string.isRequired,
115+
loginUrl: urlPropType.isRequired,
116+
initialOnList: PropTypes.oneOf(["unknown", "on", "off"]),
117+
containerClass: PropTypes.string
118+
};
119+
120+
ChecklistMaterialButtonEntry.defaultProps = {
121+
materialListUrl: "https://test.materiallist.dandigbib.org",
122+
addText: "Tilføj til min liste",
123+
addErrorText: "Det lykkedes ikke at gemme materialet.",
124+
addSuccessText: "Materialet er tilføjet",
125+
removeText: "Fjern fra min liste",
126+
removeErrorText: "Det lykkedes ikke at fjerne materialet.",
127+
removeSuccessText: "Materialet er fjernet",
128+
initialOnList: "unknown",
129+
containerClass: "ddb-checklist-material-button__container"
130+
};
131+
132+
export default ChecklistMaterialButtonEntry;

src/apps/add-to-checklist/add-to-checklist.jsx renamed to src/apps/checklist-button/checklist-material-button.jsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ import Alert from "../../components/alert/alert";
77
import User from "../../core/user";
88
import replacePlaceholders from "../../core/replacePlaceholders";
99

10-
function AddToChecklist({
10+
function ChecklistMaterialButton({
1111
status,
1212
onClick,
1313
text,
1414
errorText,
1515
successText,
1616
loginUrl,
17-
materialId
17+
materialId,
18+
containerClass
1819
}) {
1920
if (status === "processing") {
2021
return <Alert message={successText} type="polite" variant="success" />;
@@ -25,7 +26,7 @@ function AddToChecklist({
2526
}
2627

2728
return (
28-
<div className="ddb-add-to-checklist__container">
29+
<div className={containerClass}>
2930
<Button
3031
href={
3132
!User.isAuthenticated()
@@ -47,18 +48,20 @@ function AddToChecklist({
4748
);
4849
}
4950

50-
AddToChecklist.propTypes = {
51+
ChecklistMaterialButton.propTypes = {
5152
text: PropTypes.string.isRequired,
5253
errorText: PropTypes.string.isRequired,
5354
successText: PropTypes.string.isRequired,
5455
loginUrl: urlPropType.isRequired,
5556
onClick: PropTypes.func.isRequired,
5657
status: PropTypes.oneOf(["ready", "processing", "failed", "finished"]),
57-
materialId: PropTypes.string.isRequired
58+
materialId: PropTypes.string.isRequired,
59+
containerClass: PropTypes.string
5860
};
5961

60-
AddToChecklist.defaultProps = {
61-
status: "ready"
62+
ChecklistMaterialButton.defaultProps = {
63+
status: "ready",
64+
containerClass: "ddb-checklist-material-button__container"
6265
};
6366

64-
export default AddToChecklist;
67+
export default ChecklistMaterialButton;

0 commit comments

Comments
 (0)