multi-content-type-relation 0.1.0 → 2.0.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 (98) hide show
  1. package/dist/_chunks/en-Bk9okOMP.js +32 -0
  2. package/dist/_chunks/en-Cj4T04Z2.mjs +32 -0
  3. package/dist/_chunks/fr-KHPiQOFP.mjs +32 -0
  4. package/dist/_chunks/fr-ZS3aTnjj.js +32 -0
  5. package/dist/_chunks/index-5liGVtQX.js +3566 -0
  6. package/dist/_chunks/index-CQ_pNHWj.js +335 -0
  7. package/dist/_chunks/index-Cyd6H1uV.mjs +336 -0
  8. package/dist/_chunks/index-D3M5NaOA.mjs +3564 -0
  9. package/dist/admin/index.js +3 -0
  10. package/dist/admin/index.mjs +4 -0
  11. package/dist/admin/src/components/Input/InputContentSuggestions.d.ts +13 -0
  12. package/dist/admin/src/components/Input/MainInput.d.ts +16 -0
  13. package/dist/admin/src/components/Input/PublicationState.d.ts +6 -0
  14. package/dist/admin/src/components/Input/TableItem.d.ts +12 -0
  15. package/dist/admin/src/components/Input/index.d.ts +2 -0
  16. package/dist/admin/src/components/PluginIcon/index.d.ts +2 -0
  17. package/dist/admin/src/components/SidePanel/SidePanel.d.ts +7 -0
  18. package/dist/admin/src/helpers/content.d.ts +5 -0
  19. package/dist/admin/src/helpers/storage.d.ts +15 -0
  20. package/dist/admin/src/hooks/useSearchedEntries.d.ts +6 -0
  21. package/dist/admin/src/hooks/useTranslate.d.ts +4 -0
  22. package/dist/admin/src/index.d.ts +9 -0
  23. package/dist/admin/src/interface.d.ts +33 -0
  24. package/dist/admin/src/pluginId.d.ts +2 -0
  25. package/dist/server/index.js +506 -25
  26. package/dist/server/index.mjs +509 -0
  27. package/dist/server/src/bootstrap.d.ts +5 -0
  28. package/dist/server/src/config/index.d.ts +13 -0
  29. package/dist/server/src/content-types/index.d.ts +35 -0
  30. package/dist/server/src/content-types/mctr-relation/index.d.ts +33 -0
  31. package/dist/server/src/content-types/mctr-relation/schema.d.ts +31 -0
  32. package/dist/server/src/controllers/controller.d.ts +27 -0
  33. package/dist/server/src/controllers/index.d.ts +28 -0
  34. package/dist/server/src/destroy.d.ts +5 -0
  35. package/dist/server/src/helpers/index.d.ts +2 -0
  36. package/dist/server/src/index.d.ts +113 -0
  37. package/dist/server/src/interface.d.ts +42 -0
  38. package/dist/server/src/middlewares/index.d.ts +4 -0
  39. package/dist/server/src/middlewares/middleware.d.ts +2 -0
  40. package/dist/server/src/policies/index.d.ts +2 -0
  41. package/dist/server/src/register.d.ts +5 -0
  42. package/dist/server/src/routes/index.d.ts +18 -0
  43. package/dist/server/src/services/index.d.ts +8 -0
  44. package/dist/server/src/services/service.d.ts +7 -0
  45. package/dist/server/src/utils.d.ts +3 -0
  46. package/package.json +55 -27
  47. package/TODO.md +0 -4
  48. package/admin/src/components/Input/InputContentSuggestions.tsx +0 -162
  49. package/admin/src/components/Input/MainInput.tsx +0 -135
  50. package/admin/src/components/Input/PublicationState.tsx +0 -28
  51. package/admin/src/components/Input/TableItem.tsx +0 -109
  52. package/admin/src/components/Input/index.tsx +0 -27
  53. package/admin/src/components/PluginIcon/index.tsx +0 -12
  54. package/admin/src/helpers/content.ts +0 -60
  55. package/admin/src/helpers/storage.ts +0 -32
  56. package/admin/src/hooks/useSearchedEntries.ts +0 -41
  57. package/admin/src/index.tsx +0 -140
  58. package/admin/src/interface.ts +0 -37
  59. package/admin/src/pluginId.ts +0 -5
  60. package/admin/src/translations/en.json +0 -1
  61. package/admin/src/translations/fr.json +0 -1
  62. package/admin/src/utils/getTrad.ts +0 -5
  63. package/dist/server/bootstrap.js +0 -5
  64. package/dist/server/config/index.js +0 -27
  65. package/dist/server/content-types/index.js +0 -3
  66. package/dist/server/controllers/controller.js +0 -92
  67. package/dist/server/controllers/index.js +0 -9
  68. package/dist/server/destroy.js +0 -5
  69. package/dist/server/interface.js +0 -2
  70. package/dist/server/middlewares/index.js +0 -9
  71. package/dist/server/middlewares/middleware.js +0 -163
  72. package/dist/server/policies/index.js +0 -3
  73. package/dist/server/register.js +0 -15
  74. package/dist/server/routes/index.js +0 -29
  75. package/dist/server/services/index.js +0 -9
  76. package/dist/server/services/service.js +0 -8
  77. package/dist/server/utils.js +0 -15
  78. package/dist/tsconfig.server.tsbuildinfo +0 -1
  79. package/server/bootstrap.ts +0 -5
  80. package/server/config/index.ts +0 -28
  81. package/server/content-types/index.ts +0 -1
  82. package/server/controllers/controller.ts +0 -107
  83. package/server/controllers/index.ts +0 -5
  84. package/server/destroy.ts +0 -5
  85. package/server/index.ts +0 -23
  86. package/server/interface.ts +0 -50
  87. package/server/middlewares/index.ts +0 -5
  88. package/server/middlewares/middleware.ts +0 -197
  89. package/server/policies/index.ts +0 -1
  90. package/server/register.ts +0 -14
  91. package/server/routes/index.ts +0 -27
  92. package/server/services/index.ts +0 -5
  93. package/server/services/service.ts +0 -11
  94. package/server/utils.ts +0 -14
  95. package/strapi-admin.js +0 -3
  96. package/strapi-server.js +0 -3
  97. package/tsconfig.json +0 -20
  98. package/tsconfig.server.json +0 -25
