@vonaffenfels/contentful-teasermanager 1.2.18 → 1.2.19

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 (36) hide show
  1. package/.babelrc +19 -19
  2. package/.nvmrc +1 -1
  3. package/dist/TestStory.js +94 -0
  4. package/dist/TestStory2.js +94 -0
  5. package/dist/TestStory3.js +94 -0
  6. package/dist/index.html +11 -11
  7. package/dist/index.js +99233 -44287
  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/LogicEditor.js +533 -533
  12. package/src/components/Contentful/Dialog/NewestArticles.js +198 -198
  13. package/src/components/Contentful/Dialog.js +87 -87
  14. package/src/components/Contentful/EntryEditor.js +196 -196
  15. package/src/components/Contentful/Page.js +9 -9
  16. package/src/components/NoAccess.js +12 -12
  17. package/src/components/Teasermanager/Timeline.js +179 -179
  18. package/src/components/Teasermanager/Timeline.module.css +89 -89
  19. package/src/components/Teasermanager.js +269 -269
  20. package/src/components/Teasermanager.module.css +137 -137
  21. package/src/dev.js +5 -5
  22. package/src/hooks/useDebounce.js +20 -20
  23. package/src/hooks/useOnScreen.js +23 -23
  24. package/src/icons/remove.svg +7 -7
  25. package/src/index.html +11 -11
  26. package/src/index.js +51 -51
  27. package/src/lib/contentfulClient.js +12 -12
  28. package/src/lib/runLoaders.js +46 -46
  29. package/src/queryFromLogic.js +33 -33
  30. package/src/scss/index.scss +11 -11
  31. package/tailwind.config.js +5 -5
  32. package/webpack.config.dev.js +25 -25
  33. package/webpack.config.js +174 -174
  34. package/dist/_base_slate-editor_src_dev_testComponents_TestStory2_js.js +0 -94
  35. package/dist/_base_slate-editor_src_dev_testComponents_TestStory3_js.js +0 -94
  36. package/dist/_base_slate-editor_src_dev_testComponents_TestStory_js.js +0 -94
