multi-content-type-relation 2.1.0 → 2.1.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.
@@ -30,3 +30,4 @@ const en = {
30
30
  "common.locale": "en"
31
31
  };
32
32
  exports.default = en;
33
+ //# sourceMappingURL=en-Bk9okOMP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"en-Bk9okOMP.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -30,3 +30,4 @@ const en = {
30
30
  export {
31
31
  en as default
32
32
  };
33
+ //# sourceMappingURL=en-Cj4T04Z2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"en-Cj4T04Z2.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -30,3 +30,4 @@ const fr = {
30
30
  export {
31
31
  fr as default
32
32
  };
33
+ //# sourceMappingURL=fr-KHPiQOFP.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fr-KHPiQOFP.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -30,3 +30,4 @@ const fr = {
30
30
  "common.locale": "fr"
31
31
  };
32
32
  exports.default = fr;
33
+ //# sourceMappingURL=fr-ZS3aTnjj.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fr-ZS3aTnjj.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -331,3 +331,4 @@ export {
331
331
  useTranslate as u,
332
332
  validateCurrentRelations as v
333
333
  };
334
+ //# sourceMappingURL=index-BHcolZ4N.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-BHcolZ4N.mjs","sources":["../../admin/src/components/PluginIcon/index.tsx","../../admin/src/pluginId.ts","../../admin/src/helpers/content.ts","../../admin/src/helpers/storage.ts","../../admin/src/hooks/useTranslate.ts","../../admin/src/components/SidePanel/SidePanel.tsx","../../admin/src/index.ts"],"sourcesContent":["import { PuzzlePiece } from '@strapi/icons';\n\nconst PluginIcon = () => <PuzzlePiece />;\n\nexport default PluginIcon;\n","import pluginPkg from '../../package.json';\n\nconst pluginId = pluginPkg.name.replace(\n /^(@[^-,.][\\w,-]+\\/|strapi-)plugin-/i,\n ''\n);\n\nexport default pluginId;\n","import { getFetchClient } from '@strapi/strapi/admin';\n\nimport pluginId from '../pluginId';\nimport {\n FormattedStrapiEntry,\n MatchingContent,\n MatchingContentResponse,\n SelectedEntry,\n} from '../interface';\n\nexport const fetchMatchingContent = async (\n keyword: string,\n contentTypes: string,\n locale: string\n): Promise<MatchingContentResponse> => {\n const { post } = getFetchClient();\n const response = await post(`/${pluginId}/get-content`, {\n contentTypes: contentTypes.split(','),\n keyword,\n locale,\n });\n\n const data = response.data as MatchingContent[];\n\n if (!data) throw new Error('No data returned from API');\n\n const total = data.reduce((accumulator, option) => {\n if (!option.results) return accumulator;\n\n return accumulator + option.results.length;\n }, 0);\n\n return {\n data,\n total,\n };\n};\n\nexport const formatToStrapiField = (entries: SelectedEntry[]) => {\n if (entries.length === 0) return '';\n\n return JSON.stringify(\n entries\n .map((entry) => ({\n uid: entry.uid,\n documentId: entry.item.documentId,\n MRCT: true,\n }))\n .filter(Boolean)\n );\n};\n\nexport const validateCurrentRelations = async (\n entries: FormattedStrapiEntry[]\n) => {\n const { post } = getFetchClient();\n\n const response = await post(`/${pluginId}/validate-relations`, {\n entries,\n });\n\n return response.data as SelectedEntry[];\n};\n\nexport const listContentTypes = async () => {\n try {\n const { get } = getFetchClient();\n const response = await get(`/${pluginId}/list-content-types`);\n\n return response.data;\n } catch (error) {\n console.error(error);\n return [];\n }\n};\n","export type LightContentType = {\n apiName: string;\n attributes: Record<string, Record<string, unknown>>[];\n collectionName: string;\n globalId: string;\n modelName: string;\n modelType: string;\n options?: { draftAndPublish?: boolean };\n uid: string;\n};\n\nconst STORAGE_KEY = 'mctr::content_types';\n\nexport function getContentTypes() {\n const raw = sessionStorage.getItem(STORAGE_KEY);\n\n return raw ? (JSON.parse(raw) as LightContentType[]) : undefined;\n}\n\nexport function getContentTypeForUid(uid: string) {\n const contentTypes = getContentTypes();\n\n if (!Array.isArray(contentTypes)) return;\n\n return contentTypes.find((contentType) => contentType.uid === uid);\n}\n\nexport function setContentTypes(contentTypes: LightContentType[]) {\n const stringified = JSON.stringify(contentTypes);\n\n sessionStorage.setItem(STORAGE_KEY, stringified);\n}\n","import { useIntl } from 'react-intl';\n\nconst useTranslate = () => {\n const { formatMessage } = useIntl();\n\n const translate = (key: string, values?: Record<string, any>) => {\n return formatMessage({ id: key }, values);\n };\n\n return {\n translate\n };\n};\n\nexport default useTranslate;\n","import React, { useEffect, useState } from 'react';\nimport {\n Box,\n Typography,\n Card,\n CardBody,\n Flex,\n Divider\n} from '@strapi/design-system';\nimport { CardTitle, CardContent, CardBadge } from '@strapi/design-system';\nimport { getFetchClient } from '@strapi/strapi/admin';\nimport pluginId from '../../pluginId';\nimport { unstable_useContentManagerContext as useContentManagerContext } from '@strapi/strapi/admin';\nimport { Loader } from '@strapi/design-system';\nimport useTranslate from '../../hooks/useTranslate';\n\ninterface LinkedContent {\n documentId: string;\n title: string;\n type: string;\n uid: string;\n field: string;\n isSingleType: boolean;\n}\n\ninterface SidePanelProps {\n contentType?: string;\n contentId?: string;\n}\n\nconst SidePanel: React.FC<SidePanelProps> = () => {\n const { translate } = useTranslate();\n const {\n id: documentId,\n model: uid,\n isSingleType\n } = useContentManagerContext();\n\n const [linkedContent, setLinkedContent] = useState<LinkedContent[]>([]);\n const [loading, setLoading] = useState(false);\n\n useEffect(() => {\n const fetchRevertRelations = async () => {\n const { post } = getFetchClient();\n\n const response = await post(`/${pluginId}/fetch-revert-relations`, {\n documentId,\n uid,\n isSingleType\n });\n\n setLinkedContent(Array.isArray(response.data) ? response.data.filter(Boolean) : []);\n setLoading(false);\n };\n\n fetchRevertRelations();\n }, []);\n\n if (loading)\n return (\n <Box width=\"100%\">\n <Loader />\n </Box>\n );\n\n return (\n <>\n <Divider />\n <Box width=\"100%\" marginTop={4}>\n <Flex>\n <Typography\n variant=\"sigma\"\n fontWeight=\"bold\"\n textTransform=\"uppercase\"\n marginBottom={1}\n textColor=\"neutral600\"\n >\n {translate('sidePanel.linkedContent')}\n </Typography>\n </Flex>\n\n {linkedContent.length > 0 ? (\n <Flex>\n <Typography variant=\"omega\" textColor=\"neutral600\" marginBottom={3}>\n {translate('sidePanel.referencedIn')} {linkedContent.length}{' '}\n {translate('sidePanel.otherContents')}\n </Typography>\n </Flex>\n ) : (\n <Flex>\n <Typography variant=\"omega\" textColor=\"neutral600\" marginBottom={3}>\n {translate('sidePanel.notReferenced')}\n </Typography>\n </Flex>\n )}\n\n <Box marginTop={2}>\n {linkedContent.map((content, idx) => (\n <Box\n key={content.documentId}\n marginBottom={idx < linkedContent.length - 1 ? 3 : 0}\n >\n <Flex\n direction=\"row\"\n justifyContent=\"space-between\"\n alignItems=\"flex-start\"\n paddingY={2}\n paddingX={3}\n >\n <Box>\n <Box>\n <a\n href={\n content.isSingleType\n ? `/admin/content-manager/single-types/${content.uid}`\n : `/admin/content-manager/collection-types/${content.uid}/${content.documentId}`\n }\n target=\"_blank\"\n style={{ textDecoration: 'none' }}\n >\n <Typography\n >\n {content.title ?? content.documentId}\n </Typography>\n </a>\n </Box>\n <Box marginTop={1}>\n <Typography\n variant=\"pi\"\n textColor=\"neutral600\"\n style={{ lineHeight: 1.2 }}\n >\n {translate('sidePanel.field')} {content.field}\n </Typography>\n </Box>\n </Box>\n <Box marginLeft={2}>\n <CardBadge>{content.type}</CardBadge>\n </Box>\n </Flex>\n {idx < linkedContent.length - 1 && (\n <Box marginY={1}>\n <Divider />\n </Box>\n )}\n </Box>\n ))}\n </Box>\n </Box>\n </>\n );\n};\n\nexport default SidePanel;\n","import React, { ComponentType } from 'react';\n\nimport pluginPkg from '../../package.json';\n\nimport PluginIcon from './components/PluginIcon';\nimport pluginId from './pluginId';\nimport { listContentTypes } from './helpers/content';\nimport { setContentTypes } from './helpers/storage';\nimport SidePanel from './components/SidePanel/SidePanel';\n\nconst name = pluginPkg.strapi.name;\n\nexport default {\n async register(app: any) {\n const contentTypes = await listContentTypes();\n setContentTypes(contentTypes);\n\n app.customFields.register({\n name,\n pluginId,\n type: 'richtext',\n intlLabel: {\n id: 'multi-content-type-relation.text-ai.label',\n defaultMessage: 'Multi Content Type Relation'\n },\n intlDescription: {\n id: 'multi-content-type-relation.text-ai.description',\n defaultMessage: 'Write content types separated by commas'\n },\n icon: PluginIcon, // don't forget to create/import your icon component\n components: {\n Input: () =>\n import(\n /* webpackChunkName: \"input-component\" */ './components/Input'\n ) as unknown as ComponentType\n },\n inputSize: {\n default: 12,\n isResizable: false\n },\n options: {\n base: [\n /*\n Declare settings to be added to the \"Base settings\" section\n of the field in the Content-Type Builder\n */\n {\n sectionTitle: {\n id: 'multi-content-type-relation.text-ai.length',\n defaultMessage: 'Content types'\n },\n items: contentTypes.map((contentType: any) => {\n const value = contentType.info.singularName;\n\n return {\n intlLabel: {\n id: `multi-content-type-relation.options.${contentType.uid}`,\n defaultMessage: contentType.info.displayName\n },\n type: 'checkbox',\n name: `options.contentTypes.${value}`\n };\n })\n }\n ],\n advanced: [\n {\n sectionTitle: {\n id: 'global.settings',\n defaultMessage: 'Settings'\n },\n items: [\n {\n name: 'required',\n type: 'checkbox',\n intlLabel: {\n id: 'content-type-relation-select.options.advanced.requiredField',\n defaultMessage: 'Required field'\n },\n description: {\n id: 'content-type-relation-select.options.advanced.requiredField.description',\n defaultMessage:\n \"You won't be able to create an entry if this field is empty\"\n }\n },\n {\n name: 'options.min',\n type: 'number',\n intlLabel: {\n id: 'content-type-relation-select.options.advanced.minField',\n defaultMessage: 'Minimum values'\n },\n description: {\n id: 'content-type-relation-select.options.advanced.minField.description',\n defaultMessage: 'Minimum number of entries'\n }\n },\n {\n name: 'options.max',\n type: 'number',\n intlLabel: {\n id: 'content-type-relation-select.options.advanced.maxField',\n defaultMessage: 'Maximum values'\n },\n description: {\n id: 'content-type-relation-select.options.advanced.maxField.description',\n defaultMessage: 'Maximum number of entries'\n }\n }\n ]\n }\n ]\n }\n });\n },\n\n bootstrap(app: any) {\n app\n .getPlugin('content-manager')\n .injectComponent('editView', 'right-links', {\n name: 'side-panel',\n Component: SidePanel\n });\n },\n\n async registerTrads(app: any) {\n const { locales } = app;\n\n const importedTrads = await Promise.all(\n (locales as any[]).map(async (locale) => {\n const { default: data } = await import(`./translations/${locale}.json`);\n\n return {\n data,\n locale\n };\n })\n );\n\n return Promise.resolve(importedTrads);\n }\n};\n"],"names":["useContentManagerContext"],"mappings":"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"}
@@ -0,0 +1,333 @@
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(Array.isArray(response.data) ? response.data.filter(Boolean) : []);
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
+ children: content.title ?? content.documentId
175
+ }
176
+ )
177
+ }
178
+ ) }),
179
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsxs(
180
+ designSystem.Typography,
181
+ {
182
+ variant: "pi",
183
+ textColor: "neutral600",
184
+ style: { lineHeight: 1.2 },
185
+ children: [
186
+ translate("sidePanel.field"),
187
+ " ",
188
+ content.field
189
+ ]
190
+ }
191
+ ) })
192
+ ] }),
193
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginLeft: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.CardBadge, { children: content.type }) })
194
+ ]
195
+ }
196
+ ),
197
+ idx < linkedContent.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginY: 1, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, {}) })
198
+ ]
199
+ },
200
+ content.documentId
201
+ )) })
202
+ ] })
203
+ ] });
204
+ };
205
+ const name = pluginPkg.strapi.name;
206
+ const index = {
207
+ async register(app) {
208
+ const contentTypes = await listContentTypes();
209
+ setContentTypes(contentTypes);
210
+ app.customFields.register({
211
+ name,
212
+ pluginId,
213
+ type: "richtext",
214
+ intlLabel: {
215
+ id: "multi-content-type-relation.text-ai.label",
216
+ defaultMessage: "Multi Content Type Relation"
217
+ },
218
+ intlDescription: {
219
+ id: "multi-content-type-relation.text-ai.description",
220
+ defaultMessage: "Write content types separated by commas"
221
+ },
222
+ icon: PluginIcon,
223
+ // don't forget to create/import your icon component
224
+ components: {
225
+ Input: () => Promise.resolve().then(() => require(
226
+ /* webpackChunkName: "input-component" */
227
+ "./index-CyBD50Lc.js"
228
+ ))
229
+ },
230
+ inputSize: {
231
+ default: 12,
232
+ isResizable: false
233
+ },
234
+ options: {
235
+ base: [
236
+ /*
237
+ Declare settings to be added to the "Base settings" section
238
+ of the field in the Content-Type Builder
239
+ */
240
+ {
241
+ sectionTitle: {
242
+ id: "multi-content-type-relation.text-ai.length",
243
+ defaultMessage: "Content types"
244
+ },
245
+ items: contentTypes.map((contentType) => {
246
+ const value = contentType.info.singularName;
247
+ return {
248
+ intlLabel: {
249
+ id: `multi-content-type-relation.options.${contentType.uid}`,
250
+ defaultMessage: contentType.info.displayName
251
+ },
252
+ type: "checkbox",
253
+ name: `options.contentTypes.${value}`
254
+ };
255
+ })
256
+ }
257
+ ],
258
+ advanced: [
259
+ {
260
+ sectionTitle: {
261
+ id: "global.settings",
262
+ defaultMessage: "Settings"
263
+ },
264
+ items: [
265
+ {
266
+ name: "required",
267
+ type: "checkbox",
268
+ intlLabel: {
269
+ id: "content-type-relation-select.options.advanced.requiredField",
270
+ defaultMessage: "Required field"
271
+ },
272
+ description: {
273
+ id: "content-type-relation-select.options.advanced.requiredField.description",
274
+ defaultMessage: "You won't be able to create an entry if this field is empty"
275
+ }
276
+ },
277
+ {
278
+ name: "options.min",
279
+ type: "number",
280
+ intlLabel: {
281
+ id: "content-type-relation-select.options.advanced.minField",
282
+ defaultMessage: "Minimum values"
283
+ },
284
+ description: {
285
+ id: "content-type-relation-select.options.advanced.minField.description",
286
+ defaultMessage: "Minimum number of entries"
287
+ }
288
+ },
289
+ {
290
+ name: "options.max",
291
+ type: "number",
292
+ intlLabel: {
293
+ id: "content-type-relation-select.options.advanced.maxField",
294
+ defaultMessage: "Maximum values"
295
+ },
296
+ description: {
297
+ id: "content-type-relation-select.options.advanced.maxField.description",
298
+ defaultMessage: "Maximum number of entries"
299
+ }
300
+ }
301
+ ]
302
+ }
303
+ ]
304
+ }
305
+ });
306
+ },
307
+ bootstrap(app) {
308
+ app.getPlugin("content-manager").injectComponent("editView", "right-links", {
309
+ name: "side-panel",
310
+ Component: SidePanel
311
+ });
312
+ },
313
+ async registerTrads(app) {
314
+ const { locales } = app;
315
+ const importedTrads = await Promise.all(
316
+ locales.map(async (locale) => {
317
+ 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);
318
+ return {
319
+ data,
320
+ locale
321
+ };
322
+ })
323
+ );
324
+ return Promise.resolve(importedTrads);
325
+ }
326
+ };
327
+ exports.fetchMatchingContent = fetchMatchingContent;
328
+ exports.formatToStrapiField = formatToStrapiField;
329
+ exports.getContentTypeForUid = getContentTypeForUid;
330
+ exports.index = index;
331
+ exports.useTranslate = useTranslate;
332
+ exports.validateCurrentRelations = validateCurrentRelations;
333
+ //# sourceMappingURL=index-BtldAbIW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-BtldAbIW.js","sources":["../../admin/src/components/PluginIcon/index.tsx","../../admin/src/pluginId.ts","../../admin/src/helpers/content.ts","../../admin/src/helpers/storage.ts","../../admin/src/hooks/useTranslate.ts","../../admin/src/components/SidePanel/SidePanel.tsx","../../admin/src/index.ts"],"sourcesContent":["import { PuzzlePiece } from '@strapi/icons';\n\nconst PluginIcon = () => <PuzzlePiece />;\n\nexport default PluginIcon;\n","import pluginPkg from '../../package.json';\n\nconst pluginId = pluginPkg.name.replace(\n /^(@[^-,.][\\w,-]+\\/|strapi-)plugin-/i,\n ''\n);\n\nexport default pluginId;\n","import { getFetchClient } from '@strapi/strapi/admin';\n\nimport pluginId from '../pluginId';\nimport {\n FormattedStrapiEntry,\n MatchingContent,\n MatchingContentResponse,\n SelectedEntry,\n} from '../interface';\n\nexport const fetchMatchingContent = async (\n keyword: string,\n contentTypes: string,\n locale: string\n): Promise<MatchingContentResponse> => {\n const { post } = getFetchClient();\n const response = await post(`/${pluginId}/get-content`, {\n contentTypes: contentTypes.split(','),\n keyword,\n locale,\n });\n\n const data = response.data as MatchingContent[];\n\n if (!data) throw new Error('No data returned from API');\n\n const total = data.reduce((accumulator, option) => {\n if (!option.results) return accumulator;\n\n return accumulator + option.results.length;\n }, 0);\n\n return {\n data,\n total,\n };\n};\n\nexport const formatToStrapiField = (entries: SelectedEntry[]) => {\n if (entries.length === 0) return '';\n\n return JSON.stringify(\n entries\n .map((entry) => ({\n uid: entry.uid,\n documentId: entry.item.documentId,\n MRCT: true,\n }))\n .filter(Boolean)\n );\n};\n\nexport const validateCurrentRelations = async (\n entries: FormattedStrapiEntry[]\n) => {\n const { post } = getFetchClient();\n\n const response = await post(`/${pluginId}/validate-relations`, {\n entries,\n });\n\n return response.data as SelectedEntry[];\n};\n\nexport const listContentTypes = async () => {\n try {\n const { get } = getFetchClient();\n const response = await get(`/${pluginId}/list-content-types`);\n\n return response.data;\n } catch (error) {\n console.error(error);\n return [];\n }\n};\n","export type LightContentType = {\n apiName: string;\n attributes: Record<string, Record<string, unknown>>[];\n collectionName: string;\n globalId: string;\n modelName: string;\n modelType: string;\n options?: { draftAndPublish?: boolean };\n uid: string;\n};\n\nconst STORAGE_KEY = 'mctr::content_types';\n\nexport function getContentTypes() {\n const raw = sessionStorage.getItem(STORAGE_KEY);\n\n return raw ? (JSON.parse(raw) as LightContentType[]) : undefined;\n}\n\nexport function getContentTypeForUid(uid: string) {\n const contentTypes = getContentTypes();\n\n if (!Array.isArray(contentTypes)) return;\n\n return contentTypes.find((contentType) => contentType.uid === uid);\n}\n\nexport function setContentTypes(contentTypes: LightContentType[]) {\n const stringified = JSON.stringify(contentTypes);\n\n sessionStorage.setItem(STORAGE_KEY, stringified);\n}\n","import { useIntl } from 'react-intl';\n\nconst useTranslate = () => {\n const { formatMessage } = useIntl();\n\n const translate = (key: string, values?: Record<string, any>) => {\n return formatMessage({ id: key }, values);\n };\n\n return {\n translate\n };\n};\n\nexport default useTranslate;\n","import React, { useEffect, useState } from 'react';\nimport {\n Box,\n Typography,\n Card,\n CardBody,\n Flex,\n Divider\n} from '@strapi/design-system';\nimport { CardTitle, CardContent, CardBadge } from '@strapi/design-system';\nimport { getFetchClient } from '@strapi/strapi/admin';\nimport pluginId from '../../pluginId';\nimport { unstable_useContentManagerContext as useContentManagerContext } from '@strapi/strapi/admin';\nimport { Loader } from '@strapi/design-system';\nimport useTranslate from '../../hooks/useTranslate';\n\ninterface LinkedContent {\n documentId: string;\n title: string;\n type: string;\n uid: string;\n field: string;\n isSingleType: boolean;\n}\n\ninterface SidePanelProps {\n contentType?: string;\n contentId?: string;\n}\n\nconst SidePanel: React.FC<SidePanelProps> = () => {\n const { translate } = useTranslate();\n const {\n id: documentId,\n model: uid,\n isSingleType\n } = useContentManagerContext();\n\n const [linkedContent, setLinkedContent] = useState<LinkedContent[]>([]);\n const [loading, setLoading] = useState(false);\n\n useEffect(() => {\n const fetchRevertRelations = async () => {\n const { post } = getFetchClient();\n\n const response = await post(`/${pluginId}/fetch-revert-relations`, {\n documentId,\n uid,\n isSingleType\n });\n\n setLinkedContent(Array.isArray(response.data) ? response.data.filter(Boolean) : []);\n setLoading(false);\n };\n\n fetchRevertRelations();\n }, []);\n\n if (loading)\n return (\n <Box width=\"100%\">\n <Loader />\n </Box>\n );\n\n return (\n <>\n <Divider />\n <Box width=\"100%\" marginTop={4}>\n <Flex>\n <Typography\n variant=\"sigma\"\n fontWeight=\"bold\"\n textTransform=\"uppercase\"\n marginBottom={1}\n textColor=\"neutral600\"\n >\n {translate('sidePanel.linkedContent')}\n </Typography>\n </Flex>\n\n {linkedContent.length > 0 ? (\n <Flex>\n <Typography variant=\"omega\" textColor=\"neutral600\" marginBottom={3}>\n {translate('sidePanel.referencedIn')} {linkedContent.length}{' '}\n {translate('sidePanel.otherContents')}\n </Typography>\n </Flex>\n ) : (\n <Flex>\n <Typography variant=\"omega\" textColor=\"neutral600\" marginBottom={3}>\n {translate('sidePanel.notReferenced')}\n </Typography>\n </Flex>\n )}\n\n <Box marginTop={2}>\n {linkedContent.map((content, idx) => (\n <Box\n key={content.documentId}\n marginBottom={idx < linkedContent.length - 1 ? 3 : 0}\n >\n <Flex\n direction=\"row\"\n justifyContent=\"space-between\"\n alignItems=\"flex-start\"\n paddingY={2}\n paddingX={3}\n >\n <Box>\n <Box>\n <a\n href={\n content.isSingleType\n ? `/admin/content-manager/single-types/${content.uid}`\n : `/admin/content-manager/collection-types/${content.uid}/${content.documentId}`\n }\n target=\"_blank\"\n style={{ textDecoration: 'none' }}\n >\n <Typography\n >\n {content.title ?? content.documentId}\n </Typography>\n </a>\n </Box>\n <Box marginTop={1}>\n <Typography\n variant=\"pi\"\n textColor=\"neutral600\"\n style={{ lineHeight: 1.2 }}\n >\n {translate('sidePanel.field')} {content.field}\n </Typography>\n </Box>\n </Box>\n <Box marginLeft={2}>\n <CardBadge>{content.type}</CardBadge>\n </Box>\n </Flex>\n {idx < linkedContent.length - 1 && (\n <Box marginY={1}>\n <Divider />\n </Box>\n )}\n </Box>\n ))}\n </Box>\n </Box>\n </>\n );\n};\n\nexport default SidePanel;\n","import React, { ComponentType } from 'react';\n\nimport pluginPkg from '../../package.json';\n\nimport PluginIcon from './components/PluginIcon';\nimport pluginId from './pluginId';\nimport { listContentTypes } from './helpers/content';\nimport { setContentTypes } from './helpers/storage';\nimport SidePanel from './components/SidePanel/SidePanel';\n\nconst name = pluginPkg.strapi.name;\n\nexport default {\n async register(app: any) {\n const contentTypes = await listContentTypes();\n setContentTypes(contentTypes);\n\n app.customFields.register({\n name,\n pluginId,\n type: 'richtext',\n intlLabel: {\n id: 'multi-content-type-relation.text-ai.label',\n defaultMessage: 'Multi Content Type Relation'\n },\n intlDescription: {\n id: 'multi-content-type-relation.text-ai.description',\n defaultMessage: 'Write content types separated by commas'\n },\n icon: PluginIcon, // don't forget to create/import your icon component\n components: {\n Input: () =>\n import(\n /* webpackChunkName: \"input-component\" */ './components/Input'\n ) as unknown as ComponentType\n },\n inputSize: {\n default: 12,\n isResizable: false\n },\n options: {\n base: [\n /*\n Declare settings to be added to the \"Base settings\" section\n of the field in the Content-Type Builder\n */\n {\n sectionTitle: {\n id: 'multi-content-type-relation.text-ai.length',\n defaultMessage: 'Content types'\n },\n items: contentTypes.map((contentType: any) => {\n const value = contentType.info.singularName;\n\n return {\n intlLabel: {\n id: `multi-content-type-relation.options.${contentType.uid}`,\n defaultMessage: contentType.info.displayName\n },\n type: 'checkbox',\n name: `options.contentTypes.${value}`\n };\n })\n }\n ],\n advanced: [\n {\n sectionTitle: {\n id: 'global.settings',\n defaultMessage: 'Settings'\n },\n items: [\n {\n name: 'required',\n type: 'checkbox',\n intlLabel: {\n id: 'content-type-relation-select.options.advanced.requiredField',\n defaultMessage: 'Required field'\n },\n description: {\n id: 'content-type-relation-select.options.advanced.requiredField.description',\n defaultMessage:\n \"You won't be able to create an entry if this field is empty\"\n }\n },\n {\n name: 'options.min',\n type: 'number',\n intlLabel: {\n id: 'content-type-relation-select.options.advanced.minField',\n defaultMessage: 'Minimum values'\n },\n description: {\n id: 'content-type-relation-select.options.advanced.minField.description',\n defaultMessage: 'Minimum number of entries'\n }\n },\n {\n name: 'options.max',\n type: 'number',\n intlLabel: {\n id: 'content-type-relation-select.options.advanced.maxField',\n defaultMessage: 'Maximum values'\n },\n description: {\n id: 'content-type-relation-select.options.advanced.maxField.description',\n defaultMessage: 'Maximum number of entries'\n }\n }\n ]\n }\n ]\n }\n });\n },\n\n bootstrap(app: any) {\n app\n .getPlugin('content-manager')\n .injectComponent('editView', 'right-links', {\n name: 'side-panel',\n Component: SidePanel\n });\n },\n\n async registerTrads(app: any) {\n const { locales } = app;\n\n const importedTrads = await Promise.all(\n (locales as any[]).map(async (locale) => {\n const { default: data } = await import(`./translations/${locale}.json`);\n\n return {\n data,\n locale\n };\n })\n );\n\n return Promise.resolve(importedTrads);\n }\n};\n"],"names":["jsx","PuzzlePiece","getFetchClient","useIntl","useContentManagerContext","useState","useEffect","Box","Loader","jsxs","Fragment","Divider","Flex","Typography","CardBadge"],"mappings":"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"}
@@ -330,3 +330,4 @@ exports.getContentTypeForUid = getContentTypeForUid;
330
330
  exports.index = index;
