@mattisvensson/strapi-plugin-webatlas 0.1.4 → 0.1.5

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.
@@ -0,0 +1,774 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { useRef, useEffect, useState, useReducer, useCallback, useMemo } from "react";
3
+ import { Link, List, Information } from "@strapi/icons";
4
+ import { useFetchClient, unstable_useContentManagerContext } from "@strapi/strapi/admin";
5
+ import { Box, Tooltip as Tooltip$1, Typography, Flex, Field, Checkbox, Divider, Link as Link$1 } from "@strapi/design-system";
6
+ const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
7
+ const v = glob[path];
8
+ if (v) {
9
+ return typeof v === "function" ? v() : Promise.resolve(v);
10
+ }
11
+ return new Promise((_, reject) => {
12
+ (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
13
+ reject.bind(
14
+ null,
15
+ new Error(
16
+ "Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
17
+ )
18
+ )
19
+ );
20
+ });
21
+ };
22
+ const version = "0.1.4";
23
+ const keywords = [];
24
+ const type = "commonjs";
25
+ const exports = {
26
+ "./package.json": "./package.json",
27
+ "./strapi-admin": {
28
+ types: "./dist/admin/src/index.d.ts",
29
+ source: "./admin/src/index.tsx",
30
+ "import": "./dist/admin/index.mjs",
31
+ require: "./dist/admin/index.js",
32
+ "default": "./dist/admin/index.js"
33
+ },
34
+ "./strapi-server": {
35
+ types: "./dist/server/src/index.d.ts",
36
+ source: "./server/src/index.ts",
37
+ "import": "./dist/server/index.mjs",
38
+ require: "./dist/server/index.js",
39
+ "default": "./dist/server/index.js"
40
+ }
41
+ };
42
+ const files = [
43
+ "dist"
44
+ ];
45
+ const scripts = {
46
+ build: "strapi-plugin build && yalc push --publish",
47
+ watch: "strapi-plugin watch",
48
+ "watch:link": "strapi-plugin watch:link",
49
+ verify: "strapi-plugin verify",
50
+ "test:ts:front": "tsc -p admin/tsconfig.json",
51
+ "test:ts:back": "tsc -p server/tsconfig.json",
52
+ "test:jest": "ENV_PATH=./playground/.env jest --verbose --runInBand --forceExit",
53
+ "test:cypress": "cypress run",
54
+ "test:cypress:open": "cypress open",
55
+ "playground:install": "yarn playground:yalc-add-link && cd playground && yarn install",
56
+ "playground:yalc-add": "cd playground && yalc add strapi-plugin-boilerplate",
57
+ "playground:yalc-add-link": "cd playground && yalc add --link strapi-plugin-boilerplate",
58
+ "playground:build": "cd playground && yarn build",
59
+ "playground:develop": "cd playground && yarn develop",
60
+ "playground:start": "cd playground && yarn start"
61
+ };
62
+ const dependencies = {
63
+ "@dnd-kit/core": "^6.3.1",
64
+ "@dnd-kit/sortable": "^10.0.0",
65
+ "@dnd-kit/utilities": "^3.2.2",
66
+ "@strapi/design-system": "^2.0.0-rc.14",
67
+ "@strapi/icons": "^2.0.0-rc.14",
68
+ "react-intl": "^7.1.0"
69
+ };
70
+ const devDependencies = {
71
+ "@strapi/sdk-plugin": "^5.0.0",
72
+ "@strapi/strapi": "^5.0.0",
73
+ "@strapi/typescript-utils": "^5.0.0",
74
+ "@types/react": "^19.0.0",
75
+ "@types/react-dom": "^19.0.0",
76
+ cypress: "^13.9.0",
77
+ "cypress-terminal-report": "^6.0.2",
78
+ jest: "^29.7.0",
79
+ prettier: "^3.4.2",
80
+ react: "^19.0.0",
81
+ "react-router-dom": "^6.0.0",
82
+ supertest: "^7.0.0",
83
+ typescript: "^5.7.2"
84
+ };
85
+ const peerDependencies = {
86
+ "@strapi/strapi": "^5.0.0",
87
+ react: "^17.0.0 || ^18.0.0",
88
+ "react-dom": "^17.0.0 || ^18.0.0",
89
+ "react-router-dom": "^6.0.0",
90
+ "styled-components": "^6.0.0"
91
+ };
92
+ const description = "A strapi plugin to manage URL routes and navigations.";
93
+ const strapi = {
94
+ name: "webatlas",
95
+ displayName: "Webatlas",
96
+ description: "A strapi plugin to manage URL routes and navigations.",
97
+ kind: "plugin"
98
+ };
99
+ const name = "@mattisvensson/strapi-plugin-webatlas";
100
+ const license = "MIT";
101
+ const repository = {
102
+ type: "git",
103
+ url: "git+ssh://git@github.com:mattisvensson/strapi-plugin-webatlas.git"
104
+ };
105
+ const bugs = {
106
+ url: "https://github.com/mattisvensson/strapi-plugin-webatlas/issues"
107
+ };
108
+ const homepage = "https://github.com/mattisvensson/strapi-plugin-webatlas#readme";
109
+ const author = {
110
+ name: "Matti Svensson",
111
+ email: "mattisvensson@web.de",
112
+ url: "https://mattisvensson.dev"
113
+ };
114
+ const maintainers = [
115
+ {
116
+ name: "Matti Svensson",
117
+ email: "mattisvensson@web.de",
118
+ url: "https://mattisvensson.dev"
119
+ }
120
+ ];
121
+ const packageManager = "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e";
122
+ const pluginPkg = {
123
+ version,
124
+ keywords,
125
+ type,
126
+ exports,
127
+ files,
128
+ scripts,
129
+ dependencies,
130
+ devDependencies,
131
+ peerDependencies,
132
+ description,
133
+ strapi,
134
+ name,
135
+ license,
136
+ repository,
137
+ bugs,
138
+ homepage,
139
+ author,
140
+ maintainers,
141
+ packageManager
142
+ };
143
+ const PLUGIN_ID = pluginPkg.strapi.name.replace(/^(@[^-,.][\w,-]+\/|strapi-)plugin-/i, "") || "webatlas";
144
+ const Initializer = ({ setPlugin }) => {
145
+ const ref = useRef(setPlugin);
146
+ useEffect(() => {
147
+ ref.current(PLUGIN_ID);
148
+ }, []);
149
+ return null;
150
+ };
151
+ const RouteIcon = () => /* @__PURE__ */ jsx(Link, {});
152
+ const NavigationIcon = () => /* @__PURE__ */ jsx(List, {});
153
+ function useApi() {
154
+ const { get, post, put, del } = useFetchClient();
155
+ const fetchAllContentTypes = async () => {
156
+ const { data } = await get("/content-manager/content-types");
157
+ return data.data;
158
+ };
159
+ const fetchAllEntities = async (contentTypes) => {
160
+ try {
161
+ if (!contentTypes) {
162
+ const { data } = await get("/webatlas/config");
163
+ contentTypes = data?.selectedContentTypes || [];
164
+ }
165
+ const allContentTypes = await fetchAllContentTypes();
166
+ let entities = [];
167
+ if (contentTypes && contentTypes.length > 0) {
168
+ entities = await Promise.all(
169
+ contentTypes.map(async (contentType) => {
170
+ const { data } = await get(`/content-manager/collection-types/${contentType.uid}`);
171
+ const entity = allContentTypes.find((ct) => ct.uid === contentType.uid);
172
+ if (!entity) {
173
+ throw new Error(`Content type ${contentType} not found`);
174
+ }
175
+ return {
176
+ entities: data.results,
177
+ label: entity.info.displayName,
178
+ contentType
179
+ };
180
+ })
181
+ );
182
+ }
183
+ return entities;
184
+ } catch (err) {
185
+ console.error(err);
186
+ throw err;
187
+ }
188
+ };
189
+ const getRouteByRelated = async (relatedDocumentId, populate) => {
190
+ const { data } = await get(`/content-manager/collection-types/plugin::webatlas.route?filters[relatedDocumentId][$eq]=${relatedDocumentId}${populate ? "&populate" + populate : ""}`);
191
+ if (data?.results) return data.results[0];
192
+ return null;
193
+ };
194
+ const createExternalRoute = async (body) => {
195
+ const { data } = await post("/webatlas/route/external", {
196
+ data: {
197
+ ...body
198
+ }
199
+ });
200
+ return data;
201
+ };
202
+ const getRoutes = async () => {
203
+ const { data } = await get("/webatlas/route");
204
+ return data;
205
+ };
206
+ const updateRoute = async (body, documentId) => {
207
+ const { data } = await put(`/webatlas/route?documentId=${documentId}`, {
208
+ data: {
209
+ ...body
210
+ }
211
+ });
212
+ return data;
213
+ };
214
+ const createNavItem = async (body) => {
215
+ const { data } = await post("/webatlas/navitem", {
216
+ data: {
217
+ ...body
218
+ }
219
+ });
220
+ return data;
221
+ };
222
+ const updateNavItem = async (documentId, body) => {
223
+ const { data } = await put(`/webatlas/navitem?documentId=${documentId}`, {
224
+ data: {
225
+ ...body
226
+ }
227
+ });
228
+ return data;
229
+ };
230
+ const deleteNavItem = async (documentId) => {
231
+ const { data } = await del(`/webatlas/navitem?documentId=${documentId}`);
232
+ return data;
233
+ };
234
+ const getStructuredNavigation = async (documentId, variant = "nested") => {
235
+ const { data } = await get(`/webatlas/navigation?documentId=${documentId}&variant=${variant}`);
236
+ return data;
237
+ };
238
+ const deleteNavigation = async (documentId) => {
239
+ const { data } = await del(`/webatlas/navigation?documentId=${documentId}`);
240
+ return data;
241
+ };
242
+ const updateNavigation = async (documentId, body) => {
243
+ const { data } = await put(`/webatlas/navigation?documentId=${documentId}`, {
244
+ data: body
245
+ });
246
+ return data;
247
+ };
248
+ return { fetchAllContentTypes, fetchAllEntities, getRouteByRelated, createExternalRoute, getRoutes, updateRoute, createNavItem, updateNavItem, deleteNavItem, getStructuredNavigation, deleteNavigation, updateNavigation };
249
+ }
250
+ const useAllContentTypes = () => {
251
+ const { fetchAllContentTypes } = useApi();
252
+ const [contentTypes, setContentTypes] = useState([]);
253
+ const [loading, setLoading] = useState(true);
254
+ const [error, setError] = useState(null);
255
+ useEffect(() => {
256
+ const fetchEntities = async () => {
257
+ try {
258
+ const result = await fetchAllContentTypes();
259
+ setContentTypes(result);
260
+ setLoading(false);
261
+ } catch (err) {
262
+ setError(err);
263
+ setLoading(false);
264
+ }
265
+ };
266
+ fetchEntities();
267
+ }, []);
268
+ return { contentTypes, loading, error };
269
+ };
270
+ function usePluginConfig() {
271
+ const { put, get } = useFetchClient();
272
+ const [data, setData] = useState(null);
273
+ const [loading, setLoading] = useState(false);
274
+ const [error, setError] = useState(null);
275
+ useEffect(() => {
276
+ const fetchData = async () => {
277
+ setLoading(true);
278
+ try {
279
+ const { data: { data: contentTypesArray } } = await get("/content-manager/content-types");
280
+ let { data: config } = await get("/webatlas/config");
281
+ if (!config || !config.selectedContentTypes) {
282
+ throw new Error(`HTTP error! Couldn't fetch plugin config`);
283
+ }
284
+ const allowedContentTypes = contentTypesArray.filter(
285
+ (type2) => type2.pluginOptions?.webatlas?.active === true
286
+ );
287
+ const contentTypeUids = new Set(allowedContentTypes.map((type2) => type2.uid));
288
+ const activeContentTypes = config.selectedContentTypes.filter((type2) => contentTypeUids.has(type2.uid));
289
+ if (JSON.stringify(activeContentTypes) !== JSON.stringify(config.selectedContentTypes)) {
290
+ config = { ...config, selectedContentTypes: activeContentTypes };
291
+ setConfig(config);
292
+ }
293
+ setData(config);
294
+ setLoading(false);
295
+ } catch (error2) {
296
+ setError(error2.message);
297
+ setLoading(false);
298
+ }
299
+ };
300
+ fetchData();
301
+ }, []);
302
+ async function setConfig(body) {
303
+ try {
304
+ await put("/webatlas/config", {
305
+ ...body
306
+ });
307
+ } catch (error2) {
308
+ setError(error2.message);
309
+ }
310
+ }
311
+ return { data, loading, error, setConfig };
312
+ }
313
+ function transformToUrl(input) {
314
+ const specialCharMap = {
315
+ "ü": "ue",
316
+ "ä": "ae",
317
+ "ö": "oe"
318
+ };
319
+ if (!input || typeof input !== "string") return "";
320
+ input = input.toLowerCase();
321
+ input = input.replace(/\/+/g, "/");
322
+ input = input.startsWith("/") ? input.slice(1) : input;
323
+ input = input.endsWith("/") ? input.slice(0, -1) : input;
324
+ for (const char in specialCharMap) {
325
+ const regex = new RegExp(char, "g");
326
+ input = input.replace(regex, specialCharMap[char]);
327
+ }
328
+ input = input.trim();
329
+ input = input.replace(/\s+/g, "-");
330
+ input = input.replace(/[^A-Za-z0-9$\-_.+!*'()/]/g, "");
331
+ input = input.replace(/-+/g, "-");
332
+ return input;
333
+ }
334
+ function Tooltip({ description: description2 }) {
335
+ return /* @__PURE__ */ jsx(Box, { paddingLeft: 1, paddingRight: 1, children: /* @__PURE__ */ jsx(Tooltip$1, { description: description2, children: /* @__PURE__ */ jsx(Information, { "aria-hidden": "true" }) }) });
336
+ }
337
+ function debounce(func, wait) {
338
+ let timeout;
339
+ return function executedFunction(...args) {
340
+ const later = () => {
341
+ clearTimeout(timeout);
342
+ func(...args);
343
+ };
344
+ clearTimeout(timeout);
345
+ timeout = setTimeout(later, wait);
346
+ };
347
+ }
348
+ function URLInfo({ validationState, replacement }) {
349
+ if (validationState === "initial") return null;
350
+ let color = "neutral800";
351
+ let text = "Checking if URL is available...";
352
+ if (validationState === "checking") {
353
+ color = "neutral800";
354
+ text = "Checking if URL is available...";
355
+ } else if (validationState === "done") {
356
+ color = replacement ? "danger500" : "success500";
357
+ text = replacement ? `URL is not available. Replaced with "${replacement}".` : "URL is available";
358
+ }
359
+ return /* @__PURE__ */ jsx(Box, { paddingTop: 2, children: /* @__PURE__ */ jsx(Typography, { textColor: color, children: text }) });
360
+ }
361
+ async function duplicateCheck(url, routeDocumentId) {
362
+ if (!url) throw new Error("URL is required");
363
+ try {
364
+ const res = await fetch(`/webatlas/checkUniquePath?path=${transformToUrl(url)}${routeDocumentId ? `&targetRouteDocumentId=${routeDocumentId}` : ""}`);
365
+ if (!res.ok) throw new Error(`Network response was not ok: ${res.status} ${res.statusText}`);
366
+ return await res.text();
367
+ } catch (err) {
368
+ console.error("Error in duplicateCheck:", err);
369
+ throw new Error("Failed to check URL uniqueness");
370
+ }
371
+ }
372
+ function reducer(state, action) {
373
+ switch (action.type) {
374
+ case "DEFAULT":
375
+ return {
376
+ ...state,
377
+ value: transformToUrl(action.payload),
378
+ prevValue: state.value,
379
+ needsUrlCheck: true
380
+ };
381
+ case "NO_URL_CHECK":
382
+ return {
383
+ ...state,
384
+ value: transformToUrl(action.payload),
385
+ prevValue: state.value,
386
+ needsUrlCheck: false
387
+ };
388
+ case "NO_TRANSFORM_AND_CHECK":
389
+ return {
390
+ ...state,
391
+ value: action.payload,
392
+ prevValue: state.value,
393
+ needsUrlCheck: false
394
+ };
395
+ case "RESET_URL_CHECK_FLAG":
396
+ return { ...state, needsUrlCheck: false };
397
+ case "SET_UIDPATH":
398
+ return { ...state, uIdPath: action.payload };
399
+ case "SET_DOCUMENTIDPATH":
400
+ return { ...state, documentIdPath: action.payload };
401
+ default:
402
+ throw new Error();
403
+ }
404
+ }
405
+ const Alias = ({ config }) => {
406
+ const { layout, form } = unstable_useContentManagerContext();
407
+ const { initialValues, values, onChange } = form;
408
+ const { getRouteByRelated } = useApi();
409
+ const [routeId, setRouteId] = useState();
410
+ const [isOverride, setIsOverride] = useState(false);
411
+ const [validationState, setValidationState] = useState("initial");
412
+ const [replacement, setReplacement] = useState("");
413
+ const [initialLoadComplete, setInitialLoadComplete] = useState(false);
414
+ const [path, dispatchPath] = useReducer(reducer, {
415
+ needsUrlCheck: false,
416
+ value: "",
417
+ prevValue: "",
418
+ uIdPath: ""
419
+ });
420
+ const hasUserChangedField = useRef(false);
421
+ const initialPath = useRef("");
422
+ const prevValueRef = useRef(null);
423
+ if (!config) return null;
424
+ const debouncedCheckUrl = useCallback(debounce(checkUrl, 500), []);
425
+ useEffect(() => {
426
+ onChange("webatlas_path", path.value);
427
+ onChange("webatlas_override", isOverride);
428
+ }, [path.value, routeId, isOverride]);
429
+ const debouncedValueEffect = useMemo(
430
+ () => debounce((currentValues) => {
431
+ const key = config?.default;
432
+ if (!key) return;
433
+ const currentValue = currentValues[key];
434
+ if (!currentValue) {
435
+ dispatchPath({ type: "NO_URL_CHECK", payload: "" });
436
+ return;
437
+ }
438
+ if (initialLoadComplete && (hasUserChangedField.current || !routeId) && prevValueRef.current !== currentValue && !isOverride) {
439
+ const path2 = config.pattern ? `${config.pattern}/${currentValue}` : `${currentValue}`;
440
+ if (currentValue === initialValues[key]) {
441
+ dispatchPath({ type: "NO_URL_CHECK", payload: path2 });
442
+ } else {
443
+ dispatchPath({ type: "DEFAULT", payload: path2 });
444
+ }
445
+ prevValueRef.current = currentValue;
446
+ }
447
+ }, 500),
448
+ [config?.default, config?.pattern, initialValues, isOverride, initialLoadComplete, routeId]
449
+ );
450
+ useEffect(() => {
451
+ if (!initialLoadComplete) return;
452
+ const key = config?.default;
453
+ if (!key) return;
454
+ const currentValue = values[key];
455
+ const initialValue = initialValues[key];
456
+ if (currentValue !== initialValue) {
457
+ hasUserChangedField.current = true;
458
+ }
459
+ debouncedValueEffect(values);
460
+ }, [values, debouncedValueEffect, initialLoadComplete]);
461
+ useEffect(() => {
462
+ if (path.needsUrlCheck && path.value) {
463
+ if (path.uIdPath === path.value || initialPath.current === path.value) return;
464
+ debouncedCheckUrl(path.value);
465
+ dispatchPath({ type: "RESET_URL_CHECK_FLAG" });
466
+ }
467
+ }, [path.needsUrlCheck]);
468
+ useEffect(() => {
469
+ async function getTypes() {
470
+ if (!initialValues.documentId) {
471
+ setInitialLoadComplete(true);
472
+ return;
473
+ }
474
+ try {
475
+ const route = await getRouteByRelated(initialValues.documentId);
476
+ if (!route) return;
477
+ initialPath.current = initialValues.webatlas_path || route.uIdPath;
478
+ setRouteId(route.id);
479
+ setIsOverride(route.isOverride || false);
480
+ dispatchPath({ type: "NO_TRANSFORM_AND_CHECK", payload: route.fullPath || "" });
481
+ dispatchPath({ type: "SET_UIDPATH", payload: route.uidPath || "" });
482
+ dispatchPath({ type: "SET_DOCUMENTIDPATH", payload: route.documentIdPath || "" });
483
+ const key = config?.default;
484
+ if (key) {
485
+ prevValueRef.current = values[key];
486
+ }
487
+ } catch (err) {
488
+ setRouteId(null);
489
+ console.log(err);
490
+ }
491
+ setInitialLoadComplete(true);
492
+ }
493
+ getTypes();
494
+ }, [config]);
495
+ useEffect(() => {
496
+ if (initialValues.webatlas_path) dispatchPath({ type: "NO_URL_CHECK", payload: initialValues.webatlas_path });
497
+ if (initialValues.webatlas_override) setIsOverride(initialValues.webatlas_override);
498
+ }, []);
499
+ async function checkUrl(url) {
500
+ if (!url) return;
501
+ setValidationState("checking");
502
+ setReplacement("");
503
+ try {
504
+ const data = await duplicateCheck(url);
505
+ if (!data || data === url) return;
506
+ dispatchPath({ type: "NO_URL_CHECK", payload: data });
507
+ setReplacement(data);
508
+ } catch (err) {
509
+ console.log(err);
510
+ } finally {
511
+ setValidationState("done");
512
+ }
513
+ }
514
+ return /* @__PURE__ */ jsx(
515
+ Box,
516
+ {
517
+ as: "aside",
518
+ "aria-labelledby": "URL Route",
519
+ width: "100%",
520
+ children: /* @__PURE__ */ jsxs(
521
+ Flex,
522
+ {
523
+ direction: "column",
524
+ alignItems: "stretch",
525
+ gap: 4,
526
+ children: [
527
+ /* @__PURE__ */ jsxs(Box, { children: [
528
+ /* @__PURE__ */ jsxs(Field.Root, { hint: !initialValues.id && !config.default ? "[id] will be replaced with the entry ID" : "", children: [
529
+ /* @__PURE__ */ jsxs(Field.Label, { children: [
530
+ "URL",
531
+ /* @__PURE__ */ jsx(Tooltip, { description: "The following characters are valid: A-Z, a-z, 0-9, /, -, _, $, ., +, !, *, ', (, )" })
532
+ ] }),
533
+ /* @__PURE__ */ jsx(
534
+ Field.Input,
535
+ {
536
+ id: "url-input",
537
+ value: path.value,
538
+ placeholder: config.default ? `Edit the "${config.default}" field to generate a URL` : `${layout.list.settings.displayName?.toLowerCase()}/[id]`,
539
+ onChange: (e) => dispatchPath({ type: "NO_TRANSFORM_AND_CHECK", payload: e.target.value }),
540
+ disabled: !isOverride,
541
+ onBlur: (e) => {
542
+ if (e.target.value === path.prevValue) return;
543
+ dispatchPath({ type: "DEFAULT", payload: e.target.value });
544
+ }
545
+ }
546
+ ),
547
+ /* @__PURE__ */ jsx(Field.Hint, {})
548
+ ] }),
549
+ /* @__PURE__ */ jsx(URLInfo, { validationState, replacement }),
550
+ /* @__PURE__ */ jsx(
551
+ Flex,
552
+ {
553
+ gap: 2,
554
+ paddingTop: 2,
555
+ children: /* @__PURE__ */ jsx(
556
+ Checkbox,
557
+ {
558
+ id: "override-url",
559
+ checked: isOverride,
560
+ onCheckedChange: () => setIsOverride((prev) => !prev),
561
+ children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: "Override generated URL" })
562
+ }
563
+ )
564
+ }
565
+ )
566
+ ] }),
567
+ path.uIdPath && path.documentIdPath && /* @__PURE__ */ jsxs(Fragment, { children: [
568
+ /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Divider, {}) }),
569
+ /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(
570
+ Field.Root,
571
+ {
572
+ hint: "Permanent UID path, cannot be changed.",
573
+ label: "UID path",
574
+ children: [
575
+ /* @__PURE__ */ jsx(Field.Label, {}),
576
+ /* @__PURE__ */ jsx(
577
+ Field.Input,
578
+ {
579
+ value: path.uIdPath,
580
+ disabled: true
581
+ }
582
+ ),
583
+ /* @__PURE__ */ jsx(Field.Hint, {})
584
+ ]
585
+ }
586
+ ) }),
587
+ /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(
588
+ Field.Root,
589
+ {
590
+ hint: "Permanent DocumentID path, cannot be changed.",
591
+ label: "DocumentID path",
592
+ children: [
593
+ /* @__PURE__ */ jsx(Field.Label, {}),
594
+ /* @__PURE__ */ jsx(
595
+ Field.Input,
596
+ {
597
+ value: path.documentIdPath,
598
+ disabled: true
599
+ }
600
+ ),
601
+ /* @__PURE__ */ jsx(Field.Hint, {})
602
+ ]
603
+ }
604
+ ) })
605
+ ] })
606
+ ]
607
+ }
608
+ )
609
+ }
610
+ );
611
+ };
612
+ const CMEditViewAside = () => {
613
+ const { model } = unstable_useContentManagerContext();
614
+ const { contentTypes } = useAllContentTypes();
615
+ const { data: config } = usePluginConfig();
616
+ const [contentTypeConfig, setContentTypeConfig] = useState(null);
617
+ const [isAllowedContentType, setIsAllowedContentType] = useState(false);
618
+ const [isActiveContentType, setIsActiveContentType] = useState(false);
619
+ const [isLoading, setIsLoading] = useState(true);
620
+ useEffect(() => {
621
+ if (!config) return;
622
+ const contentType = contentTypes?.find((ct) => ct.uid === model);
623
+ if (contentType?.pluginOptions?.webatlas?.active) setIsAllowedContentType(true);
624
+ config?.selectedContentTypes?.map((type2) => {
625
+ if (type2.uid === model) {
626
+ setIsActiveContentType(true);
627
+ setContentTypeConfig(type2);
628
+ }
629
+ });
630
+ setIsLoading(false);
631
+ }, [config]);
632
+ useEffect(() => {
633
+ const label = Array.from(document.querySelectorAll("label")).find((l) => l.textContent?.startsWith("webatlas_path"));
634
+ if (label) {
635
+ let parentDiv = label.closest("div");
636
+ for (let i = 0; i < 2; i++) {
637
+ if (parentDiv) {
638
+ parentDiv = parentDiv.parentElement;
639
+ }
640
+ }
641
+ if (parentDiv) {
642
+ const grandParentDiv = parentDiv.parentElement;
643
+ if (grandParentDiv && grandParentDiv.children.length === 1) {
644
+ grandParentDiv.parentElement?.remove();
645
+ return;
646
+ } else {
647
+ parentDiv.remove();
648
+ }
649
+ }
650
+ }
651
+ }, []);
652
+ if (isLoading) return /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: "Loading..." });
653
+ if (!isAllowedContentType) return /* @__PURE__ */ jsxs(Typography, { textColor: "neutral600", children: [
654
+ "This content type is not allowed for ",
655
+ /* @__PURE__ */ jsx("strong", { children: "WebAtlas" }),
656
+ ". If you wish to use it, please contact your administrator."
657
+ ] });
658
+ if (!isActiveContentType || !contentTypeConfig) return /* @__PURE__ */ jsxs(Typography, { textColor: "neutral600", children: [
659
+ "This content type is not configured for ",
660
+ /* @__PURE__ */ jsx("strong", { children: "WebAtlas" }),
661
+ ". If you wish to use it, please configure it in the",
662
+ /* @__PURE__ */ jsx(Link$1, { href: "/admin/settings/webatlas/configuration", marginLeft: 1, children: "settings" }),
663
+ "."
664
+ ] });
665
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Alias, { config: contentTypeConfig }) });
666
+ };
667
+ const index = {
668
+ register(app) {
669
+ app.addMenuLink({
670
+ to: `/plugins/${PLUGIN_ID}/routes`,
671
+ icon: RouteIcon,
672
+ intlLabel: {
673
+ id: `${PLUGIN_ID}.link.routes`,
674
+ defaultMessage: "Routes"
675
+ },
676
+ Component: async () => {
677
+ const component = await import("./index-CbPRyhDU.mjs");
678
+ return { default: component.default };
679
+ },
680
+ permissions: [
681
+ // Uncomment to set the permissions of the plugin here
682
+ // {
683
+ // action: '', // the action name should be plugin::plugin-name.actionType
684
+ // subject: null,
685
+ // },
686
+ ]
687
+ });
688
+ app.addMenuLink({
689
+ to: `/plugins/${PLUGIN_ID}/navigation`,
690
+ icon: NavigationIcon,
691
+ intlLabel: {
692
+ id: `${PLUGIN_ID}.link.navigation`,
693
+ defaultMessage: "Navigation"
694
+ },
695
+ Component: async () => {
696
+ const component = await import("./index-BzxYSqKz.mjs");
697
+ return { default: component.default };
698
+ },
699
+ permissions: [
700
+ // Uncomment to set the permissions of the plugin here
701
+ // {
702
+ // action: '', // the action name should be plugin::plugin-name.actionType
703
+ // subject: null,
704
+ // },
705
+ ]
706
+ });
707
+ app.addSettingsLink(
708
+ {
709
+ id: PLUGIN_ID,
710
+ intlLabel: {
711
+ id: `${PLUGIN_ID}.settings.section`,
712
+ defaultMessage: "Webatlas"
713
+ }
714
+ },
715
+ {
716
+ intlLabel: {
717
+ id: `${PLUGIN_ID}.settings.section`,
718
+ defaultMessage: "Configuration"
719
+ },
720
+ id: PLUGIN_ID,
721
+ to: `/settings/${PLUGIN_ID}/configuration`,
722
+ Component: async () => {
723
+ return await import(
724
+ /* webpackChunkName: "webatlas-settings-page" */
725
+ "./index-Bc-aOuSa.mjs"
726
+ );
727
+ },
728
+ permissions: [
729
+ // Uncomment to set the permissions of the plugin here
730
+ // {
731
+ // action: '', // the action name should be plugin::plugin-name.actionType
732
+ // subject: null,
733
+ // },
734
+ ]
735
+ }
736
+ );
737
+ app.registerPlugin({
738
+ id: PLUGIN_ID,
739
+ initializer: Initializer,
740
+ isReady: false,
741
+ name: PLUGIN_ID
742
+ });
743
+ },
744
+ bootstrap(app) {
745
+ app.getPlugin("content-manager").apis.addEditViewSidePanel([() => ({
746
+ title: "URL Alias",
747
+ content: /* @__PURE__ */ jsx(CMEditViewAside, {})
748
+ })]);
749
+ },
750
+ async registerTrads({ locales }) {
751
+ return Promise.all(
752
+ locales.map(async (locale) => {
753
+ try {
754
+ const { default: data } = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-Byx4XI2L.mjs") }), `./translations/${locale}.json`, 3);
755
+ return { data, locale };
756
+ } catch {
757
+ return { data: {}, locale };
758
+ }
759
+ })
760
+ );
761
+ }
762
+ };
763
+ export {
764
+ Tooltip as T,
765
+ URLInfo as U,
766
+ duplicateCheck as a,
767
+ usePluginConfig as b,
768
+ useAllContentTypes as c,
769
+ debounce as d,
770
+ index as i,
771
+ transformToUrl as t,
772
+ useApi as u
773
+ };
774
+ //# sourceMappingURL=index-ByHbLuYL.mjs.map