@@ -1,269 +1,269 @@
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
- onSlotClickLogic = async () => console.error("missing onSlotClickLogic"),
19
- removeSlotData = async () => console.error("missing removeSlotData"),
20
- contentFieldName = "content",
21
- locale = "de",
22
- }) => {
23
- const contentfulClient = getContentfulClient();
24
- const [entry, setEntry] = useState(null);
25
- const wrapperRef = useRef(null);
26
- const [loading, setLoading] = useState("initial");
27
- const [loadedContent, setLoadedContent] = useState(null);
28
- const [currentDate, _setCurrentDate] = useState(null);
29
- const [currentSlotState, setCurrentSlotState] = useState(null);
30
- const [currentSlotLogicState, setCurrentSlotLogicState] = useState(null);
31
- const currentLoadingOperation = useRef(0);
32
-
33
- const setCurrentDate = (date) => {
34
- if (date) {
35
- date.setSeconds(0);
36
- }
37
-
38
- _setCurrentDate(date);
39
- };
40
-
41
- const reloadAllData = async () => {
42
- let loadingId = ++currentLoadingOperation.current;
43
- if (!currentDate) {
44
- return;
45
- }
46
-
47
- const contentValue = entry?.fields?.[contentFieldName]?.[locale];
48
- const portalValue = entry?.fields?.portal?.[locale];
49
-
50
- if (!contentValue) {
51
- setLoading("initial");
52
- setLoadedContent(null);
53
- return;
54
- }
55
-
56
- console.log(`Teasermanager :: LOADING DATA`);
57
- if (loading !== "initial") {
58
- setLoading(true);
59
- }
60
-
61
- const content = await runLoaders(
62
- contentValue, portalValue, entry?.sys?.id, currentDate,
63
- );
64
-
65
- // only apply the LAST update
66
- if (currentLoadingOperation.current === loadingId) {
67
- updateSlotStateData();
68
-
69
- console.log(`Teasermanager :: LOADED DATA`);
70
- setLoadedContent(content);
71
- setLoading(false);
72
- }
73
- };
74
-
75
- const initSlot = (node) => {
76
- const existingManagementNode = node.querySelector(`.__teasermanager_management_node`);
77
- if (existingManagementNode) {
78
- node.removeChild(existingManagementNode);
79
- }
80
-
81
- const slotId = node.dataset.teasermanagerSlot;
82
- const managementNode = document.createElement("div");
83
- managementNode.classList.add(styles.management);
84
-
85
- const managementLabelNode = document.createElement("div");
86
- managementLabelNode.classList.add(styles.label);
87
- const managementLabelNodeLogic = document.createElement("div");
88
- managementLabelNodeLogic.classList.add(styles.labelLogic);
89
-
90
- if (currentSlotState?.[slotId]) {
91
- managementNode.classList.add(styles.changedBorder);
92
- }
93
-
94
- if (currentSlotLogicState?.[slotId]) {
95
- managementNode.classList.add(styles.logicBorder);
96
- }
97
-
98
- if (currentSlotState?.[slotId] && currentSlotState?.[slotId] !== "RESET") {
99
- managementNode.classList.add(styles.changed);
100
-
101
- managementLabelNode.innerHTML = `Artikel wechseln`;
102
- const managementRemoveButtonNode = document.createElement("div");
103
- managementRemoveButtonNode.classList.add(styles.removeButton);
104
- managementRemoveButtonNode.title = `Artikel entfernen`;
105
- managementRemoveButtonNode.innerHTML = `
106
- <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">
107
- <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
108
- \tc0,137.002-111.07,248.07-248.083,248.07C111.069,496.155,0,385.087,0,248.085z"/>
109
- <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
110
- \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"/>
111
- </svg>
112
- `;
113
- managementRemoveButtonNode.addEventListener("click", (e) => {
114
- removeSlotData(slotId, currentDate).then(() => {
115
- managementNode.classList.add(styles.loading);
116
- reloadAllData().then(() => {
117
- // DONT remove, in case multiple loading operations are running we want the state to stay loading :)
118
- // managementNode.classList.remove(styles.loading);
119
- });
120
- });
121
- e.preventDefault();
122
- e.stopPropagation();
123
- return false;
124
- });
125
- managementNode.appendChild(managementRemoveButtonNode);
126
- } else {
127
- managementLabelNode.innerHTML = `Artikel festlegen`;
128
- }
129
-
130
- if (currentSlotLogicState?.[slotId]) {
131
- managementLabelNodeLogic.innerHTML = `Logik bearbeiten`;
132
- } else {
133
- managementLabelNodeLogic.innerHTML = `Logik festlegen`;
134
- }
135
-
136
- managementNode.appendChild(managementLabelNode);
137
- managementNode.appendChild(managementLabelNodeLogic);
138
- managementLabelNode.addEventListener("click", (e) => {
139
- onSlotClick(slotId, currentDate).then((entry) => {
140
- if (!entry) {
141
- return; // nothing changed, no need to reload!
142
- }
143
- managementNode.classList.add(styles.loading);
144
- reloadAllData().then(() => {
145
- // DONT remove, in case multiple loading operations are running we want the state to stay loading :)
146
- // managementNode.classList.remove(styles.loading);
147
- });
148
- });
149
- e.preventDefault();
150
- e.stopPropagation();
151
- return false;
152
- });
153
-
154
- managementLabelNodeLogic.addEventListener("click", (e) => {
155
- onSlotClickLogic(slotId, currentDate).then(() => {
156
- managementNode.classList.add(styles.loading);
157
- reloadAllData().then(() => {
158
- // DONT remove, in case multiple loading operations are running we want the state to stay loading :)
159
- // managementNode.classList.remove(styles.loading);
160
- });
161
- });
162
- e.preventDefault();
163
- e.stopPropagation();
164
- return false;
165
- });
166
-
167
-
168
- managementNode.classList.add("__teasermanager_management_node");
169
- node.appendChild(managementNode);
170
- };
171
-
172
- const updateSlots = (mutationList) => {
173
- if (!mutationList) {
174
- // update all slots
175
- const slots = wrapperRef.current.querySelectorAll(`*[data-teasermanager-slot]`);
176
- slots.forEach(initSlot);
177
- console.log(`Teasermanager :: UPDATE ALL SLOTS`);
178
- } else {
179
- // update only if the change was not a management node
180
- const isValidUpdate = mutationList?.find(mutation => {
181
- if (mutation.type === "childList") {
182
- const removedNonManagementNode = [...mutation.removedNodes]?.find(node => !node.classList.contains("__teasermanager_management_node"));
183
- const addedNonManagementNode = [...mutation.addedNodes]?.find(node => !node.classList.contains("__teasermanager_management_node"));
184
-
185
- if (!removedNonManagementNode && !addedNonManagementNode) {
186
- return false;
187
- }
188
- }
189
-
190
- return true;
191
- });
192
-
193
- if (isValidUpdate) {
194
- updateSlots();
195
- }
196
- }
197
- };
198
-
199
- useEffect(() => {
200
- if (!entryId || entry) {
201
- setEntry(null);
202
- return;
203
- }
204
-
205
- contentfulClient.getEntry(entryId).then((loadedEntry, b) => {
206
- setEntry(loadedEntry);
207
- });
208
- }, [entryId]);
209
-
210
- useEffect(() => {
211
- if (!wrapperRef.current) {
212
- return;
213
- }
214
-
215
- const observer = new MutationObserver(updateSlots);
216
- observer.observe(wrapperRef.current, {
217
- attributes: false,
218
- childList: true,
219
- subtree: true,
220
- });
221
-
222
- return () => {
223
- observer.disconnect();
224
- };
225
- }, [wrapperRef, currentDate, currentSlotState, onSlotClick, removeSlotData, reloadAllData]);
226
-
227
- const updateSlotStateData = async () => {
228
- try {
229
- if (!currentDate) {
230
- return;
231
- }
232
-
233
- const {
234
- data,
235
- logicData,
236
- } = await loadSlotStateForPage(currentDate);
237
-
238
- setCurrentSlotState(data);
239
- setCurrentSlotLogicState(logicData);
240
- } catch (e) {
241
- console.error(e);
242
- }
243
- };
244
-
245
- useEffect(() => {
246
- updateSlots();
247
- }, [currentSlotState]);
248
-
249
- useEffect(() => {
250
- reloadAllData();
251
- }, [contentFieldName, locale, entry, currentDate]);
252
-
253
- return <div className="flex w-full flex-col">
254
- <div className="w-full">
255
- <Timeline
256
- currentDate={currentDate}
257
- setCurrentDate={setCurrentDate}
258
- loadTimelineStateForPage={loadTimelineStateForPage}/>
259
- </div>
260
- <div className={classNames(styles.wrapper, {[styles.loading]: loading === "initial"})} ref={wrapperRef}>
261
- {!!loadedContent && loading !== "initial" &&
262
- <Renderer
263
- value={loadedContent}
264
- storybookComponentLoader={componentLoader}
265
- />
266
- }
267
- </div>
268
- </div>;
269
- };
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
+ onSlotClickLogic = async () => console.error("missing onSlotClickLogic"),
19
+ removeSlotData = async () => console.error("missing removeSlotData"),
20
+ contentFieldName = "content",
21
+ locale = "de",
22
+ }) => {
23
+ const contentfulClient = getContentfulClient();
24
+ const [entry, setEntry] = useState(null);
25
+ const wrapperRef = useRef(null);
26
+ const [loading, setLoading] = useState("initial");
27
+ const [loadedContent, setLoadedContent] = useState(null);
28
+ const [currentDate, _setCurrentDate] = useState(null);
29
+ const [currentSlotState, setCurrentSlotState] = useState(null);
30
+ const [currentSlotLogicState, setCurrentSlotLogicState] = useState(null);
31
+ const currentLoadingOperation = useRef(0);
32
+
33
+ const setCurrentDate = (date) => {
34
+ if (date) {
35
+ date.setSeconds(0);
36
+ }
37
+
38
+ _setCurrentDate(date);
39
+ };
40
+
41
+ const reloadAllData = async () => {
42
+ let loadingId = ++currentLoadingOperation.current;
43
+ if (!currentDate) {
44
+ return;
45
+ }
46
+
47
+ const contentValue = entry?.fields?.[contentFieldName]?.[locale];
48
+ const portalValue = entry?.fields?.portal?.[locale];
49
+
50
+ if (!contentValue) {
51
+ setLoading("initial");
52
+ setLoadedContent(null);
53
+ return;
54
+ }
55
+
56
+ console.log(`Teasermanager :: LOADING DATA`);
57
+ if (loading !== "initial") {
58
+ setLoading(true);
59
+ }
60
+
61
+ const content = await runLoaders(
62
+ contentValue, portalValue, entry?.sys?.id, currentDate,
63
+ );
64
+
65
+ // only apply the LAST update
66
+ if (currentLoadingOperation.current === loadingId) {
67
+ updateSlotStateData();
68
+
69
+ console.log(`Teasermanager :: LOADED DATA`);
70
+ setLoadedContent(content);
71
+ setLoading(false);
72
+ }
73
+ };
74
+
75
+ const initSlot = (node) => {
76
+ const existingManagementNode = node.querySelector(`.__teasermanager_management_node`);
77
+ if (existingManagementNode) {
78
+ node.removeChild(existingManagementNode);
79
+ }
80
+
81
+ const slotId = node.dataset.teasermanagerSlot;
82
+ const managementNode = document.createElement("div");
83
+ managementNode.classList.add(styles.management);
84
+
85
+ const managementLabelNode = document.createElement("div");
86
+ managementLabelNode.classList.add(styles.label);
87
+ const managementLabelNodeLogic = document.createElement("div");
88
+ managementLabelNodeLogic.classList.add(styles.labelLogic);
89
+
90
+ if (currentSlotState?.[slotId]) {
91
+ managementNode.classList.add(styles.changedBorder);
92
+ }
93
+
94
+ if (currentSlotLogicState?.[slotId]) {
95
+ managementNode.classList.add(styles.logicBorder);
96
+ }
97
+
98
+ if (currentSlotState?.[slotId] && currentSlotState?.[slotId] !== "RESET") {
99
+ managementNode.classList.add(styles.changed);
100
+
101
+ managementLabelNode.innerHTML = `Artikel wechseln`;
102
+ const managementRemoveButtonNode = document.createElement("div");
103
+ managementRemoveButtonNode.classList.add(styles.removeButton);
104
+ managementRemoveButtonNode.title = `Artikel entfernen`;
105
+ managementRemoveButtonNode.innerHTML = `
106
+ <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">
107
+ <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
108
+ \tc0,137.002-111.07,248.07-248.083,248.07C111.069,496.155,0,385.087,0,248.085z"/>
109
+ <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
110
+ \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"/>
111
+ </svg>
112
+ `;
113
+ managementRemoveButtonNode.addEventListener("click", (e) => {
114
+ removeSlotData(slotId, currentDate).then(() => {
115
+ managementNode.classList.add(styles.loading);
116
+ reloadAllData().then(() => {
117
+ // DONT remove, in case multiple loading operations are running we want the state to stay loading :)
118
+ // managementNode.classList.remove(styles.loading);
119
+ });
120
+ });
121
+ e.preventDefault();
122
+ e.stopPropagation();
123
+ return false;
124
+ });
125
+ managementNode.appendChild(managementRemoveButtonNode);
126
+ } else {
127
+ managementLabelNode.innerHTML = `Artikel festlegen`;
128
+ }
129
+
130
+ if (currentSlotLogicState?.[slotId]) {
131
+ managementLabelNodeLogic.innerHTML = `Logik bearbeiten`;
132
+ } else {
133
+ managementLabelNodeLogic.innerHTML = `Logik festlegen`;
134
+ }
135
+
136
+ managementNode.appendChild(managementLabelNode);
137
+ managementNode.appendChild(managementLabelNodeLogic);
138
+ managementLabelNode.addEventListener("click", (e) => {
139
+ onSlotClick(slotId, currentDate).then((entry) => {
140
+ if (!entry) {
141
+ return; // nothing changed, no need to reload!
142
+ }
143
+ managementNode.classList.add(styles.loading);
144
+ reloadAllData().then(() => {
145
+ // DONT remove, in case multiple loading operations are running we want the state to stay loading :)
146
+ // managementNode.classList.remove(styles.loading);
147
+ });
148
+ });
149
+ e.preventDefault();
150
+ e.stopPropagation();
151
+ return false;
152
+ });
153
+
154
+ managementLabelNodeLogic.addEventListener("click", (e) => {
155
+ onSlotClickLogic(slotId, currentDate).then(() => {
156
+ managementNode.classList.add(styles.loading);
157
+ reloadAllData().then(() => {
158
+ // DONT remove, in case multiple loading operations are running we want the state to stay loading :)
159
+ // managementNode.classList.remove(styles.loading);
160
+ });
161
+ });
162
+ e.preventDefault();
163
+ e.stopPropagation();
164
+ return false;
165
+ });
166
+
167
+
168
+ managementNode.classList.add("__teasermanager_management_node");
169
+ node.appendChild(managementNode);
170
+ };
171
+
172
+ const updateSlots = (mutationList) => {
173
+ if (!mutationList) {
174
+ // update all slots
175
+ const slots = wrapperRef.current.querySelectorAll(`*[data-teasermanager-slot]`);
176
+ slots.forEach(initSlot);
177
+ console.log(`Teasermanager :: UPDATE ALL SLOTS`);
178
+ } else {
179
+ // update only if the change was not a management node
180
+ const isValidUpdate = mutationList?.find(mutation => {
181
+ if (mutation.type === "childList") {
182
+ const removedNonManagementNode = [...mutation.removedNodes]?.find(node => !node.classList.contains("__teasermanager_management_node"));
183
+ const addedNonManagementNode = [...mutation.addedNodes]?.find(node => !node.classList.contains("__teasermanager_management_node"));
184
+
185
+ if (!removedNonManagementNode && !addedNonManagementNode) {
186
+ return false;
187
+ }
188
+ }
189
+
190
+ return true;
191
+ });
192
+
193
+ if (isValidUpdate) {
194
+ updateSlots();
195
+ }
196
+ }
197
+ };
198
+
199
+ useEffect(() => {
200
+ if (!entryId || entry) {
201
+ setEntry(null);
202
+ return;
203
+ }
204
+
205
+ contentfulClient.getEntry(entryId).then((loadedEntry, b) => {
206
+ setEntry(loadedEntry);
207
+ });
208
+ }, [entryId]);
209
+
210
+ useEffect(() => {
211
+ if (!wrapperRef.current) {
212
+ return;
213
+ }
214
+
215
+ const observer = new MutationObserver(updateSlots);
216
+ observer.observe(wrapperRef.current, {
217
+ attributes: false,
218
+ childList: true,
219
+ subtree: true,
220
+ });
221
+
222
+ return () => {
223
+ observer.disconnect();
224
+ };
225
+ }, [wrapperRef, currentDate, currentSlotState, onSlotClick, removeSlotData, reloadAllData]);
226
+
227
+ const updateSlotStateData = async () => {
228
+ try {
229
+ if (!currentDate) {
230
+ return;
231
+ }
232
+
233
+ const {
234
+ data,
235
+ logicData,
236
+ } = await loadSlotStateForPage(currentDate);
237
+
238
+ setCurrentSlotState(data);
239
+ setCurrentSlotLogicState(logicData);
240
+ } catch (e) {
241
+ console.error(e);
242
+ }
243
+ };
244
+
245
+ useEffect(() => {
246
+ updateSlots();
247
+ }, [currentSlotState]);
248
+
249
+ useEffect(() => {
250
+ reloadAllData();
251
+ }, [contentFieldName, locale, entry, currentDate]);
252
+
253
+ return <div className="flex w-full flex-col">
254
+ <div className="w-full">
255
+ <Timeline
256
+ currentDate={currentDate}
257
+ setCurrentDate={setCurrentDate}
258
+ loadTimelineStateForPage={loadTimelineStateForPage}/>
259
+ </div>
260
+ <div className={classNames(styles.wrapper, {[styles.loading]: loading === "initial"})} ref={wrapperRef}>
261
+ {!!loadedContent && loading !== "initial" &&
262
+ <Renderer
263
+ value={loadedContent}
264
+ storybookComponentLoader={componentLoader}
265
+ />
266
+ }
267
+ </div>
268
+ </div>;
269
+ };