@mattisvensson/strapi-plugin-webatlas 0.3.1 → 0.4.2

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 (56) hide show
  1. package/dist/_chunks/{EmptyBox-7D4LrvdH.mjs → EmptyBox-BM4IscSk.mjs} +2 -6
  2. package/dist/_chunks/{EmptyBox-DT6D5gcf.js → EmptyBox-T8t29l25.js} +1 -5
  3. package/dist/_chunks/FullLoader-Cmsf8xS6.js +11 -0
  4. package/dist/_chunks/FullLoader-CrPED_dY.mjs +12 -0
  5. package/dist/_chunks/{de-C8PE3n3B.mjs → de-Dn24NwJf.mjs} +11 -1
  6. package/dist/_chunks/{de-4tL_cJTC.js → de-RiCps8UH.js} +11 -1
  7. package/dist/_chunks/{en-CR1YZvJo.mjs → en-D9Lxaugc.mjs} +11 -1
  8. package/dist/_chunks/{en-Bg4z3fR7.js → en-JLW5S3ZC.js} +11 -1
  9. package/dist/_chunks/index-9db80XRS.mjs +126 -0
  10. package/dist/_chunks/{index-CwHhwtOU.mjs → index-B4pe6Yuh.mjs} +1375 -357
  11. package/dist/_chunks/{index-CKoxbSC0.js → index-CSYue_D0.js} +42 -60
  12. package/dist/_chunks/index-CVj7qbwh.mjs +281 -0
  13. package/dist/_chunks/index-CiY-8z8F.js +126 -0
  14. package/dist/_chunks/{index-BAqGJ3TM.js → index-Clikpy91.js} +1381 -363
  15. package/dist/_chunks/{index-BBL_eQ0G.mjs → index-CtJ_9-RB.mjs} +42 -60
  16. package/dist/_chunks/index-IHvD3566.js +281 -0
  17. package/dist/admin/index.js +1 -1
  18. package/dist/admin/index.mjs +1 -1
  19. package/dist/admin/src/components/UI/FullLoader.d.ts +3 -0
  20. package/dist/admin/src/components/UI/index.d.ts +2 -1
  21. package/dist/admin/src/components/modals/Delete.d.ts +3 -3
  22. package/dist/admin/src/components/modals/NavEdit.d.ts +2 -2
  23. package/dist/admin/src/components/modals/externalItem/index.d.ts +10 -4
  24. package/dist/admin/src/components/modals/internalItem/internalItemCreate.d.ts +1 -1
  25. package/dist/admin/src/components/modals/wrapperItem/index.d.ts +11 -5
  26. package/dist/admin/src/hooks/useApi.d.ts +6 -5
  27. package/dist/admin/src/hooks/useNavigations.d.ts +2 -0
  28. package/dist/admin/src/hooks/usePluginConfig.d.ts +3 -3
  29. package/dist/admin/src/pages/Navigation/PageWrapper.d.ts +7 -0
  30. package/dist/admin/src/pages/Navigation/index.d.ts +1 -1
  31. package/dist/admin/src/pages/Routes/PageWrapper.d.ts +4 -0
  32. package/dist/admin/src/pages/Routes/TableHeader.d.ts +1 -0
  33. package/dist/admin/src/pages/Routes/TableRow.d.ts +4 -0
  34. package/dist/admin/src/pages/Settings/ContentTypeAccordion.d.ts +7 -0
  35. package/dist/admin/src/pages/Settings/PageWrapper.d.ts +8 -0
  36. package/dist/admin/src/utils/createTempNavItemObject.d.ts +25 -0
  37. package/dist/admin/src/utils/index.d.ts +2 -1
  38. package/dist/server/index.js +225 -176
  39. package/dist/server/index.mjs +225 -176
  40. package/dist/server/src/controllers/admin.d.ts +1 -4
  41. package/dist/server/src/controllers/index.d.ts +1 -4
  42. package/dist/server/src/index.d.ts +2 -8
  43. package/dist/server/src/services/admin.d.ts +2 -5
  44. package/dist/server/src/services/index.d.ts +1 -4
  45. package/dist/server/src/utils/navItemHandler.d.ts +5 -0
  46. package/dist/server/src/utils/routeHandler.d.ts +3 -0
  47. package/package.json +1 -1
  48. package/dist/_chunks/_baseConvert-B84_vf8X.js +0 -864
  49. package/dist/_chunks/_baseConvert-C2SW1VHq.mjs +0 -865
  50. package/dist/_chunks/index-BOq-WidK.mjs +0 -17176
  51. package/dist/_chunks/index-C4ou6MTp.js +0 -17195
  52. package/dist/_chunks/index-DZmhgSeq.mjs +0 -92
  53. package/dist/_chunks/index-DsTyLL2l.js +0 -92
  54. package/dist/admin/src/pages/Navigation/Header.d.ts +0 -6
  55. package/dist/server/index.js.map +0 -1
  56. package/dist/server/index.mjs.map +0 -1
