@vonaffenfels/contentful-teasermanager 1.1.68 → 1.1.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/.babelrc +19 -19
  2. package/.nvmrc +1 -1
  3. package/dist/_base_slate-editor_src_dev_testComponents_TestStory2_js.js +94 -0
  4. package/dist/_base_slate-editor_src_dev_testComponents_TestStory3_js.js +94 -0
  5. package/dist/_base_slate-editor_src_dev_testComponents_TestStory_js.js +94 -0
  6. package/dist/index.html +11 -11
  7. package/dist/index.js +24853 -41112
  8. package/package.json +3 -3
  9. package/postcss.config.js +6 -6
  10. package/src/components/Contentful/ConfigScreen.js +154 -154
  11. package/src/components/Contentful/Dialog/NewestArticles.js +178 -178
  12. package/src/components/Contentful/Dialog.js +58 -58
  13. package/src/components/Contentful/EntryEditor.js +139 -139
  14. package/src/components/Contentful/Page.js +9 -9
  15. package/src/components/NoAccess.js +12 -12
  16. package/src/components/Teasermanager/Timeline.js +179 -179
  17. package/src/components/Teasermanager/Timeline.module.css +89 -89
  18. package/src/components/Teasermanager.js +237 -237
  19. package/src/components/Teasermanager.module.css +105 -105
  20. package/src/dev.js +5 -5
  21. package/src/hooks/useDebounce.js +20 -20
  22. package/src/hooks/useOnScreen.js +23 -23
  23. package/src/icons/remove.svg +7 -7
  24. package/src/index.html +11 -11
  25. package/src/index.js +51 -51
  26. package/src/lib/contentfulClient.js +12 -12
  27. package/src/lib/runLoaders.js +46 -46
  28. package/src/scss/index.scss +11 -11
  29. package/tailwind.config.js +5 -5
  30. package/webpack.config.dev.js +25 -25
  31. package/webpack.config.js +174 -174
  32. package/dist/TestStory.js +0 -94
  33. package/dist/TestStory2.js +0 -94
  34. package/dist/TestStory3.js +0 -94
