multi-content-type-relation 2.1.1 → 2.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.
Files changed (43) hide show
  1. package/README.md +6 -0
  2. package/dist/_chunks/en-Bk9okOMP.js +0 -1
  3. package/dist/_chunks/en-Cj4T04Z2.mjs +0 -1
  4. package/dist/_chunks/fr-KHPiQOFP.mjs +0 -1
  5. package/dist/_chunks/fr-ZS3aTnjj.js +0 -1
  6. package/dist/_chunks/{index-BHcolZ4N.mjs → index-BGSdnZnr.mjs} +37 -13
  7. package/dist/_chunks/index-Bu99PZdl.js +470 -0
  8. package/dist/_chunks/{index-BtldAbIW.js → index-CEXSrD4g.js} +40 -16
  9. package/dist/_chunks/index-DEkcD0zR.mjs +470 -0
  10. package/dist/admin/index.js +1 -2
  11. package/dist/admin/index.mjs +1 -2
  12. package/dist/admin/src/components/Input/InputContentSuggestions.d.ts +1 -2
  13. package/dist/admin/src/components/Input/TableItem.d.ts +2 -3
  14. package/dist/admin/src/helpers/content.d.ts +1 -1
  15. package/dist/server/index.js +129 -61
  16. package/dist/server/index.mjs +129 -61
  17. package/dist/server/src/controllers/controller.d.ts +1 -0
  18. package/dist/server/src/controllers/index.d.ts +1 -0
  19. package/dist/server/src/index.d.ts +1 -0
  20. package/dist/server/src/interface.d.ts +2 -0
  21. package/package.json +2 -1
  22. package/dist/_chunks/en-Bk9okOMP.js.map +0 -1
  23. package/dist/_chunks/en-Cj4T04Z2.mjs.map +0 -1
  24. package/dist/_chunks/fr-KHPiQOFP.mjs.map +0 -1
  25. package/dist/_chunks/fr-ZS3aTnjj.js.map +0 -1
  26. package/dist/_chunks/index-BHcolZ4N.mjs.map +0 -1
  27. package/dist/_chunks/index-BtldAbIW.js.map +0 -1
  28. package/dist/_chunks/index-CktBIBSM.js +0 -333
  29. package/dist/_chunks/index-CktBIBSM.js.map +0 -1
  30. package/dist/_chunks/index-CxWt3llJ.js +0 -3567
  31. package/dist/_chunks/index-CxWt3llJ.js.map +0 -1
  32. package/dist/_chunks/index-CyBD50Lc.js +0 -3568
  33. package/dist/_chunks/index-CyBD50Lc.js.map +0 -1
  34. package/dist/_chunks/index-D6nv39Fp.mjs +0 -3565
  35. package/dist/_chunks/index-D6nv39Fp.mjs.map +0 -1
  36. package/dist/_chunks/index-DGcImy9s.mjs +0 -3566
  37. package/dist/_chunks/index-DGcImy9s.mjs.map +0 -1
  38. package/dist/_chunks/index-DdX2rVzB.mjs +0 -334
  39. package/dist/_chunks/index-DdX2rVzB.mjs.map +0 -1
  40. package/dist/admin/index.js.map +0 -1
  41. package/dist/admin/index.mjs.map +0 -1
  42. package/dist/server/index.js.map +0 -1
  43. package/dist/server/index.mjs.map +0 -1
@@ -2,7 +2,7 @@
2
2
  const jsxRuntime = require("react/jsx-runtime");
3
3
  const icons = require("@strapi/icons");
4
4
  const admin = require("@strapi/strapi/admin");
5
- const React = require("react");
5
+ const react = require("react");
6
6
  const designSystem = require("@strapi/design-system");
7
7
  const reactIntl = require("react-intl");
8
8
  const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
@@ -52,15 +52,22 @@ const fetchMatchingContent = async (keyword, contentTypes, locale) => {
52
52
  total
53
53
  };
54
54
  };