@@ -41,7 +41,7 @@ const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
41
41
  );
42
42
  });
43
43
  };
44
- const version = "0.3.0";
44
+ const version = "0.4.1";
45
45
  const keywords = [];
46
46
  const type = "commonjs";
47
47
  const exports$1 = {
@@ -215,14 +215,6 @@ function useApi() {
215
215
  const { data } = await get(`/webatlas/route/related?documentId=${relatedDocumentId}`);
216
216
  return data;
217
217
  };
218
- const createExternalRoute = async (body) => {
219
- const { data } = await post("/webatlas/route/external", {
220
- data: {
221
- ...body
222
- }
223
- });
224
- return data;
225
- };
226
218
  const getRoutes = async () => {
227
219
  const { data } = await get("/webatlas/route");
228
220
  return data;
@@ -235,30 +227,17 @@ function useApi() {
235
227
  });
236
228
  return data;
237
229
  };
238
- const createNavItem = async (body) => {
239
- const { data } = await post("/webatlas/navitem", {
240
- data: {
241
- ...body
242
- }
243
- });
244
- return data;
245
- };
246
- const updateNavItem = async (documentId, body) => {
247
- const { data } = await put(`/webatlas/navitem?documentId=${documentId}`, {
248
- data: {
249
- ...body
250
- }
251
- });
252
- return data;
253
- };
254
- const deleteNavItem = async (documentId) => {
255
- const { data } = await del(`/webatlas/navitem?documentId=${documentId}`);
256
- return data;
257
- };
258
230
  const getStructuredNavigation = async (documentId, variant = "nested") => {
259
231
  const { data } = await get(`/webatlas/navigation?documentId=${documentId}&variant=${variant}`);
260
232
  return data;
261
233
  };
234
+ const getNavigation = async ({ documentId, variant } = {}) => {
235
+ const query = [];
236
+ if (documentId) query.push(`documentId=${documentId}`);
237
+ if (variant) query.push(`variant=${variant}`);
238
+ const { data } = await get(`/webatlas/navigation${query.length > 0 ? `?${query.join("&")}` : ""}`);
239
+ return data;
240
+ };
262
241
  const deleteNavigation = async (documentId) => {
263
242
  const { data } = await del(`/webatlas/navigation?documentId=${documentId}`);
264
243
  return data;
@@ -269,19 +248,24 @@ function useApi() {
269
248
  });
270
249
  return data;
271
250
  };
251
+ const updateNavigationItemStructure = async (documentId, navigationItems) => {
252
+ const { data } = await put(`/webatlas/navigation/items`, {
253
+ navigationId: documentId,
254
+ navigationItems
255
+ });
256
+ return data;
257
+ };
272
258
  return {
273
259
  fetchAllContentTypes,
274
260
  fetchAllEntities,
275
261
  getRelatedRoute,
276
- createExternalRoute,
277
262
  getRoutes,
278
263
  updateRoute,
279
- createNavItem,
280
- updateNavItem,
281
- deleteNavItem,
282
264
  getStructuredNavigation,
265
+ getNavigation,
283
266
  deleteNavigation,
284
- updateNavigation
267
+ updateNavigation,
268
+ updateNavigationItemStructure
285
269
  };
286
270
  }