@@ -1,237 +1,237 @@
1
- import React, {
2
- useEffect, useRef, useState,
3
- } from "react";
4
-
5
- import {getContentfulClient} from "../lib/contentfulClient";
6
- import Renderer from "@vonaffenfels/slate-editor/dist/Renderer";
7
- import componentLoader from "@vonaffenfels/slate-editor/componentLoader";
8
- import {Timeline} from "./Teasermanager/Timeline";
9
- import styles from "./Teasermanager.module.css";
10
- import {runLoaders} from "../lib/runLoaders";
11
- import classNames from "classnames";
12
-
13
- export const Teasermanager = ({
14
- entryId,
15
- loadSlotStateForPage = () => console.error("missing loadSlotStateForPage"),
16
- loadTimelineStateForPage = () => console.error("missing loadTimelineStateForPage"),
17
- onSlotClick = async () => console.error("missing onSlotClick"),
18
- removeSlotData = async () => console.error("missing removeSlotData"),
19
- contentFieldName = "content",
20
- locale = "de",
21
- }) => {
22
- const contentfulClient = getContentfulClient();
23
- const [entry, setEntry] = useState(null);
24
- const wrapperRef = useRef(null);
25
- const [loading, setLoading] = useState("initial");
26
- const [loadedContent, setLoadedContent] = useState(null);
27
- const [currentDate, _setCurrentDate] = useState(null);
28
- const [currentSlotState, setCurrentSlotState] = useState(null);
29
- const currentLoadingOperation = useRef(0);
30
-
31
- const setCurrentDate = (date) => {
32
- if (date) {
33
- date.setSeconds(0);
34
- }
35
-
36
- _setCurrentDate(date);
37
- }
38
-
39
- const reloadAllData = async () => {
40
- let loadingId = ++currentLoadingOperation.current;
41
- if (!currentDate) {
42
- return;
43
- }
44
-
45
- const contentValue = entry?.fields?.[contentFieldName]?.[locale];
46
- const portalValue = entry?.fields?.portal?.[locale];
47
-
48
- if (!contentValue) {
49
- setLoading("initial");
50
- setLoadedContent(null);
51
- return;
52
- }
53
-
54
- console.log(`Teasermanager :: LOADING DATA`);
55
- if (loading !== "initial") {
56
- setLoading(true);
57
- }
58
-
59
- const content = await runLoaders(contentValue, portalValue, entry?.sys?.id, currentDate);
60
-
61
- // only apply the LAST update
62
- if (currentLoadingOperation.current === loadingId) {
63
- updateSlotStateData();
64
-
65
- console.log(`Teasermanager :: LOADED DATA`);
66
- setLoadedContent(content);
67
- setLoading(false);
68
- }
69
- }
70
-
71
- const initSlot = (node) => {
72
- const existingManagementNode = node.querySelector(`.__teasermanager_management_node`);
73
- if (existingManagementNode) {
74
- node.removeChild(existingManagementNode);
75
- }
76
-
77
- const slotId = node.dataset.teasermanagerSlot;
78
- const managementNode = document.createElement("div");
79
- managementNode.classList.add(styles.management);
80
-
81
- const managementLabelNode = document.createElement("div");
82
- managementLabelNode.classList.add(styles.label);
83
- if (currentSlotState?.[slotId]) {
84
- managementNode.classList.add(styles.changedBorder);
85
- }
86
-
87
- if (currentSlotState?.[slotId] && currentSlotState?.[slotId] !== "RESET") {
88
- managementNode.classList.add(styles.changed);
89
-
90
- managementLabelNode.innerHTML = `Klicken um den Artikel zu wechseln`;
91
- const managementRemoveButtonNode = document.createElement("div");
92
- managementRemoveButtonNode.classList.add(styles.removeButton);
93
- managementRemoveButtonNode.title = `Artikel entfernen`;
94
- managementRemoveButtonNode.innerHTML = `
95
- <svg height="800px" width="800px" version="1.1" style="width: 20px; height: 20px;" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 496.158 496.158" xml:space="preserve">
96
- <path style="fill:#E04F5F;" d="M0,248.085C0,111.063,111.069,0.003,248.075,0.003c137.013,0,248.083,111.061,248.083,248.082
97
- \tc0,137.002-111.07,248.07-248.083,248.07C111.069,496.155,0,385.087,0,248.085z"/>
98
- <path style="fill:#FFFFFF;" d="M383.546,206.286H112.612c-3.976,0-7.199,3.225-7.199,7.2v69.187c0,3.976,3.224,7.199,7.199,7.199
99
- \th270.934c3.976,0,7.199-3.224,7.199-7.199v-69.187C390.745,209.511,387.521,206.286,383.546,206.286z"/>
100
- </svg>
101
- `;
102
- managementRemoveButtonNode.addEventListener("click", (e) => {
103
- removeSlotData(slotId, currentDate).then(() => {
104
- managementNode.classList.add(styles.loading);
105
- reloadAllData().then(() => {
106
- // DONT remove, in case multiple loading operations are running we want the state to stay loading :)
107
- //managementNode.classList.remove(styles.loading);
108
- });
109
- });
110
- e.preventDefault();
111
- e.stopPropagation();
112
- return false;
113
- });
114
- managementNode.appendChild(managementRemoveButtonNode);
115
- } else {
116
- if (currentSlotState?.[slotId] === "RESET") {
117
- managementLabelNode.innerHTML = `Hier wurde ein bereits verslotteter Artikel wieder entfernt<br />Klicken um einen neuen Artikel festzulegen`;
118
- } else {
119
- managementLabelNode.innerHTML = `Klicken um den Artikel festzulegen`;
120
- }
121
-
122
- }
123
-
124
- managementNode.appendChild(managementLabelNode);
125
- managementNode.addEventListener("click", (e) => {
126
- onSlotClick(slotId, currentDate).then((entry) => {
127
- if (!entry) {
128
- return; // nothing changed, no need to reload!
129
- }
130
- managementNode.classList.add(styles.loading);
131
- reloadAllData().then(() => {
132
- // DONT remove, in case multiple loading operations are running we want the state to stay loading :)
133
- //managementNode.classList.remove(styles.loading);
134
- });
135
- });
136
- e.preventDefault();
137
- e.stopPropagation();
138
- return false;
139
- });
140
-
141
- managementNode.classList.add("__teasermanager_management_node");
142
- node.appendChild(managementNode);
143
- };
144
-
145
- const updateSlots = (mutationList) => {
146
-
147
- if (!mutationList) {
148
- // update all slots
149
- const slots = wrapperRef.current.querySelectorAll(`*[data-teasermanager-slot]`);
150
- slots.forEach(initSlot);
151
- console.log(`Teasermanager :: UPDATE ALL SLOTS`);
152
- } else {
153
- // update only if the change was not a management node
154
- const isValidUpdate = mutationList?.find(mutation => {
155
- if (mutation.type === "childList") {
156
- const removedNonManagementNode = [...mutation.removedNodes]?.find(node => !node.classList.contains("__teasermanager_management_node"));
157
- const addedNonManagementNode = [...mutation.addedNodes]?.find(node => !node.classList.contains("__teasermanager_management_node"));
158
-
159
- if (!removedNonManagementNode && !addedNonManagementNode) {
160
- return false;
161
- }
162
- }
163
-
164
- return true;
165
- })
166
-
167
- if (isValidUpdate) {
168
- updateSlots();
169
- }
170
- }
171
-
172
- };
173
-
174
- useEffect(() => {
175
- if (!entryId || entry) {
176
- setEntry(null);
177
- return;
178
- }
179
-
180
- contentfulClient.getEntry(entryId).then((loadedEntry, b) => {
181
- setEntry(loadedEntry);
182
- });
183
- }, [entryId]);
184
-
185
- useEffect(() => {
186
- if (!wrapperRef.current) {
187
- return;
188
- }
189
-
190
- const observer = new MutationObserver(updateSlots);
191
- observer.observe(wrapperRef.current, {
192
- attributes: false,
193
- childList: true,
194
- subtree: true,
195
- });
196
-
197
- return () => {
198
- observer.disconnect();
199
- };
200
- }, [wrapperRef, currentDate, currentSlotState, onSlotClick, removeSlotData, reloadAllData]);
201
-
202
- const updateSlotStateData = async () => {
203
- try {
204
- if (!currentDate) {
205
- return;
206
- }
207
- setCurrentSlotState(await loadSlotStateForPage(currentDate))
208
- } catch (e) {
209
- console.error(e);
210
- }
211
- }
212
-
213
- useEffect(() => {
214
- updateSlots();
215
- }, [currentSlotState]);
216
-
217
- useEffect(() => {
218
- reloadAllData();
219
- }, [contentFieldName, locale, entry, currentDate]);
220
-
221
- return <div className="flex w-full flex-col">
222
- <div className="w-full">
223
- <Timeline
224
- currentDate={currentDate}
225
- setCurrentDate={setCurrentDate}
226
- loadTimelineStateForPage={loadTimelineStateForPage}/>
227
- </div>
228
- <div className={classNames(styles.wrapper, {[styles.loading]: loading === "initial"})} ref={wrapperRef}>
229
- {!!loadedContent && loading !== "initial" &&
230
- <Renderer
231
- value={loadedContent}
232
- storybookComponentLoader={componentLoader}
233
- />
234
- }
235
- </div>
236
- </div>;
237
- };
1
+ import React, {
2
+ useEffect, useRef, useState,
3
+ } from "react";
4
+
5
+ import {getContentfulClient} from "../lib/contentfulClient";
6
+ import Renderer from "@vonaffenfels/slate-editor/dist/Renderer";
7
+ import componentLoader from "@vonaffenfels/slate-editor/componentLoader";
8
+ import {Timeline} from "./Teasermanager/Timeline";
9
+ import styles from "./Teasermanager.module.css";
10
+ import {runLoaders} from "../lib/runLoaders";
11
+ import classNames from "classnames";
12
+
13
+ export const Teasermanager = ({
14
+ entryId,
15
+ loadSlotStateForPage = () => console.error("missing loadSlotStateForPage"),
16
+ loadTimelineStateForPage = () => console.error("missing loadTimelineStateForPage"),
17
+ onSlotClick = async () => console.error("missing onSlotClick"),
18
+ removeSlotData = async () => console.error("missing removeSlotData"),
19
+ contentFieldName = "content",
20
+ locale = "de",
21
+ }) => {
22
+ const contentfulClient = getContentfulClient();
23
+ const [entry, setEntry] = useState(null);
24
+ const wrapperRef = useRef(null);
25
+ const [loading, setLoading] = useState("initial");
26
+ const [loadedContent, setLoadedContent] = useState(null);
27
+ const [currentDate, _setCurrentDate] = useState(null);
28
+ const [currentSlotState, setCurrentSlotState] = useState(null);
29
+ const currentLoadingOperation = useRef(0);
30
+
31
+ const setCurrentDate = (date) => {
32
+ if (date) {
33
+ date.setSeconds(0);
34
+ }
35
+
36
+ _setCurrentDate(date);
37
+ }
38
+
39
+ const reloadAllData = async () => {
40
+ let loadingId = ++currentLoadingOperation.current;
41
+ if (!currentDate) {
42
+ return;
43
+ }
44
+
45
+ const contentValue = entry?.fields?.[contentFieldName]?.[locale];
46
+ const portalValue = entry?.fields?.portal?.[locale];
47
+
48
+ if (!contentValue) {
49
+ setLoading("initial");
50
+ setLoadedContent(null);
51
+ return;
52
+ }
53
+
54
+ console.log(`Teasermanager :: LOADING DATA`);
55
+ if (loading !== "initial") {
56
+ setLoading(true);
57
+ }
58
+
59
+ const content = await runLoaders(contentValue, portalValue, entry?.sys?.id, currentDate);
60
+
61
+ // only apply the LAST update
62
+ if (currentLoadingOperation.current === loadingId) {
63
+ updateSlotStateData();
64
+
65
+ console.log(`Teasermanager :: LOADED DATA`);
66
+ setLoadedContent(content);
67
+ setLoading(false);
68
+ }
69
+ }
70
+
71
+ const initSlot = (node) => {
72
+ const existingManagementNode = node.querySelector(`.__teasermanager_management_node`);
73
+ if (existingManagementNode) {
74
+ node.removeChild(existingManagementNode);
75
+ }
76
+
77
+ const slotId = node.dataset.teasermanagerSlot;
78
+ const managementNode = document.createElement("div");
79
+ managementNode.classList.add(styles.management);
80
+
81
+ const managementLabelNode = document.createElement("div");
82
+ managementLabelNode.classList.add(styles.label);
83
+ if (currentSlotState?.[slotId]) {
84
+ managementNode.classList.add(styles.changedBorder);
85
+ }
86
+
87
+ if (currentSlotState?.[slotId] && currentSlotState?.[slotId] !== "RESET") {
88
+ managementNode.classList.add(styles.changed);
89
+
90
+ managementLabelNode.innerHTML = `Klicken um den Artikel zu wechseln`;
91
+ const managementRemoveButtonNode = document.createElement("div");
92
+ managementRemoveButtonNode.classList.add(styles.removeButton);
93
+ managementRemoveButtonNode.title = `Artikel entfernen`;
94
+ managementRemoveButtonNode.innerHTML = `
95
+ <svg height="800px" width="800px" version="1.1" style="width: 20px; height: 20px;" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 496.158 496.158" xml:space="preserve">
96
+ <path style="fill:#E04F5F;" d="M0,248.085C0,111.063,111.069,0.003,248.075,0.003c137.013,0,248.083,111.061,248.083,248.082
97
+ \tc0,137.002-111.07,248.07-248.083,248.07C111.069,496.155,0,385.087,0,248.085z"/>
98
+ <path style="fill:#FFFFFF;" d="M383.546,206.286H112.612c-3.976,0-7.199,3.225-7.199,7.2v69.187c0,3.976,3.224,7.199,7.199,7.199
99
+ \th270.934c3.976,0,7.199-3.224,7.199-7.199v-69.187C390.745,209.511,387.521,206.286,383.546,206.286z"/>
100
+ </svg>
101
+ `;
102
+ managementRemoveButtonNode.addEventListener("click", (e) => {
103
+ removeSlotData(slotId, currentDate).then(() => {
104
+ managementNode.classList.add(styles.loading);
105
+ reloadAllData().then(() => {
106
+ // DONT remove, in case multiple loading operations are running we want the state to stay loading :)
107
+ //managementNode.classList.remove(styles.loading);
108
+ });
109
+ });
110
+ e.preventDefault();
111
+ e.stopPropagation();
112
+ return false;
113
+ });
114
+ managementNode.appendChild(managementRemoveButtonNode);
115
+ } else {
116
+ if (currentSlotState?.[slotId] === "RESET") {
117
+ managementLabelNode.innerHTML = `Hier wurde ein bereits verslotteter Artikel wieder entfernt<br />Klicken um einen neuen Artikel festzulegen`;
118
+ } else {
119
+ managementLabelNode.innerHTML = `Klicken um den Artikel festzulegen`;
120
+ }
121
+
122
+ }
123
+
124
+ managementNode.appendChild(managementLabelNode);
125
+ managementNode.addEventListener("click", (e) => {
126
+ onSlotClick(slotId, currentDate).then((entry) => {
127
+ if (!entry) {
128
+ return; // nothing changed, no need to reload!
129
+ }
130
+ managementNode.classList.add(styles.loading);
131
+ reloadAllData().then(() => {
132
+ // DONT remove, in case multiple loading operations are running we want the state to stay loading :)
133
+ //managementNode.classList.remove(styles.loading);
134
+ });
135
+ });
136
+ e.preventDefault();
137
+ e.stopPropagation();
138
+ return false;
139
+ });
140
+
141
+ managementNode.classList.add("__teasermanager_management_node");
142
+ node.appendChild(managementNode);
143
+ };
144
+
145
+ const updateSlots = (mutationList) => {
146
+
147
+ if (!mutationList) {
148
+ // update all slots
149
+ const slots = wrapperRef.current.querySelectorAll(`*[data-teasermanager-slot]`);
150
+ slots.forEach(initSlot);
151
+ console.log(`Teasermanager :: UPDATE ALL SLOTS`);
152
+ } else {
153
+ // update only if the change was not a management node
154
+ const isValidUpdate = mutationList?.find(mutation => {
155
+ if (mutation.type === "childList") {
156
+ const removedNonManagementNode = [...mutation.removedNodes]?.find(node => !node.classList.contains("__teasermanager_management_node"));
157
+ const addedNonManagementNode = [...mutation.addedNodes]?.find(node => !node.classList.contains("__teasermanager_management_node"));
158
+
159
+ if (!removedNonManagementNode && !addedNonManagementNode) {
160
+ return false;
161
+ }
162
+ }
163
+
164
+ return true;
165
+ })
166
+
167
+ if (isValidUpdate) {
168
+ updateSlots();
169
+ }
170
+ }
171
+
172
+ };
173
+
174
+ useEffect(() => {
175
+ if (!entryId || entry) {
176
+ setEntry(null);
177
+ return;
178
+ }
179
+
180
+ contentfulClient.getEntry(entryId).then((loadedEntry, b) => {
181
+ setEntry(loadedEntry);
182
+ });
183
+ }, [entryId]);
184
+
185
+ useEffect(() => {
186
+ if (!wrapperRef.current) {
187
+ return;
188
+ }
189
+
190
+ const observer = new MutationObserver(updateSlots);
191
+ observer.observe(wrapperRef.current, {
192
+ attributes: false,
193
+ childList: true,
194
+ subtree: true,
195
+ });
196
+
197
+ return () => {
198
+ observer.disconnect();
199
+ };
200
+ }, [wrapperRef, currentDate, currentSlotState, onSlotClick, removeSlotData, reloadAllData]);
201
+
202
+ const updateSlotStateData = async () => {
203
+ try {
204
+ if (!currentDate) {
205
+ return;
206
+ }
207
+ setCurrentSlotState(await loadSlotStateForPage(currentDate))
208
+ } catch (e) {
209
+ console.error(e);
210
+ }
211
+ }
212
+
213
+ useEffect(() => {
214
+ updateSlots();
215
+ }, [currentSlotState]);
216
+
217
+ useEffect(() => {
218
+ reloadAllData();
219
+ }, [contentFieldName, locale, entry, currentDate]);
220
+
221
+ return <div className="flex w-full flex-col">
222
+ <div className="w-full">
223
+ <Timeline
224
+ currentDate={currentDate}
225
+ setCurrentDate={setCurrentDate}
226
+ loadTimelineStateForPage={loadTimelineStateForPage}/>
227
+ </div>
228
+ <div className={classNames(styles.wrapper, {[styles.loading]: loading === "initial"})} ref={wrapperRef}>
229
+ {!!loadedContent && loading !== "initial" &&
230
+ <Renderer
231
+ value={loadedContent}
232
+ storybookComponentLoader={componentLoader}
233
+ />
234
+ }
235
+ </div>
236
+ </div>;
237
+ };