55
- const formatToStrapiField = (entries) => {
55
+ const formatToStrapiField = (entries, locale) => {
56
56
  if (entries.length === 0) return "";
57
- return JSON.stringify(
58
- entries.map((entry) => ({
59
- uid: entry.uid,
60
- documentId: entry.item.documentId,
61
- MRCT: true
62
- })).filter(Boolean)
57
+ const storedData = JSON.stringify(
58
+ entries.map((entry) => {
59
+ const obj = {
60
+ uid: entry.uid,
61
+ documentId: entry.item.documentId,
62
+ MRCT: true
63
+ };
64
+ if (locale) {
65
+ obj.locale = locale;
66
+ }
67
+ return obj;
68
+ }).filter(Boolean)
63
69
  );
70
+ return storedData;
64
71
  };
65
72
  const validateCurrentRelations = async (entries) => {
66
73
  const { post } = admin.getFetchClient();
@@ -109,23 +116,41 @@ const SidePanel = () => {
109
116
  model: uid,
110
117
  isSingleType
111
118
  } = admin.unstable_useContentManagerContext();
112
- const [linkedContent, setLinkedContent] = React.useState([]);
113
- const [loading, setLoading] = React.useState(false);
114
- React.useEffect(() => {
119
+ const currentLocale = new URLSearchParams(location.search).get(
120
+ "plugins[i18n][locale]"
121
+ );
122
+ const [linkedContent, setLinkedContent] = react.useState([]);
123
+ const [loading, setLoading] = react.useState(true);
124
+ const [disabled, setDisabledFeature] = react.useState(false);
125
+ react.useEffect(() => {
115
126
  const fetchRevertRelations = async () => {
116
127
  const { post } = admin.getFetchClient();
117
128
  const response = await post(`/${pluginId}/fetch-revert-relations`, {
118
129
  documentId,
119
130
  uid,
120
- isSingleType
131
+ isSingleType,
132
+ locale: currentLocale
121
133
  });
122
134
  setLinkedContent(Array.isArray(response.data) ? response.data.filter(Boolean) : []);
123
135
  setLoading(false);
124
136
  };
125
- fetchRevertRelations();
137
+ const fetchConfiguration = async () => {
138
+ const { get } = admin.getFetchClient();
139
+ const response = await get(`/${pluginId}/get-configuration`);
140
+ if (response.data.disableRevertRelations) {
141
+ setDisabledFeature(true);
142
+ setLoading(false);
143
+ } else {
144
+ fetchRevertRelations();
145
+ }
146
+ };
147
+ fetchConfiguration();
126
148
  }, []);
127
149
  if (loading)
128
150
  return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, {}) });
151
+ if (disabled) {
152
+ return /* @__PURE__ */ jsxRuntime.jsx("div", {});
153
+ }
129
154
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
130
155
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, {}),
131
156
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { width: "100%", marginTop: 4, children: [
@@ -165,7 +190,7 @@ const SidePanel = () => {
165
190
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(
166
191
  "a",
167
192
  {
168
- href: content.isSingleType ? `/admin/content-manager/single-types/${content.uid}` : `/admin/content-manager/collection-types/${content.uid}/${content.documentId}`,
193
+ href: content.isSingleType ? `/admin/content-manager/single-types/${content.uid}${currentLocale ? `?plugins[i18n][locale]=${currentLocale}` : ""}` : `/admin/content-manager/collection-types/${content.uid}/${content.documentId}${currentLocale ? `?plugins[i18n][locale]=${currentLocale}` : ""}`,
169
194
  target: "_blank",
170
195
  style: { textDecoration: "none" },
171
196
  children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -224,7 +249,7 @@ const index = {
224
249
  components: {
225
250
  Input: () => Promise.resolve().then(() => require(
226
251
  /* webpackChunkName: "input-component" */
227
- "./index-CyBD50Lc.js"
252
+ "./index-Bu99PZdl.js"
228
253
  ))
229
254
  },
230
255
  inputSize: {
@@ -330,4 +355,3 @@ exports.getContentTypeForUid = getContentTypeForUid;
330
355
  exports.index = index;
331
356
  exports.useTranslate = useTranslate;
332
357
  exports.validateCurrentRelations = validateCurrentRelations;
333
- //# sourceMappingURL=index-BtldAbIW.js.map
@@ -0,0 +1,470 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { useState, useEffect, useMemo } from "react";
3
+ import { useIntl } from "react-intl";
4
+ import { useLocation } from "react-router-dom";
5
+ import { Status, Typography, Td, IconButton, Flex, Box, Table, Thead, Tr, Th, Tbody, Loader, Field, TextInput, DesignSystemProvider } from "@strapi/design-system";
6
+ import { f as fetchMatchingContent, u as useTranslate, g as getContentTypeForUid, a as formatToStrapiField, v as validateCurrentRelations } from "./index-BGSdnZnr.mjs";
7
+ import { useSensors, useSensor, PointerSensor, DndContext, closestCenter } from "@dnd-kit/core";
8
+ import { useSortable, SortableContext, verticalListSortingStrategy, arrayMove } from "@dnd-kit/sortable";
9
+ import { Drag, Eye, Plus, Trash } from "@strapi/icons";
10
+ function useSearchedEntries(keyword, contentTypes, locale) {
11
+ const [loading, setLoading] = useState(false);
12
+ const [results, setResults] = useState([]);
13
+ const [total, setTotal] = useState(0);
14
+ async function fetchEntries() {
15
+ setResults([]);
16
+ setTotal(0);
17
+ if (loading || !keyword) return;
18
+ try {
19
+ const { data, total: total2 } = await fetchMatchingContent(
20
+ keyword,
21
+ contentTypes,
22
+ locale
23
+ );
24
+ setResults(data);
25
+ setTotal(total2);
26
+ } finally {
27
+ setLoading(false);
28
+ }
29
+ }
30
+ useEffect(() => {
31
+ const timeout = setTimeout(() => fetchEntries(), 500);
32
+ return () => clearTimeout(timeout);
33
+ }, [keyword]);
34
+ return useMemo(
35
+ () => ({
36
+ loading,
37
+ results,
38
+ total
39
+ }),
40
+ [results, total]
41
+ );
42
+ }
43
+ const PublicationState = ({
44
+ isPublished,
45
+ hasDraftAndPublish
46
+ }) => {
47
+ const { translate } = useTranslate();
48
+ const configuration = useMemo(() => {
49
+ const conf = {
50
+ variant: "alternative",
51
+ text: translate("publicationState.na")
52
+ };
53
+ if (hasDraftAndPublish) {
54
+ conf.variant = isPublished ? "success" : "secondary";
55
+ conf.text = isPublished ? translate("publicationState.published") : translate("publicationState.draft");
56
+ }
57
+ return conf;
58
+ }, [isPublished, hasDraftAndPublish, translate]);
59
+ return /* @__PURE__ */ jsx(
60
+ Status,
61
+ {
62
+ showbullet: "false",
63
+ variant: configuration.variant,
64
+ size: "S",
65
+ width: "min-content",
66
+ style: { paddingLeft: 12, paddingRight: 12 },
67
+ children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: `${configuration.variant}700`, children: configuration.text })
68
+ }
69
+ );
70
+ };
71
+ const CSS = /* @__PURE__ */ Object.freeze({
72
+ Translate: {
73
+ toString(transform) {
74
+ if (!transform) {
75
+ return;
76
+ }
77
+ const {
78
+ x,
79
+ y
80
+ } = transform;
81
+ return "translate3d(" + (x ? Math.round(x) : 0) + "px, " + (y ? Math.round(y) : 0) + "px, 0)";
82
+ }
83
+ },
84
+ Scale: {
85
+ toString(transform) {
86
+ if (!transform) {
87
+ return;
88
+ }
89
+ const {
90
+ scaleX,
91
+ scaleY
92
+ } = transform;
93
+ return "scaleX(" + scaleX + ") scaleY(" + scaleY + ")";
94
+ }
95
+ },
96
+ Transform: {
97
+ toString(transform) {
98
+ if (!transform) {
99
+ return;
100
+ }
101
+ return [CSS.Translate.toString(transform), CSS.Scale.toString(transform)].join(" ");
102
+ }
103
+ },
104
+ Transition: {
105
+ toString(_ref) {
106
+ let {
107
+ property,
108
+ duration,
109
+ easing
110
+ } = _ref;
111
+ return property + " " + duration + "ms " + easing;
112
+ }
113
+ }
114
+ });
115
+ const TableItem = ({
116
+ entry,
117
+ id,
118
+ type,
119
+ disabled,
120
+ onAdd,
121
+ onDelete
122
+ }) => {
123
+ const { translate } = useTranslate();
124
+ const contentType = getContentTypeForUid(entry.uid);
125
+ const location = useLocation();
126
+ const { setDraggableNodeRef, setDroppableNodeRef, transform, transition, attributes, listeners } = useSortable({ id });
127
+ const style = {
128
+ transform: CSS.Transform.toString(transform),
129
+ transition
130
+ };
131
+ const [currentLocale, setCurrentLocale] = useState("");
132
+ useEffect(() => {
133
+ const searchParams = new URLSearchParams(location.search);
134
+ const locale = searchParams.get("plugins[i18n][locale]");
135
+ if (!locale) return;
136
+ setCurrentLocale(locale);
137
+ }, [location]);
138
+ const goToEntry = () => {
139
+ if (!currentLocale) return;
140
+ const contentTypes = window.sessionStorage.getItem("mctr::content_types");
141
+ if (contentTypes) {
142
+ try {
143
+ const parsedContentTypes = JSON.parse(contentTypes);
144
+ if (Array.isArray(parsedContentTypes)) {
145
+ const contentType2 = parsedContentTypes.find(
146
+ (ct) => ct.uid === entry.uid
147
+ );
148
+ if (contentType2) {
149
+ const kind = contentType2.kind;
150
+ let url = "";
151
+ if (kind === "collectionType") {
152
+ url = `/admin/content-manager/collection-types/${entry.uid}/${entry.item.documentId}`;
153
+ } else {
154
+ url = `/admin/content-manager/single-types/${entry.uid}`;
155
+ }
156
+ url += `?plugins[i18n][locale]=${currentLocale}`;
157
+ window.open(url, "_blank");
158
+ return;
159
+ }
160
+ }
161
+ } catch (e) {
162
+ console.error("[MCTR] Failed to retrieve content types");
163
+ }
164
+ } else {
165
+ alert(translate("tableItem.error"));
166
+ }
167
+ };
168
+ return /* @__PURE__ */ jsxs(
169
+ "tr",
170
+ {
171
+ style,
172
+ ref: setDroppableNodeRef,
173
+ ...attributes,
174
+ children: [
175
+ /* @__PURE__ */ jsx(Td, { children: type === "selected" ? /* @__PURE__ */ jsx(IconButton, { ref: setDraggableNodeRef, ...listeners, children: /* @__PURE__ */ jsx(Drag, {}) }) : null }),
176
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { color: "neutral800", children: entry.item[entry.searchableField] }) }),
177
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { color: "neutral800", children: entry.displayName }) }),
178
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(
179
+ PublicationState,
180
+ {
181
+ isPublished: !!entry.item.publishedAt,
182
+ hasDraftAndPublish: contentType?.options?.draftAndPublish
183
+ }
184
+ ) }),
185
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsxs(Flex, { children: [
186
+ /* @__PURE__ */ jsx(
187
+ IconButton,
188
+ {
189
+ label: translate("tableItem.goToEntry"),
190
+ onClick: goToEntry,
191
+ style: { "marginRight": "5px" },
192
+ children: /* @__PURE__ */ jsx(Eye, {})
193
+ }
194
+ ),
195
+ type === "suggestion" ? /* @__PURE__ */ jsx(
196
+ IconButton,
197
+ {
198
+ label: translate("tableItem.add"),
199
+ onClick: () => onAdd(entry),
200
+ disabled,
201
+ marginLeft: 1,
202
+ children: /* @__PURE__ */ jsx(Plus, {})
203
+ }
204
+ ) : type === "selected" ? /* @__PURE__ */ jsx(
205
+ IconButton,
206
+ {
207
+ label: translate("tableItem.delete"),
208
+ onClick: () => onDelete(entry),
209
+ marginLeft: 1,
210
+ children: /* @__PURE__ */ jsx(Trash, {})
211
+ }
212
+ ) : null
213
+ ] }) })
214
+ ]
215
+ }
216
+ );
217
+ };
218
+ function InputContentSuggestions({
219
+ uniqueId,
220
+ suggestions,
221
+ selected,
222
+ onAddEntry,
223
+ onDeleteEntry,
224
+ onEntriesSorted,
225
+ maximum
226
+ }) {
227
+ const { translate } = useTranslate();
228
+ const suggestionAsSelectedEntry = useMemo(() => {
229
+ return (suggestions || []).flatMap(
230
+ (suggestion) => suggestion.results.map((entrySuggestion) => ({
231
+ displayName: suggestion.displayName,
232
+ item: entrySuggestion,
233
+ searchableField: suggestion.searchableField,
234
+ uid: suggestion.uid
235
+ }))
236
+ ).slice(0, 10);
237
+ }, [suggestions]);
238
+ const buildSelectedId = (entry) => {
239
+ return `${uniqueId}-${entry.uid}-${entry.item.documentId}`;
240
+ };
241
+ const availableSuggestions = useMemo(() => {
242
+ const selectedIdentifiers = (selected || []).map(buildSelectedId);
243
+ return suggestionAsSelectedEntry.filter(
244
+ (suggestion) => !selectedIdentifiers.includes(buildSelectedId(suggestion))
245
+ );
246
+ }, [suggestions, selected]);
247
+ const onAdd = (entry) => {
248
+ if (typeof onAddEntry === "function") {
249
+ onAddEntry(entry);
250
+ }
251
+ };
252
+ const onDelete = (entry) => {
253
+ if (typeof onDeleteEntry === "function") {
254
+ onDeleteEntry(entry);
255
+ }
256
+ };
257
+ const onSort = (entries) => {
258
+ if (typeof onEntriesSorted === "function") {
259
+ onEntriesSorted(entries);
260
+ }
261
+ };
262
+ const sensors = useSensors(
263
+ useSensor(PointerSensor)
264
+ );
265
+ const sortableItems = useMemo(() => {
266
+ const items = selected?.map((entry) => buildSelectedId(entry)) ?? [];
267
+ return items;
268
+ }, [selected]);
269
+ const handleDragEnd = (event) => {
270
+ const { active, over } = event;
271
+ if (!active || !over) return;
272
+ if (active.id !== over.id) {
273
+ const oldIndex = selected.findIndex(
274
+ (entry) => buildSelectedId(entry) === active.id
275
+ );
276
+ const newIndex = selected.findIndex(
277
+ (entry) => buildSelectedId(entry) === over.id
278
+ );
279
+ onSort(arrayMove(selected, oldIndex, newIndex));
280
+ }
281
+ };
282
+ if (!availableSuggestions?.length && !selected?.length) return null;
283
+ return /* @__PURE__ */ jsx(Box, { padding: [2, 0, 2, 0], background: "neutral100", children: /* @__PURE__ */ jsxs(Table, { style: { whiteSpace: "unset", borderCollapse: "separate", borderSpacing: "0 10px" }, children: [
284
+ /* @__PURE__ */ jsx(Thead, { children: /* @__PURE__ */ jsxs(Tr, { children: [
285
+ /* @__PURE__ */ jsx(Th, {}),
286
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: translate("contentSuggestions.title") }) }),
287
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: translate("contentSuggestions.contentType") }) }),
288
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: translate("contentSuggestions.state") }) })
289
+ ] }) }),
290
+ /* @__PURE__ */ jsxs(Tbody, { children: [
291
+ selected?.length ? /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
292
+ DndContext,
293
+ {
294
+ sensors,
295
+ collisionDetection: closestCenter,
296
+ onDragEnd: handleDragEnd,
297
+ children: /* @__PURE__ */ jsx(
298
+ SortableContext,
299
+ {
300
+ items: sortableItems,
301
+ strategy: verticalListSortingStrategy,
302
+ children: selected.map((entry) => /* @__PURE__ */ jsx(
303
+ TableItem,
304
+ {
305
+ id: buildSelectedId(entry),
306
+ entry,
307
+ type: "selected",
308
+ onDelete
309
+ },
310
+ buildSelectedId(entry)
311
+ ))
312
+ }
313
+ )
314
+ }
315
+ ) }) : null,
316
+ availableSuggestions.length && selected?.length ? /* @__PURE__ */ jsx(Tr, { children: /* @__PURE__ */ jsx(Td, { colSpan: 5, children: /* @__PURE__ */ jsx("hr", { style: { width: "100%" } }) }) }) : null,
317
+ availableSuggestions.map((entry) => /* @__PURE__ */ jsx(
318
+ TableItem,
319
+ {
320
+ id: buildSelectedId(entry),
321
+ entry,
322
+ type: "suggestion",
323
+ onAdd,
324
+ disabled: typeof maximum === "number" ? (selected?.length ?? 0) >= maximum : false
325
+ },
326
+ buildSelectedId(entry)
327
+ ))
328
+ ] })
329
+ ] }) });
330
+ }
331
+ const MainInput = ({
332
+ name,
333
+ error,
334
+ description,
335
+ onChange,
336
+ value,
337
+ labelAction,
338
+ label,
339
+ attribute,
340
+ required
341
+ }) => {
342
+ const { formatMessage } = useIntl();
343
+ const { translate } = useTranslate();
344
+ const location = useLocation();
345
+ const maximumItems = attribute.options.max;
346
+ const minimumItems = attribute.options.min || 0;
347
+ const currentLocale = new URLSearchParams(location.search).get(
348
+ "plugins[i18n][locale]"
349
+ );
350
+ const [keyword, setKeyword] = useState("");
351
+ const [selected, setSelected] = useState([]);
352
+ const [loading, setLoading] = useState(true);
353
+ useEffect(() => {
354
+ const value2 = selected.length > maximumItems || selected.length < minimumItems ? [] : selected;
355
+ onChange({ target: { name, value: formatToStrapiField(value2, currentLocale) } });
356
+ }, [selected]);
357
+ const hint = useMemo(() => {
358
+ const minLabel = minimumItems > 0 ? `${translate("input.hint.min")} ${minimumItems} ${minimumItems > 1 ? translate("input.hint.entries") : translate("input.hint.entry")}` : "";
359
+ const maxLabel = maximumItems > 0 ? `${translate("input.hint.max")} ${maximumItems} ${maximumItems > 1 ? translate("input.hint.entries") : translate("input.hint.entry")}` : "";
360
+ return `
361
+ ${minLabel ? `${minLabel}` : ""}
362
+ ${minLabel && maxLabel ? ", " : ""}
363
+ ${maxLabel}
364
+ ${minLabel || maxLabel ? translate("input.hint.separator") : ""}
365
+ ${selected.length} ${translate("input.hint.selected")}
366
+ `;
367
+ }, [selected, maximumItems, minimumItems, translate]);
368
+ const inputError = useMemo(() => {
369
+ if (!error) return "";
370
+ if (selected.length < minimumItems)
371
+ return `${error} - ${translate("input.error.min")} ${minimumItems} ${translate("input.error.required")}`;
372
+ if (selected.length > maximumItems)
373
+ return `${error} - ${translate("input.error.max")} ${maximumItems} ${translate("input.error.required")}`;
374
+ return error;
375
+ }, [error, maximumItems, minimumItems, selected, translate]);
376
+ const { loading: searchLoading, results } = useSearchedEntries(
377
+ keyword,
378
+ attribute.options.contentTypes,
379
+ currentLocale
380
+ );
381
+ useEffect(() => {
382
+ async function validateContent() {
383
+ if (!value) {
384
+ setLoading(false);
385
+ return;
386
+ }
387
+ const entries = JSON.parse(value);
388
+ const result = await validateCurrentRelations(entries);
389
+ setSelected(result);
390
+ setLoading(false);
391
+ }
392
+ validateContent();
393
+ }, []);
394
+ const onAddEntry = (entry) => {
395
+ const alreadyDefined = selected.some(
396
+ (selectedEntry) => selectedEntry.uid === entry.uid && selectedEntry.item.id === entry.item.id
397
+ );
398
+ if (alreadyDefined) return;
399
+ setSelected([...selected, entry]);
400
+ };
401
+ const onDeleteEntry = (entry) => {
402
+ const newSelected = selected.filter(
403
+ (selectedEntry) => !(selectedEntry.uid === entry.uid && selectedEntry.item.id === entry.item.id)
404
+ );
405
+ setSelected(newSelected);
406
+ };
407
+ const onEntriesSorted = (entries) => {
408
+ setSelected(entries);
409
+ };
410
+ if (loading) return /* @__PURE__ */ jsx(Loader, {});
411
+ return /* @__PURE__ */ jsxs(
412
+ Field.Root,
413
+ {
414
+ name,
415
+ id: name,
416
+ error,
417
+ hint: description,
418
+ required,
419
+ children: [
420
+ /* @__PURE__ */ jsx(Field.Label, { action: labelAction, children: label }),
421
+ /* @__PURE__ */ jsx(
422
+ TextInput,
423
+ {
424
+ placeholder: translate("input.placeholder"),
425
+ required,
426
+ hint,
427
+ error: inputError,
428
+ value: keyword,
429
+ onChange: (e) => setKeyword(e.target.value)
430
+ }
431
+ ),
432
+ searchLoading ? /* @__PURE__ */ jsx(Loader, {}) : /* @__PURE__ */ jsx(
433
+ InputContentSuggestions,
434
+ {
435
+ uniqueId: Date.now(),
436
+ suggestions: results,
437
+ selected,
438
+ onAddEntry,
439
+ onDeleteEntry,
440
+ onEntriesSorted,
441
+ maximum: maximumItems
442
+ }
443
+ )
444
+ ]
445
+ }
446
+ );
447
+ };
448
+ const Index = (props) => {
449
+ const { locale } = useIntl();
450
+ const theme = useMemo(() => ({}), []);
451
+ const attribute = useMemo(() => {
452
+ if (!props.attribute) return props.attribute;
453
+ if (!props.attribute.options) return props.attribute;
454
+ if (!props.attribute.options.contentTypes) return props.attribute;
455
+ const contentTypes = Object.keys(
456
+ props.attribute.options.contentTypes
457
+ ).filter((key) => props.attribute.options.contentTypes[key]);
458
+ return {
459
+ ...props.attribute,
460
+ options: {
461
+ ...props.attribute.options,
462
+ contentTypes: contentTypes.join(",")
463
+ }
464
+ };
465
+ }, [props.attribute]);
466
+ return /* @__PURE__ */ jsx(DesignSystemProvider, { theme, children: /* @__PURE__ */ jsx(MainInput, { ...props, attribute }) });
467
+ };
468
+ export {
469
+ Index as default
470
+ };
@@ -1,4 +1,3 @@
1
1
  "use strict";