@@ -0,0 +1,335 @@
1
+ "use strict";
2
+ const jsxRuntime = require("react/jsx-runtime");
3
+ const icons = require("@strapi/icons");
4
+ const admin = require("@strapi/strapi/admin");
5
+ const React = require("react");
6
+ const designSystem = require("@strapi/design-system");
7
+ const reactIntl = require("react-intl");
8
+ const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
9
+ const v = glob[path];
10
+ if (v) {
11
+ return typeof v === "function" ? v() : Promise.resolve(v);
12
+ }
13
+ return new Promise((_, reject) => {
14
+ (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
15
+ reject.bind(
16
+ null,
17
+ new Error(
18
+ "Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
19
+ )
20
+ )
21
+ );
22
+ });
23
+ };
24
+ const name$1 = "multi-content-type-relation";
25
+ const strapi = {
26
+ name: "multi-content-type-relation"
27
+ };
28
+ const pluginPkg = {
29
+ name: name$1,
30
+ strapi
31
+ };
32
+ const PluginIcon = () => /* @__PURE__ */ jsxRuntime.jsx(icons.PuzzlePiece, {});
33
+ const pluginId = pluginPkg.name.replace(
34
+ /^(@[^-,.][\w,-]+\/|strapi-)plugin-/i,
35
+ ""
36
+ );
37
+ const fetchMatchingContent = async (keyword, contentTypes, locale) => {
38
+ const { post } = admin.getFetchClient();
39
+ const response = await post(`/${pluginId}/get-content`, {
40
+ contentTypes: contentTypes.split(","),
41
+ keyword,
42
+ locale
43
+ });
44
+ const data = response.data;
45
+ if (!data) throw new Error("No data returned from API");
46
+ const total = data.reduce((accumulator, option) => {
47
+ if (!option.results) return accumulator;
48
+ return accumulator + option.results.length;
49
+ }, 0);
50
+ return {
51
+ data,
52
+ total
53
+ };
54
+ };
55
+ const formatToStrapiField = (entries) => {
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)
63
+ );
64
+ };
65
+ const validateCurrentRelations = async (entries) => {
66
+ const { post } = admin.getFetchClient();
67
+ const response = await post(`/${pluginId}/validate-relations`, {
68
+ entries
69
+ });
70
+ return response.data;
71
+ };
72
+ const listContentTypes = async () => {
73
+ try {
74
+ const { get } = admin.getFetchClient();
75
+ const response = await get(`/${pluginId}/list-content-types`);
76
+ return response.data;
77
+ } catch (error) {
78
+ console.error(error);
79
+ return [];
80
+ }
81
+ };
82
+ const STORAGE_KEY = "mctr::content_types";
83
+ function getContentTypes() {
84
+ const raw = sessionStorage.getItem(STORAGE_KEY);
85
+ return raw ? JSON.parse(raw) : void 0;
86
+ }
87
+ function getContentTypeForUid(uid) {
88
+ const contentTypes = getContentTypes();
89
+ if (!Array.isArray(contentTypes)) return;
90
+ return contentTypes.find((contentType) => contentType.uid === uid);
91
+ }
92
+ function setContentTypes(contentTypes) {
93
+ const stringified = JSON.stringify(contentTypes);
94
+ sessionStorage.setItem(STORAGE_KEY, stringified);
95
+ }
96
+ const useTranslate = () => {
97
+ const { formatMessage } = reactIntl.useIntl();
98
+ const translate = (key, values) => {
99
+ return formatMessage({ id: key }, values);
100
+ };
101
+ return {
102
+ translate
103
+ };
104
+ };
105
+ const SidePanel = () => {
106
+ const { translate } = useTranslate();
107
+ const {
108
+ id: documentId,
109
+ model: uid,
110
+ isSingleType
111
+ } = admin.unstable_useContentManagerContext();
112
+ const [linkedContent, setLinkedContent] = React.useState([]);
113
+ const [loading, setLoading] = React.useState(false);
114
+ React.useEffect(() => {
115
+ const fetchRevertRelations = async () => {
116
+ const { post } = admin.getFetchClient();
117
+ const response = await post(`/${pluginId}/fetch-revert-relations`, {
118
+ documentId,
119
+ uid,
120
+ isSingleType
121
+ });
122
+ setLinkedContent(response.data);
123
+ setLoading(false);
124
+ };
125
+ fetchRevertRelations();
126
+ }, []);
127
+ if (loading)
128
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, {}) });
129
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
130
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, {}),
131
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { width: "100%", marginTop: 4, children: [
132
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(
133
+ designSystem.Typography,
134
+ {
135
+ variant: "sigma",
136
+ fontWeight: "bold",
137
+ textTransform: "uppercase",
138
+ marginBottom: 1,
139
+ textColor: "neutral600",
140
+ children: translate("sidePanel.linkedContent")
141
+ }
142
+ ) }),
143
+ linkedContent.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "omega", textColor: "neutral600", marginBottom: 3, children: [
144
+ translate("sidePanel.referencedIn"),
145
+ " ",
146
+ linkedContent.length,
147
+ " ",
148
+ translate("sidePanel.otherContents")
149
+ ] }) }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", textColor: "neutral600", marginBottom: 3, children: translate("sidePanel.notReferenced") }) }),
150
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 2, children: linkedContent.map((content, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
151
+ designSystem.Box,
152
+ {
153
+ marginBottom: idx < linkedContent.length - 1 ? 3 : 0,
154
+ children: [
155
+ /* @__PURE__ */ jsxRuntime.jsxs(
156
+ designSystem.Flex,
157
+ {
158
+ direction: "row",
159
+ justifyContent: "space-between",
160
+ alignItems: "flex-start",
161
+ paddingY: 2,
162
+ paddingX: 3,
163
+ children: [
164
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
165
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(
166
+ "a",
167
+ {
168
+ href: content.isSingleType ? `/admin/content-manager/single-types/${content.uid}` : `/admin/content-manager/collection-types/${content.uid}/${content.documentId}`,
169
+ target: "_blank",
170
+ style: { textDecoration: "none" },
171
+ children: /* @__PURE__ */ jsxRuntime.jsx(
172
+ designSystem.Typography,
173
+ {
174
+ variant: "beta",
175
+ fontWeight: "bold",
176
+ textColor: "neutral800",
177
+ children: content.title
178
+ }
179
+ )
180
+ }
181
+ ) }),
182
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsxs(
183
+ designSystem.Typography,
184
+ {
185
+ variant: "pi",
186
+ textColor: "neutral600",
187
+ style: { lineHeight: 1.2 },
188
+ children: [
189
+ translate("sidePanel.field"),
190
+ " ",
191
+ content.field
192
+ ]
193
+ }
194
+ ) })
195
+ ] }),
196
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginLeft: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.CardBadge, { children: content.type }) })
197
+ ]
198
+ }
199
+ ),
200
+ idx < linkedContent.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginY: 1, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, {}) })
201
+ ]
202
+ },
203
+ content.documentId
204
+ )) })
205
+ ] })
206
+ ] });
207
+ };
208
+ const name = pluginPkg.strapi.name;
209
+ const index = {
210
+ async register(app) {
211
+ const contentTypes = await listContentTypes();
212
+ setContentTypes(contentTypes);
213
+ app.customFields.register({
214
+ name,
215
+ pluginId,
216
+ type: "richtext",
217
+ intlLabel: {
218
+ id: "multi-content-type-relation.text-ai.label",
219
+ defaultMessage: "Multi Content Type Relation"
220
+ },
221
+ intlDescription: {
222
+ id: "multi-content-type-relation.text-ai.description",
223
+ defaultMessage: "Write content types separated by commas"
224
+ },
225
+ icon: PluginIcon,
226
+ // don't forget to create/import your icon component
227
+ components: {
228
+ Input: () => Promise.resolve().then(() => require(
229
+ /* webpackChunkName: "input-component" */
230
+ "./index-5liGVtQX.js"
231
+ ))
232
+ },
233
+ inputSize: {
234
+ default: 12,
235
+ isResizable: false
236
+ },
237
+ options: {
238
+ base: [
239
+ /*
240
+ Declare settings to be added to the "Base settings" section
241
+ of the field in the Content-Type Builder
242
+ */
243
+ {
244
+ sectionTitle: {
245
+ id: "multi-content-type-relation.text-ai.length",
246
+ defaultMessage: "Content types"
247
+ },
248
+ items: contentTypes.map((contentType) => {
249
+ const value = contentType.info.singularName;
250
+ return {
251
+ intlLabel: {
252
+ id: `multi-content-type-relation.options.${contentType.uid}`,
253
+ defaultMessage: contentType.info.displayName
254
+ },
255
+ type: "checkbox",
256
+ name: `options.contentTypes.${value}`
257
+ };
258
+ })
259
+ }
260
+ ],
261
+ advanced: [
262
+ {
263
+ sectionTitle: {
264
+ id: "global.settings",
265
+ defaultMessage: "Settings"
266
+ },
267
+ items: [
268
+ {
269
+ name: "required",
270
+ type: "checkbox",
271
+ intlLabel: {
272
+ id: "content-type-relation-select.options.advanced.requiredField",
273
+ defaultMessage: "Required field"
274
+ },
275
+ description: {
276
+ id: "content-type-relation-select.options.advanced.requiredField.description",
277
+ defaultMessage: "You won't be able to create an entry if this field is empty"
278
+ }
279
+ },
280
+ {
281
+ name: "options.min",
282
+ type: "number",
283
+ intlLabel: {
284
+ id: "content-type-relation-select.options.advanced.minField",
285
+ defaultMessage: "Minimum values"
286
+ },
287
+ description: {
288
+ id: "content-type-relation-select.options.advanced.minField.description",
289
+ defaultMessage: "Minimum number of entries"
290
+ }
291
+ },
292
+ {
293
+ name: "options.max",
294
+ type: "number",
295
+ intlLabel: {
296
+ id: "content-type-relation-select.options.advanced.maxField",
297
+ defaultMessage: "Maximum values"
298
+ },
299
+ description: {
300
+ id: "content-type-relation-select.options.advanced.maxField.description",
301
+ defaultMessage: "Maximum number of entries"
302
+ }
303
+ }
304
+ ]
305
+ }
306
+ ]
307
+ }
308
+ });
309
+ },
310
+ bootstrap(app) {
311
+ app.getPlugin("content-manager").injectComponent("editView", "right-links", {
312
+ name: "side-panel",
313
+ Component: SidePanel
314
+ });
315
+ },
316
+ async registerTrads(app) {
317
+ const { locales } = app;
318
+ const importedTrads = await Promise.all(
319
+ locales.map(async (locale) => {
320
+ const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-Bk9okOMP.js")), "./translations/fr.json": () => Promise.resolve().then(() => require("./fr-ZS3aTnjj.js")) }), `./translations/${locale}.json`, 3);
321
+ return {
322
+ data,
323
+ locale
324
+ };
325
+ })
326
+ );
327
+ return Promise.resolve(importedTrads);
328
+ }
329
+ };
330
+ exports.fetchMatchingContent = fetchMatchingContent;
331
+ exports.formatToStrapiField = formatToStrapiField;
332
+ exports.getContentTypeForUid = getContentTypeForUid;
333
+ exports.index = index;
334
+ exports.useTranslate = useTranslate;
335
+ exports.validateCurrentRelations = validateCurrentRelations;
@@ -0,0 +1,336 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { PuzzlePiece } from "@strapi/icons";
3
+ import { getFetchClient, unstable_useContentManagerContext } from "@strapi/strapi/admin";
4
+ import { useState, useEffect } from "react";
5
+ import { Box, Loader, Divider, Flex, Typography, CardBadge } from "@strapi/design-system";
6
+ import { useIntl } from "react-intl";
7
+ const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
8
+ const v = glob[path];
9
+ if (v) {
10
+ return typeof v === "function" ? v() : Promise.resolve(v);
11
+ }
12
+ return new Promise((_, reject) => {
13
+ (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
14
+ reject.bind(
15
+ null,
16
+ new Error(
17
+ "Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
18
+ )
19
+ )
20
+ );
21
+ });
22
+ };
23
+ const name$1 = "multi-content-type-relation";
24
+ const strapi = {
25
+ name: "multi-content-type-relation"
26
+ };
27
+ const pluginPkg = {
28
+ name: name$1,
29
+ strapi
30
+ };
31
+ const PluginIcon = () => /* @__PURE__ */ jsx(PuzzlePiece, {});
32
+ const pluginId = pluginPkg.name.replace(
33
+ /^(@[^-,.][\w,-]+\/|strapi-)plugin-/i,
34
+ ""
35
+ );
36
+ const fetchMatchingContent = async (keyword, contentTypes, locale) => {
37
+ const { post } = getFetchClient();
38
+ const response = await post(`/${pluginId}/get-content`, {
39
+ contentTypes: contentTypes.split(","),
40
+ keyword,
41
+ locale
42
+ });
43
+ const data = response.data;
44
+ if (!data) throw new Error("No data returned from API");
45
+ const total = data.reduce((accumulator, option) => {
46
+ if (!option.results) return accumulator;
47
+ return accumulator + option.results.length;
48
+ }, 0);
49
+ return {
50
+ data,
51
+ total
52
+ };
53
+ };
54
+ const formatToStrapiField = (entries) => {
55
+ if (entries.length === 0) return "";
56
+ return JSON.stringify(
57
+ entries.map((entry) => ({
58
+ uid: entry.uid,
59
+ documentId: entry.item.documentId,
60
+ MRCT: true
61
+ })).filter(Boolean)
62
+ );
63
+ };
64
+ const validateCurrentRelations = async (entries) => {
65
+ const { post } = getFetchClient();
66
+ const response = await post(`/${pluginId}/validate-relations`, {
67
+ entries
68
+ });
69
+ return response.data;
70
+ };
71
+ const listContentTypes = async () => {
72
+ try {
73
+ const { get } = getFetchClient();
74
+ const response = await get(`/${pluginId}/list-content-types`);
75
+ return response.data;
76
+ } catch (error) {
77
+ console.error(error);
78
+ return [];
79
+ }
80
+ };
81
+ const STORAGE_KEY = "mctr::content_types";
82
+ function getContentTypes() {
83
+ const raw = sessionStorage.getItem(STORAGE_KEY);
84
+ return raw ? JSON.parse(raw) : void 0;
85
+ }
86
+ function getContentTypeForUid(uid) {
87
+ const contentTypes = getContentTypes();
88
+ if (!Array.isArray(contentTypes)) return;
89
+ return contentTypes.find((contentType) => contentType.uid === uid);
90
+ }
91
+ function setContentTypes(contentTypes) {
92
+ const stringified = JSON.stringify(contentTypes);
93
+ sessionStorage.setItem(STORAGE_KEY, stringified);
94
+ }
95
+ const useTranslate = () => {
96
+ const { formatMessage } = useIntl();
97
+ const translate = (key, values) => {
98
+ return formatMessage({ id: key }, values);
99
+ };
100
+ return {
101
+ translate
102
+ };
103
+ };
104
+ const SidePanel = () => {
105
+ const { translate } = useTranslate();
106
+ const {
107
+ id: documentId,
108
+ model: uid,
109
+ isSingleType
110
+ } = unstable_useContentManagerContext();
111
+ const [linkedContent, setLinkedContent] = useState([]);
112
+ const [loading, setLoading] = useState(false);
113
+ useEffect(() => {
114
+ const fetchRevertRelations = async () => {
115
+ const { post } = getFetchClient();
116
+ const response = await post(`/${pluginId}/fetch-revert-relations`, {
117
+ documentId,
118
+ uid,
119
+ isSingleType
120
+ });
121
+ setLinkedContent(response.data);
122
+ setLoading(false);
123
+ };
124
+ fetchRevertRelations();
125
+ }, []);
126
+ if (loading)
127
+ return /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsx(Loader, {}) });
128
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
129
+ /* @__PURE__ */ jsx(Divider, {}),
130
+ /* @__PURE__ */ jsxs(Box, { width: "100%", marginTop: 4, children: [
131
+ /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
132
+ Typography,
133
+ {
134
+ variant: "sigma",
135
+ fontWeight: "bold",
136
+ textTransform: "uppercase",
137
+ marginBottom: 1,
138
+ textColor: "neutral600",
139
+ children: translate("sidePanel.linkedContent")
140
+ }
141
+ ) }),
142
+ linkedContent.length > 0 ? /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsxs(Typography, { variant: "omega", textColor: "neutral600", marginBottom: 3, children: [
143
+ translate("sidePanel.referencedIn"),
144
+ " ",
145
+ linkedContent.length,
146
+ " ",
147
+ translate("sidePanel.otherContents")
148
+ ] }) }) : /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", marginBottom: 3, children: translate("sidePanel.notReferenced") }) }),
149
+ /* @__PURE__ */ jsx(Box, { marginTop: 2, children: linkedContent.map((content, idx) => /* @__PURE__ */ jsxs(
150
+ Box,
151
+ {
152
+ marginBottom: idx < linkedContent.length - 1 ? 3 : 0,
153
+ children: [
154
+ /* @__PURE__ */ jsxs(
155
+ Flex,
156
+ {
157
+ direction: "row",
158
+ justifyContent: "space-between",
159
+ alignItems: "flex-start",
160
+ paddingY: 2,
161
+ paddingX: 3,
162
+ children: [
163
+ /* @__PURE__ */ jsxs(Box, { children: [
164
+ /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
165
+ "a",
166
+ {
167
+ href: content.isSingleType ? `/admin/content-manager/single-types/${content.uid}` : `/admin/content-manager/collection-types/${content.uid}/${content.documentId}`,
168
+ target: "_blank",
169
+ style: { textDecoration: "none" },
170
+ children: /* @__PURE__ */ jsx(
171
+ Typography,
172
+ {
173
+ variant: "beta",
174
+ fontWeight: "bold",
175
+ textColor: "neutral800",
176
+ children: content.title
177
+ }
178
+ )
179
+ }
180
+ ) }),
181
+ /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(
182
+ Typography,
183
+ {
184
+ variant: "pi",
185
+ textColor: "neutral600",
186
+ style: { lineHeight: 1.2 },
187
+ children: [
188
+ translate("sidePanel.field"),
189
+ " ",
190
+ content.field
191
+ ]
192
+ }
193
+ ) })
194
+ ] }),
195
+ /* @__PURE__ */ jsx(Box, { marginLeft: 2, children: /* @__PURE__ */ jsx(CardBadge, { children: content.type }) })
196
+ ]
197
+ }
198
+ ),
199
+ idx < linkedContent.length - 1 && /* @__PURE__ */ jsx(Box, { marginY: 1, children: /* @__PURE__ */ jsx(Divider, {}) })
200
+ ]
201
+ },
202
+ content.documentId
203
+ )) })
204
+ ] })
205
+ ] });
206
+ };
207
+ const name = pluginPkg.strapi.name;
208
+ const index = {
209
+ async register(app) {
210
+ const contentTypes = await listContentTypes();
211
+ setContentTypes(contentTypes);
212
+ app.customFields.register({
213
+ name,
214
+ pluginId,
215
+ type: "richtext",
216
+ intlLabel: {
217
+ id: "multi-content-type-relation.text-ai.label",
218
+ defaultMessage: "Multi Content Type Relation"
219
+ },
220
+ intlDescription: {
221
+ id: "multi-content-type-relation.text-ai.description",
222
+ defaultMessage: "Write content types separated by commas"
223
+ },
224
+ icon: PluginIcon,
225
+ // don't forget to create/import your icon component
226
+ components: {
227
+ Input: () => import(
228
+ /* webpackChunkName: "input-component" */
229
+ "./index-D3M5NaOA.mjs"
230
+ )
231
+ },
232
+ inputSize: {
233
+ default: 12,
234
+ isResizable: false
235
+ },
236
+ options: {
237
+ base: [
238
+ /*
239
+ Declare settings to be added to the "Base settings" section
240
+ of the field in the Content-Type Builder
241
+ */
242
+ {
243
+ sectionTitle: {
244
+ id: "multi-content-type-relation.text-ai.length",
245
+ defaultMessage: "Content types"
246
+ },
247
+ items: contentTypes.map((contentType) => {
248
+ const value = contentType.info.singularName;
249
+ return {
250
+ intlLabel: {
251
+ id: `multi-content-type-relation.options.${contentType.uid}`,
252
+ defaultMessage: contentType.info.displayName
253
+ },
254
+ type: "checkbox",
255
+ name: `options.contentTypes.${value}`
256
+ };
257
+ })
258
+ }
259
+ ],
260
+ advanced: [
261
+ {
262
+ sectionTitle: {
263
+ id: "global.settings",
264
+ defaultMessage: "Settings"
265
+ },
266
+ items: [
267
+ {
268
+ name: "required",
269
+ type: "checkbox",
270
+ intlLabel: {
271
+ id: "content-type-relation-select.options.advanced.requiredField",
272
+ defaultMessage: "Required field"
273
+ },
274
+ description: {
275
+ id: "content-type-relation-select.options.advanced.requiredField.description",
276
+ defaultMessage: "You won't be able to create an entry if this field is empty"
277
+ }
278
+ },
279
+ {
280
+ name: "options.min",
281
+ type: "number",
282
+ intlLabel: {
283
+ id: "content-type-relation-select.options.advanced.minField",
284
+ defaultMessage: "Minimum values"
285
+ },
286
+ description: {
287
+ id: "content-type-relation-select.options.advanced.minField.description",
288
+ defaultMessage: "Minimum number of entries"
289
+ }
290
+ },
291
+ {
292
+ name: "options.max",
293
+ type: "number",
294
+ intlLabel: {
295
+ id: "content-type-relation-select.options.advanced.maxField",
296
+ defaultMessage: "Maximum values"
297
+ },
298
+ description: {
299
+ id: "content-type-relation-select.options.advanced.maxField.description",
300
+ defaultMessage: "Maximum number of entries"
301
+ }
302
+ }
303
+ ]
304
+ }
305
+ ]
306
+ }
307
+ });
308
+ },
309
+ bootstrap(app) {
310
+ app.getPlugin("content-manager").injectComponent("editView", "right-links", {
311
+ name: "side-panel",
312
+ Component: SidePanel
313
+ });
314
+ },
315
+ async registerTrads(app) {
316
+ const { locales } = app;
317
+ const importedTrads = await Promise.all(
318
+ locales.map(async (locale) => {
319
+ const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-Cj4T04Z2.mjs"), "./translations/fr.json": () => import("./fr-KHPiQOFP.mjs") }), `./translations/${locale}.json`, 3);
320
+ return {
321
+ data,
322
+ locale
323
+ };
324
+ })
325
+ );
326
+ return Promise.resolve(importedTrads);
327
+ }
328
+ };
329
+ export {
330
+ formatToStrapiField as a,
331
+ fetchMatchingContent as f,
332
+ getContentTypeForUid as g,
333
+ index as i,
334
+ useTranslate as u,
335
+ validateCurrentRelations as v
336
+ };