331
331
  exports.useTranslate = useTranslate;
332
332
  exports.validateCurrentRelations = validateCurrentRelations;
333
+ //# sourceMappingURL=index-CktBIBSM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-CktBIBSM.js","sources":["../../admin/src/components/PluginIcon/index.tsx","../../admin/src/pluginId.ts","../../admin/src/helpers/content.ts","../../admin/src/helpers/storage.ts","../../admin/src/hooks/useTranslate.ts","../../admin/src/components/SidePanel/SidePanel.tsx","../../admin/src/index.ts"],"sourcesContent":["import { PuzzlePiece } from '@strapi/icons';\n\nconst PluginIcon = () => <PuzzlePiece />;\n\nexport default PluginIcon;\n","import pluginPkg from '../../package.json';\n\nconst pluginId = pluginPkg.name.replace(\n /^(@[^-,.][\\w,-]+\\/|strapi-)plugin-/i,\n ''\n);\n\nexport default pluginId;\n","import { getFetchClient } from '@strapi/strapi/admin';\n\nimport pluginId from '../pluginId';\nimport {\n FormattedStrapiEntry,\n MatchingContent,\n MatchingContentResponse,\n SelectedEntry,\n} from '../interface';\n\nexport const fetchMatchingContent = async (\n keyword: string,\n contentTypes: string,\n locale: string\n): Promise<MatchingContentResponse> => {\n const { post } = getFetchClient();\n const response = await post(`/${pluginId}/get-content`, {\n contentTypes: contentTypes.split(','),\n keyword,\n locale,\n });\n\n const data = response.data as MatchingContent[];\n\n if (!data) throw new Error('No data returned from API');\n\n const total = data.reduce((accumulator, option) => {\n if (!option.results) return accumulator;\n\n return accumulator + option.results.length;\n }, 0);\n\n return {\n data,\n total,\n };\n};\n\nexport const formatToStrapiField = (entries: SelectedEntry[]) => {\n if (entries.length === 0) return '';\n\n return JSON.stringify(\n entries\n .map((entry) => ({\n uid: entry.uid,\n documentId: entry.item.documentId,\n MRCT: true,\n }))\n .filter(Boolean)\n );\n};\n\nexport const validateCurrentRelations = async (\n entries: FormattedStrapiEntry[]\n) => {\n const { post } = getFetchClient();\n\n const response = await post(`/${pluginId}/validate-relations`, {\n entries,\n });\n\n return response.data as SelectedEntry[];\n};\n\nexport const listContentTypes = async () => {\n try {\n const { get } = getFetchClient();\n const response = await get(`/${pluginId}/list-content-types`);\n\n return response.data;\n } catch (error) {\n console.error(error);\n return [];\n }\n};\n","export type LightContentType = {\n apiName: string;\n attributes: Record<string, Record<string, unknown>>[];\n collectionName: string;\n globalId: string;\n modelName: string;\n modelType: string;\n options?: { draftAndPublish?: boolean };\n uid: string;\n};\n\nconst STORAGE_KEY = 'mctr::content_types';\n\nexport function getContentTypes() {\n const raw = sessionStorage.getItem(STORAGE_KEY);\n\n return raw ? (JSON.parse(raw) as LightContentType[]) : undefined;\n}\n\nexport function getContentTypeForUid(uid: string) {\n const contentTypes = getContentTypes();\n\n if (!Array.isArray(contentTypes)) return;\n\n return contentTypes.find((contentType) => contentType.uid === uid);\n}\n\nexport function setContentTypes(contentTypes: LightContentType[]) {\n const stringified = JSON.stringify(contentTypes);\n\n sessionStorage.setItem(STORAGE_KEY, stringified);\n}\n","import { useIntl } from 'react-intl';\n\nconst useTranslate = () => {\n const { formatMessage } = useIntl();\n\n const translate = (key: string, values?: Record<string, any>) => {\n return formatMessage({ id: key }, values);\n };\n\n return {\n translate\n };\n};\n\nexport default useTranslate;\n","import React, { useEffect, useState } from 'react';\nimport {\n Box,\n Typography,\n Card,\n CardBody,\n Flex,\n Divider\n} from '@strapi/design-system';\nimport { CardTitle, CardContent, CardBadge } from '@strapi/design-system';\nimport { getFetchClient } from '@strapi/strapi/admin';\nimport pluginId from '../../pluginId';\nimport { unstable_useContentManagerContext as useContentManagerContext } from '@strapi/strapi/admin';\nimport { Loader } from '@strapi/design-system';\nimport useTranslate from '../../hooks/useTranslate';\n\ninterface LinkedContent {\n documentId: string;\n title: string;\n type: string;\n uid: string;\n field: string;\n isSingleType: boolean;\n}\n\ninterface SidePanelProps {\n contentType?: string;\n contentId?: string;\n}\n\nconst SidePanel: React.FC<SidePanelProps> = () => {\n const { translate } = useTranslate();\n const {\n id: documentId,\n model: uid,\n isSingleType\n } = useContentManagerContext();\n\n const [linkedContent, setLinkedContent] = useState<LinkedContent[]>([]);\n const [loading, setLoading] = useState(false);\n\n useEffect(() => {\n const fetchRevertRelations = async () => {\n const { post } = getFetchClient();\n\n const response = await post(`/${pluginId}/fetch-revert-relations`, {\n documentId,\n uid,\n isSingleType\n });\n\n setLinkedContent(Array.isArray(response.data) ? response.data.filter(Boolean) : []);\n setLoading(false);\n };\n\n fetchRevertRelations();\n }, []);\n\n if (loading)\n return (\n <Box width=\"100%\">\n <Loader />\n </Box>\n );\n\n return (\n <>\n <Divider />\n <Box width=\"100%\" marginTop={4}>\n <Flex>\n <Typography\n variant=\"sigma\"\n fontWeight=\"bold\"\n textTransform=\"uppercase\"\n marginBottom={1}\n textColor=\"neutral600\"\n >\n {translate('sidePanel.linkedContent')}\n </Typography>\n </Flex>\n\n {linkedContent.length > 0 ? (\n <Flex>\n <Typography variant=\"omega\" textColor=\"neutral600\" marginBottom={3}>\n {translate('sidePanel.referencedIn')} {linkedContent.length}{' '}\n {translate('sidePanel.otherContents')}\n </Typography>\n </Flex>\n ) : (\n <Flex>\n <Typography variant=\"omega\" textColor=\"neutral600\" marginBottom={3}>\n {translate('sidePanel.notReferenced')}\n </Typography>\n </Flex>\n )}\n\n <Box marginTop={2}>\n {linkedContent.map((content, idx) => (\n <Box\n key={content.documentId}\n marginBottom={idx < linkedContent.length - 1 ? 3 : 0}\n >\n <Flex\n direction=\"row\"\n justifyContent=\"space-between\"\n alignItems=\"flex-start\"\n paddingY={2}\n paddingX={3}\n >\n <Box>\n <Box>\n <a\n href={\n content.isSingleType\n ? `/admin/content-manager/single-types/${content.uid}`\n : `/admin/content-manager/collection-types/${content.uid}/${content.documentId}`\n }\n target=\"_blank\"\n style={{ textDecoration: 'none' }}\n >\n <Typography\n >\n {content.title ?? content.documentId}\n </Typography>\n </a>\n </Box>\n <Box marginTop={1}>\n <Typography\n variant=\"pi\"\n textColor=\"neutral600\"\n style={{ lineHeight: 1.2 }}\n >\n {translate('sidePanel.field')} {content.field}\n </Typography>\n </Box>\n </Box>\n <Box marginLeft={2}>\n <CardBadge>{content.type}</CardBadge>\n </Box>\n </Flex>\n {idx < linkedContent.length - 1 && (\n <Box marginY={1}>\n <Divider />\n </Box>\n )}\n </Box>\n ))}\n </Box>\n </Box>\n </>\n );\n};\n\nexport default SidePanel;\n","import React, { ComponentType } from 'react';\n\nimport pluginPkg from '../../package.json';\n\nimport PluginIcon from './components/PluginIcon';\nimport pluginId from './pluginId';\nimport { listContentTypes } from './helpers/content';\nimport { setContentTypes } from './helpers/storage';\nimport SidePanel from './components/SidePanel/SidePanel';\n\nconst name = pluginPkg.strapi.name;\n\nexport default {\n async register(app: any) {\n const contentTypes = await listContentTypes();\n setContentTypes(contentTypes);\n\n app.customFields.register({\n name,\n pluginId,\n type: 'richtext',\n intlLabel: {\n id: 'multi-content-type-relation.text-ai.label',\n defaultMessage: 'Multi Content Type Relation'\n },\n intlDescription: {\n id: 'multi-content-type-relation.text-ai.description',\n defaultMessage: 'Write content types separated by commas'\n },\n icon: PluginIcon, // don't forget to create/import your icon component\n components: {\n Input: () =>\n import(\n /* webpackChunkName: \"input-component\" */ './components/Input'\n ) as unknown as ComponentType\n },\n inputSize: {\n default: 12,\n isResizable: false\n },\n options: {\n base: [\n /*\n Declare settings to be added to the \"Base settings\" section\n of the field in the Content-Type Builder\n */\n {\n sectionTitle: {\n id: 'multi-content-type-relation.text-ai.length',\n defaultMessage: 'Content types'\n },\n items: contentTypes.map((contentType: any) => {\n const value = contentType.info.singularName;\n\n return {\n intlLabel: {\n id: `multi-content-type-relation.options.${contentType.uid}`,\n defaultMessage: contentType.info.displayName\n },\n type: 'checkbox',\n name: `options.contentTypes.${value}`\n };\n })\n }\n ],\n advanced: [\n {\n sectionTitle: {\n id: 'global.settings',\n defaultMessage: 'Settings'\n },\n items: [\n {\n name: 'required',\n type: 'checkbox',\n intlLabel: {\n id: 'content-type-relation-select.options.advanced.requiredField',\n defaultMessage: 'Required field'\n },\n description: {\n id: 'content-type-relation-select.options.advanced.requiredField.description',\n defaultMessage:\n \"You won't be able to create an entry if this field is empty\"\n }\n },\n {\n name: 'options.min',\n type: 'number',\n intlLabel: {\n id: 'content-type-relation-select.options.advanced.minField',\n defaultMessage: 'Minimum values'\n },\n description: {\n id: 'content-type-relation-select.options.advanced.minField.description',\n defaultMessage: 'Minimum number of entries'\n }\n },\n {\n name: 'options.max',\n type: 'number',\n intlLabel: {\n id: 'content-type-relation-select.options.advanced.maxField',\n defaultMessage: 'Maximum values'\n },\n description: {\n id: 'content-type-relation-select.options.advanced.maxField.description',\n defaultMessage: 'Maximum number of entries'\n }\n }\n ]\n }\n ]\n }\n });\n },\n\n bootstrap(app: any) {\n app\n .getPlugin('content-manager')\n .injectComponent('editView', 'right-links', {\n name: 'side-panel',\n Component: SidePanel\n });\n },\n\n async registerTrads(app: any) {\n const { locales } = app;\n\n const importedTrads = await Promise.all(\n (locales as any[]).map(async (locale) => {\n const { default: data } = await import(`./translations/${locale}.json`);\n\n return {\n data,\n locale\n };\n })\n );\n\n return Promise.resolve(importedTrads);\n }\n};\n"],"names":["jsx","PuzzlePiece","getFetchClient","useIntl","useContentManagerContext","useState","useEffect","Box","Loader","jsxs","Fragment","Divider","Flex","Typography","CardBadge"],"mappings":"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"}
@@ -3564,3 +3564,4 @@ const Index = (props) => {
3564
3564
  return /* @__PURE__ */ jsxRuntime.jsx(MainInput, { ...props, attribute });
3565
3565
  };
3566
3566
  exports.default = Index;
3567
+ //# sourceMappingURL=index-CxWt3llJ.js.map