@vonaffenfels/contentful-teasermanager 1.2.0 → 1.2.1
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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vonaffenfels/contentful-teasermanager",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"prepublish": "yarn run build",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"classnames": "^2.3.2",
|
|
71
71
|
"clean-webpack-plugin": "^3.0.0",
|
|
72
72
|
"cloudinary": "^1.25.1",
|
|
73
|
-
"contentful-management": "^
|
|
73
|
+
"contentful-management": "^11",
|
|
74
74
|
"copy-webpack-plugin": "^8.1.1",
|
|
75
75
|
"cross-env": "^7.0.3",
|
|
76
76
|
"css-loader": "^5.2.4",
|
|
@@ -98,9 +98,10 @@
|
|
|
98
98
|
},
|
|
99
99
|
"dependencies": {
|
|
100
100
|
"@vonaffenfels/slate-editor": "^1.2.0",
|
|
101
|
+
"contentful-resolve-response": "^1.9.2",
|
|
101
102
|
"webpack": "5.88.2"
|
|
102
103
|
},
|
|
103
|
-
"gitHead": "
|
|
104
|
+
"gitHead": "b06b79ed032fecf1dfeef2e7e312eb0d42f2e84e",
|
|
104
105
|
"publishConfig": {
|
|
105
106
|
"access": "public"
|
|
106
107
|
}
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
DndContext, useDraggable, useDroppable,
|
|
11
11
|
PointerSensor, useSensor, useSensors,
|
|
12
12
|
} from '@dnd-kit/core';
|
|
13
|
+
import contentfulResolveResponse from "contentful-resolve-response";
|
|
13
14
|
import {
|
|
14
15
|
useEffect, useState,
|
|
15
16
|
} from "react";
|
|
@@ -61,7 +62,8 @@ const LogicEditorInner = ({
|
|
|
61
62
|
}) => {
|
|
62
63
|
const contentfulClient = getContentfulClient();
|
|
63
64
|
const [loading, setLoading] = useState(false);
|
|
64
|
-
const [
|
|
65
|
+
const [tags, setTags] = useState([]);
|
|
66
|
+
const [categories, setCategories] = useState([]);
|
|
65
67
|
const [searchQuery, setSearchQuery] = useState("");
|
|
66
68
|
const [addTimepoint, setAddTimepoint] = useState(7);
|
|
67
69
|
const debouncedSearch = useDebounce(searchQuery, 500);
|
|
@@ -102,14 +104,48 @@ const LogicEditorInner = ({
|
|
|
102
104
|
"sys.id",
|
|
103
105
|
].join(","),
|
|
104
106
|
};
|
|
107
|
+
const paramsNavigation = {
|
|
108
|
+
limit: 1,
|
|
109
|
+
content_type: "navigation",
|
|
110
|
+
include: 2,
|
|
111
|
+
locale,
|
|
112
|
+
"fields.portal": portal,
|
|
113
|
+
"fields.type": "main",
|
|
114
|
+
};
|
|
105
115
|
|
|
106
116
|
if (debouncedSearch) {
|
|
107
117
|
params["fields.title[match]"] = debouncedSearch;
|
|
108
118
|
}
|
|
109
119
|
|
|
110
|
-
|
|
120
|
+
Promise.all([
|
|
121
|
+
contentfulClient.getEntries(params),
|
|
122
|
+
contentfulClient.getEntries(paramsNavigation).then(async (response) => {
|
|
123
|
+
if (!response?.items?.[0]) {
|
|
124
|
+
return [];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const references = await sdk.cma.entry.references({entryId: response.items[0].sys.id}, {include: 7});
|
|
128
|
+
const resolved = contentfulResolveResponse(references);
|
|
129
|
+
const allCategories = {};
|
|
130
|
+
|
|
131
|
+
for (const category of resolved) {
|
|
132
|
+
if (!category?.fields?.children?.de) {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const children = category.fields.children.de || [];
|
|
137
|
+
|
|
138
|
+
for (const child of children) {
|
|
139
|
+
getAllTagsFromCategory(child, allCategories);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return Object.values(allCategories);
|
|
144
|
+
}),
|
|
145
|
+
]).then(([tags, categories]) => {
|
|
111
146
|
setLoading(false);
|
|
112
|
-
|
|
147
|
+
setTags(tags.items);
|
|
148
|
+
setCategories(categories);
|
|
113
149
|
});
|
|
114
150
|
}, [debouncedSearch, portal, locale]);
|
|
115
151
|
|
|
@@ -117,7 +153,7 @@ const LogicEditorInner = ({
|
|
|
117
153
|
const orTags = selectedTags.filter((t) => t.type === "or");
|
|
118
154
|
|
|
119
155
|
return <div className="flex flex-col gap-2 p-4">
|
|
120
|
-
<div className="
|
|
156
|
+
<div className="z-10 flex w-full flex-col gap-4 border-b border-gray-200 bg-white py-4">
|
|
121
157
|
<div className="flex w-full flex-row items-center gap-2" style={{minHeight: 36}}>
|
|
122
158
|
<SectionHeading style={{marginBottom: 0}}>Gewählte Zeitpunkte:</SectionHeading>
|
|
123
159
|
<div className="flex flex-row items-center gap-2">
|
|
@@ -159,53 +195,55 @@ const LogicEditorInner = ({
|
|
|
159
195
|
</div>
|
|
160
196
|
<div className="flex w-full flex-row items-center gap-2" style={{minHeight: 36}}>
|
|
161
197
|
<SectionHeading style={{marginBottom: 0}}>Gewählte Kategorien & Tags:</SectionHeading>
|
|
162
|
-
<div className="grid
|
|
163
|
-
<div>
|
|
164
|
-
<
|
|
198
|
+
<div className="grid grid-cols-2 gap-4">
|
|
199
|
+
<div className="flex flex-col gap-2">
|
|
200
|
+
<div>
|
|
201
|
+
<SectionHeading style={{marginBottom: 0}}>Oder</SectionHeading>
|
|
202
|
+
</div>
|
|
203
|
+
<div
|
|
204
|
+
ref={setOrNodeRef}
|
|
205
|
+
style={{
|
|
206
|
+
minHeight: 36,
|
|
207
|
+
backgroundColor: isOrOver ? "rgba(0, 255, 0, 0.3)" : "transparent",
|
|
208
|
+
}}
|
|
209
|
+
className="flex h-full w-full flex-row flex-wrap gap-2"
|
|
210
|
+
>
|
|
211
|
+
{orTags.map((tag) => {
|
|
212
|
+
return <DraggablePill
|
|
213
|
+
key={tag.id}
|
|
214
|
+
id={tag.id}
|
|
215
|
+
variant="active"
|
|
216
|
+
label={(`${tag.label}`)}
|
|
217
|
+
onClose={() => {
|
|
218
|
+
setSelectedTags(selectedTags.filter((t) => t.id !== tag.id));
|
|
219
|
+
}}
|
|
220
|
+
/>;
|
|
221
|
+
})}
|
|
222
|
+
</div>
|
|
165
223
|
</div>
|
|
166
|
-
<div>
|
|
224
|
+
<div className="flex flex-col gap-2">
|
|
167
225
|
<SectionHeading style={{marginBottom: 0}}>Und</SectionHeading>
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
<div
|
|
190
|
-
ref={setAndNodeRef}
|
|
191
|
-
style={{
|
|
192
|
-
minHeight: 36,
|
|
193
|
-
backgroundColor: isAndOver ? "rgba(0, 255, 0, 0.3)" : "transparent",
|
|
194
|
-
}}
|
|
195
|
-
className="flex w-full flex-row flex-wrap gap-2"
|
|
196
|
-
>
|
|
197
|
-
{andTags.map((tag) => {
|
|
198
|
-
return <DraggablePill
|
|
199
|
-
key={tag.id}
|
|
200
|
-
id={tag.id}
|
|
201
|
-
testId={tag.id}
|
|
202
|
-
variant="active"
|
|
203
|
-
label={(`${tag.label}`)}
|
|
204
|
-
onClose={() => {
|
|
205
|
-
setSelectedTags(selectedTags.filter((t) => t.id !== tag.id));
|
|
206
|
-
}}
|
|
207
|
-
/>;
|
|
208
|
-
})}
|
|
226
|
+
<div
|
|
227
|
+
ref={setAndNodeRef}
|
|
228
|
+
style={{
|
|
229
|
+
minHeight: 36,
|
|
230
|
+
backgroundColor: isAndOver ? "rgba(0, 255, 0, 0.3)" : "transparent",
|
|
231
|
+
}}
|
|
232
|
+
className="flex h-full w-full flex-row flex-wrap gap-2"
|
|
233
|
+
>
|
|
234
|
+
{andTags.map((tag) => {
|
|
235
|
+
return <DraggablePill
|
|
236
|
+
key={tag.id}
|
|
237
|
+
id={tag.id}
|
|
238
|
+
testId={tag.id}
|
|
239
|
+
variant="active"
|
|
240
|
+
label={(`${tag.label}`)}
|
|
241
|
+
onClose={() => {
|
|
242
|
+
setSelectedTags(selectedTags.filter((t) => t.id !== tag.id));
|
|
243
|
+
}}
|
|
244
|
+
/>;
|
|
245
|
+
})}
|
|
246
|
+
</div>
|
|
209
247
|
</div>
|
|
210
248
|
</div>
|
|
211
249
|
</div>
|
|
@@ -217,28 +255,73 @@ const LogicEditorInner = ({
|
|
|
217
255
|
/>
|
|
218
256
|
</div>
|
|
219
257
|
</div>
|
|
220
|
-
<div className="grid grid-cols-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
<
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
258
|
+
<div className="grid grid-cols-2 gap-4 overflow-y-auto">
|
|
259
|
+
<div className="flex flex-col gap-4">
|
|
260
|
+
<div>
|
|
261
|
+
<SectionHeading style={{marginBottom: 0}}>Kategorien</SectionHeading>
|
|
262
|
+
</div>
|
|
263
|
+
<div className="grid grid-cols-3 gap-4">
|
|
264
|
+
{categories?.map((category) => {
|
|
265
|
+
return (
|
|
266
|
+
<Checkbox
|
|
267
|
+
key={category.id}
|
|
268
|
+
isChecked={selectedTags.some((t) => category.tags.some((c) => c.id === t.id))}
|
|
269
|
+
onChange={(e) => {
|
|
270
|
+
let newTags = [...selectedTags];
|
|
271
|
+
|
|
272
|
+
if (e.target.checked) {
|
|
273
|
+
for (const tag of category.tags) {
|
|
274
|
+
if (!selectedTags.find((t) => t.id === tag.id)) {
|
|
275
|
+
newTags.push({
|
|
276
|
+
label: tag.label,
|
|
277
|
+
id: tag.id,
|
|
278
|
+
type: "or",
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
} else {
|
|
283
|
+
for (const tag of category.tags) {
|
|
284
|
+
newTags = newTags.filter((t) => t.id !== tag.id);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
setSelectedTags(newTags);
|
|
289
|
+
}}
|
|
290
|
+
>
|
|
291
|
+
{category.title} ({selectedTags.filter((t) => category.tags.some((c) => c.id === t.id)).length}/{category.tags.length})
|
|
292
|
+
</Checkbox>
|
|
293
|
+
);
|
|
294
|
+
})}
|
|
295
|
+
</div>
|
|
296
|
+
</div>
|
|
297
|
+
<div className="flex flex-col gap-4">
|
|
298
|
+
<div>
|
|
299
|
+
<SectionHeading style={{marginBottom: 0}}>Tags</SectionHeading>
|
|
300
|
+
</div>
|
|
301
|
+
<div className="grid grid-cols-3 gap-4">
|
|
302
|
+
{tags?.map((tag) => {
|
|
303
|
+
return (
|
|
304
|
+
<Checkbox
|
|
305
|
+
key={tag.sys.id}
|
|
306
|
+
isChecked={!!selectedTags.find((t) => t.id === tag.sys.id)}
|
|
307
|
+
onChange={(e) => {
|
|
308
|
+
if (e.target.checked) {
|
|
309
|
+
setSelectedTags([...selectedTags, {
|
|
310
|
+
label: tag.fields.title[locale],
|
|
311
|
+
id: tag.sys.id,
|
|
312
|
+
type: "or",
|
|
313
|
+
}]);
|
|
314
|
+
} else {
|
|
315
|
+
setSelectedTags(selectedTags.filter((t) => t.id !== tag.sys.id));
|
|
316
|
+
}
|
|
317
|
+
}}
|
|
318
|
+
>
|
|
319
|
+
{tag.fields.title[locale]}
|
|
320
|
+
</Checkbox>
|
|
321
|
+
);
|
|
322
|
+
})}
|
|
323
|
+
</div>
|
|
324
|
+
</div>
|
|
242
325
|
</div>
|
|
243
326
|
<div className="sticky bottom-0 flex w-full flex-row justify-between gap-2 border-t border-gray-200 bg-white py-4">
|
|
244
327
|
<Button
|
|
@@ -259,6 +342,62 @@ const LogicEditorInner = ({
|
|
|
259
342
|
</div>;
|
|
260
343
|
};
|
|
261
344
|
|
|
345
|
+
function getAllTagsFromCategory(categoryNode, allCategories = {}) {
|
|
346
|
+
if (!categoryNode || !categoryNode.fields?.children) {
|
|
347
|
+
return allCategories;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const children = categoryNode.fields.children.de || [];
|
|
351
|
+
|
|
352
|
+
allCategories[categoryNode.sys.id] = {
|
|
353
|
+
title: categoryNode.fields.title.de,
|
|
354
|
+
tags: [],
|
|
355
|
+
id: categoryNode.sys.id,
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
if (categoryNode?.fields?.tags?.de) {
|
|
359
|
+
for (const tag of categoryNode.fields.tags.de) {
|
|
360
|
+
if (!tag?.fields?.title) {
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
if (!allCategories[categoryNode.sys.id].tags.find((c) => c.id === tag.sys.id)) {
|
|
365
|
+
allCategories[categoryNode.sys.id].tags.push({
|
|
366
|
+
label: tag.fields.title.de,
|
|
367
|
+
id: tag.sys.id,
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
for (const child of children) {
|
|
374
|
+
if (!child || !child.fields) {
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (child?.fields?.tags?.de) {
|
|
379
|
+
for (const tag of child.fields.tags.de) {
|
|
380
|
+
if (!allCategories[categoryNode.sys.id].tags.find((c) => c.id === tag.sys.id)) {
|
|
381
|
+
if (!tag?.fields?.title) {
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
allCategories[categoryNode.sys.id].tags.push({
|
|
386
|
+
label: tag.fields.title.de,
|
|
387
|
+
id: tag.sys.id,
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
getAllTagsFromCategory(child, allCategories);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
allCategories[categoryNode.sys.id].tags = [...new Set(allCategories[categoryNode.sys.id].tags)];
|
|
397
|
+
|
|
398
|
+
return allCategories;
|
|
399
|
+
}
|
|
400
|
+
|
|
262
401
|
|
|
263
402
|
function DraggablePill({
|
|
264
403
|
id, ...props
|
|
@@ -276,19 +415,21 @@ function DraggablePill({
|
|
|
276
415
|
};
|
|
277
416
|
|
|
278
417
|
return (
|
|
279
|
-
<
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
418
|
+
<div>
|
|
419
|
+
<Pill
|
|
420
|
+
dragHandleComponent={
|
|
421
|
+
<DragHandle
|
|
422
|
+
label="Reorder item"
|
|
423
|
+
variant="transparent"
|
|
424
|
+
{...attributes}
|
|
425
|
+
{...listeners}
|
|
426
|
+
/>
|
|
427
|
+
}
|
|
428
|
+
isDraggable
|
|
429
|
+
ref={setNodeRef}
|
|
430
|
+
style={style}
|
|
431
|
+
{...props}
|
|
432
|
+
/>
|
|
433
|
+
</div>
|
|
293
434
|
);
|
|
294
435
|
}
|