2
- const index = require("../_chunks/index-BtldAbIW.js");
2
+ const index = require("../_chunks/index-CEXSrD4g.js");
3
3
  module.exports = index.index;
4
- //# sourceMappingURL=index.js.map
@@ -1,5 +1,4 @@
1
- import { i } from "../_chunks/index-DdX2rVzB.mjs";
1
+ import { i } from "../_chunks/index-BGSdnZnr.mjs";
2
2
  export {
3
3
  i as default
4
4
  };
5
- //# sourceMappingURL=index.mjs.map
@@ -6,8 +6,7 @@ type Props = {
6
6
  onAddEntry?(entry: SelectedEntry): void;
7
7
  onDeleteEntry?(entry: SelectedEntry): void;
8
8
  onEntriesSorted?(entries: SelectedEntry[]): void;
9
- sortable?: boolean;
10
9
  maximum?: number;
11
10
  };
12
- export declare function InputContentSuggestions({ uniqueId, suggestions, selected, onAddEntry, onDeleteEntry, onEntriesSorted, maximum, sortable }: Props): import("react/jsx-runtime").JSX.Element | null;
11
+ export declare function InputContentSuggestions({ uniqueId, suggestions, selected, onAddEntry, onDeleteEntry, onEntriesSorted, maximum, }: Props): import("react/jsx-runtime").JSX.Element | null;
13
12
  export {};