287
271
  const useAllContentTypes = () => {
@@ -306,31 +290,32 @@ const useAllContentTypes = () => {
306
290
  };
307
291
  function usePluginConfig() {
308
292
  const { put, get } = admin.useFetchClient();
309
- const [data, setData] = React.useState(null);
310
- const [loading, setLoading] = React.useState(false);
311
- const [error, setError] = React.useState(null);
293
+ const [config, setConfigData] = React.useState(null);
294
+ const [loading, setLoading] = React.useState(true);
295
+ const [fetchError, setFetchError] = React.useState(null);
312
296
  React.useEffect(() => {
313
297
  const fetchData = async () => {
314
298
  setLoading(true);
299
+ setFetchError(null);
315
300
  try {
316
301
  const { data: { data: contentTypesArray } } = await get("/content-manager/content-types");
317
- let { data: config } = await get("/webatlas/config");
318
- if (!config || !config.selectedContentTypes) {
319
- throw new Error(`HTTP error! Couldn't fetch plugin config`);
302
+ let { data: config2 } = await get("/webatlas/config");
303
+ if (!config2 || !config2.selectedContentTypes) {
304
+ throw new Error(`Couldn't fetch plugin config`);
320
305
  }
321
306
  const allowedContentTypes = contentTypesArray.filter(
322
307
  (type2) => type2.pluginOptions?.webatlas?.active === true
323
308
  );
324
309
  const contentTypeUids = new Set(allowedContentTypes.map((type2) => type2.uid));
325
- const activeContentTypes = config.selectedContentTypes.filter((type2) => contentTypeUids.has(type2.uid));
326
- if (JSON.stringify(activeContentTypes) !== JSON.stringify(config.selectedContentTypes)) {
327
- config = { ...config, selectedContentTypes: activeContentTypes };
328
- setConfig(config);
310
+ const activeContentTypes = config2.selectedContentTypes.filter((type2) => contentTypeUids.has(type2.uid));
311
+ if (JSON.stringify(activeContentTypes) !== JSON.stringify(config2.selectedContentTypes)) {
312
+ config2 = { ...config2, selectedContentTypes: activeContentTypes };
313
+ await setConfig(config2);
329
314
  }
330
- setData(config);
331
- setLoading(false);
332
- } catch (error2) {
333
- setError(error2.message);
315
+ setConfigData(config2);
316
+ } catch (error) {
317
+ setFetchError(error.message);
318
+ } finally {
334
319
  setLoading(false);
335
320
  }
336
321
  };
@@ -338,14 +323,12 @@ function usePluginConfig() {
338
323
  }, []);
339
324
  async function setConfig(body) {
340
325
  try {
341
- await put("/webatlas/config", {
342
- ...body
343
- });
344
- } catch (error2) {
345
- setError(error2.message);
326
+ await put("/webatlas/config", { ...body });
327
+ } catch (error) {
328
+ throw error;
346
329
  }
347
330
  }
348
- return { data, loading, error, setConfig };
331
+ return { config, loading, fetchError, setConfig };
349
332
  }
350
333
  function transformToUrl(input) {
351
334
  const specialCharMap = {
@@ -4006,7 +3989,7 @@ const Alias = ({ config }) => {
4006
3989
  const CMEditViewAside = () => {
4007
3990
  const { model } = admin.unstable_useContentManagerContext();
4008
3991
  const { contentTypes } = useAllContentTypes();
4009
- const { data: config } = usePluginConfig();
3992
+ const { config } = usePluginConfig();
4010
3993
  const [contentTypeConfig, setContentTypeConfig] = React.useState(null);
4011
3994
  const [isAllowedContentType, setIsAllowedContentType] = React.useState(false);
4012
3995
  const [isActiveContentType, setIsActiveContentType] = React.useState(false);
@@ -4094,7 +4077,7 @@ const index = {
4094
4077
  defaultMessage: "Routes"
4095
4078
  },
4096
4079
  Component: async () => {
4097
- const component = await Promise.resolve().then(() => require("./index-DsTyLL2l.js"));
4080
+ const component = await Promise.resolve().then(() => require("./index-CiY-8z8F.js"));
4098
4081
  return { default: component.default };
4099
4082
  },
4100
4083
  permissions: [
@@ -4113,7 +4096,7 @@ const index = {
4113
4096
  defaultMessage: "Navigation"
4114
4097
  },
4115
4098
  Component: async () => {
4116
- const component = await Promise.resolve().then(() => require("./index-BAqGJ3TM.js"));
4099
+ const component = await Promise.resolve().then(() => require("./index-Clikpy91.js"));
4117
4100
  return { default: component.default };
4118
4101
  },
4119
4102
  permissions: [
@@ -4142,7 +4125,7 @@ const index = {
4142
4125
  Component: async () => {
4143
4126
  return await Promise.resolve().then(() => require(
4144
4127
  /* webpackChunkName: "webatlas-settings-page" */
4145
- "./index-C4ou6MTp.js"
4128
+ "./index-IHvD3566.js"
4146
4129
  ));
4147
4130
  },
4148
4131
  permissions: [
@@ -4171,7 +4154,7 @@ const index = {
4171
4154
  return Promise.all(
4172
4155
  locales.map(async (locale) => {
4173
4156
  try {
4174
- const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => Promise.resolve().then(() => require("./de-4tL_cJTC.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-Bg4z3fR7.js")) }), `./translations/${locale}.json`, 3);
4157
+ const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/de.json": () => Promise.resolve().then(() => require("./de-RiCps8UH.js")), "./translations/en.json": () => Promise.resolve().then(() => require("./en-JLW5S3ZC.js")) }), `./translations/${locale}.json`, 3);
4175
4158
  return { data, locale };
4176
4159
  } catch {
4177
4160
  return { data: {}, locale };
@@ -4183,7 +4166,6 @@ const index = {
4183
4166
  exports.PLUGIN_NAME = PLUGIN_NAME;
4184
4167
  exports.Tooltip = Tooltip;
4185
4168
  exports.URLInfo = URLInfo;
4186
- exports._extends = _extends;
4187
4169
  exports.debounce = debounce;
4188
4170
  exports.duplicateCheck = duplicateCheck;
4189
4171
  exports.getTranslation = getTranslation;
@@ -0,0 +1,281 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useReducer, useState, useEffect } from "react";
3
+ import { Button, Box, Accordion, Field, SingleSelect, SingleSelectOption, MultiSelect, MultiSelectOption } from "@strapi/design-system";
4
+ import { Page, Layouts, useNotification } from "@strapi/strapi/admin";
5
+ import { P as PLUGIN_NAME, g as getTranslation, T as Tooltip, b as usePluginConfig, c as useAllContentTypes, t as transformToUrl } from "./index-CtJ_9-RB.mjs";
6
+ import { useIntl } from "react-intl";
7
+ import "@strapi/icons/symbols";
8
+ import { F as FullLoader } from "./FullLoader-CrPED_dY.mjs";
9
+ function PageWrapper({
10
+ settingsState,
11
+ initialState,
12
+ save,
13
+ isSaving,
14
+ children
15
+ }) {
16
+ const { formatMessage } = useIntl();
17
+ return /* @__PURE__ */ jsxs(Page.Main, { children: [
18
+ /* @__PURE__ */ jsx(
19
+ Layouts.Header,
20
+ {
21
+ title: PLUGIN_NAME,
22
+ subtitle: formatMessage({
23
+ id: getTranslation("settings.page.subtitle"),
24
+ defaultMessage: "Settings"
25
+ }),
26
+ primaryAction: settingsState && initialState && save && /* @__PURE__ */ jsx(
27
+ Button,
28
+ {
29
+ type: "submit",
30
+ onClick: () => save(),
31
+ loading: isSaving,
32
+ disabled: JSON.stringify(settingsState) === JSON.stringify(initialState) || settingsState.selectedContentTypes.find((cta) => !cta.default) !== void 0 || isSaving,
33
+ children: formatMessage({
34
+ id: getTranslation("save"),
35
+ defaultMessage: "Save"
36
+ })
37
+ }
38
+ )
39
+ }
40
+ ),
41
+ /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsx(
42
+ Box,
43
+ {
44
+ background: "neutral0",
45
+ borderColor: "neutral150",
46
+ hasRadius: true,
47
+ paddingBottom: 4,
48
+ paddingLeft: 4,
49
+ paddingRight: 4,
50
+ paddingTop: 6,
51
+ shadow: "tableShadow",
52
+ children
53
+ }
54
+ ) })
55
+ ] });
56
+ }
57
+ function ContentTypeAccordion({
58
+ contentType,
59
+ contentTypeSettings,
60
+ dispatch
61
+ }) {
62
+ const { formatMessage } = useIntl();
63
+ if (!contentType) return null;
64
+ return /* @__PURE__ */ jsx(
65
+ Box,
66
+ {
67
+ borderColor: !contentTypeSettings.default && "danger500",
68
+ children: /* @__PURE__ */ jsxs(Accordion.Item, { value: contentType.uid, size: "S", children: [
69
+ /* @__PURE__ */ jsx(Accordion.Header, { children: /* @__PURE__ */ jsx(Accordion.Trigger, { children: contentType?.info.displayName }) }),
70
+ /* @__PURE__ */ jsx(Accordion.Content, { children: /* @__PURE__ */ jsxs(Box, { padding: 3, children: [
71
+ /* @__PURE__ */ jsxs(
72
+ Field.Root,
73
+ {
74
+ name: "selectedContentTypes",
75
+ hint: formatMessage({
76
+ id: getTranslation("settings.page.defaultField.hint"),
77
+ defaultMessage: 'The selected field from the content type will be used to generate the URL alias. Use a field that is unique and descriptive, such as a "title" or "name".'
78
+ }),
79
+ error: !contentTypeSettings.default && formatMessage({
80
+ id: getTranslation("settings.page.defaultField.error"),
81
+ defaultMessage: "Please select a default field"
82
+ }),
83
+ required: true,
84
+ children: [
85
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
86
+ id: getTranslation("settings.page.defaultField"),
87
+ defaultMessage: "Default URL Alias field"
88
+ }) }),
89
+ /* @__PURE__ */ jsx(
90
+ SingleSelect,
91
+ {
92
+ name: `defaultField-${contentType.uid}`,
93
+ onClear: () => dispatch({ type: "SET_DEFAULT_FIELD", payload: { ctUid: contentType.uid, field: "" } }),
94
+ value: contentTypeSettings?.default || "",
95
+ onChange: (value) => dispatch({ type: "SET_DEFAULT_FIELD", payload: { ctUid: contentType.uid, field: value } }),
96
+ children: Object.entries(contentType.attributes).map(([key], index) => {
97
+ if (key === "id" || key === "documentId" || key === "createdAt" || key === "updatedAt" || key === "createdBy" || key === "updatedBy" || key === "webatlas_path" || key === "webatlas_override") return null;
98
+ return /* @__PURE__ */ jsx(SingleSelectOption, { value: key, children: key }, index);
99
+ })
100
+ }
101
+ ),
102
+ /* @__PURE__ */ jsx(Field.Hint, {})
103
+ ]
104
+ }
105
+ ),
106
+ /* @__PURE__ */ jsx(Box, { paddingTop: 4, children: /* @__PURE__ */ jsxs(
107
+ Field.Root,
108
+ {
109
+ name: "urlAliasPattern",
110
+ hint: formatMessage({
111
+ id: getTranslation("settings.page.urlAliasPattern.hint"),
112
+ defaultMessage: 'The pattern to prepend to the generated URL alias. For example, if you enter "blog" and the value of default field is "My First Post", the generated URL alias will be "blog/my-first-post". Leave empty for no prefix.'
113
+ }),
114
+ children: [
115
+ /* @__PURE__ */ jsxs(Field.Label, { children: [
116
+ formatMessage({
117
+ id: getTranslation("settings.page.urlAliasPattern"),
118
+ defaultMessage: "URL Alias Pattern"
119
+ }),
120
+ /* @__PURE__ */ jsx(Tooltip, { description: formatMessage({
121
+ id: getTranslation("settings.page.urlAliasPattern.tooltip"),
122
+ defaultMessage: "Leading and trailing slashes will be removed. Spaces will be replaced with hyphens. Special characters will be encoded."
123
+ }) })
124
+ ] }),
125
+ /* @__PURE__ */ jsx(
126
+ Field.Input,
127
+ {
128
+ value: contentTypeSettings.pattern,
129
+ onChange: (e) => dispatch({ type: "SET_PATTERN", payload: { ctUid: contentType.uid, pattern: e.target.value } }),
130
+ disabled: !contentTypeSettings.default,
131
+ type: "text",
132
+ placeholder: formatMessage({
133
+ id: getTranslation("settings.page.urlAliasPattern.placeholder"),
134
+ defaultMessage: "e.g. blog"
135
+ })
136
+ }
137
+ ),
138
+ /* @__PURE__ */ jsx(Field.Hint, {})
139
+ ]
140
+ }
141
+ ) })
142
+ ] }) })
143
+ ] }, contentType.uid)
144
+ },
145
+ contentType.uid
146
+ );
147
+ }
148
+ function reducer(settingsState, action) {
149
+ let updatedContentTypes;
150
+ switch (action.type) {
151
+ case "SET_SELECTED_CONTENT_TYPES":
152
+ updatedContentTypes = action.payload.map((ct) => {
153
+ return settingsState.selectedContentTypes.find((cta) => cta.uid === ct.uid) || ct;
154
+ });
155
+ return { ...settingsState, selectedContentTypes: updatedContentTypes };
156
+ case "SET_DEFAULT_FIELD":
157
+ updatedContentTypes = settingsState.selectedContentTypes.map(
158
+ (ct) => ct.uid === action.payload.ctUid ? { ...ct, default: action.payload.field } : ct
159
+ );
160
+ return { ...settingsState, selectedContentTypes: updatedContentTypes };
161
+ case "SET_PATTERN":
162
+ updatedContentTypes = settingsState.selectedContentTypes.map(
163
+ (ct) => ct.uid === action.payload.ctUid ? { ...ct, pattern: transformToUrl(action.payload.pattern) } : ct
164
+ );
165
+ return { ...settingsState, selectedContentTypes: updatedContentTypes };
166
+ default:
167
+ throw new Error();
168
+ }
169
+ }
170
+ const Settings = () => {
171
+ const { config, setConfig, loading, fetchError } = usePluginConfig();
172
+ const [settingsState, dispatch] = useReducer(reducer, config || { selectedContentTypes: [] });
173
+ const { contentTypes: allContentTypesData } = useAllContentTypes();
174
+ const allContentTypes = allContentTypesData?.filter((ct) => ct.pluginOptions?.webatlas?.active === true);
175
+ const [initialState, setInitialState] = useState(config || { selectedContentTypes: [] });
176
+ const { toggleNotification } = useNotification();
177
+ const { formatMessage } = useIntl();
178
+ const [isSaving, setIsSaving] = useState(false);
179
+ useEffect(() => {
180
+ setInitialState(config || { selectedContentTypes: [] });
181
+ }, [config]);
182
+ useEffect(() => {
183
+ if (!config) return;
184
+ dispatch({ type: "SET_SELECTED_CONTENT_TYPES", payload: config.selectedContentTypes });
185
+ }, [config]);
186
+ useEffect(() => {
187
+ if (fetchError) {
188
+ toggleNotification({
189
+ type: "danger",
190
+ message: formatMessage({
191
+ id: getTranslation("notification.error"),
192
+ defaultMessage: "An error occurred"
193
+ }) + ": " + fetchError
194
+ });
195
+ }
196
+ }, [fetchError, toggleNotification, formatMessage]);
197
+ async function save() {
198
+ if (!settingsState || settingsState.selectedContentTypes.find((cta) => !cta.default) !== void 0) return;
199
+ setIsSaving(true);
200
+ try {
201
+ await setConfig(settingsState);
202
+ setInitialState(settingsState);
203
+ toggleNotification({
204
+ type: "success",
205
+ message: formatMessage({
206
+ id: getTranslation("notification.settings.saved"),
207
+ defaultMessage: "Settings saved successfully"
208
+ })
209
+ });
210
+ setIsSaving(false);
211
+ } catch (err) {
212
+ setIsSaving(false);
213
+ toggleNotification({
214
+ type: "danger",
215
+ message: formatMessage({
216
+ id: getTranslation("notification.error"),
217
+ defaultMessage: "An error occurred"
218
+ }) + ": " + err
219
+ });
220
+ console.error(err);
221
+ }
222
+ }
223
+ if (loading) {
224
+ return /* @__PURE__ */ jsx(PageWrapper, { children: /* @__PURE__ */ jsx(FullLoader, { height: 200 }) });
225
+ }
226
+ return /* @__PURE__ */ jsxs(PageWrapper, { settingsState, initialState, save, isSaving, children: [
227
+ /* @__PURE__ */ jsxs(
228
+ Field.Root,
229
+ {
230
+ name: "selectedContentTypes",
231
+ hint: formatMessage({
232
+ id: getTranslation("settings.page.enabledContentTypes.hint"),
233
+ defaultMessage: "Select the content types for which you want to enable URL aliases"
234
+ }),
235
+ children: [
236
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
237
+ id: getTranslation("settings.page.enabledContentTypes"),
238
+ defaultMessage: "Enabled Content Types"
239
+ }) }),
240
+ /* @__PURE__ */ jsx(
241
+ MultiSelect,
242
+ {
243
+ placeholder: formatMessage({
244
+ id: getTranslation("settings.page.enabledContentTypes.placeholder"),
245
+ defaultMessage: "Select content types..."
246
+ }),
247
+ onClear: () => dispatch({ type: "SET_SELECTED_CONTENT_TYPES", payload: [] }),
248
+ value: [...settingsState.selectedContentTypes.map((ct) => ct.uid)],
249
+ onChange: (value) => dispatch({
250
+ type: "SET_SELECTED_CONTENT_TYPES",
251
+ payload: value.map((v) => ({
252
+ uid: v,
253
+ default: "",
254
+ pattern: ""
255
+ }))
256
+ }),
257
+ withTags: true,
258
+ children: allContentTypes && allContentTypes.map(
259
+ (item) => /* @__PURE__ */ jsx(MultiSelectOption, { value: item.uid, children: item.info.displayName }, item.uid)
260
+ )
261
+ }
262
+ ),
263
+ /* @__PURE__ */ jsx(Field.Hint, {})
264
+ ]
265
+ }
266
+ ),
267
+ settingsState.selectedContentTypes && settingsState.selectedContentTypes.length > 0 && /* @__PURE__ */ jsx(Box, { paddingTop: 4, children: /* @__PURE__ */ jsxs(Field.Root, { name: "selectedContentTypesAccordion", children: [
268
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
269
+ id: getTranslation("settings.page.contentTypeSettings"),
270
+ defaultMessage: "Content Type settings"
271
+ }) }),
272
+ /* @__PURE__ */ jsx(Accordion.Root, { children: settingsState.selectedContentTypes?.map((contentTypeSettings) => {
273
+ const ct = allContentTypes?.find((item) => item.uid === contentTypeSettings.uid);
274
+ return /* @__PURE__ */ jsx(ContentTypeAccordion, { contentType: ct, contentTypeSettings, dispatch }, contentTypeSettings.uid);
275
+ }) })
276
+ ] }) })
277
+ ] });
278
+ };
279
+ export {
280
+ Settings as default
281
+ };
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const React = require("react");
5
+ const designSystem = require("@strapi/design-system");
6
+ const index = require("./index-CSYue_D0.js");
7
+ const admin = require("@strapi/strapi/admin");
8
+ const FullLoader = require("./FullLoader-Cmsf8xS6.js");
9
+ const EmptyBox = require("./EmptyBox-T8t29l25.js");
10
+ const reactIntl = require("react-intl");
11
+ const icons = require("@strapi/icons");
12
+ function getRouteType(route) {
13
+ if (route.wrapper) {
14
+ return "wrapper";
15
+ } else if (!route.internal) {
16
+ return "external";
17
+ } else {
18
+ return "internal";
19
+ }
20
+ }
21
+ function TableHeader() {
22
+ const { formatMessage } = reactIntl.useIntl();
23
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Thead, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
24
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "ID" }) }),
25
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: formatMessage({
26
+ id: index.getTranslation("title"),
27
+ defaultMessage: "Title"
28
+ }) }) }),
29
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: formatMessage({
30
+ id: index.getTranslation("route"),
31
+ defaultMessage: "Route"
32
+ }) }) }),
33
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: formatMessage({
34
+ id: index.getTranslation("routes.page.column.type"),
35
+ defaultMessage: "Type"
36
+ }) }) }),
37
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { children: formatMessage({
38
+ id: index.getTranslation("actions"),
39
+ defaultMessage: "Actions"
40
+ }) }) })
41
+ ] }) });
42
+ }
43
+ function TableRow({ route }) {
44
+ const { formatMessage } = reactIntl.useIntl();
45
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
46
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", children: route.id }) }),
47
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", children: route.title }) }),
48
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", children: route.fullPath }) }),
49
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", children: formatMessage({
50
+ id: index.getTranslation(`route.type.${getRouteType(route)}`),
51
+ defaultMessage: "-"
52
+ }) }) }),
53
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, justifyContent: "end", children: route.internal && /* @__PURE__ */ jsxRuntime.jsx(
54
+ designSystem.LinkButton,
55
+ {
56
+ variant: "secondary",
57
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, {}),
58
+ href: `/admin/content-manager/collection-types/${route.relatedContentType}/${route.relatedDocumentId}`,
59
+ children: formatMessage({
60
+ id: index.getTranslation("edit"),
61
+ defaultMessage: "Edit"
62
+ })
63
+ }
64
+ ) }) })
65
+ ] });
66
+ }
67
+ function PageWrapper({ children }) {
68
+ const { formatMessage } = reactIntl.useIntl();
69
+ return /* @__PURE__ */ jsxRuntime.jsxs(admin.Page.Main, { children: [
70
+ /* @__PURE__ */ jsxRuntime.jsx(
71
+ admin.Layouts.Header,
72
+ {
73
+ title: formatMessage({
74
+ id: index.getTranslation("routes.page.title"),
75
+ defaultMessage: "Routes"
76
+ }),
77
+ subtitle: formatMessage({
78
+ id: index.getTranslation("routes.page.subtitle"),
79
+ defaultMessage: "Overview of all existing routes"
80
+ })
81
+ }
82
+ ),
83
+ /* @__PURE__ */ jsxRuntime.jsx(admin.Layouts.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children }) })
84
+ ] });
85
+ }
86
+ const Routes = () => {
87
+ const { getRoutes } = index.useApi();
88
+ const { formatMessage } = reactIntl.useIntl();
89
+ const { toggleNotification } = admin.useNotification();
90
+ const [routes, setRoutes] = React.useState([]);
91
+ const [loading, setLoading] = React.useState(true);
92
+ React.useEffect(() => {
93
+ async function fetchRoutes() {
94
+ try {
95
+ const data = await getRoutes();
96
+ setRoutes(data);
97
+ } catch (err) {
98
+ console.error("Failed to fetch routes:", err);
99
+ toggleNotification({
100
+ type: "danger",
101
+ message: formatMessage({
102
+ id: index.getTranslation("notification.routes.fetchFailed"),
103
+ defaultMessage: "Failed to fetch routes"
104
+ })
105
+ });
106
+ } finally {
107
+ setLoading(false);
108
+ }
109
+ }
110
+ fetchRoutes();
111
+ }, []);
112
+ if (loading) {
113
+ return /* @__PURE__ */ jsxRuntime.jsx(PageWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(FullLoader.FullLoader, {}) });
114
+ }
115
+ if (routes.length === 0) {
116
+ return /* @__PURE__ */ jsxRuntime.jsx(PageWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(FullLoader.Center, { height: 400, children: /* @__PURE__ */ jsxRuntime.jsx(EmptyBox.EmptyBox, { msg: formatMessage({
117
+ id: index.getTranslation("routes.page.emptyRoutes"),
118
+ defaultMessage: "No routes found"
119
+ }) }) }) });
120
+ }
121
+ return /* @__PURE__ */ jsxRuntime.jsx(PageWrapper, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Table, { colCount: 4, rowCount: routes.length, children: [
122
+ /* @__PURE__ */ jsxRuntime.jsx(TableHeader, {}),
123
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: routes.map((route) => /* @__PURE__ */ jsxRuntime.jsx(TableRow, { route }, route.id)) })
124
+ ] }) });
125
+ };
126
+ exports.default = Routes;