@@ -1,12 +1,11 @@
1
1
  import { SelectedEntry } from '../../interface';
2
2
  type Props = {
3
3
  entry: SelectedEntry;
4
+ id: string;
4
5
  type: 'suggestion' | 'selected';
5
- uniqueId: number;
6
6
  onAdd?(entry: SelectedEntry): void;
7
7
  onDelete?(entry: SelectedEntry): void;
8
8
  disabled?: boolean;
9
- sortable?: boolean;
10
9
  };
11
- export declare const TableItem: ({ entry, type, uniqueId, disabled, onAdd, onDelete }: Props) => import("react/jsx-runtime").JSX.Element;
10
+ export declare const TableItem: ({ entry, id, type, disabled, onAdd, onDelete }: Props) => import("react/jsx-runtime").JSX.Element;
12
11
  export {};
@@ -1,5 +1,5 @@
1
1
  import { FormattedStrapiEntry, MatchingContentResponse, SelectedEntry } from '../interface';
2
2
  export declare const fetchMatchingContent: (keyword: string, contentTypes: string, locale: string) => Promise<MatchingContentResponse>;
3
- export declare const formatToStrapiField: (entries: SelectedEntry[]) => string;
3
+ export declare const formatToStrapiField: (entries: SelectedEntry[], locale: string) => string;
4
4
  export declare const validateCurrentRelations: (entries: FormattedStrapiEntry[]) => Promise<SelectedEntry[]>;
5
5
  export declare const listContentTypes: () => Promise<any>;